aboutsummaryrefslogtreecommitdiffhomepage
path: root/java
diff options
context:
space:
mode:
authorGravatar Jisi Liu <jisi.liu@gmail.com>2017-10-18 12:22:18 -0700
committerGravatar Jisi Liu <jisi.liu@gmail.com>2017-10-18 12:22:18 -0700
commit1a7a7fca804afa1cf67f8be5e71092898ba40334 (patch)
tree04b3da27c71c607510f34a12cf7856a1b94181ae /java
parentc4f59dcc5c13debc572154c8f636b8a9361aacde (diff)
Merge from google internal
Diffstat (limited to 'java')
-rw-r--r--java/core/src/main/java/com/google/protobuf/AbstractMessage.java7
-rw-r--r--java/core/src/main/java/com/google/protobuf/CodedInputStream.java3
-rw-r--r--java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java68
-rw-r--r--java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java6
-rw-r--r--java/core/src/main/java/com/google/protobuf/Message.java2
-rw-r--r--java/core/src/test/java/com/google/protobuf/FieldPresenceTest.java30
-rw-r--r--java/core/src/test/java/com/google/protobuf/LiteTest.java9
-rw-r--r--java/util/src/main/java/com/google/protobuf/util/FieldMaskTree.java6
-rw-r--r--java/util/src/test/java/com/google/protobuf/util/FieldMaskTreeTest.java8
9 files changed, 91 insertions, 48 deletions
diff --git a/java/core/src/main/java/com/google/protobuf/AbstractMessage.java b/java/core/src/main/java/com/google/protobuf/AbstractMessage.java
index 065fa1a9..908764df 100644
--- a/java/core/src/main/java/com/google/protobuf/AbstractMessage.java
+++ b/java/core/src/main/java/com/google/protobuf/AbstractMessage.java
@@ -380,6 +380,10 @@ public abstract class AbstractMessage
@Override
public BuilderType mergeFrom(final Message other) {
+ return mergeFrom(other, other.getAllFields());
+ }
+
+ BuilderType mergeFrom(final Message other, Map<FieldDescriptor, Object> allFields) {
if (other.getDescriptorForType() != getDescriptorForType()) {
throw new IllegalArgumentException(
"mergeFrom(Message) can only merge messages of the same type.");
@@ -394,8 +398,7 @@ public abstract class AbstractMessage
// TODO(kenton): Provide a function somewhere called makeDeepCopy()
// which allows people to make secure deep copies of messages.
- for (final Map.Entry<FieldDescriptor, Object> entry :
- other.getAllFields().entrySet()) {
+ for (final Map.Entry<FieldDescriptor, Object> entry : allFields.entrySet()) {
final FieldDescriptor field = entry.getKey();
if (field.isRepeated()) {
for (final Object element : (List)entry.getValue()) {
diff --git a/java/core/src/main/java/com/google/protobuf/CodedInputStream.java b/java/core/src/main/java/com/google/protobuf/CodedInputStream.java
index 511501d4..e08a993b 100644
--- a/java/core/src/main/java/com/google/protobuf/CodedInputStream.java
+++ b/java/core/src/main/java/com/google/protobuf/CodedInputStream.java
@@ -413,8 +413,7 @@ public abstract class CodedInputStream {
private boolean explicitDiscardUnknownFields = false;
- /** TODO(liujisi): flip the default.*/
- private static volatile boolean proto3DiscardUnknownFieldsDefault = true;
+ private static volatile boolean proto3DiscardUnknownFieldsDefault = false;
static void setProto3DiscardUnknownsByDefaultForTest() {
proto3DiscardUnknownFieldsDefault = true;
diff --git a/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java b/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java
index 99864964..09084646 100644
--- a/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java
+++ b/java/core/src/main/java/com/google/protobuf/GeneratedMessageLite.java
@@ -31,7 +31,6 @@
package com.google.protobuf;
import com.google.protobuf.AbstractMessageLite.Builder.LimitedInputStream;
-import com.google.protobuf.GeneratedMessageLite.EqualsVisitor.NotEqualsException;
import com.google.protobuf.Internal.BooleanList;
import com.google.protobuf.Internal.DoubleList;
import com.google.protobuf.Internal.EnumLiteMap;
@@ -52,6 +51,7 @@ 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}.
@@ -62,6 +62,12 @@ public abstract class GeneratedMessageLite<
MessageType extends GeneratedMessageLite<MessageType, BuilderType>,
BuilderType extends GeneratedMessageLite.Builder<MessageType, BuilderType>>
extends AbstractMessageLite<MessageType, BuilderType> {
+ // BEGIN REGULAR
+ static final boolean ENABLE_EXPERIMENTAL_RUNTIME_AT_BUILD_TIME = false;
+ // END REGULAR
+ // BEGIN EXPERIMENTAL
+ // static final boolean ENABLE_EXPERIMENTAL_RUNTIME_AT_BUILD_TIME = true;
+ // END EXPERIMENTAL
/** For use by generated code only. Lazily initialized to reduce allocations. */
protected UnknownFieldSetLite unknownFields = UnknownFieldSetLite.getDefaultInstance();
@@ -110,12 +116,19 @@ public abstract class GeneratedMessageLite<
if (memoizedHashCode != 0) {
return memoizedHashCode;
}
+ // BEGIN EXPERIMENTAL
+ // memoizedHashCode = Protobuf.getInstance().schemaFor(this).hashCode(this);
+ // return memoizedHashCode;
+ // END EXPERIMENTAL
+ // BEGIN REGULAR
HashCodeVisitor visitor = new HashCodeVisitor();
visit(visitor, (MessageType) this);
memoizedHashCode = visitor.hashCode;
return memoizedHashCode;
+ // END REGULAR
}
+ // BEGIN REGULAR
@SuppressWarnings("unchecked") // Guaranteed by runtime
int hashCode(HashCodeVisitor visitor) {
if (memoizedHashCode == 0) {
@@ -127,6 +140,7 @@ public abstract class GeneratedMessageLite<
}
return memoizedHashCode;
}
+ // END REGULAR
@SuppressWarnings("unchecked") // Guaranteed by isInstance + runtime
@Override
@@ -139,18 +153,22 @@ public abstract class GeneratedMessageLite<
return false;
}
+ // BEGIN EXPERIMENTAL
+ // return Protobuf.getInstance().schemaFor(this).equals(this, (MessageType) other);
+ // END EXPERIMENTAL
+ // BEGIN REGULAR
try {
visit(EqualsVisitor.INSTANCE, (MessageType) other);
- } catch (NotEqualsException e) {
+ } catch (EqualsVisitor.NotEqualsException e) {
return false;
}
return true;
+ // END REGULAR
}
- /**
- * Same as {@link #equals(Object)} but throws {@code NotEqualsException}.
- */
+ // BEGIN REGULAR
+ /** Same as {@link #equals(Object)} but throws {@code NotEqualsException}. */
@SuppressWarnings("unchecked") // Guaranteed by isInstance + runtime
boolean equals(EqualsVisitor visitor, MessageLite other) {
if (this == other) {
@@ -164,14 +182,13 @@ public abstract class GeneratedMessageLite<
visit(visitor, (MessageType) other);
return true;
}
+ // END REGULAR
// 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.
- */
+ /** Lazily initializes unknown fields. */
private final void ensureUnknownFieldsInitialized() {
if (unknownFields == UnknownFieldSetLite.getDefaultInstance()) {
unknownFields = UnknownFieldSetLite.newInstance();
@@ -218,6 +235,20 @@ public abstract class GeneratedMessageLite<
unknownFields.makeImmutable();
}
+ 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);
@@ -238,11 +269,13 @@ public abstract class GeneratedMessageLite<
* For use by generated code only.
*/
public static enum MethodToInvoke {
- // Rely on/modify instance state
IS_INITIALIZED,
+ // BEGIN REGULAR
+ VISIT,
+ // END REGULAR
+ // Rely on/modify instance state
GET_MEMOIZED_IS_INITIALIZED,
SET_MEMOIZED_IS_INITIALIZED,
- VISIT,
MERGE_FROM_STREAM,
MAKE_IMMUTABLE,
@@ -299,10 +332,13 @@ public abstract class GeneratedMessageLite<
return dynamicMethod(method, null, null);
}
+ // BEGIN REGULAR
void visit(Visitor visitor, MessageType other) {
dynamicMethod(MethodToInvoke.VISIT, visitor, other);
unknownFields = visitor.visitUnknownFields(unknownFields, other.unknownFields);
}
+ // END REGULAR
+
/**
@@ -399,7 +435,12 @@ public abstract class GeneratedMessageLite<
}
private void mergeFromInstance(MessageType dest, MessageType src) {
+ // BEGIN EXPERIMENTAL
+ // Protobuf.getInstance().schemaFor(dest).mergeFrom(dest, src);
+ // END EXPERIMENTAL
+ // BEGIN REGULAR
dest.visit(MergeFromVisitor.INSTANCE, src);
+ // END REGULAR
}
@Override
@@ -477,11 +518,13 @@ public abstract class GeneratedMessageLite<
extensions.mergeFrom(((ExtendableMessage) other).extensions);
}
+ // BEGIN REGULAR
@Override
final void visit(Visitor visitor, MessageType other) {
super.visit(visitor, other);
extensions = visitor.visitExtensions(extensions, other.extensions);
}
+ // END REGULAR
/**
* Parse an unknown field or an extension. For use by generated code only.
@@ -494,7 +537,8 @@ public abstract class GeneratedMessageLite<
MessageType defaultInstance,
CodedInputStream input,
ExtensionRegistryLite extensionRegistry,
- int tag) throws IOException {
+ int tag)
+ throws IOException {
int fieldNumber = WireFormat.getTagFieldNumber(tag);
// TODO(dweis): How much bytecode would be saved by not requiring the generated code to
@@ -1716,6 +1760,7 @@ public abstract class GeneratedMessageLite<
return message;
}
+ // BEGIN REGULAR
/**
* An abstract visitor that the generated code calls into that we use to implement various
* features. Fields that are not members of oneofs are always visited. Members of a oneof are only
@@ -2401,4 +2446,5 @@ public abstract class GeneratedMessageLite<
return mine;
}
}
+ // END REGULAR
}
diff --git a/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java b/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java
index 592869a1..4acd8f2f 100644
--- a/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java
+++ b/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java
@@ -358,6 +358,10 @@ public abstract class GeneratedMessageV3 extends AbstractMessage
throw e.unwrapIOException();
}
}
+
+ protected static boolean canUseUnsafe() {
+ return UnsafeUtil.hasUnsafeArrayOperations() && UnsafeUtil.hasUnsafeByteBufferOperations();
+ }
@Override
public void writeTo(final CodedOutputStream output) throws IOException {
@@ -655,6 +659,7 @@ public abstract class GeneratedMessageV3 extends AbstractMessage
.build());
}
+
@Override
public boolean isInitialized() {
for (final FieldDescriptor field : getDescriptorForType().getFields()) {
@@ -2853,3 +2858,4 @@ public abstract class GeneratedMessageV3 extends AbstractMessage
}
}
}
+
diff --git a/java/core/src/main/java/com/google/protobuf/Message.java b/java/core/src/main/java/com/google/protobuf/Message.java
index 94590fb9..0770d417 100644
--- a/java/core/src/main/java/com/google/protobuf/Message.java
+++ b/java/core/src/main/java/com/google/protobuf/Message.java
@@ -125,7 +125,7 @@ public interface Message extends MessageLite, MessageOrBuilder {
* 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.
+ * with the elements in this message.<br>
* * 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.
diff --git a/java/core/src/test/java/com/google/protobuf/FieldPresenceTest.java b/java/core/src/test/java/com/google/protobuf/FieldPresenceTest.java
index ff686a0c..42da5bb3 100644
--- a/java/core/src/test/java/com/google/protobuf/FieldPresenceTest.java
+++ b/java/core/src/test/java/com/google/protobuf/FieldPresenceTest.java
@@ -404,34 +404,4 @@ public class FieldPresenceTest extends TestCase {
assertTrue(builder.buildPartial().isInitialized());
}
-
- // Test that unknown fields are dropped.
- public void testUnknownFields() throws Exception {
- TestAllTypes.Builder builder = TestAllTypes.newBuilder();
- builder.setOptionalInt32(1234);
- builder.addRepeatedInt32(5678);
- TestAllTypes message = builder.build();
- ByteString data = message.toByteString();
-
- TestOptionalFieldsOnly optionalOnlyMessage =
- TestOptionalFieldsOnly.parseFrom(data);
- // UnknownFieldSet should be empty.
- assertEquals(
- 0, optionalOnlyMessage.getUnknownFields().toByteString().size());
- assertEquals(1234, optionalOnlyMessage.getOptionalInt32());
- message = TestAllTypes.parseFrom(optionalOnlyMessage.toByteString());
- assertEquals(1234, message.getOptionalInt32());
- // The repeated field is discarded because it's unknown to the optional-only
- // message.
- assertEquals(0, message.getRepeatedInt32Count());
-
- DynamicMessage dynamicOptionalOnlyMessage =
- DynamicMessage.getDefaultInstance(
- TestOptionalFieldsOnly.getDescriptor())
- .getParserForType().parseFrom(data);
- assertEquals(
- 0, dynamicOptionalOnlyMessage.getUnknownFields().toByteString().size());
- assertEquals(optionalOnlyMessage.toByteString(),
- dynamicOptionalOnlyMessage.toByteString());
- }
}
diff --git a/java/core/src/test/java/com/google/protobuf/LiteTest.java b/java/core/src/test/java/com/google/protobuf/LiteTest.java
index ba4d539d..40b44538 100644
--- a/java/core/src/test/java/com/google/protobuf/LiteTest.java
+++ b/java/core/src/test/java/com/google/protobuf/LiteTest.java
@@ -1453,6 +1453,15 @@ public class LiteTest extends TestCase {
UnittestLite.optionalFixed32ExtensionLite));
}
+ public void testBuilderMergeFromNull() throws Exception {
+ try {
+ TestAllTypesLite.newBuilder().mergeFrom((TestAllTypesLite) null);
+ fail("Expected exception");
+ } catch (NullPointerException e) {
+ // Pass.
+ }
+ }
+
// Builder.mergeFrom() should keep existing extensions.
public void testBuilderMergeFromWithExtensions() throws Exception {
TestAllExtensionsLite message =
diff --git a/java/util/src/main/java/com/google/protobuf/util/FieldMaskTree.java b/java/util/src/main/java/com/google/protobuf/util/FieldMaskTree.java
index b192b53e..e017b987 100644
--- a/java/util/src/main/java/com/google/protobuf/util/FieldMaskTree.java
+++ b/java/util/src/main/java/com/google/protobuf/util/FieldMaskTree.java
@@ -34,7 +34,6 @@ import com.google.protobuf.Descriptors.Descriptor;
import com.google.protobuf.Descriptors.FieldDescriptor;
import com.google.protobuf.FieldMask;
import com.google.protobuf.Message;
-
import java.util.ArrayList;
import java.util.List;
import java.util.Map.Entry;
@@ -244,6 +243,11 @@ final class FieldMaskTree {
+ "singluar message field and cannot have sub-fields.");
continue;
}
+ if (!source.hasField(field) && !destination.hasField(field)) {
+ // If the message field is not present in both source and destination, skip recursing
+ // so we don't create unneccessary empty messages.
+ continue;
+ }
String childPath = path.isEmpty() ? entry.getKey() : path + "." + entry.getKey();
merge(
entry.getValue(),
diff --git a/java/util/src/test/java/com/google/protobuf/util/FieldMaskTreeTest.java b/java/util/src/test/java/com/google/protobuf/util/FieldMaskTreeTest.java
index 3ee0fc6e..853b6151 100644
--- a/java/util/src/test/java/com/google/protobuf/util/FieldMaskTreeTest.java
+++ b/java/util/src/test/java/com/google/protobuf/util/FieldMaskTreeTest.java
@@ -33,7 +33,6 @@ package com.google.protobuf.util;
import protobuf_unittest.UnittestProto.NestedTestAllTypes;
import protobuf_unittest.UnittestProto.TestAllTypes;
import protobuf_unittest.UnittestProto.TestAllTypes.NestedMessage;
-
import junit.framework.TestCase;
public class FieldMaskTreeTest extends TestCase {
@@ -222,6 +221,13 @@ public class FieldMaskTreeTest extends TestCase {
new FieldMaskTree().addFieldPath("payload").merge(clearedSource, builder, options);
assertEquals(false, builder.hasPayload());
+ // Skip a message field if they are unset in both source and target.
+ builder = NestedTestAllTypes.newBuilder();
+ new FieldMaskTree()
+ .addFieldPath("payload.optional_int32")
+ .merge(clearedSource, builder, options);
+ assertEquals(false, builder.hasPayload());
+
// Change to replace message fields.
options.setReplaceMessageFields(true);
builder = NestedTestAllTypes.newBuilder();