diff --git a/src/google/protobuf/generated_message_reflection.cc b/src/google/protobuf/generated_message_reflection.cc index 647b4cc747..164669cabe 100644 --- a/src/google/protobuf/generated_message_reflection.cc +++ b/src/google/protobuf/generated_message_reflection.cc @@ -2659,20 +2659,6 @@ const FieldDescriptor* Reflection::FindKnownExtensionByNumber( // These simple template accessors obtain pointers (or references) to // the given field. -template -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(message, field_offset); - } - const void* split = GetSplitField(&message); - if (SplitFieldHasExtraIndirection(field)) { - return **GetConstPointerAtOffset(split, field_offset); - } - return *GetConstPointerAtOffset(split, field_offset); -} - void Reflection::PrepareSplitMessageForWrite(Message* message) const { ABSL_DCHECK_NE(message, schema_.default_instance_); void** split = MutableSplitField(message); @@ -2705,38 +2691,42 @@ static Type* AllocIfDefault(const FieldDescriptor* field, Type*& ptr, return ptr; } -template -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(message, field_offset); - } PrepareSplitMessageForWrite(message); void** split = MutableSplitField(message); if (SplitFieldHasExtraIndirection(field)) { return AllocIfDefault(field, - *GetPointerAtOffset(*split, field_offset), + *GetPointerAtOffset(*split, field_offset), message->GetArena()); } - return GetPointerAtOffset(*split, field_offset); + return GetPointerAtOffset(*split, field_offset); } -template -Type* Reflection::MutableRaw(Message* message, - const FieldDescriptor* field) const { - const uint32_t field_offset = schema_.GetFieldOffset(field); - if (!schema_.IsSplit(field)) { - return GetPointerAtOffset(message, field_offset); +void* Reflection::MutableRawNonOneofImpl(Message* message, + const FieldDescriptor* field) const { + if (PROTOBUF_PREDICT_FALSE(schema_.IsSplit(field))) { + return MutableRawSplitImpl(message, field); } - PrepareSplitMessageForWrite(message); - void** split = MutableSplitField(message); - if (SplitFieldHasExtraIndirection(field)) { - return AllocIfDefault(field, - *GetPointerAtOffset(*split, field_offset), - message->GetArena()); + + const uint32_t field_offset = schema_.GetFieldOffsetNonOneof(field); + return GetPointerAtOffset(message, field_offset); +} + +void* Reflection::MutableRawImpl(Message* message, + const FieldDescriptor* field) const { + if (PROTOBUF_PREDICT_TRUE(!schema_.InRealOneof(field))) { + return MutableRawNonOneofImpl(message, field); } - return GetPointerAtOffset(*split, field_offset); + + // Oneof fields are not split. + ABSL_DCHECK(!schema_.IsSplit(field)); + + const uint32_t field_offset = schema_.GetFieldOffset(field); + return GetPointerAtOffset(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 d25c2d7815..f9e88d79d1 100644 --- a/src/google/protobuf/message.h +++ b/src/google/protobuf/message.h @@ -1105,19 +1105,34 @@ class PROTOBUF_EXPORT Reflection final { const T& GetRawNonOneof(const Message& message, const FieldDescriptor* field) const; template - T* MutableRawNonOneof(Message* message, const FieldDescriptor* field) const; - + const T& GetRawSplit(const Message& message, + const FieldDescriptor* field) const; template 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 - inline Type* MutableRaw(Message* message, const FieldDescriptor* field) const; + Type* MutableRawNonOneof(Message* message, + const FieldDescriptor* field) const { + return reinterpret_cast(MutableRawNonOneofImpl(message, field)); + } + template + Type* MutableRaw(Message* message, const FieldDescriptor* field) const { + return reinterpret_cast(MutableRawImpl(message, field)); + } + template 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 @@ class PROTOBUF_EXPORT Reflection final { 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 @@ class PROTOBUF_EXPORT Reflection final { 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 inline const Type& GetField(const Message& message, @@ -1546,21 +1559,45 @@ class RawMessageBase : public Message { } // namespace internal template -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(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(field)) { return **internal::GetConstPointerAtOffset(split, field_offset); } return *internal::GetConstPointerAtOffset(split, field_offset); } +template +const Type& Reflection::GetRawNonOneof(const Message& message, + const FieldDescriptor* field) const { + if (PROTOBUF_PREDICT_FALSE(schema_.IsSplit(field))) { + return GetRawSplit(message, field); + } + const uint32_t field_offset = schema_.GetFieldOffsetNonOneof(field); + return internal::GetConstRefAtOffset(message, field_offset); +} + +template +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(message, field); + } + + // Oneof fields are not split. + ABSL_DCHECK(!schema_.IsSplit(field)); + + const uint32_t field_offset = schema_.GetFieldOffset(field); + return internal::GetConstRefAtOffset(message, field_offset); +} + template RepeatedFieldRef Reflection::GetRepeatedFieldRef( const Message& message, const FieldDescriptor* field) const {