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");
}