File protobuf-6c92f9dff1807c142edf6780d775b58a3b078591.patch of Package protobuf.26315

From 6c92f9dff1807c142edf6780d775b58a3b078591 Mon Sep 17 00:00:00 2001
From: Rafi Kamal <rafikamal@google.com>
Date: Fri, 11 Oct 2019 12:05:46 -0700
Subject: [PATCH] Down integrate to GitHub

---
 java/core/src/main/java/com/google/protobuf/ExtensionRegistryFactory.java |   38 -
 java/core/src/main/java/com/google/protobuf/ExtensionRegistryLite.java    |   24 
 java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java     |   25 
 java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java       |  291 ----------
 java/core/src/main/java/com/google/protobuf/RopeByteString.java           |   21 
 java/core/src/test/java/com/google/protobuf/GeneratedMessageTest.java     |   34 -
 java/core/src/test/java/com/google/protobuf/LiteralByteStringTest.java    |    7 
 src/google/protobuf/compiler/java/java_enum_field_lite.cc                 |   22 
 src/google/protobuf/compiler/java/java_file.cc                            |    1 
 src/google/protobuf/compiler/java/java_map_field_lite.cc                  |   10 
 src/google/protobuf/compiler/java/java_message.cc                         |    3 
 src/google/protobuf/compiler/java/java_message_field_lite.cc              |   90 ---
 src/google/protobuf/compiler/java/java_primitive_field_lite.cc            |    7 
 src/google/protobuf/compiler/java/java_string_field_lite.cc               |   20 
 14 files changed, 130 insertions(+), 463 deletions(-)

--- a/java/core/src/main/java/com/google/protobuf/ExtensionRegistryFactory.java
+++ b/java/core/src/main/java/com/google/protobuf/ExtensionRegistryFactory.java
@@ -59,26 +59,16 @@ final class ExtensionRegistryFactory {
 
   /** Construct a new, empty instance. */
   public static ExtensionRegistryLite create() {
-    if (EXTENSION_REGISTRY_CLASS != null) {
-      try {
-        return invokeSubclassFactory("newInstance");
-      } catch (Exception e) {
-        // return a Lite registry.
-      }
-    }
-    return new ExtensionRegistryLite();
+    ExtensionRegistryLite result = invokeSubclassFactory("newInstance");
+
+    return result != null ? result : new ExtensionRegistryLite();
   }
 
   /** Get the unmodifiable singleton empty instance. */
   public static ExtensionRegistryLite createEmpty() {
-    if (EXTENSION_REGISTRY_CLASS != null) {
-      try {
-        return invokeSubclassFactory("getEmptyRegistry");
-      } catch (Exception e) {
-        // return a Lite registry.
-      }
-    }
-    return EMPTY_REGISTRY_LITE;
+    ExtensionRegistryLite result = invokeSubclassFactory("getEmptyRegistry");
+
+    return result != null ? result : EMPTY_REGISTRY_LITE;
   }
 
 
@@ -87,9 +77,17 @@ final class ExtensionRegistryFactory {
         && EXTENSION_REGISTRY_CLASS.isAssignableFrom(registry.getClass());
   }
 
-  private static final ExtensionRegistryLite invokeSubclassFactory(String methodName)
-      throws Exception {
-    return (ExtensionRegistryLite)
-        EXTENSION_REGISTRY_CLASS.getDeclaredMethod(methodName).invoke(null);
+  /* @Nullable */
+  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;
+    }
   }
 }
--- a/java/core/src/main/java/com/google/protobuf/ExtensionRegistryLite.java
+++ b/java/core/src/main/java/com/google/protobuf/ExtensionRegistryLite.java
@@ -83,19 +83,21 @@ public class ExtensionRegistryLite {
   // Visible for testing.
   static final String EXTENSION_CLASS_NAME = "com.google.protobuf.Extension";
 
-  /* @Nullable */
-  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;
+  private static class ExtensionClassHolder {
+    /* @Nullable */
+    static final Class<?> INSTANCE = resolveExtensionClass();
+
+    /* @Nullable */
+    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;
+      }
     }
   }
 
-  /* @Nullable */
-  private static final Class<?> extensionClass = resolveExtensionClass();
-
   public static boolean isEagerlyParseMessageSets() {
     return eagerlyParseMessageSets;
   }
@@ -175,7 +177,7 @@ public class ExtensionRegistryLite {
     }
     if (doFullRuntimeInheritanceCheck && ExtensionRegistryFactory.isFullRegistry(this)) {
       try {
-        this.getClass().getMethod("add", extensionClass).invoke(this, extension);
+        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);
--- a/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java
+++ b/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java
@@ -115,7 +115,8 @@ public abstract class GeneratedMessageLi
 
   @SuppressWarnings("unchecked") // Guaranteed by isInstance + runtime
   @Override
-  public boolean equals(Object other) {
+  public boolean equals(
+          Object other) {
     if (this == other) {
       return true;
     }
@@ -348,16 +349,20 @@ public abstract class GeneratedMessageLi
      * 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 void copyOnWrite() {
+    protected final void copyOnWrite() {
       if (isBuilt) {
-        MessageType newInstance =
-            (MessageType) instance.dynamicMethod(MethodToInvoke.NEW_MUTABLE_INSTANCE);
-        mergeFromInstance(newInstance, instance);
-        instance = newInstance;
+        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);
@@ -919,12 +924,8 @@ public abstract class GeneratedMessageLi
     }
 
     @Override
-    protected void copyOnWrite() {
-      if (!isBuilt) {
-        return;
-      }
-
-      super.copyOnWrite();
+    protected void copyOnWriteInternal() {
+      super.copyOnWriteInternal();
       instance.extensions = instance.extensions.clone();
     }
 
--- a/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java
+++ b/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java
@@ -58,8 +58,6 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.ObjectStreamException;
 import java.io.Serializable;
-import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodHandles;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
@@ -81,17 +79,11 @@ import java.util.TreeMap;
 public abstract class GeneratedMessageV3 extends AbstractMessage
     implements Serializable {
   private static final long serialVersionUID = 1L;
-  // Whether to use reflection for FieldAccessor
-  private static boolean forTestUseReflection = false;
-
-  static void setForTestUseReflection(boolean useReflection) {
-    forTestUseReflection = useReflection;
-  }
 
   /**
-   * For testing. Allows a test to disable the optimization that avoids using
-   * field builders for nested messages until they are requested. By disabling
-   * this optimization, existing tests can be reused to test the field builders.
+   * For testing. Allows a test to disable the optimization that avoids using field builders for
+   * nested messages until they are requested. By disabling this optimization, existing tests can be
+   * reused to test the field builders.
    */
   protected static boolean alwaysUseFieldBuilders = false;
 
@@ -1880,32 +1872,14 @@ public abstract class GeneratedMessageV3
     }
   }
 
-  /** Calls invoke and throws a RuntimeException if it fails. */
-  private static RuntimeException handleException(Throwable e) {
-    if (e instanceof ClassCastException) {
-      // Reflection throws a bad param type as an IllegalArgumentException, whereas MethodHandle
-      // throws it as a ClassCastException; convert for backwards compatibility
-      throw new IllegalArgumentException(e);
-    } else if (e instanceof RuntimeException) {
-      throw (RuntimeException) e;
-    } else if (e instanceof Error) {
-      throw (Error) e;
-    } else {
-      throw new RuntimeException(
-          "Unexpected exception thrown by generated accessor method.", e);
-    }
-  }
-
   /**
-   * Gets the map field with the given field number. This method should be
-   * overridden in the generated message class if the message contains map
-   * fields.
+   * Gets the map field with the given field number. This method should be overridden in the
+   * generated message class if the message contains map fields.
    *
-   * Unlike other field types, reflection support for map fields can't be
-   * implemented based on generated public API because we need to access a
-   * map field as a list in reflection API but the generated API only allows
-   * us to access it as a map. This method returns the underlying map field
-   * directly and thus enables us to access the map field as a list.
+   * <p>Unlike other field types, reflection support for map fields can't be implemented based on
+   * generated public API because we need to access a map field as a list in reflection API but the
+   * generated API only allows us to access it as a map. This method returns the underlying map
+   * field directly and thus enables us to access the map field as a list.
    */
   @SuppressWarnings({"rawtypes", "unused"})
   protected MapField internalGetMapField(int fieldNumber) {
@@ -2237,108 +2211,9 @@ public abstract class GeneratedMessageV3
         }
       }
 
-      private static final class MethodHandleInvoker implements MethodInvoker {
-        protected final MethodHandle getMethod;
-        protected final MethodHandle getMethodBuilder;
-        protected final MethodHandle setMethod;
-        protected final MethodHandle hasMethod;
-        protected final MethodHandle hasMethodBuilder;
-        protected final MethodHandle clearMethod;
-        protected final MethodHandle caseMethod;
-        protected final MethodHandle caseMethodBuilder;
-
-        MethodHandleInvoker(ReflectionInvoker accessor) throws IllegalAccessException {
-          MethodHandles.Lookup lookup = MethodHandles.publicLookup();
-
-          this.getMethod = lookup.unreflect(accessor.getMethod);
-          this.getMethodBuilder = lookup.unreflect(accessor.getMethodBuilder);
-          this.setMethod = lookup.unreflect(accessor.setMethod);
-          this.hasMethod =
-              (accessor.hasMethod != null) ? lookup.unreflect(accessor.hasMethod) : null;
-          this.hasMethodBuilder = (accessor.hasMethodBuilder != null)
-              ? lookup.unreflect(accessor.hasMethodBuilder) : null;
-          this.clearMethod = lookup.unreflect(accessor.clearMethod);
-          this.caseMethod =
-              (accessor.caseMethod != null) ? lookup.unreflect(accessor.caseMethod) : null;
-          this.caseMethodBuilder = (accessor.caseMethodBuilder != null)
-              ? lookup.unreflect(accessor.caseMethodBuilder) : null;
-        }
-
-        @Override
-        public Object get(final GeneratedMessageV3 message) {
-          try {
-            return getMethod.invoke(message);
-          } catch (Throwable e) {
-            throw handleException(e);
-          }
-        }
-
-        @Override
-        public Object get(GeneratedMessageV3.Builder<?> builder) {
-          try {
-            return getMethodBuilder.invoke(builder);
-          } catch (Throwable e) {
-            throw handleException(e);
-          }
-        }
-
-        @Override
-        public int getOneofFieldNumber(final GeneratedMessageV3 message) {
-          try {
-            return ((Internal.EnumLite) caseMethod.invoke(message)).getNumber();
-          } catch (Throwable e) {
-            throw handleException(e);
-          }
-        }
-
-        @Override
-        public int getOneofFieldNumber(final GeneratedMessageV3.Builder<?> builder) {
-          try {
-            return ((Internal.EnumLite) caseMethodBuilder.invoke(builder)).getNumber();
-          } catch (Throwable e) {
-            throw handleException(e);
-          }
-        }
-
-        @Override
-        public void set(final GeneratedMessageV3.Builder<?> builder, final Object value) {
-          try {
-            setMethod.invoke(builder, value);
-          } catch (Throwable e) {
-            throw handleException(e);
-          }
-        }
-
-        @Override
-        public boolean has(final GeneratedMessageV3 message) {
-          try {
-            return (Boolean) hasMethod.invoke(message);
-          } catch (Throwable e) {
-            throw handleException(e);
-          }
-        }
-
-        @Override
-        public boolean has(GeneratedMessageV3.Builder<?> builder) {
-          try {
-            return (Boolean) hasMethodBuilder.invoke(builder);
-          } catch (Throwable e) {
-            throw handleException(e);
-          }
-        }
-
-        @Override
-        public void clear(final GeneratedMessageV3.Builder<?> builder) {
-          try {
-            clearMethod.invoke(builder);
-          } catch (Throwable e) {
-            throw handleException(e);
-          }
-        }
-      }
-
       SingularFieldAccessor(
-          final FieldDescriptor descriptor, final String camelCaseName,
+          final FieldDescriptor descriptor,
+          final String camelCaseName,
           final Class<? extends GeneratedMessageV3> messageClass,
           final Class<? extends Builder> builderClass,
           final String containingOneofCamelCaseName) {
@@ -2356,23 +2231,11 @@ public abstract class GeneratedMessageV3
                 hasHasMethod);
         field = descriptor;
         type = reflectionInvoker.getMethod.getReturnType();
-        invoker = tryGetMethodHandleInvoke(reflectionInvoker);
+        invoker = getMethodInvoker(reflectionInvoker);
       }
 
-      static MethodInvoker tryGetMethodHandleInvoke(ReflectionInvoker accessor) {
-        if (forTestUseReflection) {
-          return accessor;
-        }
-        try {
-          return new MethodHandleInvoker(accessor);
-        } catch (NoClassDefFoundError e) {
-          // Fall back to reflection if MethodHandleInvoker isn't available,
-          // allowing clients that don't want to use method handles to opt out
-          // by deleting the class.
-          return accessor;
-        } catch (IllegalAccessException e) {
-          throw new RuntimeException(e);
-        }
+      static MethodInvoker getMethodInvoker(ReflectionInvoker accessor) {
+        return accessor;
       }
 
       // Note:  We use Java reflection to call public methods rather than
@@ -2581,114 +2444,6 @@ public abstract class GeneratedMessageV3
         }
       }
 
-      private static final class MethodHandleInvoker implements MethodInvoker {
-        protected final MethodHandle getMethod;
-        protected final MethodHandle getMethodBuilder;
-        protected final MethodHandle getRepeatedMethod;
-        protected final MethodHandle getRepeatedMethodBuilder;
-        protected final MethodHandle setRepeatedMethod;
-        protected final MethodHandle addRepeatedMethod;
-        protected final MethodHandle getCountMethod;
-        protected final MethodHandle getCountMethodBuilder;
-        protected final MethodHandle clearMethod;
-
-        MethodHandleInvoker(ReflectionInvoker accessor) throws IllegalAccessException {
-          MethodHandles.Lookup lookup = MethodHandles.lookup();
-
-          this.getMethod = lookup.unreflect(accessor.getMethod);
-          this.getMethodBuilder = lookup.unreflect(accessor.getMethodBuilder);
-          this.getRepeatedMethod = lookup.unreflect(accessor.getRepeatedMethod);
-          this.getRepeatedMethodBuilder = lookup.unreflect(accessor.getRepeatedMethodBuilder);
-          this.setRepeatedMethod = lookup.unreflect(accessor.setRepeatedMethod);
-          this.addRepeatedMethod = lookup.unreflect(accessor.addRepeatedMethod);
-          this.getCountMethod = lookup.unreflect(accessor.getCountMethod);
-          this.getCountMethodBuilder = lookup.unreflect(accessor.getCountMethodBuilder);
-          this.clearMethod = lookup.unreflect(accessor.clearMethod);
-        }
-
-        @Override
-        public Object get(final GeneratedMessageV3 message) {
-          try {
-            return getMethod.invoke(message);
-          } catch (Throwable e) {
-            throw handleException(e);
-          }
-        }
-
-        @Override
-        public Object get(GeneratedMessageV3.Builder<?> builder) {
-          try {
-            return getMethodBuilder.invoke(builder);
-          } catch (Throwable e) {
-            throw handleException(e);
-          }
-        }
-
-        @Override
-        public Object getRepeated(final GeneratedMessageV3 message, final int index) {
-          try {
-            return getRepeatedMethod.invoke(message, index);
-          } catch (Throwable e) {
-            throw handleException(e);
-          }
-        }
-
-        @Override
-        public Object getRepeated(GeneratedMessageV3.Builder<?> builder, int index) {
-          try {
-            return getRepeatedMethodBuilder.invoke(builder, index);
-          } catch (Throwable e) {
-            throw handleException(e);
-          }
-        }
-
-        @Override
-        public void setRepeated(
-            final GeneratedMessageV3.Builder<?> builder, final int index, final Object value) {
-          try {
-            setRepeatedMethod.invoke(builder, index, value);
-          } catch (Throwable e) {
-            throw handleException(e);
-          }
-        }
-
-        @Override
-        public void addRepeated(final GeneratedMessageV3.Builder<?> builder, final Object value) {
-          try {
-            addRepeatedMethod.invoke(builder, value);
-          } catch (Throwable e) {
-            throw handleException(e);
-          }
-        }
-
-        @Override
-        public int getRepeatedCount(final GeneratedMessageV3 message) {
-          try {
-            return (Integer) getCountMethod.invoke(message);
-          } catch (Throwable e) {
-            throw handleException(e);
-          }
-        }
-
-        @Override
-        public int getRepeatedCount(GeneratedMessageV3.Builder<?> builder) {
-          try {
-            return (Integer) getCountMethodBuilder.invoke(builder);
-          } catch (Throwable e) {
-            throw handleException(e);
-          }
-        }
-
-        @Override
-        public void clear(final GeneratedMessageV3.Builder<?> builder) {
-          try {
-            clearMethod.invoke(builder);
-          } catch (Throwable e) {
-            throw handleException(e);
-          }
-        }
-      }
-
       protected final Class type;
       protected final MethodInvoker invoker;
 
@@ -2699,23 +2454,11 @@ public abstract class GeneratedMessageV3
         ReflectionInvoker reflectionInvoker =
             new ReflectionInvoker(descriptor, camelCaseName, messageClass, builderClass);
         type = reflectionInvoker.getRepeatedMethod.getReturnType();
-        invoker = tryGetMethodHandleInvoke(reflectionInvoker);
+        invoker = getMethodInvoker(reflectionInvoker);
       }
 
-      static MethodInvoker tryGetMethodHandleInvoke(ReflectionInvoker accessor) {
-        if (forTestUseReflection) {
-          return accessor;
-        }
-        try {
-          return new MethodHandleInvoker(accessor);
-        } catch (NoClassDefFoundError e) {
-          // Fall back to reflection if MethodHandleInvoker isn't available,
-          // allowing clients that don't want to use method handles to opt out
-          // by deleting the class.
-          return accessor;
-        } catch (IllegalAccessException e) {
-          throw new RuntimeException(e);
-        }
+      static MethodInvoker getMethodInvoker(ReflectionInvoker accessor) {
+        return accessor;
       }
 
       @Override
--- a/java/core/src/main/java/com/google/protobuf/RopeByteString.java
+++ b/java/core/src/main/java/com/google/protobuf/RopeByteString.java
@@ -811,6 +811,16 @@ final class RopeByteString extends ByteS
       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) {
@@ -818,7 +828,12 @@ final class RopeByteString extends ByteS
       } else if (offset < 0 || length < 0 || length > b.length - offset) {
         throw new IndexOutOfBoundsException();
       }
-      return readSkipInternal(b, offset, length);
+      int bytesRead = readSkipInternal(b, offset, length);
+      if (bytesRead == 0) {
+        return -1;
+      } else {
+        return bytesRead;
+      }
     }
 
     @Override
@@ -845,10 +860,6 @@ final class RopeByteString extends ByteS
       while (bytesRemaining > 0) {
         advanceIfCurrentPieceFullyRead();
         if (currentPiece == null) {
-          if (bytesRemaining == length) {
-            // We didn't manage to read anything
-            return -1;
-          }
           break;
         } else {
           // Copy the bytes from this piece.
--- a/java/core/src/test/java/com/google/protobuf/GeneratedMessageTest.java
+++ b/java/core/src/test/java/com/google/protobuf/GeneratedMessageTest.java
@@ -69,7 +69,6 @@ import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
 import junit.framework.TestCase;
-import junit.framework.TestSuite;
 
 /**
  * Unit test for generated messages and generated code. See also {@link MessageTest}, which tests
@@ -81,37 +80,8 @@ public class GeneratedMessageTest extend
   TestUtil.ReflectionTester reflectionTester =
       new TestUtil.ReflectionTester(TestAllTypes.getDescriptor(), null);
 
-  public static TestSuite suite() {
-    TestSuite suite = new TestSuite();
-    suite.addTestSuite(ReflectionTest.class);
-    suite.addTestSuite(FastInvokeTest.class);
-    return suite;
-  }
-
-  public static class ReflectionTest extends GeneratedMessageTest {
-    public ReflectionTest() {
-      super(true);
-    }
-  }
-
-  public static class FastInvokeTest extends GeneratedMessageTest {
-    public FastInvokeTest() {
-      super(false);
-    }
-  }
-
-  private final boolean useReflection;
-
-  GeneratedMessageTest(boolean useReflection) {
-    this.useReflection = useReflection;
-  }
-
-  @Override public void setUp() {
-    GeneratedMessageV3.setForTestUseReflection(useReflection);
-  }
-
-  @Override public void tearDown() {
-    GeneratedMessageV3.setForTestUseReflection(false);
+  @Override
+  public void tearDown() {
     GeneratedMessageV3.setAlwaysUseFieldBuildersForTesting(false);
   }
 
--- a/java/core/src/test/java/com/google/protobuf/LiteralByteStringTest.java
+++ b/java/core/src/test/java/com/google/protobuf/LiteralByteStringTest.java
@@ -30,6 +30,8 @@
 
 package com.google.protobuf;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.io.EOFException;
@@ -516,6 +518,7 @@ public class LiteralByteStringTest exten
     InputStream input = stringUnderTest.newInput();
     int stringSize = stringUnderTest.size();
     int nearEndIndex = stringSize * 2 / 3;
+
     long skipped1 = input.skip(nearEndIndex);
     assertEquals("InputStream.skip()", skipped1, nearEndIndex);
     assertEquals("InputStream.available()", stringSize - skipped1, input.available());
@@ -524,10 +527,14 @@ public class LiteralByteStringTest exten
     assertEquals(
         "InputStream.skip(), read()", stringUnderTest.byteAt(nearEndIndex) & 0xFF, input.read());
     assertEquals("InputStream.available()", stringSize - skipped1 - 1, input.available());
+
     long skipped2 = input.skip(stringSize);
     assertEquals("InputStream.skip() incomplete", skipped2, stringSize - skipped1 - 1);
     assertEquals("InputStream.skip(), no more input", 0, input.available());
     assertEquals("InputStream.skip(), no more input", -1, input.read());
+    assertThat(input.skip(1)).isEqualTo(0);
+    assertThat(input.read(new byte[1], /* off= */ 0, /*len=*/ 0)).isEqualTo(-1);
+
     input.reset();
     assertEquals("InputStream.reset() succeded", stringSize - skipped1, input.available());
     assertEquals(
--- a/src/google/protobuf/compiler/java/java_enum_field_lite.cc
+++ b/src/google/protobuf/compiler/java/java_enum_field_lite.cc
@@ -117,6 +117,10 @@ void SetEnumVariables(const FieldDescrip
   } else {
     (*variables)["unknown"] = (*variables)["default"];
   }
+
+  // We use `x.getClass()` as a null check because it generates less bytecode
+  // than an `if (x == null) { throw ... }` statement.
+  (*variables)["null_check"] = "value.getClass();\n";
 }
 
 }  // namespace
@@ -201,11 +205,8 @@ void ImmutableEnumFieldLiteGenerator::Ge
   WriteFieldAccessorDocComment(printer, descriptor_, SETTER);
   printer->Print(variables_,
                  "private void set$capitalized_name$($type$ value) {\n"
-                 "  if (value == null) {\n"
-                 "    throw new NullPointerException();\n"
-                 "  }\n"
-                 "  $set_has_field_bit_message$\n"
                  "  $name$_ = value.getNumber();\n"
+                 "  $set_has_field_bit_message$\n"
                  "}\n");
   WriteFieldAccessorDocComment(printer, descriptor_, CLEARER);
   printer->Print(variables_,
@@ -364,11 +365,8 @@ void ImmutableEnumOneofFieldLiteGenerato
   WriteFieldAccessorDocComment(printer, descriptor_, SETTER);
   printer->Print(variables_,
                  "private void set$capitalized_name$($type$ value) {\n"
-                 "  if (value == null) {\n"
-                 "    throw new NullPointerException();\n"
-                 "  }\n"
-                 "  $set_oneof_case_message$;\n"
                  "  $oneof_name$_ = value.getNumber();\n"
+                 "  $set_oneof_case_message$;\n"
                  "}\n");
   WriteFieldAccessorDocComment(printer, descriptor_, CLEARER);
   printer->Print(variables_,
@@ -578,18 +576,14 @@ void RepeatedImmutableEnumFieldLiteGener
   printer->Print(variables_,
                  "private void set$capitalized_name$(\n"
                  "    int index, $type$ value) {\n"
-                 "  if (value == null) {\n"
-                 "    throw new NullPointerException();\n"
-                 "  }\n"
+                 "  $null_check$"
                  "  ensure$capitalized_name$IsMutable();\n"
                  "  $name$_.setInt(index, value.getNumber());\n"
                  "}\n");
   WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER);
   printer->Print(variables_,
                  "private void add$capitalized_name$($type$ value) {\n"
-                 "  if (value == null) {\n"
-                 "    throw new NullPointerException();\n"
-                 "  }\n"
+                 "  $null_check$"
                  "  ensure$capitalized_name$IsMutable();\n"
                  "  $name$_.addInt(value.getNumber());\n"
                  "}\n");
--- a/src/google/protobuf/compiler/java/java_file.cc
+++ b/src/google/protobuf/compiler/java/java_file.cc
@@ -268,6 +268,7 @@ void FileGenerator::Generate(io::Printer
   }
   PrintGeneratedAnnotation(
       printer, '$', options_.annotate_code ? classname_ + ".java.pb.meta" : "");
+
   printer->Print(
       "$deprecation$public final class $classname$ {\n"
       "  private $ctor$() {}\n",
--- a/src/google/protobuf/compiler/java/java_map_field_lite.cc
+++ b/src/google/protobuf/compiler/java/java_map_field_lite.cc
@@ -92,14 +92,12 @@ void SetMessageVariables(const FieldDesc
   (*variables)["boxed_key_type"] = TypeName(key, name_resolver, true);
   (*variables)["key_wire_type"] = WireType(key);
   (*variables)["key_default_value"] = DefaultValue(key, true, name_resolver);
+  // We use `x.getClass()` as a null check because it generates less bytecode
+  // than an `if (x == null) { throw ... }` statement.
   (*variables)["key_null_check"] =
-      IsReferenceType(keyJavaType)
-          ? "if (key == null) { throw new java.lang.NullPointerException(); }"
-          : "";
+      IsReferenceType(keyJavaType) ? "key.getClass();" : "";
   (*variables)["value_null_check"] =
-      IsReferenceType(valueJavaType)
-          ? "if (value == null) { throw new java.lang.NullPointerException(); }"
-          : "";
+      IsReferenceType(valueJavaType) ? "value.getClass();" : "";
 
   if (GetJavaType(value) == JAVATYPE_ENUM) {
     // We store enums as Integers internally.
--- a/src/google/protobuf/compiler/java/java_message.cc
+++ b/src/google/protobuf/compiler/java/java_message.cc
@@ -1001,7 +1001,8 @@ void ImmutableMessageGenerator::Generate
     io::Printer* printer) {
   printer->Print(
       "@java.lang.Override\n"
-      "public boolean equals(final java.lang.Object obj) {\n");
+      "public boolean equals(");
+  printer->Print("final java.lang.Object obj) {\n");
   printer->Indent();
   printer->Print(
       "if (obj == this) {\n"
--- a/src/google/protobuf/compiler/java/java_message_field_lite.cc
+++ b/src/google/protobuf/compiler/java/java_message_field_lite.cc
@@ -97,6 +97,10 @@ void SetMessageVariables(const FieldDesc
       GenerateGetBitFromLocal(builderBitIndex);
   (*variables)["set_has_field_bit_to_local"] =
       GenerateSetBitToLocal(messageBitIndex);
+
+  // We use `x.getClass()` as a null check because it generates less bytecode
+  // than an `if (x == null) { throw ... }` statement.
+  (*variables)["null_check"] = "value.getClass();\n";
 }
 
 }  // namespace
@@ -173,31 +177,18 @@ void ImmutableMessageFieldLiteGenerator:
   WriteFieldDocComment(printer, descriptor_);
   printer->Print(variables_,
                  "private void set$capitalized_name$($type$ value) {\n"
-                 "  if (value == null) {\n"
-                 "    throw new NullPointerException();\n"
-                 "  }\n"
+                 "  $null_check$"
                  "  $name$_ = value;\n"
                  "  $set_has_field_bit_message$\n"
                  "  }\n");
 
-  // Field.Builder setField(Field.Builder builderForValue)
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-                 "private void set$capitalized_name$(\n"
-                 "    $type$.Builder builderForValue) {\n"
-                 "  $name$_ = builderForValue.build();\n"
-                 "  $set_has_field_bit_message$\n"
-                 "}\n");
-
   // Field.Builder mergeField(Field value)
   WriteFieldDocComment(printer, descriptor_);
   printer->Print(
       variables_,
       "@java.lang.SuppressWarnings({\"ReferenceEquality\"})\n"
       "private void merge$capitalized_name$($type$ value) {\n"
-      "  if (value == null) {\n"
-      "    throw new NullPointerException();\n"
-      "  }\n"
+      "  $null_check$"
       "  if ($name$_ != null &&\n"
       "      $name$_ != $type$.getDefaultInstance()) {\n"
       "    $name$_ =\n"
@@ -257,7 +248,7 @@ void ImmutableMessageFieldLiteGenerator:
                  "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
                  "    $type$.Builder builderForValue) {\n"
                  "  copyOnWrite();\n"
-                 "  instance.set$capitalized_name$(builderForValue);\n"
+                 "  instance.set$capitalized_name$(builderForValue.build());\n"
                  "  return this;\n"
                  "}\n");
   printer->Annotate("{", "}", descriptor_);
@@ -284,7 +275,6 @@ void ImmutableMessageFieldLiteGenerator:
   printer->Annotate("{", "}", descriptor_);
 }
 
-
 void ImmutableMessageFieldLiteGenerator::GenerateFieldInfo(
     io::Printer* printer, std::vector<uint16>* output) const {
   WriteIntToUtf16CharSequence(descriptor_->number(), output);
@@ -343,30 +333,17 @@ void ImmutableMessageOneofFieldLiteGener
   WriteFieldDocComment(printer, descriptor_);
   printer->Print(variables_,
                  "private void set$capitalized_name$($type$ value) {\n"
-                 "  if (value == null) {\n"
-                 "    throw new NullPointerException();\n"
-                 "  }\n"
+                 "  $null_check$"
                  "  $oneof_name$_ = value;\n"
                  "  $set_oneof_case_message$;\n"
                  "}\n");
 
-  // Field.Builder setField(Field.Builder builderForValue)
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-                 "private void set$capitalized_name$(\n"
-                 "    $type$.Builder builderForValue) {\n"
-                 "  $oneof_name$_ = builderForValue.build();\n"
-                 "  $set_oneof_case_message$;\n"
-                 "}\n");
-
   // Field.Builder mergeField(Field value)
   WriteFieldDocComment(printer, descriptor_);
   printer->Print(
       variables_,
       "private void merge$capitalized_name$($type$ value) {\n"
-      "  if (value == null) {\n"
-      "    throw new NullPointerException();\n"
-      "  }\n"
+      "  $null_check$"
       "  if ($has_oneof_case_message$ &&\n"
       "      $oneof_name$_ != $type$.getDefaultInstance()) {\n"
       "    $oneof_name$_ = $type$.newBuilder(($type$) $oneof_name$_)\n"
@@ -437,7 +414,7 @@ void ImmutableMessageOneofFieldLiteGener
                  "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
                  "    $type$.Builder builderForValue) {\n"
                  "  copyOnWrite();\n"
-                 "  instance.set$capitalized_name$(builderForValue);\n"
+                 "  instance.set$capitalized_name$(builderForValue.build());\n"
                  "  return this;\n"
                  "}\n");
   printer->Annotate("{", "}", descriptor_);
@@ -564,29 +541,16 @@ void RepeatedImmutableMessageFieldLiteGe
   printer->Print(variables_,
                  "private void set$capitalized_name$(\n"
                  "    int index, $type$ value) {\n"
-                 "  if (value == null) {\n"
-                 "    throw new NullPointerException();\n"
-                 "  }\n"
+                 "  $null_check$"
                  "  ensure$capitalized_name$IsMutable();\n"
                  "  $name$_.set(index, value);\n"
                  "}\n");
 
-  // Builder setRepeatedField(int index, Field.Builder builderForValue)
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-                 "private void set$capitalized_name$(\n"
-                 "    int index, $type$.Builder builderForValue) {\n"
-                 "  ensure$capitalized_name$IsMutable();\n"
-                 "  $name$_.set(index, builderForValue.build());\n"
-                 "}\n");
-
   // Builder addRepeatedField(Field value)
   WriteFieldDocComment(printer, descriptor_);
   printer->Print(variables_,
                  "private void add$capitalized_name$($type$ value) {\n"
-                 "  if (value == null) {\n"
-                 "    throw new NullPointerException();\n"
-                 "  }\n"
+                 "  $null_check$"
                  "  ensure$capitalized_name$IsMutable();\n"
                  "  $name$_.add(value);\n"
                  "}\n");
@@ -596,29 +560,10 @@ void RepeatedImmutableMessageFieldLiteGe
   printer->Print(variables_,
                  "private void add$capitalized_name$(\n"
                  "    int index, $type$ value) {\n"
-                 "  if (value == null) {\n"
-                 "    throw new NullPointerException();\n"
-                 "  }\n"
+                 "  $null_check$"
                  "  ensure$capitalized_name$IsMutable();\n"
                  "  $name$_.add(index, value);\n"
                  "}\n");
-  // Builder addRepeatedField(Field.Builder builderForValue)
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-                 "private void add$capitalized_name$(\n"
-                 "    $type$.Builder builderForValue) {\n"
-                 "  ensure$capitalized_name$IsMutable();\n"
-                 "  $name$_.add(builderForValue.build());\n"
-                 "}\n");
-
-  // Builder addRepeatedField(int index, Field.Builder builderForValue)
-  WriteFieldDocComment(printer, descriptor_);
-  printer->Print(variables_,
-                 "private void add$capitalized_name$(\n"
-                 "    int index, $type$.Builder builderForValue) {\n"
-                 "  ensure$capitalized_name$IsMutable();\n"
-                 "  $name$_.add(index, builderForValue.build());\n"
-                 "}\n");
 
   // Builder addAllRepeatedField(Iterable<Field> values)
   WriteFieldDocComment(printer, descriptor_);
@@ -699,7 +644,8 @@ void RepeatedImmutableMessageFieldLiteGe
                  "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
                  "    int index, $type$.Builder builderForValue) {\n"
                  "  copyOnWrite();\n"
-                 "  instance.set$capitalized_name$(index, builderForValue);\n"
+                 "  instance.set$capitalized_name$(index,\n"
+                 "      builderForValue.build());\n"
                  "  return this;\n"
                  "}\n");
   printer->Annotate("{", "}", descriptor_);
@@ -731,7 +677,7 @@ void RepeatedImmutableMessageFieldLiteGe
                  "$deprecation$public Builder ${$add$capitalized_name$$}$(\n"
                  "    $type$.Builder builderForValue) {\n"
                  "  copyOnWrite();\n"
-                 "  instance.add$capitalized_name$(builderForValue);\n"
+                 "  instance.add$capitalized_name$(builderForValue.build());\n"
                  "  return this;\n"
                  "}\n");
   printer->Annotate("{", "}", descriptor_);
@@ -742,7 +688,8 @@ void RepeatedImmutableMessageFieldLiteGe
                  "$deprecation$public Builder ${$add$capitalized_name$$}$(\n"
                  "    int index, $type$.Builder builderForValue) {\n"
                  "  copyOnWrite();\n"
-                 "  instance.add$capitalized_name$(index, builderForValue);\n"
+                 "  instance.add$capitalized_name$(index,\n"
+                 "      builderForValue.build());\n"
                  "  return this;\n"
                  "}\n");
   printer->Annotate("{", "}", descriptor_);
@@ -781,7 +728,6 @@ void RepeatedImmutableMessageFieldLiteGe
   printer->Annotate("{", "}", descriptor_);
 }
 
-
 void RepeatedImmutableMessageFieldLiteGenerator::GenerateFieldInfo(
     io::Printer* printer, std::vector<uint16>* output) const {
   WriteIntToUtf16CharSequence(descriptor_->number(), output);
--- a/src/google/protobuf/compiler/java/java_primitive_field_lite.cc
+++ b/src/google/protobuf/compiler/java/java_primitive_field_lite.cc
@@ -125,10 +125,9 @@ void SetPrimitiveVariables(const FieldDe
   }
 
   if (IsReferenceType(javaType)) {
-    (*variables)["null_check"] =
-        "  if (value == null) {\n"
-        "    throw new NullPointerException();\n"
-        "  }\n";
+    // We use `x.getClass()` as a null check because it generates less bytecode
+    // than an `if (x == null) { throw ... }` statement.
+    (*variables)["null_check"] = "  value.getClass();\n";
   } else {
     (*variables)["null_check"] = "";
   }
--- a/src/google/protobuf/compiler/java/java_string_field_lite.cc
+++ b/src/google/protobuf/compiler/java/java_string_field_lite.cc
@@ -75,10 +75,9 @@ void SetPrimitiveVariables(const FieldDe
       StrCat(static_cast<int32>(WireFormat::MakeTag(descriptor)));
   (*variables)["tag_size"] = StrCat(
       WireFormat::TagSize(descriptor->number(), GetType(descriptor)));
-  (*variables)["null_check"] =
-      "  if (value == null) {\n"
-      "    throw new NullPointerException();\n"
-      "  }\n";
+  // We use `x.getClass()` as a null check because it generates less bytecode
+  // than an `if (x == null) { throw ... }` statement.
+  (*variables)["null_check"] = "  value.getClass();\n";
 
   // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
   // by the proto compiler
@@ -230,14 +229,13 @@ void ImmutableStringFieldLiteGenerator::
   WriteFieldStringBytesAccessorDocComment(printer, descriptor_, SETTER);
   printer->Print(variables_,
                  "private void set$capitalized_name$Bytes(\n"
-                 "    com.google.protobuf.ByteString value) {\n"
-                 "$null_check$");
+                 "    com.google.protobuf.ByteString value) {\n");
   if (CheckUtf8(descriptor_)) {
     printer->Print(variables_, "  checkByteStringIsUtf8(value);\n");
   }
   printer->Print(variables_,
-                 "  $set_has_field_bit_message$\n"
                  "  $name$_ = value.toStringUtf8();\n"
+                 "  $set_has_field_bit_message$\n"
                  "}\n");
 }
 
@@ -400,15 +398,14 @@ void ImmutableStringOneofFieldLiteGenera
   WriteFieldStringBytesAccessorDocComment(printer, descriptor_, SETTER);
   printer->Print(variables_,
                  "private void ${$set$capitalized_name$Bytes$}$(\n"
-                 "    com.google.protobuf.ByteString value) {\n"
-                 "$null_check$");
+                 "    com.google.protobuf.ByteString value) {\n");
   printer->Annotate("{", "}", descriptor_);
   if (CheckUtf8(descriptor_)) {
     printer->Print(variables_, "  checkByteStringIsUtf8(value);\n");
   }
   printer->Print(variables_,
-                 "  $set_oneof_case_message$;\n"
                  "  $oneof_name$_ = value.toStringUtf8();\n"
+                 "  $set_oneof_case_message$;\n"
                  "}\n");
 }
 
@@ -605,8 +602,7 @@ void RepeatedImmutableStringFieldLiteGen
   WriteFieldStringBytesAccessorDocComment(printer, descriptor_, LIST_ADDER);
   printer->Print(variables_,
                  "private void add$capitalized_name$Bytes(\n"
-                 "    com.google.protobuf.ByteString value) {\n"
-                 "$null_check$");
+                 "    com.google.protobuf.ByteString value) {\n");
   if (CheckUtf8(descriptor_)) {
     printer->Print(variables_, "  checkByteStringIsUtf8(value);\n");
   }
openSUSE Build Service is sponsored by