diff options
author | jieluo@google.com <jieluo@google.com@630680e5-0e50-0410-840e-4b1c322b438d> | 2014-07-18 00:47:59 +0000 |
---|---|---|
committer | jieluo@google.com <jieluo@google.com@630680e5-0e50-0410-840e-4b1c322b438d> | 2014-07-18 00:47:59 +0000 |
commit | 4de8f55113007fdc8e34107950e605fc0209d465 (patch) | |
tree | 92b7da8757a7740d9e1f2d3ead233542947d8c8c /java/src/main/java/com/google/protobuf/FieldSet.java | |
parent | c5553a3d18f80132b9079c5504bc0aa1f7f950a0 (diff) | |
download | protobuf-4de8f55113007fdc8e34107950e605fc0209d465.tar.gz protobuf-4de8f55113007fdc8e34107950e605fc0209d465.tar.bz2 protobuf-4de8f55113007fdc8e34107950e605fc0209d465.zip |
down integrate to svn
Diffstat (limited to 'java/src/main/java/com/google/protobuf/FieldSet.java')
-rw-r--r-- | java/src/main/java/com/google/protobuf/FieldSet.java | 100 |
1 files changed, 73 insertions, 27 deletions
diff --git a/java/src/main/java/com/google/protobuf/FieldSet.java b/java/src/main/java/com/google/protobuf/FieldSet.java index 2663694f..01b6a35c 100644 --- a/java/src/main/java/com/google/protobuf/FieldSet.java +++ b/java/src/main/java/com/google/protobuf/FieldSet.java @@ -146,6 +146,7 @@ final class FieldSet<FieldDescriptorType extends return clone; } + // ================================================================= /** See {@link Message.Builder#clear()}. */ @@ -376,10 +377,13 @@ final class FieldSet<FieldDescriptorType extends case DOUBLE: isValid = value instanceof Double ; break; case BOOLEAN: isValid = value instanceof Boolean ; break; case STRING: isValid = value instanceof String ; break; - case BYTE_STRING: isValid = value instanceof ByteString; break; + case BYTE_STRING: + isValid = value instanceof ByteString || value instanceof byte[]; + break; case ENUM: // TODO(kenton): Caller must do type checking here, I guess. - isValid = value instanceof Internal.EnumLite; + isValid = + (value instanceof Integer || value instanceof Internal.EnumLite); break; case MESSAGE: // TODO(kenton): Caller must do type checking here, I guess. @@ -483,6 +487,17 @@ final class FieldSet<FieldDescriptorType extends } } + private Object cloneIfMutable(Object value) { + if (value instanceof byte[]) { + byte[] bytes = (byte[]) value; + byte[] copy = new byte[bytes.length]; + System.arraycopy(bytes, 0, copy, 0, bytes.length); + return copy; + } else { + return value; + } + } + @SuppressWarnings({"unchecked", "rawtypes"}) private void mergeFromField( final Map.Entry<FieldDescriptorType, Object> entry) { @@ -495,28 +510,26 @@ final class FieldSet<FieldDescriptorType extends if (descriptor.isRepeated()) { Object value = getField(descriptor); if (value == null) { - // Our list is empty, but we still need to make a defensive copy of - // the other list since we don't know if the other FieldSet is still - // mutable. - fields.put(descriptor, new ArrayList((List) otherValue)); - } else { - // Concatenate the lists. - ((List) value).addAll((List) otherValue); + value = new ArrayList(); + } + for (Object element : (List) otherValue) { + ((List) value).add(cloneIfMutable(element)); } + fields.put(descriptor, value); } else if (descriptor.getLiteJavaType() == WireFormat.JavaType.MESSAGE) { Object value = getField(descriptor); if (value == null) { - fields.put(descriptor, otherValue); + fields.put(descriptor, cloneIfMutable(otherValue)); } else { // Merge the messages. - fields.put( - descriptor, - descriptor.internalMergeFrom( + value = descriptor.internalMergeFrom( ((MessageLite) value).toBuilder(), (MessageLite) otherValue) - .build()); + .build(); + + fields.put(descriptor, value); } } else { - fields.put(descriptor, otherValue); + fields.put(descriptor, cloneIfMutable(otherValue)); } } @@ -524,11 +537,13 @@ final class FieldSet<FieldDescriptorType extends // other class. Probably WireFormat. /** - * Read a field of any primitive type from a CodedInputStream. Enums, - * groups, and embedded messages are not handled by this method. + * Read a field of any primitive type for immutable messages from a + * CodedInputStream. Enums, groups, and embedded messages are not handled by + * this method. * * @param input The stream from which to read. * @param type Declared type of the field. + * @param checkUtf8 When true, check that the input is valid utf8. * @return An object representing the field's value, of the exact * type which would be returned by * {@link Message#getField(Descriptors.FieldDescriptor)} for @@ -536,7 +551,8 @@ final class FieldSet<FieldDescriptorType extends */ public static Object readPrimitiveField( CodedInputStream input, - final WireFormat.FieldType type) throws IOException { + final WireFormat.FieldType type, + boolean checkUtf8) throws IOException { switch (type) { case DOUBLE : return input.readDouble (); case FLOAT : return input.readFloat (); @@ -546,7 +562,11 @@ final class FieldSet<FieldDescriptorType extends case FIXED64 : return input.readFixed64 (); case FIXED32 : return input.readFixed32 (); case BOOL : return input.readBool (); - case STRING : return input.readString (); + case STRING : if (checkUtf8) { + return input.readStringRequireUtf8(); + } else { + return input.readString(); + } case BYTES : return input.readBytes (); case UINT32 : return input.readUInt32 (); case SFIXED32: return input.readSFixed32(); @@ -571,6 +591,7 @@ final class FieldSet<FieldDescriptorType extends "There is no way to get here, but the compiler thinks otherwise."); } + /** See {@link Message#writeTo(CodedOutputStream)}. */ public void writeTo(final CodedOutputStream output) throws IOException { @@ -605,8 +626,12 @@ final class FieldSet<FieldDescriptorType extends final FieldDescriptorType descriptor = entry.getKey(); if (descriptor.getLiteJavaType() == WireFormat.JavaType.MESSAGE && !descriptor.isRepeated() && !descriptor.isPacked()) { + Object value = entry.getValue(); + if (value instanceof LazyField) { + value = ((LazyField) value).getValue(); + } output.writeMessageSetExtension(entry.getKey().getNumber(), - (MessageLite) entry.getValue()); + (MessageLite) value); } else { writeField(descriptor, entry.getValue(), output); } @@ -630,7 +655,7 @@ final class FieldSet<FieldDescriptorType extends // Special case for groups, which need a start and end tag; other fields // can just use writeTag() and writeFieldNoTag(). if (type == WireFormat.FieldType.GROUP) { - output.writeGroup(number, (MessageLite) value); + output.writeGroup(number, (MessageLite) value); } else { output.writeTag(number, getWireFormatForFieldType(type, false)); writeElementNoTag(output, type, value); @@ -663,7 +688,13 @@ final class FieldSet<FieldDescriptorType extends case STRING : output.writeStringNoTag ((String ) value); break; case GROUP : output.writeGroupNoTag ((MessageLite) value); break; case MESSAGE : output.writeMessageNoTag ((MessageLite) value); break; - case BYTES : output.writeBytesNoTag ((ByteString ) value); break; + case BYTES: + if (value instanceof ByteString) { + output.writeBytesNoTag((ByteString) value); + } else { + output.writeByteArrayNoTag((byte[]) value); + } + break; case UINT32 : output.writeUInt32NoTag ((Integer ) value); break; case SFIXED32: output.writeSFixed32NoTag((Integer ) value); break; case SFIXED64: output.writeSFixed64NoTag((Long ) value); break; @@ -671,7 +702,11 @@ final class FieldSet<FieldDescriptorType extends case SINT64 : output.writeSInt64NoTag ((Long ) value); break; case ENUM: - output.writeEnumNoTag(((Internal.EnumLite) value).getNumber()); + if (value instanceof Internal.EnumLite) { + output.writeEnumNoTag(((Internal.EnumLite) value).getNumber()); + } else { + output.writeEnumNoTag(((Integer) value).intValue()); + } break; } } @@ -778,7 +813,9 @@ final class FieldSet<FieldDescriptorType extends final int number, final Object value) { int tagSize = CodedOutputStream.computeTagSize(number); if (type == WireFormat.FieldType.GROUP) { - tagSize *= 2; + // Only count the end group tag for proto2 messages as for proto1 the end + // group tag will be counted as a part of getSerializedSize(). + tagSize *= 2; } return tagSize + computeElementSizeNoTag(type, value); } @@ -808,7 +845,12 @@ final class FieldSet<FieldDescriptorType extends case BOOL : return CodedOutputStream.computeBoolSizeNoTag ((Boolean )value); case STRING : return CodedOutputStream.computeStringSizeNoTag ((String )value); case GROUP : return CodedOutputStream.computeGroupSizeNoTag ((MessageLite)value); - case BYTES : return CodedOutputStream.computeBytesSizeNoTag ((ByteString )value); + case BYTES : + if (value instanceof ByteString) { + return CodedOutputStream.computeBytesSizeNoTag((ByteString) value); + } else { + return CodedOutputStream.computeByteArraySizeNoTag((byte[]) value); + } case UINT32 : return CodedOutputStream.computeUInt32SizeNoTag ((Integer )value); case SFIXED32: return CodedOutputStream.computeSFixed32SizeNoTag((Integer )value); case SFIXED64: return CodedOutputStream.computeSFixed64SizeNoTag((Long )value); @@ -823,8 +865,12 @@ final class FieldSet<FieldDescriptorType extends } case ENUM: - return CodedOutputStream.computeEnumSizeNoTag( - ((Internal.EnumLite) value).getNumber()); + if (value instanceof Internal.EnumLite) { + return CodedOutputStream.computeEnumSizeNoTag( + ((Internal.EnumLite) value).getNumber()); + } else { + return CodedOutputStream.computeEnumSizeNoTag((Integer) value); + } } throw new RuntimeException( |