Allow friendly use of Reflection::MutableRaw(), Reflection::MutableRawNonOneof().

PiperOrigin-RevId: 591330894
diff --git a/src/google/protobuf/generated_message_reflection.cc b/src/google/protobuf/generated_message_reflection.cc
index 647b4cc..164669c 100644
--- a/src/google/protobuf/generated_message_reflection.cc
+++ b/src/google/protobuf/generated_message_reflection.cc
@@ -2659,20 +2659,6 @@
 // These simple template accessors obtain pointers (or references) to
 // the given field.
 
-template <class Type>
-const Type& Reflection::GetRawNonOneof(const Message& message,
-                                       const FieldDescriptor* field) const {
-  const uint32_t field_offset = schema_.GetFieldOffsetNonOneof(field);
-  if (!schema_.IsSplit(field)) {
-    return GetConstRefAtOffset<Type>(message, field_offset);
-  }
-  const void* split = GetSplitField(&message);
-  if (SplitFieldHasExtraIndirection(field)) {
-    return **GetConstPointerAtOffset<Type*>(split, field_offset);
-  }
-  return *GetConstPointerAtOffset<Type>(split, field_offset);
-}
-
 void Reflection::PrepareSplitMessageForWrite(Message* message) const {
   ABSL_DCHECK_NE(message, schema_.default_instance_);
   void** split = MutableSplitField(message);
@@ -2705,38 +2691,42 @@
   return ptr;
 }
 
-template <class Type>
-Type* Reflection::MutableRawNonOneof(Message* message,
-                                     const FieldDescriptor* field) const {
+void* Reflection::MutableRawSplitImpl(Message* message,
+                                      const FieldDescriptor* field) const {
+  ABSL_DCHECK(!schema_.InRealOneof(field)) << "Field = " << field->full_name();
+
   const uint32_t field_offset = schema_.GetFieldOffsetNonOneof(field);
-  if (!schema_.IsSplit(field)) {
-    return GetPointerAtOffset<Type>(message, field_offset);
-  }
   PrepareSplitMessageForWrite(message);
   void** split = MutableSplitField(message);
   if (SplitFieldHasExtraIndirection(field)) {
     return AllocIfDefault(field,
-                          *GetPointerAtOffset<Type*>(*split, field_offset),
+                          *GetPointerAtOffset<void*>(*split, field_offset),
                           message->GetArena());
   }
-  return GetPointerAtOffset<Type>(*split, field_offset);
+  return GetPointerAtOffset<void>(*split, field_offset);
 }
 
-template <typename Type>
-Type* Reflection::MutableRaw(Message* message,
-                             const FieldDescriptor* field) const {
+void* Reflection::MutableRawNonOneofImpl(Message* message,
+                                         const FieldDescriptor* field) const {
+  if (PROTOBUF_PREDICT_FALSE(schema_.IsSplit(field))) {
+    return MutableRawSplitImpl(message, field);
+  }
+
+  const uint32_t field_offset = schema_.GetFieldOffsetNonOneof(field);
+  return GetPointerAtOffset<void>(message, field_offset);
+}
+
+void* Reflection::MutableRawImpl(Message* message,
+                                 const FieldDescriptor* field) const {
+  if (PROTOBUF_PREDICT_TRUE(!schema_.InRealOneof(field))) {
+    return MutableRawNonOneofImpl(message, field);
+  }
+
+  // Oneof fields are not split.
+  ABSL_DCHECK(!schema_.IsSplit(field));
+
   const uint32_t field_offset = schema_.GetFieldOffset(field);
-  if (!schema_.IsSplit(field)) {
-    return GetPointerAtOffset<Type>(message, field_offset);
-  }
-  PrepareSplitMessageForWrite(message);
-  void** split = MutableSplitField(message);
-  if (SplitFieldHasExtraIndirection(field)) {
-    return AllocIfDefault(field,
-                          *GetPointerAtOffset<Type*>(*split, field_offset),
-                          message->GetArena());
-  }
-  return GetPointerAtOffset<Type>(*split, field_offset);
+  return GetPointerAtOffset<void>(message, field_offset);
 }
 
 const uint32_t* Reflection::GetHasBits(const Message& message) const {
diff --git a/src/google/protobuf/message.h b/src/google/protobuf/message.h
index d25c2d7..f9e88d7 100644
--- a/src/google/protobuf/message.h
+++ b/src/google/protobuf/message.h
@@ -1105,19 +1105,34 @@
   const T& GetRawNonOneof(const Message& message,
                           const FieldDescriptor* field) const;
   template <class T>
-  T* MutableRawNonOneof(Message* message, const FieldDescriptor* field) const;
-
+  const T& GetRawSplit(const Message& message,
+                       const FieldDescriptor* field) const;
   template <typename Type>
   const Type& GetRaw(const Message& message,
                      const FieldDescriptor* field) const;
+
+  void* MutableRawNonOneofImpl(Message* message,
+                               const FieldDescriptor* field) const;
+  void* MutableRawSplitImpl(Message* message,
+                            const FieldDescriptor* field) const;
+  void* MutableRawImpl(Message* message, const FieldDescriptor* field) const;
+
   template <typename Type>
-  inline Type* MutableRaw(Message* message, const FieldDescriptor* field) const;
+  Type* MutableRawNonOneof(Message* message,
+                           const FieldDescriptor* field) const {
+    return reinterpret_cast<Type*>(MutableRawNonOneofImpl(message, field));
+  }
+  template <typename Type>
+  Type* MutableRaw(Message* message, const FieldDescriptor* field) const {
+    return reinterpret_cast<Type*>(MutableRawImpl(message, field));
+  }
+
   template <typename Type>
   const Type& DefaultRaw(const FieldDescriptor* field) const;
 
   const Message* GetDefaultMessageInstance(const FieldDescriptor* field) const;
 
-  inline const uint32_t* GetHasBits(const Message& message) const;
+  const uint32_t* GetHasBits(const Message& message) const;
   inline uint32_t* MutableHasBits(Message* message) const;
   uint32_t GetOneofCase(const Message& message,
                         const OneofDescriptor* oneof_descriptor) const;
@@ -1136,9 +1151,8 @@
 
   inline bool IsInlined(const FieldDescriptor* field) const;
 
-  inline bool HasBit(const Message& message,
-                     const FieldDescriptor* field) const;
-  inline void SetBit(Message* message, const FieldDescriptor* field) const;
+  bool HasBit(const Message& message, const FieldDescriptor* field) const;
+  void SetBit(Message* message, const FieldDescriptor* field) const;
   inline void ClearBit(Message* message, const FieldDescriptor* field) const;
   inline void SwapBit(Message* message1, Message* message2,
                       const FieldDescriptor* field) const;
@@ -1188,8 +1202,7 @@
                             const FieldDescriptor* field) const;
   inline void SetOneofCase(Message* message,
                            const FieldDescriptor* field) const;
-  inline void ClearOneofField(Message* message,
-                              const FieldDescriptor* field) const;
+  void ClearOneofField(Message* message, const FieldDescriptor* field) const;
 
   template <typename Type>
   inline const Type& GetField(const Message& message,
@@ -1546,21 +1559,45 @@
 }  // namespace internal
 
 template <typename Type>
-const Type& Reflection::GetRaw(const Message& message,
-                               const FieldDescriptor* field) const {
-  ABSL_DCHECK(!schema_.InRealOneof(field) || HasOneofField(message, field))
-      << "Field = " << field->full_name();
-  const uint32_t field_offset = schema_.GetFieldOffset(field);
-  if (!schema_.IsSplit(field)) {
-    return internal::GetConstRefAtOffset<Type>(message, field_offset);
-  }
+const Type& Reflection::GetRawSplit(const Message& message,
+                                    const FieldDescriptor* field) const {
+  ABSL_DCHECK(!schema_.InRealOneof(field)) << "Field = " << field->full_name();
+
   const void* split = GetSplitField(&message);
+  const uint32_t field_offset = schema_.GetFieldOffsetNonOneof(field);
   if (internal::SplitFieldHasExtraIndirectionStatic<Type>(field)) {
     return **internal::GetConstPointerAtOffset<Type*>(split, field_offset);
   }
   return *internal::GetConstPointerAtOffset<Type>(split, field_offset);
 }
 
+template <class Type>
+const Type& Reflection::GetRawNonOneof(const Message& message,
+                                       const FieldDescriptor* field) const {
+  if (PROTOBUF_PREDICT_FALSE(schema_.IsSplit(field))) {
+    return GetRawSplit<Type>(message, field);
+  }
+  const uint32_t field_offset = schema_.GetFieldOffsetNonOneof(field);
+  return internal::GetConstRefAtOffset<Type>(message, field_offset);
+}
+
+template <typename Type>
+const Type& Reflection::GetRaw(const Message& message,
+                               const FieldDescriptor* field) const {
+  ABSL_DCHECK(!schema_.InRealOneof(field) || HasOneofField(message, field))
+      << "Field = " << field->full_name();
+
+  if (PROTOBUF_PREDICT_TRUE(!schema_.InRealOneof(field))) {
+    return GetRawNonOneof<Type>(message, field);
+  }
+
+  // Oneof fields are not split.
+  ABSL_DCHECK(!schema_.IsSplit(field));
+
+  const uint32_t field_offset = schema_.GetFieldOffset(field);
+  return internal::GetConstRefAtOffset<Type>(message, field_offset);
+}
+
 template <typename T>
 RepeatedFieldRef<T> Reflection::GetRepeatedFieldRef(
     const Message& message, const FieldDescriptor* field) const {