Index: third_party/protobuf/java/util/src/main/java/com/google/protobuf/util/FieldMaskTree.java |
diff --git a/third_party/protobuf/java/util/src/main/java/com/google/protobuf/util/FieldMaskTree.java b/third_party/protobuf/java/util/src/main/java/com/google/protobuf/util/FieldMaskTree.java |
index dc2f4b841e9bb04c152aebca4e76a9a96e076683..668d65ab169e006a2c74df064f1c0dfaf19be84f 100644 |
--- a/third_party/protobuf/java/util/src/main/java/com/google/protobuf/util/FieldMaskTree.java |
+++ b/third_party/protobuf/java/util/src/main/java/com/google/protobuf/util/FieldMaskTree.java |
@@ -60,10 +60,9 @@ import java.util.logging.Logger; |
* FieldMask in a message tree. |
*/ |
class FieldMaskTree { |
- private static final Logger logger = |
- Logger.getLogger(FieldMaskTree.class.getName()); |
- |
- private static final String FIELD_PATH_SEPARATOR_REGEX = "\\."; |
+ private static final Logger logger = Logger.getLogger(FieldMaskTree.class.getName()); |
+ |
+ private static final String FIELD_PATH_SEPARATOR_REGEX = "\\."; |
private static class Node { |
public TreeMap<String, Node> children = new TreeMap<String, Node>(); |
@@ -73,12 +72,12 @@ class FieldMaskTree { |
/** Creates an empty FieldMaskTree. */ |
public FieldMaskTree() {} |
- |
+ |
/** Creates a FieldMaskTree for a given FieldMask. */ |
public FieldMaskTree(FieldMask mask) { |
mergeFromFieldMask(mask); |
} |
- |
+ |
@Override |
public String toString() { |
return FieldMaskUtil.toString(toFieldMask()); |
@@ -121,7 +120,7 @@ class FieldMaskTree { |
node.children.clear(); |
return this; |
} |
- |
+ |
/** |
* Merges all field paths in a FieldMask into this tree. |
*/ |
@@ -149,8 +148,7 @@ class FieldMaskTree { |
return; |
} |
for (Entry<String, Node> entry : node.children.entrySet()) { |
- String childPath = path.isEmpty() |
- ? entry.getKey() : path + "." + entry.getKey(); |
+ String childPath = path.isEmpty() ? entry.getKey() : path + "." + entry.getKey(); |
getFieldPaths(entry.getValue(), childPath, paths); |
} |
} |
@@ -193,11 +191,10 @@ class FieldMaskTree { |
* Merges all fields specified by this FieldMaskTree from {@code source} to |
* {@code destination}. |
*/ |
- public void merge(Message source, Message.Builder destination, |
- FieldMaskUtil.MergeOptions options) { |
+ public void merge( |
+ Message source, Message.Builder destination, FieldMaskUtil.MergeOptions options) { |
if (source.getDescriptorForType() != destination.getDescriptorForType()) { |
- throw new IllegalArgumentException( |
- "Cannot merge messages of different types."); |
+ throw new IllegalArgumentException("Cannot merge messages of different types."); |
} |
if (root.children.isEmpty()) { |
return; |
@@ -208,30 +205,41 @@ class FieldMaskTree { |
/** Merges all fields specified by a sub-tree from {@code source} to |
* {@code destination}. |
*/ |
- private void merge(Node node, String path, Message source, |
- Message.Builder destination, FieldMaskUtil.MergeOptions options) { |
+ private void merge( |
+ Node node, |
+ String path, |
+ Message source, |
+ Message.Builder destination, |
+ FieldMaskUtil.MergeOptions options) { |
assert source.getDescriptorForType() == destination.getDescriptorForType(); |
- |
+ |
Descriptor descriptor = source.getDescriptorForType(); |
for (Entry<String, Node> entry : node.children.entrySet()) { |
- FieldDescriptor field = |
- descriptor.findFieldByName(entry.getKey()); |
+ FieldDescriptor field = descriptor.findFieldByName(entry.getKey()); |
if (field == null) { |
- logger.warning("Cannot find field \"" + entry.getKey() |
- + "\" in message type " + descriptor.getFullName()); |
+ logger.warning( |
+ "Cannot find field \"" |
+ + entry.getKey() |
+ + "\" in message type " |
+ + descriptor.getFullName()); |
continue; |
} |
if (!entry.getValue().children.isEmpty()) { |
- if (field.isRepeated() |
- || field.getJavaType() != FieldDescriptor.JavaType.MESSAGE) { |
- logger.warning("Field \"" + field.getFullName() + "\" is not a " |
- + "singluar message field and cannot have sub-fields."); |
+ if (field.isRepeated() || field.getJavaType() != FieldDescriptor.JavaType.MESSAGE) { |
+ logger.warning( |
+ "Field \"" |
+ + field.getFullName() |
+ + "\" is not a " |
+ + "singluar message field and cannot have sub-fields."); |
continue; |
} |
- String childPath = path.isEmpty() |
- ? entry.getKey() : path + "." + entry.getKey(); |
- merge(entry.getValue(), childPath, (Message) source.getField(field), |
- destination.getFieldBuilder(field), options); |
+ String childPath = path.isEmpty() ? entry.getKey() : path + "." + entry.getKey(); |
+ merge( |
+ entry.getValue(), |
+ childPath, |
+ (Message) source.getField(field), |
+ destination.getFieldBuilder(field), |
+ options); |
continue; |
} |
if (field.isRepeated()) { |
@@ -245,13 +253,22 @@ class FieldMaskTree { |
} else { |
if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { |
if (options.replaceMessageFields()) { |
- destination.setField(field, source.getField(field)); |
+ if (!source.hasField(field)) { |
+ destination.clearField(field); |
+ } else { |
+ destination.setField(field, source.getField(field)); |
+ } |
} else { |
- destination.getFieldBuilder(field).mergeFrom( |
- (Message) source.getField(field)); |
+ if (source.hasField(field)) { |
+ destination.getFieldBuilder(field).mergeFrom((Message) source.getField(field)); |
+ } |
} |
} else { |
- destination.setField(field, source.getField(field)); |
+ if (source.hasField(field) || !options.replacePrimitiveFields()) { |
+ destination.setField(field, source.getField(field)); |
+ } else { |
+ destination.clearField(field); |
+ } |
} |
} |
} |