diff options
Diffstat (limited to 'java/src/main/java/com/google/protobuf/FieldSet.java')
-rw-r--r-- | java/src/main/java/com/google/protobuf/FieldSet.java | 433 |
1 files changed, 314 insertions, 119 deletions
diff --git a/java/src/main/java/com/google/protobuf/FieldSet.java b/java/src/main/java/com/google/protobuf/FieldSet.java index 93e55f2..392f4ef 100644 --- a/java/src/main/java/com/google/protobuf/FieldSet.java +++ b/java/src/main/java/com/google/protobuf/FieldSet.java @@ -1,6 +1,6 @@ // Protocol Buffers - Google's data interchange format // Copyright 2008 Google Inc. All rights reserved. -// http://code.google.com/p/protobuf/ +// https://developers.google.com/protocol-buffers/ // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are @@ -30,13 +30,14 @@ package com.google.protobuf; +import com.google.protobuf.LazyField.LazyIterator; + +import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; -import java.util.TreeMap; import java.util.List; import java.util.Map; -import java.io.IOException; /** * A class which represents an arbitrary set of fields of some message type. @@ -67,16 +68,13 @@ final class FieldSet<FieldDescriptorType extends MessageLite.Builder to, MessageLite from); } - private Map<FieldDescriptorType, Object> fields; + private final SmallSortedMap<FieldDescriptorType, Object> fields; + private boolean isImmutable; + private boolean hasLazyField = false; /** Construct a new FieldSet. */ private FieldSet() { - // Use a TreeMap because fields need to be in canonical order when - // serializing. - // TODO(kenton): Maybe use some sort of sparse array instead? It would - // even make sense to store the first 16 or so tags in a flat array - // to make DynamicMessage faster. - fields = new TreeMap<FieldDescriptorType, Object>(); + this.fields = SmallSortedMap.newFieldMap(16); } /** @@ -84,7 +82,8 @@ final class FieldSet<FieldDescriptorType extends * DEFAULT_INSTANCE. */ private FieldSet(final boolean dummy) { - this.fields = Collections.emptyMap(); + this.fields = SmallSortedMap.newFieldMap(0); + makeImmutable(); } /** Construct a new FieldSet. */ @@ -99,41 +98,106 @@ final class FieldSet<FieldDescriptorType extends FieldSet<T> emptySet() { return DEFAULT_INSTANCE; } - @SuppressWarnings("unchecked") + @SuppressWarnings("rawtypes") private static final FieldSet DEFAULT_INSTANCE = new FieldSet(true); /** Make this FieldSet immutable from this point forward. */ @SuppressWarnings("unchecked") public void makeImmutable() { - for (final Map.Entry<FieldDescriptorType, Object> entry: - fields.entrySet()) { - if (entry.getKey().isRepeated()) { - final List value = (List)entry.getValue(); - fields.put(entry.getKey(), Collections.unmodifiableList(value)); - } + if (isImmutable) { + return; + } + fields.makeImmutable(); + isImmutable = true; + } + + /** + * Returns whether the FieldSet is immutable. This is true if it is the + * {@link #emptySet} or if {@link #makeImmutable} were called. + * + * @return whether the FieldSet is immutable. + */ + public boolean isImmutable() { + return isImmutable; + } + + /** + * Clones the FieldSet. The returned FieldSet will be mutable even if the + * original FieldSet was immutable. + * + * @return the newly cloned FieldSet + */ + @Override + public FieldSet<FieldDescriptorType> clone() { + // We can't just call fields.clone because List objects in the map + // should not be shared. + FieldSet<FieldDescriptorType> clone = FieldSet.newFieldSet(); + for (int i = 0; i < fields.getNumArrayEntries(); i++) { + Map.Entry<FieldDescriptorType, Object> entry = fields.getArrayEntryAt(i); + FieldDescriptorType descriptor = entry.getKey(); + clone.setField(descriptor, entry.getValue()); + } + for (Map.Entry<FieldDescriptorType, Object> entry : + fields.getOverflowEntries()) { + FieldDescriptorType descriptor = entry.getKey(); + clone.setField(descriptor, entry.getValue()); } - fields = Collections.unmodifiableMap(fields); + clone.hasLazyField = hasLazyField; + return clone; } + // ================================================================= /** See {@link Message.Builder#clear()}. */ public void clear() { fields.clear(); + hasLazyField = false; } /** * Get a simple map containing all the fields. */ public Map<FieldDescriptorType, Object> getAllFields() { - return Collections.unmodifiableMap(fields); + if (hasLazyField) { + SmallSortedMap<FieldDescriptorType, Object> result = + SmallSortedMap.newFieldMap(16); + for (int i = 0; i < fields.getNumArrayEntries(); i++) { + cloneFieldEntry(result, fields.getArrayEntryAt(i)); + } + for (Map.Entry<FieldDescriptorType, Object> entry : + fields.getOverflowEntries()) { + cloneFieldEntry(result, entry); + } + if (fields.isImmutable()) { + result.makeImmutable(); + } + return result; + } + return fields.isImmutable() ? fields : Collections.unmodifiableMap(fields); + } + + private void cloneFieldEntry(Map<FieldDescriptorType, Object> map, + Map.Entry<FieldDescriptorType, Object> entry) { + FieldDescriptorType key = entry.getKey(); + Object value = entry.getValue(); + if (value instanceof LazyField) { + map.put(key, ((LazyField) value).getValue()); + } else { + map.put(key, value); + } } /** - * Get an iterator to the field map. This iterator should not be leaked - * out of the protobuf library as it is not protected from mutation. + * Get an iterator to the field map. This iterator should not be leaked out + * of the protobuf library as it is not protected from mutation when fields + * is not immutable. */ public Iterator<Map.Entry<FieldDescriptorType, Object>> iterator() { + if (hasLazyField) { + return new LazyIterator<FieldDescriptorType>( + fields.entrySet().iterator()); + } return fields.entrySet().iterator(); } @@ -157,14 +221,18 @@ final class FieldSet<FieldDescriptorType extends * to the caller to fetch the field's default value. */ public Object getField(final FieldDescriptorType descriptor) { - return fields.get(descriptor); + Object o = fields.get(descriptor); + if (o instanceof LazyField) { + return ((LazyField) o).getValue(); + } + return o; } /** * Useful for implementing * {@link Message.Builder#setField(Descriptors.FieldDescriptor,Object)}. */ - @SuppressWarnings("unchecked") + @SuppressWarnings({"unchecked", "rawtypes"}) public void setField(final FieldDescriptorType descriptor, Object value) { if (descriptor.isRepeated()) { @@ -176,7 +244,7 @@ final class FieldSet<FieldDescriptorType extends // Wrap the contents in a new list so that the caller cannot change // the list's contents after setting it. final List newList = new ArrayList(); - newList.addAll((List)value); + newList.addAll((List) value); for (final Object element : newList) { verifyType(descriptor.getLiteType(), element); } @@ -185,6 +253,9 @@ final class FieldSet<FieldDescriptorType extends verifyType(descriptor.getLiteType(), value); } + if (value instanceof LazyField) { + hasLazyField = true; + } fields.put(descriptor, value); } @@ -194,6 +265,9 @@ final class FieldSet<FieldDescriptorType extends */ public void clearField(final FieldDescriptorType descriptor) { fields.remove(descriptor); + if (fields.isEmpty()) { + hasLazyField = false; + } } /** @@ -206,11 +280,11 @@ final class FieldSet<FieldDescriptorType extends "getRepeatedField() can only be called on repeated fields."); } - final Object value = fields.get(descriptor); + final Object value = getField(descriptor); if (value == null) { return 0; } else { - return ((List) value).size(); + return ((List<?>) value).size(); } } @@ -225,12 +299,12 @@ final class FieldSet<FieldDescriptorType extends "getRepeatedField() can only be called on repeated fields."); } - final Object value = fields.get(descriptor); + final Object value = getField(descriptor); if (value == null) { throw new IndexOutOfBoundsException(); } else { - return ((List) value).get(index); + return ((List<?>) value).get(index); } } @@ -247,13 +321,13 @@ final class FieldSet<FieldDescriptorType extends "getRepeatedField() can only be called on repeated fields."); } - final Object list = fields.get(descriptor); + final Object list = getField(descriptor); if (list == null) { throw new IndexOutOfBoundsException(); } verifyType(descriptor.getLiteType(), value); - ((List) list).set(index, value); + ((List<Object>) list).set(index, value); } /** @@ -270,13 +344,13 @@ final class FieldSet<FieldDescriptorType extends verifyType(descriptor.getLiteType(), value); - final Object existingValue = fields.get(descriptor); - List list; + final Object existingValue = getField(descriptor); + List<Object> list; if (existingValue == null) { - list = new ArrayList(); + list = new ArrayList<Object>(); fields.put(descriptor, list); } else { - list = (List) existingValue; + list = (List<Object>) existingValue; } list.add(value); @@ -303,14 +377,18 @@ 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. - isValid = value instanceof MessageLite; + isValid = + (value instanceof MessageLite) || (value instanceof LazyField); break; } @@ -336,27 +414,47 @@ final class FieldSet<FieldDescriptorType extends * aren't actually present in the set, it is up to the caller to check * that all required fields are present. */ - @SuppressWarnings("unchecked") public boolean isInitialized() { - for (final Map.Entry<FieldDescriptorType, Object> entry: - fields.entrySet()) { - final FieldDescriptorType descriptor = entry.getKey(); - if (descriptor.getLiteJavaType() == WireFormat.JavaType.MESSAGE) { - if (descriptor.isRepeated()) { - for (final MessageLite element: - (List<MessageLite>) entry.getValue()) { - if (!element.isInitialized()) { - return false; - } + for (int i = 0; i < fields.getNumArrayEntries(); i++) { + if (!isInitialized(fields.getArrayEntryAt(i))) { + return false; + } + } + for (final Map.Entry<FieldDescriptorType, Object> entry : + fields.getOverflowEntries()) { + if (!isInitialized(entry)) { + return false; + } + } + return true; + } + + @SuppressWarnings("unchecked") + private boolean isInitialized( + final Map.Entry<FieldDescriptorType, Object> entry) { + final FieldDescriptorType descriptor = entry.getKey(); + if (descriptor.getLiteJavaType() == WireFormat.JavaType.MESSAGE) { + if (descriptor.isRepeated()) { + for (final MessageLite element: + (List<MessageLite>) entry.getValue()) { + if (!element.isInitialized()) { + return false; } - } else { - if (!((MessageLite) entry.getValue()).isInitialized()) { + } + } else { + Object value = entry.getValue(); + if (value instanceof MessageLite) { + if (!((MessageLite) value).isInitialized()) { return false; } + } else if (value instanceof LazyField) { + return true; + } else { + throw new IllegalArgumentException( + "Wrong object type used with protocol message reflection."); } } } - return true; } @@ -376,41 +474,62 @@ final class FieldSet<FieldDescriptorType extends } /** - * Like {@link #mergeFrom(Message)}, but merges from another {@link FieldSet}. + * Like {@link Message.Builder#mergeFrom(Message)}, but merges from another + * {@link FieldSet}. */ - @SuppressWarnings("unchecked") public void mergeFrom(final FieldSet<FieldDescriptorType> other) { - for (final Map.Entry<FieldDescriptorType, Object> entry: - other.fields.entrySet()) { - final FieldDescriptorType descriptor = entry.getKey(); - final Object otherValue = entry.getValue(); + for (int i = 0; i < other.fields.getNumArrayEntries(); i++) { + mergeFromField(other.fields.getArrayEntryAt(i)); + } + for (final Map.Entry<FieldDescriptorType, Object> entry : + other.fields.getOverflowEntries()) { + mergeFromField(entry); + } + } - if (descriptor.isRepeated()) { - Object value = fields.get(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); - } - } else if (descriptor.getLiteJavaType() == WireFormat.JavaType.MESSAGE) { - Object value = fields.get(descriptor); - if (value == null) { - fields.put(descriptor, otherValue); - } else { - // Merge the messages. - fields.put(descriptor, - descriptor.internalMergeFrom( - ((MessageLite) value).toBuilder(), (MessageLite) otherValue) - .build()); - } + 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) { + final FieldDescriptorType descriptor = entry.getKey(); + Object otherValue = entry.getValue(); + if (otherValue instanceof LazyField) { + otherValue = ((LazyField) otherValue).getValue(); + } + if (descriptor.isRepeated()) { + Object value = getField(descriptor); + if (value == null) { + 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, cloneIfMutable(otherValue)); } else { - fields.put(descriptor, otherValue); + // Merge the messages. + value = descriptor.internalMergeFrom( + ((MessageLite) value).toBuilder(), (MessageLite) otherValue) + .build(); + + fields.put(descriptor, value); } + } else { + fields.put(descriptor, cloneIfMutable(otherValue)); } } @@ -418,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 @@ -430,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 (); @@ -440,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(); @@ -465,11 +591,17 @@ 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 { - for (final Map.Entry<FieldDescriptorType, Object> entry: - fields.entrySet()) { + for (int i = 0; i < fields.getNumArrayEntries(); i++) { + final Map.Entry<FieldDescriptorType, Object> entry = + fields.getArrayEntryAt(i); + writeField(entry.getKey(), entry.getValue(), output); + } + for (final Map.Entry<FieldDescriptorType, Object> entry : + fields.getOverflowEntries()) { writeField(entry.getKey(), entry.getValue(), output); } } @@ -479,16 +611,29 @@ final class FieldSet<FieldDescriptorType extends */ public void writeMessageSetTo(final CodedOutputStream output) throws IOException { - for (final Map.Entry<FieldDescriptorType, Object> entry: - fields.entrySet()) { - final FieldDescriptorType descriptor = entry.getKey(); - if (descriptor.getLiteJavaType() == WireFormat.JavaType.MESSAGE && - !descriptor.isRepeated() && !descriptor.isPacked()) { - output.writeMessageSetExtension(entry.getKey().getNumber(), - (MessageLite) entry.getValue()); - } else { - writeField(descriptor, entry.getValue(), output); + for (int i = 0; i < fields.getNumArrayEntries(); i++) { + writeMessageSetTo(fields.getArrayEntryAt(i), output); + } + for (final Map.Entry<FieldDescriptorType, Object> entry : + fields.getOverflowEntries()) { + writeMessageSetTo(entry, output); + } + } + + private void writeMessageSetTo( + final Map.Entry<FieldDescriptorType, Object> entry, + final CodedOutputStream output) throws IOException { + 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) value); + } else { + writeField(descriptor, entry.getValue(), output); } } @@ -510,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); @@ -543,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; @@ -551,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; } } @@ -564,7 +719,7 @@ final class FieldSet<FieldDescriptorType extends WireFormat.FieldType type = descriptor.getLiteType(); int number = descriptor.getNumber(); if (descriptor.isRepeated()) { - final List valueList = (List)value; + final List<?> valueList = (List<?>)value; if (descriptor.isPacked()) { output.writeTag(number, WireFormat.WIRETYPE_LENGTH_DELIMITED); // Compute the total data size so the length can be written. @@ -583,7 +738,11 @@ final class FieldSet<FieldDescriptorType extends } } } else { - writeElement(output, type, number, value); + if (value instanceof LazyField) { + writeElement(output, type, number, ((LazyField) value).getValue()); + } else { + writeElement(output, type, number, value); + } } } @@ -593,8 +752,13 @@ final class FieldSet<FieldDescriptorType extends */ public int getSerializedSize() { int size = 0; - for (final Map.Entry<FieldDescriptorType, Object> entry: - fields.entrySet()) { + for (int i = 0; i < fields.getNumArrayEntries(); i++) { + final Map.Entry<FieldDescriptorType, Object> entry = + fields.getArrayEntryAt(i); + size += computeFieldSize(entry.getKey(), entry.getValue()); + } + for (final Map.Entry<FieldDescriptorType, Object> entry : + fields.getOverflowEntries()) { size += computeFieldSize(entry.getKey(), entry.getValue()); } return size; @@ -605,18 +769,32 @@ final class FieldSet<FieldDescriptorType extends */ public int getMessageSetSerializedSize() { int size = 0; - for (final Map.Entry<FieldDescriptorType, Object> entry: - fields.entrySet()) { - final FieldDescriptorType descriptor = entry.getKey(); - if (descriptor.getLiteJavaType() == WireFormat.JavaType.MESSAGE && - !descriptor.isRepeated() && !descriptor.isPacked()) { - size += CodedOutputStream.computeMessageSetExtensionSize( - entry.getKey().getNumber(), (MessageLite) entry.getValue()); + for (int i = 0; i < fields.getNumArrayEntries(); i++) { + size += getMessageSetSerializedSize(fields.getArrayEntryAt(i)); + } + for (final Map.Entry<FieldDescriptorType, Object> entry : + fields.getOverflowEntries()) { + size += getMessageSetSerializedSize(entry); + } + return size; + } + + private int getMessageSetSerializedSize( + final Map.Entry<FieldDescriptorType, Object> entry) { + final FieldDescriptorType descriptor = entry.getKey(); + Object value = entry.getValue(); + if (descriptor.getLiteJavaType() == WireFormat.JavaType.MESSAGE + && !descriptor.isRepeated() && !descriptor.isPacked()) { + if (value instanceof LazyField) { + return CodedOutputStream.computeLazyFieldMessageSetExtensionSize( + entry.getKey().getNumber(), (LazyField) value); } else { - size += computeFieldSize(descriptor, entry.getValue()); + return CodedOutputStream.computeMessageSetExtensionSize( + entry.getKey().getNumber(), (MessageLite) value); } + } else { + return computeFieldSize(descriptor, value); } - return size; } /** @@ -635,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); } @@ -665,17 +845,32 @@ 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 MESSAGE : return CodedOutputStream.computeMessageSizeNoTag ((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); case SINT32 : return CodedOutputStream.computeSInt32SizeNoTag ((Integer )value); case SINT64 : return CodedOutputStream.computeSInt64SizeNoTag ((Long )value); + case MESSAGE: + if (value instanceof LazyField) { + return CodedOutputStream.computeLazyFieldSizeNoTag((LazyField) value); + } else { + return CodedOutputStream.computeMessageSizeNoTag((MessageLite) value); + } + 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( @@ -692,7 +887,7 @@ final class FieldSet<FieldDescriptorType extends if (descriptor.isRepeated()) { if (descriptor.isPacked()) { int dataSize = 0; - for (final Object element : (List)value) { + for (final Object element : (List<?>)value) { dataSize += computeElementSizeNoTag(type, element); } return dataSize + @@ -700,7 +895,7 @@ final class FieldSet<FieldDescriptorType extends CodedOutputStream.computeRawVarint32Size(dataSize); } else { int size = 0; - for (final Object element : (List)value) { + for (final Object element : (List<?>)value) { size += computeElementSize(type, number, element); } return size; |