Introduce getMessageExtensionOrNull for extendable messages to avoid the code pattern of hasExtension() ? getExtension : null which takes an extra extension lookup.

PiperOrigin-RevId: 926787242
This commit is contained in:
Protobuf Team Bot 2026-06-04 11:14:48 -07:00 committed by Copybara-Service
parent c99b4fbc40
commit 94de7ab2b3

View file

@ -961,6 +961,10 @@ public abstract class GeneratedMessage extends AbstractMessage implements Serial
/** Get the value of an extension. */
<T> T getExtension(ExtensionLite<? extends MessageT, T> extension);
/** Get the value of a message-typed extension, or null if it is not set. */
<T extends MessageLite> T getMessageTypedExtensionOrNull(
ExtensionLite<? extends MessageT, T> extension);
/** Overload to maintain ABI compatibility. See {@link #getExtension(ExtensionLite)}. */
default <T> T getExtension(Extension<? extends MessageT, T> extension) {
return getExtension((ExtensionLite<? extends MessageT, T>) extension);
@ -1098,6 +1102,21 @@ public abstract class GeneratedMessage extends AbstractMessage implements Serial
return (T) extension.fromReflectionType(value);
}
@Override
@SuppressWarnings("unchecked") // Safe as fromReflectionType will always match the type of T.
public final <T extends MessageLite> T getMessageTypedExtensionOrNull(
final ExtensionLite<? extends MessageT, T> extensionLite) {
Extension<MessageT, T> extension = checkNotLite(extensionLite);
final FieldDescriptor descriptor = extension.getDescriptor();
verifyExtensionContainingType(descriptor);
final Object value = extensions.getField(descriptor);
if (value == null) {
return null;
}
return (T) extension.fromReflectionType(value);
}
/** Get one element of a repeated extension. */
@Override
@SuppressWarnings("unchecked")
@ -1484,6 +1503,22 @@ public abstract class GeneratedMessage extends AbstractMessage implements Serial
return (T) extension.fromReflectionType(value);
}
@Override
@SuppressWarnings("unchecked") // Safe as fromReflectionType will always match the type of T.
public final <T extends MessageLite> T getMessageTypedExtensionOrNull(
final ExtensionLite<? extends MessageT, T> extensionLite) {
Extension<MessageT, T> extension = checkNotLite(extensionLite);
verifyExtensionContainingType(extension);
if (extensions == null) {
return null;
}
final Object value = extensions.getField(extension.getDescriptor());
if (value == null) {
return null;
}
return (T) extension.fromReflectionType(value);
}
/** Get one element of a repeated extension. */
@Override
public final <T> T getExtension(