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

PiperOrigin-RevId: 926787242
diff --git a/java/core/src/main/java/com/google/protobuf/GeneratedMessage.java b/java/core/src/main/java/com/google/protobuf/GeneratedMessage.java
index 4e955b0..45e69f0 100644
--- a/java/core/src/main/java/com/google/protobuf/GeneratedMessage.java
+++ b/java/core/src/main/java/com/google/protobuf/GeneratedMessage.java
@@ -961,6 +961,10 @@
     /** 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 @@
       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 @@
       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(