Index: third_party/protobuf/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java |
diff --git a/third_party/protobuf/java/core/src/main/java/com/google/protobuf/GeneratedMessage.java b/third_party/protobuf/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java |
similarity index 81% |
copy from third_party/protobuf/java/core/src/main/java/com/google/protobuf/GeneratedMessage.java |
copy to third_party/protobuf/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java |
index 790cb622a7eb84de07af5a1fad1ac5a2cf12d59a..2a5d8b50b7f0d8a2c7373c6c7d4911c4b408d0bb 100644 |
--- a/third_party/protobuf/java/core/src/main/java/com/google/protobuf/GeneratedMessage.java |
+++ b/third_party/protobuf/java/core/src/main/java/com/google/protobuf/GeneratedMessageV3.java |
@@ -36,6 +36,17 @@ import com.google.protobuf.Descriptors.EnumValueDescriptor; |
import com.google.protobuf.Descriptors.FieldDescriptor; |
import com.google.protobuf.Descriptors.FileDescriptor; |
import com.google.protobuf.Descriptors.OneofDescriptor; |
+// In opensource protobuf, we have versioned this GeneratedMessageV3 class to GeneratedMessageV3V3 and |
+// in the future may have GeneratedMessageV3V4 etc. This allows us to change some aspects of this |
+// class without breaking binary compatibility with old generated code that still subclasses |
+// the old GeneratedMessageV3 class. To allow these different GeneratedMessageV3V? classes to |
+// interoperate (e.g., a GeneratedMessageV3V3 object has a message extension field whose class |
+// type is GeneratedMessageV3V4), these classes still share a common parent class AbstarctMessage |
+// and are using the same GeneratedMessage.GeneratedExtension class for extension definitions. |
+// Since this class becomes GeneratedMessageV3V? in opensource, we have to add an import here |
+// to be able to use GeneratedMessage.GeneratedExtension. The GeneratedExtension definition in |
+// this file is also excluded from opensource to avoid conflict. |
+import com.google.protobuf.GeneratedMessage.GeneratedExtension; |
import java.io.IOException; |
import java.io.InputStream; |
@@ -44,6 +55,7 @@ import java.io.Serializable; |
import java.lang.reflect.InvocationTargetException; |
import java.lang.reflect.Method; |
import java.util.ArrayList; |
+import java.util.Arrays; |
import java.util.Collections; |
import java.util.Iterator; |
import java.util.List; |
@@ -58,7 +70,7 @@ import java.util.TreeMap; |
* |
* @author kenton@google.com Kenton Varda |
*/ |
-public abstract class GeneratedMessage extends AbstractMessage |
+public abstract class GeneratedMessageV3 extends AbstractMessage |
implements Serializable { |
private static final long serialVersionUID = 1L; |
@@ -72,16 +84,16 @@ public abstract class GeneratedMessage extends AbstractMessage |
/** For use by generated code only. */ |
protected UnknownFieldSet unknownFields; |
- protected GeneratedMessage() { |
+ protected GeneratedMessageV3() { |
unknownFields = UnknownFieldSet.getDefaultInstance(); |
} |
- protected GeneratedMessage(Builder<?> builder) { |
+ protected GeneratedMessageV3(Builder<?> builder) { |
unknownFields = builder.getUnknownFields(); |
} |
@Override |
- public Parser<? extends GeneratedMessage> getParserForType() { |
+ public Parser<? extends GeneratedMessageV3> getParserForType() { |
throw new UnsupportedOperationException( |
"This is supposed to be overridden by subclasses."); |
} |
@@ -355,31 +367,30 @@ public abstract class GeneratedMessage extends AbstractMessage |
// Noop for messages without extensions. |
} |
- protected abstract Message.Builder newBuilderForType(BuilderParent parent); |
+ /** |
+ * TODO(xiaofeng): remove this after b/29368482 is fixed. We need to move this |
+ * interface to AbstractMessage in order to versioning GeneratedMessageV3 but |
+ * this move breaks binary compatibility for AppEngine. After AppEngine is |
+ * fixed we can exlude this from google3. |
+ */ |
+ protected interface BuilderParent extends AbstractMessage.BuilderParent {} |
/** |
- * Interface for the parent of a Builder that allows the builder to |
- * communicate invalidations back to the parent for use when using nested |
- * builders. |
+ * TODO(xiaofeng): remove this together with GeneratedMessageV3.BuilderParent. |
*/ |
- protected interface BuilderParent { |
+ protected abstract Message.Builder newBuilderForType(BuilderParent parent); |
- /** |
- * A builder becomes dirty whenever a field is modified -- including fields |
- * in nested builders -- and becomes clean when build() is called. Thus, |
- * when a builder becomes dirty, all its parents become dirty as well, and |
- * when it becomes clean, all its children become clean. The dirtiness |
- * state is used to invalidate certain cached values. |
- * <br> |
- * To this end, a builder calls markAsDirty() on its parent whenever it |
- * transitions from clean to dirty. The parent must propagate this call to |
- * its own parent, unless it was already dirty, in which case the |
- * grandparent must necessarily already be dirty as well. The parent can |
- * only transition back to "clean" after calling build() on all children. |
- */ |
- void markDirty(); |
+ @Override |
+ protected Message.Builder newBuilderForType(final AbstractMessage.BuilderParent parent) { |
+ return newBuilderForType(new BuilderParent() { |
+ @Override |
+ public void markDirty() { |
+ parent.markDirty(); |
+ } |
+ }); |
} |
+ |
@SuppressWarnings("unchecked") |
public abstract static class Builder <BuilderType extends Builder<BuilderType>> |
extends AbstractMessage.Builder<BuilderType> { |
@@ -389,7 +400,7 @@ public abstract class GeneratedMessage extends AbstractMessage |
private BuilderParentImpl meAsParent; |
// Indicates that we've built a message and so we are now obligated |
- // to dispatch dirty invalidations. See GeneratedMessage.BuilderListener. |
+ // to dispatch dirty invalidations. See GeneratedMessageV3.BuilderListener. |
private boolean isClean; |
private UnknownFieldSet unknownFields = |
@@ -403,6 +414,7 @@ public abstract class GeneratedMessage extends AbstractMessage |
this.builderParent = builderParent; |
} |
+ @Override |
void dispose() { |
builderParent = null; |
} |
@@ -420,6 +432,7 @@ public abstract class GeneratedMessage extends AbstractMessage |
* Called by the subclass or a builder to notify us that a message was |
* built and may be cached and therefore invalidations are needed. |
*/ |
+ @Override |
protected void markClean() { |
this.isClean = true; |
} |
@@ -755,6 +768,33 @@ public abstract class GeneratedMessage extends AbstractMessage |
<Type> Type getExtension( |
ExtensionLite<MessageType, List<Type>> extension, |
int index); |
+ |
+ /** Check if a singular extension is present. */ |
+ <Type> boolean hasExtension( |
+ Extension<MessageType, Type> extension); |
+ /** Check if a singular extension is present. */ |
+ <Type> boolean hasExtension( |
+ GeneratedExtension<MessageType, Type> extension); |
+ /** Get the number of elements in a repeated extension. */ |
+ <Type> int getExtensionCount( |
+ Extension<MessageType, List<Type>> extension); |
+ /** Get the number of elements in a repeated extension. */ |
+ <Type> int getExtensionCount( |
+ GeneratedExtension<MessageType, List<Type>> extension); |
+ /** Get the value of an extension. */ |
+ <Type> Type getExtension( |
+ Extension<MessageType, Type> extension); |
+ /** Get the value of an extension. */ |
+ <Type> Type getExtension( |
+ GeneratedExtension<MessageType, Type> extension); |
+ /** Get one element of a repeated extension. */ |
+ <Type> Type getExtension( |
+ Extension<MessageType, List<Type>> extension, |
+ int index); |
+ /** Get one element of a repeated extension. */ |
+ <Type> Type getExtension( |
+ GeneratedExtension<MessageType, List<Type>> extension, |
+ int index); |
} |
/** |
@@ -794,7 +834,7 @@ public abstract class GeneratedMessage extends AbstractMessage |
*/ |
public abstract static class ExtendableMessage< |
MessageType extends ExtendableMessage> |
- extends GeneratedMessage |
+ extends GeneratedMessageV3 |
implements ExtendableMessageOrBuilder<MessageType> { |
private static final long serialVersionUID = 1L; |
@@ -881,6 +921,53 @@ public abstract class GeneratedMessage extends AbstractMessage |
extensions.getRepeatedField(descriptor, index)); |
} |
+ /** Check if a singular extension is present. */ |
+ @Override |
+ public final <Type> boolean hasExtension(final Extension<MessageType, Type> extension) { |
+ return hasExtension((ExtensionLite<MessageType, Type>) extension); |
+ } |
+ /** Check if a singular extension is present. */ |
+ @Override |
+ public final <Type> boolean hasExtension( |
+ final GeneratedExtension<MessageType, Type> extension) { |
+ return hasExtension((ExtensionLite<MessageType, Type>) extension); |
+ } |
+ /** Get the number of elements in a repeated extension. */ |
+ @Override |
+ public final <Type> int getExtensionCount( |
+ final Extension<MessageType, List<Type>> extension) { |
+ return getExtensionCount((ExtensionLite<MessageType, List<Type>>) extension); |
+ } |
+ /** Get the number of elements in a repeated extension. */ |
+ @Override |
+ public final <Type> int getExtensionCount( |
+ final GeneratedExtension<MessageType, List<Type>> extension) { |
+ return getExtensionCount((ExtensionLite<MessageType, List<Type>>) extension); |
+ } |
+ /** Get the value of an extension. */ |
+ @Override |
+ public final <Type> Type getExtension(final Extension<MessageType, Type> extension) { |
+ return getExtension((ExtensionLite<MessageType, Type>) extension); |
+ } |
+ /** Get the value of an extension. */ |
+ @Override |
+ public final <Type> Type getExtension( |
+ final GeneratedExtension<MessageType, Type> extension) { |
+ return getExtension((ExtensionLite<MessageType, Type>) extension); |
+ } |
+ /** Get one element of a repeated extension. */ |
+ @Override |
+ public final <Type> Type getExtension( |
+ final Extension<MessageType, List<Type>> extension, final int index) { |
+ return getExtension((ExtensionLite<MessageType, List<Type>>) extension, index); |
+ } |
+ /** Get one element of a repeated extension. */ |
+ @Override |
+ public final <Type> Type getExtension( |
+ final GeneratedExtension<MessageType, List<Type>> extension, final int index) { |
+ return getExtension((ExtensionLite<MessageType, List<Type>>) extension, index); |
+ } |
+ |
/** Called by subclasses to check if all extensions are initialized. */ |
protected boolean extensionsAreInitialized() { |
return extensions.isInitialized(); |
@@ -1130,14 +1217,6 @@ public abstract class GeneratedMessage extends AbstractMessage |
return super.clear(); |
} |
- // This is implemented here only to work around an apparent bug in the |
- // Java compiler and/or build system. See bug #1898463. The mere presence |
- // of this clone() implementation makes it go away. |
- @Override |
- public BuilderType clone() { |
- return super.clone(); |
- } |
- |
private void ensureExtensionsIsMutable() { |
if (extensions.isImmutable()) { |
extensions = extensions.clone(); |
@@ -1269,6 +1348,95 @@ public abstract class GeneratedMessage extends AbstractMessage |
return (BuilderType) this; |
} |
+ /** Check if a singular extension is present. */ |
+ @Override |
+ public final <Type> boolean hasExtension(final Extension<MessageType, Type> extension) { |
+ return hasExtension((ExtensionLite<MessageType, Type>) extension); |
+ } |
+ /** Check if a singular extension is present. */ |
+ @Override |
+ public final <Type> boolean hasExtension( |
+ final GeneratedExtension<MessageType, Type> extension) { |
+ return hasExtension((ExtensionLite<MessageType, Type>) extension); |
+ } |
+ /** Get the number of elements in a repeated extension. */ |
+ @Override |
+ public final <Type> int getExtensionCount( |
+ final Extension<MessageType, List<Type>> extension) { |
+ return getExtensionCount((ExtensionLite<MessageType, List<Type>>) extension); |
+ } |
+ /** Get the number of elements in a repeated extension. */ |
+ @Override |
+ public final <Type> int getExtensionCount( |
+ final GeneratedExtension<MessageType, List<Type>> extension) { |
+ return getExtensionCount((ExtensionLite<MessageType, List<Type>>) extension); |
+ } |
+ /** Get the value of an extension. */ |
+ @Override |
+ public final <Type> Type getExtension(final Extension<MessageType, Type> extension) { |
+ return getExtension((ExtensionLite<MessageType, Type>) extension); |
+ } |
+ /** Get the value of an extension. */ |
+ @Override |
+ public final <Type> Type getExtension( |
+ final GeneratedExtension<MessageType, Type> extension) { |
+ return getExtension((ExtensionLite<MessageType, Type>) extension); |
+ } |
+ /** Get the value of an extension. */ |
+ @Override |
+ public final <Type> Type getExtension( |
+ final Extension<MessageType, List<Type>> extension, final int index) { |
+ return getExtension((ExtensionLite<MessageType, List<Type>>) extension, index); |
+ } |
+ /** Get the value of an extension. */ |
+ @Override |
+ public final <Type> Type getExtension( |
+ final GeneratedExtension<MessageType, List<Type>> extension, final int index) { |
+ return getExtension((ExtensionLite<MessageType, List<Type>>) extension, index); |
+ } |
+ /** Set the value of an extension. */ |
+ public final <Type> BuilderType setExtension( |
+ final Extension<MessageType, Type> extension, final Type value) { |
+ return setExtension((ExtensionLite<MessageType, Type>) extension, value); |
+ } |
+ /** Set the value of an extension. */ |
+ public <Type> BuilderType setExtension( |
+ final GeneratedExtension<MessageType, Type> extension, final Type value) { |
+ return setExtension((ExtensionLite<MessageType, Type>) extension, value); |
+ } |
+ /** Set the value of one element of a repeated extension. */ |
+ public final <Type> BuilderType setExtension( |
+ final Extension<MessageType, List<Type>> extension, |
+ final int index, final Type value) { |
+ return setExtension((ExtensionLite<MessageType, List<Type>>) extension, index, value); |
+ } |
+ /** Set the value of one element of a repeated extension. */ |
+ public <Type> BuilderType setExtension( |
+ final GeneratedExtension<MessageType, List<Type>> extension, |
+ final int index, final Type value) { |
+ return setExtension((ExtensionLite<MessageType, List<Type>>) extension, index, value); |
+ } |
+ /** Append a value to a repeated extension. */ |
+ public final <Type> BuilderType addExtension( |
+ final Extension<MessageType, List<Type>> extension, final Type value) { |
+ return addExtension((ExtensionLite<MessageType, List<Type>>) extension, value); |
+ } |
+ /** Append a value to a repeated extension. */ |
+ public <Type> BuilderType addExtension( |
+ final GeneratedExtension<MessageType, List<Type>> extension, final Type value) { |
+ return addExtension((ExtensionLite<MessageType, List<Type>>) extension, value); |
+ } |
+ /** Clear an extension. */ |
+ public final <Type> BuilderType clearExtension( |
+ final Extension<MessageType, ?> extension) { |
+ return clearExtension((ExtensionLite<MessageType, ?>) extension); |
+ } |
+ /** Clear an extension. */ |
+ public <Type> BuilderType clearExtension( |
+ final GeneratedExtension<MessageType, ?> extension) { |
+ return clearExtension((ExtensionLite<MessageType, ?>) extension); |
+ } |
+ |
/** Called by subclasses to check if all extensions are initialized. */ |
protected boolean extensionsAreInitialized() { |
return extensions.isInitialized(); |
@@ -1444,355 +1612,6 @@ public abstract class GeneratedMessage extends AbstractMessage |
FieldDescriptor getDescriptor(); |
} |
- /** For use by generated code only. */ |
- public static <ContainingType extends Message, Type> |
- GeneratedExtension<ContainingType, Type> |
- newMessageScopedGeneratedExtension(final Message scope, |
- final int descriptorIndex, |
- final Class singularType, |
- final Message defaultInstance) { |
- // For extensions scoped within a Message, we use the Message to resolve |
- // the outer class's descriptor, from which the extension descriptor is |
- // obtained. |
- return new GeneratedExtension<ContainingType, Type>( |
- new CachedDescriptorRetriever() { |
- @Override |
- public FieldDescriptor loadDescriptor() { |
- return scope.getDescriptorForType().getExtensions().get(descriptorIndex); |
- } |
- }, |
- singularType, |
- defaultInstance, |
- Extension.ExtensionType.IMMUTABLE); |
- } |
- |
- /** For use by generated code only. */ |
- public static <ContainingType extends Message, Type> |
- GeneratedExtension<ContainingType, Type> |
- newFileScopedGeneratedExtension(final Class singularType, |
- final Message defaultInstance) { |
- // For extensions scoped within a file, we rely on the outer class's |
- // static initializer to call internalInit() on the extension when the |
- // descriptor is available. |
- return new GeneratedExtension<ContainingType, Type>( |
- null, // ExtensionDescriptorRetriever is initialized in internalInit(); |
- singularType, |
- defaultInstance, |
- Extension.ExtensionType.IMMUTABLE); |
- } |
- |
- private abstract static class CachedDescriptorRetriever |
- implements ExtensionDescriptorRetriever { |
- private volatile FieldDescriptor descriptor; |
- protected abstract FieldDescriptor loadDescriptor(); |
- |
- @Override |
- public FieldDescriptor getDescriptor() { |
- if (descriptor == null) { |
- synchronized (this) { |
- if (descriptor == null) { |
- descriptor = loadDescriptor(); |
- } |
- } |
- } |
- return descriptor; |
- } |
- } |
- |
- /** |
- * Used in proto1 generated code only. |
- * |
- * After enabling bridge, we can define proto2 extensions (the extended type |
- * is a proto2 mutable message) in a proto1 .proto file. For these extensions |
- * we should generate proto2 GeneratedExtensions. |
- */ |
- public static <ContainingType extends Message, Type> |
- GeneratedExtension<ContainingType, Type> |
- newMessageScopedGeneratedExtension( |
- final Message scope, final String name, |
- final Class singularType, final Message defaultInstance) { |
- // For extensions scoped within a Message, we use the Message to resolve |
- // the outer class's descriptor, from which the extension descriptor is |
- // obtained. |
- return new GeneratedExtension<ContainingType, Type>( |
- new CachedDescriptorRetriever() { |
- @Override |
- protected FieldDescriptor loadDescriptor() { |
- return scope.getDescriptorForType().findFieldByName(name); |
- } |
- }, |
- singularType, |
- defaultInstance, |
- Extension.ExtensionType.MUTABLE); |
- } |
- |
- /** |
- * Used in proto1 generated code only. |
- * |
- * After enabling bridge, we can define proto2 extensions (the extended type |
- * is a proto2 mutable message) in a proto1 .proto file. For these extensions |
- * we should generate proto2 GeneratedExtensions. |
- */ |
- public static <ContainingType extends Message, Type> |
- GeneratedExtension<ContainingType, Type> |
- newFileScopedGeneratedExtension( |
- final Class singularType, final Message defaultInstance, |
- final String descriptorOuterClass, final String extensionName) { |
- // For extensions scoped within a file, we load the descriptor outer |
- // class and rely on it to get the FileDescriptor which then can be |
- // used to obtain the extension's FieldDescriptor. |
- return new GeneratedExtension<ContainingType, Type>( |
- new CachedDescriptorRetriever() { |
- @Override |
- protected FieldDescriptor loadDescriptor() { |
- try { |
- Class clazz = singularType.getClassLoader().loadClass(descriptorOuterClass); |
- FileDescriptor file = (FileDescriptor) clazz.getField("descriptor").get(null); |
- return file.findExtensionByName(extensionName); |
- } catch (Exception e) { |
- throw new RuntimeException( |
- "Cannot load descriptors: " |
- + descriptorOuterClass |
- + " is not a valid descriptor class name", |
- e); |
- } |
- } |
- }, |
- singularType, |
- defaultInstance, |
- Extension.ExtensionType.MUTABLE); |
- } |
- |
- /** |
- * Type used to represent generated extensions. The protocol compiler |
- * generates a static singleton instance of this class for each extension. |
- * |
- * <p>For example, imagine you have the {@code .proto} file: |
- * |
- * <pre> |
- * option java_class = "MyProto"; |
- * |
- * message Foo { |
- * extensions 1000 to max; |
- * } |
- * |
- * extend Foo { |
- * optional int32 bar; |
- * } |
- * </pre> |
- * |
- * <p>Then, {@code MyProto.Foo.bar} has type |
- * {@code GeneratedExtension<MyProto.Foo, Integer>}. |
- * |
- * <p>In general, users should ignore the details of this type, and simply use |
- * these static singletons as parameters to the extension accessors defined |
- * in {@link ExtendableMessage} and {@link ExtendableBuilder}. |
- */ |
- public static class GeneratedExtension< |
- ContainingType extends Message, Type> extends |
- Extension<ContainingType, Type> { |
- // TODO(kenton): Find ways to avoid using Java reflection within this |
- // class. Also try to avoid suppressing unchecked warnings. |
- |
- // We can't always initialize the descriptor of a GeneratedExtension when |
- // we first construct it due to initialization order difficulties (namely, |
- // the descriptor may not have been constructed yet, since it is often |
- // constructed by the initializer of a separate module). |
- // |
- // In the case of nested extensions, we initialize the |
- // ExtensionDescriptorRetriever with an instance that uses the scoping |
- // Message's default instance to retrieve the extension's descriptor. |
- // |
- // In the case of non-nested extensions, we initialize the |
- // ExtensionDescriptorRetriever to null and rely on the outer class's static |
- // initializer to call internalInit() after the descriptor has been parsed. |
- GeneratedExtension(ExtensionDescriptorRetriever descriptorRetriever, |
- Class singularType, |
- Message messageDefaultInstance, |
- ExtensionType extensionType) { |
- if (Message.class.isAssignableFrom(singularType) && |
- !singularType.isInstance(messageDefaultInstance)) { |
- throw new IllegalArgumentException( |
- "Bad messageDefaultInstance for " + singularType.getName()); |
- } |
- this.descriptorRetriever = descriptorRetriever; |
- this.singularType = singularType; |
- this.messageDefaultInstance = messageDefaultInstance; |
- |
- if (ProtocolMessageEnum.class.isAssignableFrom(singularType)) { |
- this.enumValueOf = getMethodOrDie(singularType, "valueOf", |
- EnumValueDescriptor.class); |
- this.enumGetValueDescriptor = |
- getMethodOrDie(singularType, "getValueDescriptor"); |
- } else { |
- this.enumValueOf = null; |
- this.enumGetValueDescriptor = null; |
- } |
- this.extensionType = extensionType; |
- } |
- |
- /** For use by generated code only. */ |
- public void internalInit(final FieldDescriptor descriptor) { |
- if (descriptorRetriever != null) { |
- throw new IllegalStateException("Already initialized."); |
- } |
- descriptorRetriever = |
- new ExtensionDescriptorRetriever() { |
- @Override |
- public FieldDescriptor getDescriptor() { |
- return descriptor; |
- } |
- }; |
- } |
- |
- private ExtensionDescriptorRetriever descriptorRetriever; |
- private final Class singularType; |
- private final Message messageDefaultInstance; |
- private final Method enumValueOf; |
- private final Method enumGetValueDescriptor; |
- private final ExtensionType extensionType; |
- |
- @Override |
- public FieldDescriptor getDescriptor() { |
- if (descriptorRetriever == null) { |
- throw new IllegalStateException( |
- "getDescriptor() called before internalInit()"); |
- } |
- return descriptorRetriever.getDescriptor(); |
- } |
- |
- /** |
- * If the extension is an embedded message or group, returns the default |
- * instance of the message. |
- */ |
- @Override |
- public Message getMessageDefaultInstance() { |
- return messageDefaultInstance; |
- } |
- |
- @Override |
- protected ExtensionType getExtensionType() { |
- return extensionType; |
- } |
- |
- /** |
- * Convert from the type used by the reflection accessors to the type used |
- * by native accessors. E.g., for enums, the reflection accessors use |
- * EnumValueDescriptors but the native accessors use the generated enum |
- * type. |
- */ |
- @Override |
- @SuppressWarnings("unchecked") |
- protected Object fromReflectionType(final Object value) { |
- FieldDescriptor descriptor = getDescriptor(); |
- if (descriptor.isRepeated()) { |
- if (descriptor.getJavaType() == FieldDescriptor.JavaType.MESSAGE || |
- descriptor.getJavaType() == FieldDescriptor.JavaType.ENUM) { |
- // Must convert the whole list. |
- final List result = new ArrayList(); |
- for (final Object element : (List) value) { |
- result.add(singularFromReflectionType(element)); |
- } |
- return result; |
- } else { |
- return value; |
- } |
- } else { |
- return singularFromReflectionType(value); |
- } |
- } |
- |
- /** |
- * Like {@link #fromReflectionType(Object)}, but if the type is a repeated |
- * type, this converts a single element. |
- */ |
- @Override |
- protected Object singularFromReflectionType(final Object value) { |
- FieldDescriptor descriptor = getDescriptor(); |
- switch (descriptor.getJavaType()) { |
- case MESSAGE: |
- if (singularType.isInstance(value)) { |
- return value; |
- } else { |
- return messageDefaultInstance.newBuilderForType() |
- .mergeFrom((Message) value).build(); |
- } |
- case ENUM: |
- return invokeOrDie(enumValueOf, null, (EnumValueDescriptor) value); |
- default: |
- return value; |
- } |
- } |
- |
- /** |
- * Convert from the type used by the native accessors to the type used |
- * by reflection accessors. E.g., for enums, the reflection accessors use |
- * EnumValueDescriptors but the native accessors use the generated enum |
- * type. |
- */ |
- @Override |
- @SuppressWarnings("unchecked") |
- protected Object toReflectionType(final Object value) { |
- FieldDescriptor descriptor = getDescriptor(); |
- if (descriptor.isRepeated()) { |
- if (descriptor.getJavaType() == FieldDescriptor.JavaType.ENUM) { |
- // Must convert the whole list. |
- final List result = new ArrayList(); |
- for (final Object element : (List) value) { |
- result.add(singularToReflectionType(element)); |
- } |
- return result; |
- } else { |
- return value; |
- } |
- } else { |
- return singularToReflectionType(value); |
- } |
- } |
- |
- /** |
- * Like {@link #toReflectionType(Object)}, but if the type is a repeated |
- * type, this converts a single element. |
- */ |
- @Override |
- protected Object singularToReflectionType(final Object value) { |
- FieldDescriptor descriptor = getDescriptor(); |
- switch (descriptor.getJavaType()) { |
- case ENUM: |
- return invokeOrDie(enumGetValueDescriptor, value); |
- default: |
- return value; |
- } |
- } |
- |
- @Override |
- public int getNumber() { |
- return getDescriptor().getNumber(); |
- } |
- |
- @Override |
- public WireFormat.FieldType getLiteType() { |
- return getDescriptor().getLiteType(); |
- } |
- |
- @Override |
- public boolean isRepeated() { |
- return getDescriptor().isRepeated(); |
- } |
- |
- @Override |
- @SuppressWarnings("unchecked") |
- public Type getDefaultValue() { |
- if (isRepeated()) { |
- return (Type) Collections.emptyList(); |
- } |
- if (getDescriptor().getJavaType() == FieldDescriptor.JavaType.MESSAGE) { |
- return (Type) messageDefaultInstance; |
- } |
- return (Type) singularFromReflectionType( |
- getDescriptor().getDefaultValue()); |
- } |
- } |
// ================================================================= |
@@ -1869,7 +1688,7 @@ public abstract class GeneratedMessage extends AbstractMessage |
public FieldAccessorTable( |
final Descriptor descriptor, |
final String[] camelCaseNames, |
- final Class<? extends GeneratedMessage> messageClass, |
+ final Class<? extends GeneratedMessageV3> messageClass, |
final Class<? extends Builder> builderClass) { |
this(descriptor, camelCaseNames); |
ensureFieldAccessorsInitialized(messageClass, builderClass); |
@@ -1889,11 +1708,6 @@ public abstract class GeneratedMessage extends AbstractMessage |
initialized = false; |
} |
- private boolean isMapFieldEnabled(FieldDescriptor field) { |
- boolean result = true; |
- return result; |
- } |
- |
/** |
* Ensures the field accessors are initialized. This method is thread-safe. |
* |
@@ -1902,7 +1716,7 @@ public abstract class GeneratedMessage extends AbstractMessage |
* @return this |
*/ |
public FieldAccessorTable ensureFieldAccessorsInitialized( |
- Class<? extends GeneratedMessage> messageClass, |
+ Class<? extends GeneratedMessageV3> messageClass, |
Class<? extends Builder> builderClass) { |
if (initialized) { return this; } |
synchronized (this) { |
@@ -1917,7 +1731,7 @@ public abstract class GeneratedMessage extends AbstractMessage |
} |
if (field.isRepeated()) { |
if (field.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { |
- if (field.isMapField() && isMapFieldEnabled(field)) { |
+ if (field.isMapField()) { |
fields[i] = new MapFieldAccessor( |
field, camelCaseNames[i], messageClass, builderClass); |
} else { |
@@ -1998,26 +1812,26 @@ public abstract class GeneratedMessage extends AbstractMessage |
* implemented differently depending on the field type and cardinality. |
*/ |
private interface FieldAccessor { |
- Object get(GeneratedMessage message); |
- Object get(GeneratedMessage.Builder builder); |
- Object getRaw(GeneratedMessage message); |
- Object getRaw(GeneratedMessage.Builder builder); |
+ Object get(GeneratedMessageV3 message); |
+ Object get(GeneratedMessageV3.Builder builder); |
+ Object getRaw(GeneratedMessageV3 message); |
+ Object getRaw(GeneratedMessageV3.Builder builder); |
void set(Builder builder, Object value); |
- Object getRepeated(GeneratedMessage message, int index); |
- Object getRepeated(GeneratedMessage.Builder builder, int index); |
- Object getRepeatedRaw(GeneratedMessage message, int index); |
- Object getRepeatedRaw(GeneratedMessage.Builder builder, int index); |
+ Object getRepeated(GeneratedMessageV3 message, int index); |
+ Object getRepeated(GeneratedMessageV3.Builder builder, int index); |
+ Object getRepeatedRaw(GeneratedMessageV3 message, int index); |
+ Object getRepeatedRaw(GeneratedMessageV3.Builder builder, int index); |
void setRepeated(Builder builder, |
int index, Object value); |
void addRepeated(Builder builder, Object value); |
- boolean has(GeneratedMessage message); |
- boolean has(GeneratedMessage.Builder builder); |
- int getRepeatedCount(GeneratedMessage message); |
- int getRepeatedCount(GeneratedMessage.Builder builder); |
+ boolean has(GeneratedMessageV3 message); |
+ boolean has(GeneratedMessageV3.Builder builder); |
+ int getRepeatedCount(GeneratedMessageV3 message); |
+ int getRepeatedCount(GeneratedMessageV3.Builder builder); |
void clear(Builder builder); |
Message.Builder newBuilder(); |
- Message.Builder getBuilder(GeneratedMessage.Builder builder); |
- Message.Builder getRepeatedBuilder(GeneratedMessage.Builder builder, |
+ Message.Builder getBuilder(GeneratedMessageV3.Builder builder); |
+ Message.Builder getRepeatedBuilder(GeneratedMessageV3.Builder builder, |
int index); |
} |
@@ -2025,7 +1839,7 @@ public abstract class GeneratedMessage extends AbstractMessage |
private static class OneofAccessor { |
OneofAccessor( |
final Descriptor descriptor, final String camelCaseName, |
- final Class<? extends GeneratedMessage> messageClass, |
+ final Class<? extends GeneratedMessageV3> messageClass, |
final Class<? extends Builder> builderClass) { |
this.descriptor = descriptor; |
caseMethod = |
@@ -2040,21 +1854,21 @@ public abstract class GeneratedMessage extends AbstractMessage |
private final Method caseMethodBuilder; |
private final Method clearMethod; |
- public boolean has(final GeneratedMessage message) { |
+ public boolean has(final GeneratedMessageV3 message) { |
if (((Internal.EnumLite) invokeOrDie(caseMethod, message)).getNumber() == 0) { |
return false; |
} |
return true; |
} |
- public boolean has(GeneratedMessage.Builder builder) { |
+ public boolean has(GeneratedMessageV3.Builder builder) { |
if (((Internal.EnumLite) invokeOrDie(caseMethodBuilder, builder)).getNumber() == 0) { |
return false; |
} |
return true; |
} |
- public FieldDescriptor get(final GeneratedMessage message) { |
+ public FieldDescriptor get(final GeneratedMessageV3 message) { |
int fieldNumber = ((Internal.EnumLite) invokeOrDie(caseMethod, message)).getNumber(); |
if (fieldNumber > 0) { |
return descriptor.findFieldByNumber(fieldNumber); |
@@ -2062,7 +1876,7 @@ public abstract class GeneratedMessage extends AbstractMessage |
return null; |
} |
- public FieldDescriptor get(GeneratedMessage.Builder builder) { |
+ public FieldDescriptor get(GeneratedMessageV3.Builder builder) { |
int fieldNumber = ((Internal.EnumLite) invokeOrDie(caseMethodBuilder, builder)).getNumber(); |
if (fieldNumber > 0) { |
return descriptor.findFieldByNumber(fieldNumber); |
@@ -2084,7 +1898,7 @@ public abstract class GeneratedMessage extends AbstractMessage |
private static class SingularFieldAccessor implements FieldAccessor { |
SingularFieldAccessor( |
final FieldDescriptor descriptor, final String camelCaseName, |
- final Class<? extends GeneratedMessage> messageClass, |
+ final Class<? extends GeneratedMessageV3> messageClass, |
final Class<? extends Builder> builderClass, |
final String containingOneofCamelCaseName) { |
field = descriptor; |
@@ -2122,28 +1936,28 @@ public abstract class GeneratedMessage extends AbstractMessage |
protected final boolean isOneofField; |
protected final boolean hasHasMethod; |
- private int getOneofFieldNumber(final GeneratedMessage message) { |
+ private int getOneofFieldNumber(final GeneratedMessageV3 message) { |
return ((Internal.EnumLite) invokeOrDie(caseMethod, message)).getNumber(); |
} |
- private int getOneofFieldNumber(final GeneratedMessage.Builder builder) { |
+ private int getOneofFieldNumber(final GeneratedMessageV3.Builder builder) { |
return ((Internal.EnumLite) invokeOrDie(caseMethodBuilder, builder)).getNumber(); |
} |
@Override |
- public Object get(final GeneratedMessage message) { |
+ public Object get(final GeneratedMessageV3 message) { |
return invokeOrDie(getMethod, message); |
} |
@Override |
- public Object get(GeneratedMessage.Builder builder) { |
+ public Object get(GeneratedMessageV3.Builder builder) { |
return invokeOrDie(getMethodBuilder, builder); |
} |
@Override |
- public Object getRaw(final GeneratedMessage message) { |
+ public Object getRaw(final GeneratedMessageV3 message) { |
return get(message); |
} |
@Override |
- public Object getRaw(GeneratedMessage.Builder builder) { |
+ public Object getRaw(GeneratedMessageV3.Builder builder) { |
return get(builder); |
} |
@Override |
@@ -2151,22 +1965,22 @@ public abstract class GeneratedMessage extends AbstractMessage |
invokeOrDie(setMethod, builder, value); |
} |
@Override |
- public Object getRepeated(final GeneratedMessage message, final int index) { |
+ public Object getRepeated(final GeneratedMessageV3 message, final int index) { |
throw new UnsupportedOperationException( |
"getRepeatedField() called on a singular field."); |
} |
@Override |
- public Object getRepeatedRaw(final GeneratedMessage message, final int index) { |
+ public Object getRepeatedRaw(final GeneratedMessageV3 message, final int index) { |
throw new UnsupportedOperationException( |
"getRepeatedFieldRaw() called on a singular field."); |
} |
@Override |
- public Object getRepeated(GeneratedMessage.Builder builder, int index) { |
+ public Object getRepeated(GeneratedMessageV3.Builder builder, int index) { |
throw new UnsupportedOperationException( |
"getRepeatedField() called on a singular field."); |
} |
@Override |
- public Object getRepeatedRaw(GeneratedMessage.Builder builder, int index) { |
+ public Object getRepeatedRaw(GeneratedMessageV3.Builder builder, int index) { |
throw new UnsupportedOperationException( |
"getRepeatedFieldRaw() called on a singular field."); |
} |
@@ -2181,7 +1995,7 @@ public abstract class GeneratedMessage extends AbstractMessage |
"addRepeatedField() called on a singular field."); |
} |
@Override |
- public boolean has(final GeneratedMessage message) { |
+ public boolean has(final GeneratedMessageV3 message) { |
if (!hasHasMethod) { |
if (isOneofField) { |
return getOneofFieldNumber(message) == field.getNumber(); |
@@ -2191,7 +2005,7 @@ public abstract class GeneratedMessage extends AbstractMessage |
return (Boolean) invokeOrDie(hasMethod, message); |
} |
@Override |
- public boolean has(GeneratedMessage.Builder builder) { |
+ public boolean has(GeneratedMessageV3.Builder builder) { |
if (!hasHasMethod) { |
if (isOneofField) { |
return getOneofFieldNumber(builder) == field.getNumber(); |
@@ -2201,12 +2015,12 @@ public abstract class GeneratedMessage extends AbstractMessage |
return (Boolean) invokeOrDie(hasMethodBuilder, builder); |
} |
@Override |
- public int getRepeatedCount(final GeneratedMessage message) { |
+ public int getRepeatedCount(final GeneratedMessageV3 message) { |
throw new UnsupportedOperationException( |
"getRepeatedFieldSize() called on a singular field."); |
} |
@Override |
- public int getRepeatedCount(GeneratedMessage.Builder builder) { |
+ public int getRepeatedCount(GeneratedMessageV3.Builder builder) { |
throw new UnsupportedOperationException( |
"getRepeatedFieldSize() called on a singular field."); |
} |
@@ -2220,12 +2034,12 @@ public abstract class GeneratedMessage extends AbstractMessage |
"newBuilderForField() called on a non-Message type."); |
} |
@Override |
- public Message.Builder getBuilder(GeneratedMessage.Builder builder) { |
+ public Message.Builder getBuilder(GeneratedMessageV3.Builder builder) { |
throw new UnsupportedOperationException( |
"getFieldBuilder() called on a non-Message type."); |
} |
@Override |
- public Message.Builder getRepeatedBuilder(GeneratedMessage.Builder builder, int index) { |
+ public Message.Builder getRepeatedBuilder(GeneratedMessageV3.Builder builder, int index) { |
throw new UnsupportedOperationException( |
"getRepeatedFieldBuilder() called on a non-Message type."); |
} |
@@ -2245,7 +2059,7 @@ public abstract class GeneratedMessage extends AbstractMessage |
RepeatedFieldAccessor( |
final FieldDescriptor descriptor, final String camelCaseName, |
- final Class<? extends GeneratedMessage> messageClass, |
+ final Class<? extends GeneratedMessageV3> messageClass, |
final Class<? extends Builder> builderClass) { |
getMethod = getMethodOrDie(messageClass, |
"get" + camelCaseName + "List"); |
@@ -2270,19 +2084,19 @@ public abstract class GeneratedMessage extends AbstractMessage |
} |
@Override |
- public Object get(final GeneratedMessage message) { |
+ public Object get(final GeneratedMessageV3 message) { |
return invokeOrDie(getMethod, message); |
} |
@Override |
- public Object get(GeneratedMessage.Builder builder) { |
+ public Object get(GeneratedMessageV3.Builder builder) { |
return invokeOrDie(getMethodBuilder, builder); |
} |
@Override |
- public Object getRaw(final GeneratedMessage message) { |
+ public Object getRaw(final GeneratedMessageV3 message) { |
return get(message); |
} |
@Override |
- public Object getRaw(GeneratedMessage.Builder builder) { |
+ public Object getRaw(GeneratedMessageV3.Builder builder) { |
return get(builder); |
} |
@Override |
@@ -2297,19 +2111,19 @@ public abstract class GeneratedMessage extends AbstractMessage |
} |
} |
@Override |
- public Object getRepeated(final GeneratedMessage message, final int index) { |
+ public Object getRepeated(final GeneratedMessageV3 message, final int index) { |
return invokeOrDie(getRepeatedMethod, message, index); |
} |
@Override |
- public Object getRepeated(GeneratedMessage.Builder builder, int index) { |
+ public Object getRepeated(GeneratedMessageV3.Builder builder, int index) { |
return invokeOrDie(getRepeatedMethodBuilder, builder, index); |
} |
@Override |
- public Object getRepeatedRaw(GeneratedMessage message, int index) { |
+ public Object getRepeatedRaw(GeneratedMessageV3 message, int index) { |
return getRepeated(message, index); |
} |
@Override |
- public Object getRepeatedRaw(GeneratedMessage.Builder builder, int index) { |
+ public Object getRepeatedRaw(GeneratedMessageV3.Builder builder, int index) { |
return getRepeated(builder, index); |
} |
@Override |
@@ -2321,21 +2135,21 @@ public abstract class GeneratedMessage extends AbstractMessage |
invokeOrDie(addRepeatedMethod, builder, value); |
} |
@Override |
- public boolean has(final GeneratedMessage message) { |
+ public boolean has(final GeneratedMessageV3 message) { |
throw new UnsupportedOperationException( |
"hasField() called on a repeated field."); |
} |
@Override |
- public boolean has(GeneratedMessage.Builder builder) { |
+ public boolean has(GeneratedMessageV3.Builder builder) { |
throw new UnsupportedOperationException( |
"hasField() called on a repeated field."); |
} |
@Override |
- public int getRepeatedCount(final GeneratedMessage message) { |
+ public int getRepeatedCount(final GeneratedMessageV3 message) { |
return (Integer) invokeOrDie(getCountMethod, message); |
} |
@Override |
- public int getRepeatedCount(GeneratedMessage.Builder builder) { |
+ public int getRepeatedCount(GeneratedMessageV3.Builder builder) { |
return (Integer) invokeOrDie(getCountMethodBuilder, builder); |
} |
@Override |
@@ -2348,12 +2162,12 @@ public abstract class GeneratedMessage extends AbstractMessage |
"newBuilderForField() called on a non-Message type."); |
} |
@Override |
- public Message.Builder getBuilder(GeneratedMessage.Builder builder) { |
+ public Message.Builder getBuilder(GeneratedMessageV3.Builder builder) { |
throw new UnsupportedOperationException( |
"getFieldBuilder() called on a non-Message type."); |
} |
@Override |
- public Message.Builder getRepeatedBuilder(GeneratedMessage.Builder builder, int index) { |
+ public Message.Builder getRepeatedBuilder(GeneratedMessageV3.Builder builder, int index) { |
throw new UnsupportedOperationException( |
"getRepeatedFieldBuilder() called on a non-Message type."); |
} |
@@ -2362,13 +2176,13 @@ public abstract class GeneratedMessage extends AbstractMessage |
private static class MapFieldAccessor implements FieldAccessor { |
MapFieldAccessor( |
final FieldDescriptor descriptor, final String camelCaseName, |
- final Class<? extends GeneratedMessage> messageClass, |
+ final Class<? extends GeneratedMessageV3> messageClass, |
final Class<? extends Builder> builderClass) { |
field = descriptor; |
Method getDefaultInstanceMethod = |
getMethodOrDie(messageClass, "getDefaultInstance"); |
MapField defaultMapField = getMapField( |
- (GeneratedMessage) invokeOrDie(getDefaultInstanceMethod, null)); |
+ (GeneratedMessageV3) invokeOrDie(getDefaultInstanceMethod, null)); |
mapEntryMessageDefaultInstance = |
defaultMapField.getMapEntryMessageDefaultInstance(); |
} |
@@ -2376,22 +2190,36 @@ public abstract class GeneratedMessage extends AbstractMessage |
private final FieldDescriptor field; |
private final Message mapEntryMessageDefaultInstance; |
- private MapField<?, ?> getMapField(GeneratedMessage message) { |
+ private MapField<?, ?> getMapField(GeneratedMessageV3 message) { |
return (MapField<?, ?>) message.internalGetMapField(field.getNumber()); |
} |
- private MapField<?, ?> getMapField(GeneratedMessage.Builder builder) { |
+ private MapField<?, ?> getMapField(GeneratedMessageV3.Builder builder) { |
return (MapField<?, ?>) builder.internalGetMapField(field.getNumber()); |
} |
private MapField<?, ?> getMutableMapField( |
- GeneratedMessage.Builder builder) { |
+ GeneratedMessageV3.Builder builder) { |
return (MapField<?, ?>) builder.internalGetMutableMapField( |
field.getNumber()); |
} |
+ private Message coerceType(Message value) { |
+ if (value == null) { |
+ return null; |
+ } |
+ if (mapEntryMessageDefaultInstance.getClass().isInstance(value)) { |
+ return value; |
+ } |
+ // The value is not the exact right message type. However, if it |
+ // is an alternative implementation of the same type -- e.g. a |
+ // DynamicMessage -- we should accept it. In this case we can make |
+ // a copy of the message. |
+ return mapEntryMessageDefaultInstance.toBuilder().mergeFrom(value).build(); |
+ } |
+ |
@Override |
- public Object get(GeneratedMessage message) { |
+ public Object get(GeneratedMessageV3 message) { |
List result = new ArrayList(); |
for (int i = 0; i < getRepeatedCount(message); i++) { |
result.add(getRepeated(message, i)); |
@@ -2409,12 +2237,12 @@ public abstract class GeneratedMessage extends AbstractMessage |
} |
@Override |
- public Object getRaw(GeneratedMessage message) { |
+ public Object getRaw(GeneratedMessageV3 message) { |
return get(message); |
} |
@Override |
- public Object getRaw(GeneratedMessage.Builder builder) { |
+ public Object getRaw(GeneratedMessageV3.Builder builder) { |
return get(builder); |
} |
@@ -2427,7 +2255,7 @@ public abstract class GeneratedMessage extends AbstractMessage |
} |
@Override |
- public Object getRepeated(GeneratedMessage message, int index) { |
+ public Object getRepeated(GeneratedMessageV3 message, int index) { |
return getMapField(message).getList().get(index); |
} |
@@ -2437,7 +2265,7 @@ public abstract class GeneratedMessage extends AbstractMessage |
} |
@Override |
- public Object getRepeatedRaw(GeneratedMessage message, int index) { |
+ public Object getRepeatedRaw(GeneratedMessageV3 message, int index) { |
return getRepeated(message, index); |
} |
@@ -2445,19 +2273,19 @@ public abstract class GeneratedMessage extends AbstractMessage |
public Object getRepeatedRaw(Builder builder, int index) { |
return getRepeated(builder, index); |
} |
- |
+ |
@Override |
public void setRepeated(Builder builder, int index, Object value) { |
- getMutableMapField(builder).getMutableList().set(index, (Message) value); |
+ getMutableMapField(builder).getMutableList().set(index, coerceType((Message) value)); |
} |
@Override |
public void addRepeated(Builder builder, Object value) { |
- getMutableMapField(builder).getMutableList().add((Message) value); |
+ getMutableMapField(builder).getMutableList().add(coerceType((Message) value)); |
} |
@Override |
- public boolean has(GeneratedMessage message) { |
+ public boolean has(GeneratedMessageV3 message) { |
throw new UnsupportedOperationException( |
"hasField() is not supported for repeated fields."); |
} |
@@ -2469,7 +2297,7 @@ public abstract class GeneratedMessage extends AbstractMessage |
} |
@Override |
- public int getRepeatedCount(GeneratedMessage message) { |
+ public int getRepeatedCount(GeneratedMessageV3 message) { |
return getMapField(message).getList().size(); |
} |
@@ -2507,7 +2335,7 @@ public abstract class GeneratedMessage extends AbstractMessage |
extends SingularFieldAccessor { |
SingularEnumFieldAccessor( |
final FieldDescriptor descriptor, final String camelCaseName, |
- final Class<? extends GeneratedMessage> messageClass, |
+ final Class<? extends GeneratedMessageV3> messageClass, |
final Class<? extends Builder> builderClass, |
final String containingOneofCamelCaseName) { |
super(descriptor, camelCaseName, messageClass, builderClass, containingOneofCamelCaseName); |
@@ -2541,7 +2369,7 @@ public abstract class GeneratedMessage extends AbstractMessage |
private Method setValueMethod; |
@Override |
- public Object get(final GeneratedMessage message) { |
+ public Object get(final GeneratedMessageV3 message) { |
if (supportUnknownEnumValue) { |
int value = (Integer) invokeOrDie(getValueMethod, message); |
return enumDescriptor.findValueByNumberCreatingIfUnknown(value); |
@@ -2550,7 +2378,7 @@ public abstract class GeneratedMessage extends AbstractMessage |
} |
@Override |
- public Object get(final GeneratedMessage.Builder builder) { |
+ public Object get(final GeneratedMessageV3.Builder builder) { |
if (supportUnknownEnumValue) { |
int value = (Integer) invokeOrDie(getValueMethodBuilder, builder); |
return enumDescriptor.findValueByNumberCreatingIfUnknown(value); |
@@ -2573,7 +2401,7 @@ public abstract class GeneratedMessage extends AbstractMessage |
extends RepeatedFieldAccessor { |
RepeatedEnumFieldAccessor( |
final FieldDescriptor descriptor, final String camelCaseName, |
- final Class<? extends GeneratedMessage> messageClass, |
+ final Class<? extends GeneratedMessageV3> messageClass, |
final Class<? extends Builder> builderClass) { |
super(descriptor, camelCaseName, messageClass, builderClass); |
@@ -2609,7 +2437,7 @@ public abstract class GeneratedMessage extends AbstractMessage |
@Override |
@SuppressWarnings("unchecked") |
- public Object get(final GeneratedMessage message) { |
+ public Object get(final GeneratedMessageV3 message) { |
final List newList = new ArrayList(); |
final int size = getRepeatedCount(message); |
for (int i = 0; i < size; i++) { |
@@ -2620,7 +2448,7 @@ public abstract class GeneratedMessage extends AbstractMessage |
@Override |
@SuppressWarnings("unchecked") |
- public Object get(final GeneratedMessage.Builder builder) { |
+ public Object get(final GeneratedMessageV3.Builder builder) { |
final List newList = new ArrayList(); |
final int size = getRepeatedCount(builder); |
for (int i = 0; i < size; i++) { |
@@ -2630,7 +2458,7 @@ public abstract class GeneratedMessage extends AbstractMessage |
} |
@Override |
- public Object getRepeated(final GeneratedMessage message, |
+ public Object getRepeated(final GeneratedMessageV3 message, |
final int index) { |
if (supportUnknownEnumValue) { |
int value = (Integer) invokeOrDie(getRepeatedValueMethod, message, index); |
@@ -2640,7 +2468,7 @@ public abstract class GeneratedMessage extends AbstractMessage |
super.getRepeated(message, index)); |
} |
@Override |
- public Object getRepeated(final GeneratedMessage.Builder builder, |
+ public Object getRepeated(final GeneratedMessageV3.Builder builder, |
final int index) { |
if (supportUnknownEnumValue) { |
int value = (Integer) invokeOrDie(getRepeatedValueMethodBuilder, builder, index); |
@@ -2688,7 +2516,7 @@ public abstract class GeneratedMessage extends AbstractMessage |
extends SingularFieldAccessor { |
SingularStringFieldAccessor( |
final FieldDescriptor descriptor, final String camelCaseName, |
- final Class<? extends GeneratedMessage> messageClass, |
+ final Class<? extends GeneratedMessageV3> messageClass, |
final Class<? extends Builder> builderClass, |
final String containingOneofCamelCaseName) { |
super(descriptor, camelCaseName, messageClass, builderClass, |
@@ -2706,17 +2534,17 @@ public abstract class GeneratedMessage extends AbstractMessage |
private final Method setBytesMethodBuilder; |
@Override |
- public Object getRaw(final GeneratedMessage message) { |
+ public Object getRaw(final GeneratedMessageV3 message) { |
return invokeOrDie(getBytesMethod, message); |
} |
@Override |
- public Object getRaw(GeneratedMessage.Builder builder) { |
+ public Object getRaw(GeneratedMessageV3.Builder builder) { |
return invokeOrDie(getBytesMethodBuilder, builder); |
} |
@Override |
- public void set(GeneratedMessage.Builder builder, Object value) { |
+ public void set(GeneratedMessageV3.Builder builder, Object value) { |
if (value instanceof ByteString) { |
invokeOrDie(setBytesMethodBuilder, builder, value); |
} else { |
@@ -2731,7 +2559,7 @@ public abstract class GeneratedMessage extends AbstractMessage |
extends SingularFieldAccessor { |
SingularMessageFieldAccessor( |
final FieldDescriptor descriptor, final String camelCaseName, |
- final Class<? extends GeneratedMessage> messageClass, |
+ final Class<? extends GeneratedMessageV3> messageClass, |
final Class<? extends Builder> builderClass, |
final String containingOneofCamelCaseName) { |
super(descriptor, camelCaseName, messageClass, builderClass, |
@@ -2767,7 +2595,7 @@ public abstract class GeneratedMessage extends AbstractMessage |
return (Message.Builder) invokeOrDie(newBuilderMethod, null); |
} |
@Override |
- public Message.Builder getBuilder(GeneratedMessage.Builder builder) { |
+ public Message.Builder getBuilder(GeneratedMessageV3.Builder builder) { |
return (Message.Builder) invokeOrDie(getBuilderMethodBuilder, builder); |
} |
} |
@@ -2776,7 +2604,7 @@ public abstract class GeneratedMessage extends AbstractMessage |
extends RepeatedFieldAccessor { |
RepeatedMessageFieldAccessor( |
final FieldDescriptor descriptor, final String camelCaseName, |
- final Class<? extends GeneratedMessage> messageClass, |
+ final Class<? extends GeneratedMessageV3> messageClass, |
final Class<? extends Builder> builderClass) { |
super(descriptor, camelCaseName, messageClass, builderClass); |
@@ -2816,7 +2644,7 @@ public abstract class GeneratedMessage extends AbstractMessage |
} |
@Override |
public Message.Builder getRepeatedBuilder( |
- final GeneratedMessage.Builder builder, final int index) { |
+ final GeneratedMessageV3.Builder builder, final int index) { |
return (Message.Builder) invokeOrDie( |
getBuilderMethodBuilder, builder, index); |
} |
@@ -2880,4 +2708,131 @@ public abstract class GeneratedMessage extends AbstractMessage |
output.writeBytesNoTag((ByteString) value); |
} |
} |
+ |
+ protected static <V> void serializeIntegerMapTo( |
+ CodedOutputStream out, |
+ MapField<Integer, V> field, |
+ MapEntry<Integer, V> defaultEntry, |
+ int fieldNumber) throws IOException { |
+ Map<Integer, V> m = field.getMap(); |
+ if (!out.isSerializationDeterministic()) { |
+ serializeMapTo(out, m, defaultEntry, fieldNumber); |
+ return; |
+ } |
+ // Sorting the unboxed keys and then look up the values during serialziation is 2x faster |
+ // than sorting map entries with a custom comparator directly. |
+ int[] keys = new int[m.size()]; |
+ int index = 0; |
+ for (int k : m.keySet()) { |
+ keys[index++] = k; |
+ } |
+ Arrays.sort(keys); |
+ for (int key : keys) { |
+ out.writeMessage(fieldNumber, |
+ defaultEntry.newBuilderForType() |
+ .setKey(key) |
+ .setValue(m.get(key)) |
+ .build()); |
+ } |
+ } |
+ |
+ protected static <V> void serializeLongMapTo( |
+ CodedOutputStream out, |
+ MapField<Long, V> field, |
+ MapEntry<Long, V> defaultEntry, |
+ int fieldNumber) |
+ throws IOException { |
+ Map<Long, V> m = field.getMap(); |
+ if (!out.isSerializationDeterministic()) { |
+ serializeMapTo(out, m, defaultEntry, fieldNumber); |
+ return; |
+ } |
+ |
+ long[] keys = new long[m.size()]; |
+ int index = 0; |
+ for (long k : m.keySet()) { |
+ keys[index++] = k; |
+ } |
+ Arrays.sort(keys); |
+ for (long key : keys) { |
+ out.writeMessage(fieldNumber, |
+ defaultEntry.newBuilderForType() |
+ .setKey(key) |
+ .setValue(m.get(key)) |
+ .build()); |
+ } |
+ } |
+ |
+ protected static <V> void serializeStringMapTo( |
+ CodedOutputStream out, |
+ MapField<String, V> field, |
+ MapEntry<String, V> defaultEntry, |
+ int fieldNumber) |
+ throws IOException { |
+ Map<String, V> m = field.getMap(); |
+ if (!out.isSerializationDeterministic()) { |
+ serializeMapTo(out, m, defaultEntry, fieldNumber); |
+ return; |
+ } |
+ |
+ // Sorting the String keys and then look up the values during serialziation is 25% faster than |
+ // sorting map entries with a custom comparator directly. |
+ String[] keys = new String[m.size()]; |
+ keys = m.keySet().toArray(keys); |
+ Arrays.sort(keys); |
+ for (String key : keys) { |
+ out.writeMessage(fieldNumber, |
+ defaultEntry.newBuilderForType() |
+ .setKey(key) |
+ .setValue(m.get(key)) |
+ .build()); |
+ } |
+ } |
+ |
+ protected static <V> void serializeBooleanMapTo( |
+ CodedOutputStream out, |
+ MapField<Boolean, V> field, |
+ MapEntry<Boolean, V> defaultEntry, |
+ int fieldNumber) |
+ throws IOException { |
+ Map<Boolean, V> m = field.getMap(); |
+ if (!out.isSerializationDeterministic()) { |
+ serializeMapTo(out, m, defaultEntry, fieldNumber); |
+ return; |
+ } |
+ maybeSerializeBooleanEntryTo(out, m, defaultEntry, fieldNumber, false); |
+ maybeSerializeBooleanEntryTo(out, m, defaultEntry, fieldNumber, true); |
+ } |
+ |
+ private static <V> void maybeSerializeBooleanEntryTo( |
+ CodedOutputStream out, |
+ Map<Boolean, V> m, |
+ MapEntry<Boolean, V> defaultEntry, |
+ int fieldNumber, |
+ boolean key) |
+ throws IOException { |
+ if (m.containsKey(key)) { |
+ out.writeMessage(fieldNumber, |
+ defaultEntry.newBuilderForType() |
+ .setKey(key) |
+ .setValue(m.get(key)) |
+ .build()); |
+ } |
+ } |
+ |
+ /** Serialize the map using the iteration order. */ |
+ private static <K, V> void serializeMapTo( |
+ CodedOutputStream out, |
+ Map<K, V> m, |
+ MapEntry<K, V> defaultEntry, |
+ int fieldNumber) |
+ throws IOException { |
+ for (Map.Entry<K, V> entry : m.entrySet()) { |
+ out.writeMessage(fieldNumber, |
+ defaultEntry.newBuilderForType() |
+ .setKey(entry.getKey()) |
+ .setValue(entry.getValue()) |
+ .build()); |
+ } |
+ } |
} |