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 {