aboutsummaryrefslogtreecommitdiff
path: root/java/core/src/main/java/com/google/protobuf/ExtensionRegistry.java
diff options
context:
space:
mode:
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.java184
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;
}
}