diff options
Diffstat (limited to 'java/core/src/main/java/com/google/protobuf/ExtensionRegistry.java')
-rw-r--r-- | java/core/src/main/java/com/google/protobuf/ExtensionRegistry.java | 184 |
1 files changed, 77 insertions, 107 deletions
diff --git a/java/core/src/main/java/com/google/protobuf/ExtensionRegistry.java b/java/core/src/main/java/com/google/protobuf/ExtensionRegistry.java index a22a74a0..aeeaee53 100644 --- a/java/core/src/main/java/com/google/protobuf/ExtensionRegistry.java +++ b/java/core/src/main/java/com/google/protobuf/ExtensionRegistry.java @@ -40,11 +40,10 @@ import java.util.Map; import java.util.Set; /** - * A table of known extensions, searchable by name or field number. When - * parsing a protocol message that might have extensions, you must provide - * an {@code ExtensionRegistry} in which you have registered any extensions - * that you want to be able to parse. Otherwise, those extensions will just - * be treated like unknown fields. + * A table of known extensions, searchable by name or field number. When parsing a protocol message + * that might have extensions, you must provide an {@code ExtensionRegistry} in which you have + * registered any extensions that you want to be able to parse. Otherwise, those extensions will + * just be treated like unknown fields. * * <p>For example, if you had the {@code .proto} file: * @@ -70,25 +69,22 @@ import java.util.Set; * * <p>Background: * - * <p>You might wonder why this is necessary. Two alternatives might come to - * mind. First, you might imagine a system where generated extensions are - * automatically registered when their containing classes are loaded. This - * is a popular technique, but is bad design; among other things, it creates a - * situation where behavior can change depending on what classes happen to be - * loaded. It also introduces a security vulnerability, because an - * unprivileged class could cause its code to be called unexpectedly from a - * privileged class by registering itself as an extension of the right type. + * <p>You might wonder why this is necessary. Two alternatives might come to mind. First, you might + * imagine a system where generated extensions are automatically registered when their containing + * classes are loaded. This is a popular technique, but is bad design; among other things, it + * creates a situation where behavior can change depending on what classes happen to be loaded. It + * also introduces a security vulnerability, because an unprivileged class could cause its code to + * be called unexpectedly from a privileged class by registering itself as an extension of the right + * type. * - * <p>Another option you might consider is lazy parsing: do not parse an - * extension until it is first requested, at which point the caller must - * provide a type to use. This introduces a different set of problems. First, - * it would require a mutex lock any time an extension was accessed, which - * would be slow. Second, corrupt data would not be detected until first - * access, at which point it would be much harder to deal with it. Third, it - * could violate the expectation that message objects are immutable, since the - * type provided could be any arbitrary message class. An unprivileged user - * could take advantage of this to inject a mutable object into a message - * belonging to privileged code and create mischief. + * <p>Another option you might consider is lazy parsing: do not parse an extension until it is first + * requested, at which point the caller must provide a type to use. This introduces a different set + * of problems. First, it would require a mutex lock any time an extension was accessed, which would + * be slow. Second, corrupt data would not be detected until first access, at which point it would + * be much harder to deal with it. Third, it could violate the expectation that message objects are + * immutable, since the type provided could be any arbitrary message class. An unprivileged user + * could take advantage of this to inject a mutable object into a message belonging to privileged + * code and create mischief. * * @author kenton@google.com Kenton Varda */ @@ -116,8 +112,8 @@ public class ExtensionRegistry extends ExtensionRegistryLite { public final FieldDescriptor descriptor; /** - * A default instance of the extension's type, if it has a message type. - * Otherwise, {@code null}. + * A default instance of the extension's type, if it has a message type. Otherwise, {@code + * null}. */ public final Message defaultInstance; @@ -125,48 +121,41 @@ public class ExtensionRegistry extends ExtensionRegistryLite { this.descriptor = descriptor; defaultInstance = null; } - private ExtensionInfo(final FieldDescriptor descriptor, - final Message defaultInstance) { + + private ExtensionInfo(final FieldDescriptor descriptor, final Message defaultInstance) { this.descriptor = descriptor; this.defaultInstance = defaultInstance; } } - /** - * Deprecated. Use {@link #findImmutableExtensionByName(String)} instead. - */ + /** Deprecated. Use {@link #findImmutableExtensionByName(String)} instead. */ + @Deprecated public ExtensionInfo findExtensionByName(final String fullName) { return findImmutableExtensionByName(fullName); } /** - * Find an extension for immutable APIs by fully-qualified field name, - * in the proto namespace. i.e. {@code result.descriptor.fullName()} will - * match {@code fullName} if a match is found. + * Find an extension for immutable APIs by fully-qualified field name, in the proto namespace. + * i.e. {@code result.descriptor.fullName()} will match {@code fullName} if a match is found. * - * @return Information about the extension if found, or {@code null} - * otherwise. + * @return Information about the extension if found, or {@code null} otherwise. */ public ExtensionInfo findImmutableExtensionByName(final String fullName) { return immutableExtensionsByName.get(fullName); } /** - * Find an extension for mutable APIs by fully-qualified field name, - * in the proto namespace. i.e. {@code result.descriptor.fullName()} will - * match {@code fullName} if a match is found. + * Find an extension for mutable APIs by fully-qualified field name, in the proto namespace. i.e. + * {@code result.descriptor.fullName()} will match {@code fullName} if a match is found. * - * @return Information about the extension if found, or {@code null} - * otherwise. + * @return Information about the extension if found, or {@code null} otherwise. */ public ExtensionInfo findMutableExtensionByName(final String fullName) { return mutableExtensionsByName.get(fullName); } - /** - * Deprecated. Use {@link #findImmutableExtensionByNumber( - * Descriptors.Descriptor, int)} - */ + /** Deprecated. Use {@link #findImmutableExtensionByNumber( Descriptors.Descriptor, int)} */ + @Deprecated public ExtensionInfo findExtensionByNumber( final Descriptor containingType, final int fieldNumber) { return findImmutableExtensionByNumber(containingType, fieldNumber); @@ -175,34 +164,28 @@ public class ExtensionRegistry extends ExtensionRegistryLite { /** * Find an extension by containing type and field number for immutable APIs. * - * @return Information about the extension if found, or {@code null} - * otherwise. + * @return Information about the extension if found, or {@code null} otherwise. */ public ExtensionInfo findImmutableExtensionByNumber( final Descriptor containingType, final int fieldNumber) { - return immutableExtensionsByNumber.get( - new DescriptorIntPair(containingType, fieldNumber)); + return immutableExtensionsByNumber.get(new DescriptorIntPair(containingType, fieldNumber)); } /** * Find an extension by containing type and field number for mutable APIs. * - * @return Information about the extension if found, or {@code null} - * otherwise. + * @return Information about the extension if found, or {@code null} otherwise. */ public ExtensionInfo findMutableExtensionByNumber( final Descriptor containingType, final int fieldNumber) { - return mutableExtensionsByNumber.get( - new DescriptorIntPair(containingType, fieldNumber)); + return mutableExtensionsByNumber.get(new DescriptorIntPair(containingType, fieldNumber)); } /** - * Find all extensions for mutable APIs by fully-qualified name of - * extended class. Note that this method is more computationally expensive - * than getting a single extension by name or number. + * Find all extensions for mutable APIs by fully-qualified name of extended class. Note that this + * method is more computationally expensive than getting a single extension by name or number. * - * @return Information about the extensions found, or {@code null} if there - * are none. + * @return Information about the extensions found, or {@code null} if there are none. */ public Set<ExtensionInfo> getAllMutableExtensionsByExtendedType(final String fullName) { HashSet<ExtensionInfo> extensions = new HashSet<ExtensionInfo>(); @@ -215,12 +198,11 @@ public class ExtensionRegistry extends ExtensionRegistryLite { } /** - * Find all extensions for immutable APIs by fully-qualified name of - * extended class. Note that this method is more computationally expensive - * than getting a single extension by name or number. + * Find all extensions for immutable APIs by fully-qualified name of extended class. Note that + * this method is more computationally expensive than getting a single extension by name or + * number. * - * @return Information about the extensions found, or {@code null} if there - * are none. + * @return Information about the extensions found, or {@code null} if there are none. */ public Set<ExtensionInfo> getAllImmutableExtensionsByExtendedType(final String fullName) { HashSet<ExtensionInfo> extensions = new HashSet<ExtensionInfo>(); @@ -234,8 +216,8 @@ public class ExtensionRegistry extends ExtensionRegistryLite { /** Add an extension from a generated file to the registry. */ public void add(final Extension<?, ?> extension) { - if (extension.getExtensionType() != Extension.ExtensionType.IMMUTABLE && - extension.getExtensionType() != Extension.ExtensionType.MUTABLE) { + if (extension.getExtensionType() != Extension.ExtensionType.IMMUTABLE + && extension.getExtensionType() != Extension.ExtensionType.MUTABLE) { // do not support other extension types. ignore return; } @@ -248,15 +230,14 @@ public class ExtensionRegistry extends ExtensionRegistryLite { } static ExtensionInfo newExtensionInfo(final Extension<?, ?> extension) { - if (extension.getDescriptor().getJavaType() == - FieldDescriptor.JavaType.MESSAGE) { + if (extension.getDescriptor().getJavaType() == FieldDescriptor.JavaType.MESSAGE) { if (extension.getMessageDefaultInstance() == null) { throw new IllegalStateException( - "Registered message-type extension had null default instance: " + - extension.getDescriptor().getFullName()); + "Registered message-type extension had null default instance: " + + extension.getDescriptor().getFullName()); } - return new ExtensionInfo(extension.getDescriptor(), - (Message) extension.getMessageDefaultInstance()); + return new ExtensionInfo( + extension.getDescriptor(), (Message) extension.getMessageDefaultInstance()); } else { return new ExtensionInfo(extension.getDescriptor(), null); } @@ -266,8 +247,8 @@ public class ExtensionRegistry extends ExtensionRegistryLite { public void add(final FieldDescriptor type) { if (type.getJavaType() == FieldDescriptor.JavaType.MESSAGE) { throw new IllegalArgumentException( - "ExtensionRegistry.add() must be provided a default instance when " + - "adding an embedded message extension."); + "ExtensionRegistry.add() must be provided a default instance when " + + "adding an embedded message extension."); } ExtensionInfo info = new ExtensionInfo(type, null); add(info, Extension.ExtensionType.IMMUTABLE); @@ -278,11 +259,9 @@ public class ExtensionRegistry extends ExtensionRegistryLite { public void add(final FieldDescriptor type, final Message defaultInstance) { if (type.getJavaType() != FieldDescriptor.JavaType.MESSAGE) { throw new IllegalArgumentException( - "ExtensionRegistry.add() provided a default instance for a " + - "non-message extension."); + "ExtensionRegistry.add() provided a default instance for a non-message extension."); } - add(new ExtensionInfo(type, defaultInstance), - Extension.ExtensionType.IMMUTABLE); + add(new ExtensionInfo(type, defaultInstance), Extension.ExtensionType.IMMUTABLE); } // ================================================================= @@ -291,22 +270,17 @@ public class ExtensionRegistry extends ExtensionRegistryLite { private ExtensionRegistry() { this.immutableExtensionsByName = new HashMap<String, ExtensionInfo>(); this.mutableExtensionsByName = new HashMap<String, ExtensionInfo>(); - this.immutableExtensionsByNumber = - new HashMap<DescriptorIntPair, ExtensionInfo>(); - this.mutableExtensionsByNumber = - new HashMap<DescriptorIntPair, ExtensionInfo>(); + this.immutableExtensionsByNumber = new HashMap<DescriptorIntPair, ExtensionInfo>(); + this.mutableExtensionsByNumber = new HashMap<DescriptorIntPair, ExtensionInfo>(); } private ExtensionRegistry(ExtensionRegistry other) { super(other); - this.immutableExtensionsByName = - Collections.unmodifiableMap(other.immutableExtensionsByName); - this.mutableExtensionsByName = - Collections.unmodifiableMap(other.mutableExtensionsByName); + this.immutableExtensionsByName = Collections.unmodifiableMap(other.immutableExtensionsByName); + this.mutableExtensionsByName = Collections.unmodifiableMap(other.mutableExtensionsByName); this.immutableExtensionsByNumber = Collections.unmodifiableMap(other.immutableExtensionsByNumber); - this.mutableExtensionsByNumber = - Collections.unmodifiableMap(other.mutableExtensionsByNumber); + this.mutableExtensionsByNumber = Collections.unmodifiableMap(other.mutableExtensionsByNumber); } private final Map<String, ExtensionInfo> immutableExtensionsByName; @@ -316,24 +290,19 @@ public class ExtensionRegistry extends ExtensionRegistryLite { ExtensionRegistry(boolean empty) { super(EMPTY_REGISTRY_LITE); - this.immutableExtensionsByName = - Collections.<String, ExtensionInfo>emptyMap(); - this.mutableExtensionsByName = - Collections.<String, ExtensionInfo>emptyMap(); - this.immutableExtensionsByNumber = - Collections.<DescriptorIntPair, ExtensionInfo>emptyMap(); - this.mutableExtensionsByNumber = - Collections.<DescriptorIntPair, ExtensionInfo>emptyMap(); + this.immutableExtensionsByName = Collections.<String, ExtensionInfo>emptyMap(); + this.mutableExtensionsByName = Collections.<String, ExtensionInfo>emptyMap(); + this.immutableExtensionsByNumber = Collections.<DescriptorIntPair, ExtensionInfo>emptyMap(); + this.mutableExtensionsByNumber = Collections.<DescriptorIntPair, ExtensionInfo>emptyMap(); } + static final ExtensionRegistry EMPTY_REGISTRY = new ExtensionRegistry(true); - private void add( - final ExtensionInfo extension, - final Extension.ExtensionType extensionType) { + private void add(final ExtensionInfo extension, final Extension.ExtensionType extensionType) { if (!extension.descriptor.isExtension()) { throw new IllegalArgumentException( - "ExtensionRegistry.add() was given a FieldDescriptor for a regular " + - "(non-extension) field."); + "ExtensionRegistry.add() was given a FieldDescriptor for a regular " + + "(non-extension) field."); } Map<String, ExtensionInfo> extensionsByName; @@ -354,15 +323,15 @@ public class ExtensionRegistry extends ExtensionRegistryLite { extensionsByName.put(extension.descriptor.getFullName(), extension); extensionsByNumber.put( - new DescriptorIntPair(extension.descriptor.getContainingType(), - extension.descriptor.getNumber()), - extension); + new DescriptorIntPair( + extension.descriptor.getContainingType(), extension.descriptor.getNumber()), + extension); final FieldDescriptor field = extension.descriptor; - if (field.getContainingType().getOptions().getMessageSetWireFormat() && - field.getType() == FieldDescriptor.Type.MESSAGE && - field.isOptional() && - field.getExtensionScope() == field.getMessageType()) { + if (field.getContainingType().getOptions().getMessageSetWireFormat() + && field.getType() == FieldDescriptor.Type.MESSAGE + && field.isOptional() + && field.getExtensionScope() == field.getMessageType()) { // This is an extension of a MessageSet type defined within the extension // type's own scope. For backwards-compatibility, allow it to be looked // up by type name. @@ -384,12 +353,13 @@ public class ExtensionRegistry extends ExtensionRegistryLite { public int hashCode() { return descriptor.hashCode() * ((1 << 16) - 1) + number; } + @Override public boolean equals(final Object obj) { if (!(obj instanceof DescriptorIntPair)) { return false; } - final DescriptorIntPair other = (DescriptorIntPair)obj; + final DescriptorIntPair other = (DescriptorIntPair) obj; return descriptor == other.descriptor && number == other.number; } } |