diff --git a/src/google/protobuf/generated_message_reflection.cc b/src/google/protobuf/generated_message_reflection.cc index 164669cabe..647b4cc747 100644 --- a/src/google/protobuf/generated_message_reflection.cc +++ b/src/google/protobuf/generated_message_reflection.cc @@ -2659,6 +2659,20 @@ 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); @@ -2691,42 +2705,38 @@ static Type* AllocIfDefault(const FieldDescriptor* field, Type*& ptr, return ptr; } -void* Reflection::MutableRawSplitImpl(Message* message, - const FieldDescriptor* field) const { - ABSL_DCHECK(!schema_.InRealOneof(field)) << "Field = " << field->full_name(); - +template +Type* Reflection::MutableRawNonOneof(Message* message, + const FieldDescriptor* field) const { 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); } -void* Reflection::MutableRawNonOneofImpl(Message* message, - const FieldDescriptor* field) const { - if (PROTOBUF_PREDICT_FALSE(schema_.IsSplit(field))) { - return MutableRawSplitImpl(message, field); +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); } - - 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); + PrepareSplitMessageForWrite(message); + void** split = MutableSplitField(message); + if (SplitFieldHasExtraIndirection(field)) { + return AllocIfDefault(field, + *GetPointerAtOffset(*split, field_offset), + message->GetArena()); } - - // Oneof fields are not split. - ABSL_DCHECK(!schema_.IsSplit(field)); - - const uint32_t field_offset = schema_.GetFieldOffset(field); - return GetPointerAtOffset(message, field_offset); + return GetPointerAtOffset(*split, 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 f9e88d79d1..d25c2d7815 100644 --- a/src/google/protobuf/message.h +++ b/src/google/protobuf/message.h @@ -1105,34 +1105,19 @@ class PROTOBUF_EXPORT Reflection final { const T& GetRawNonOneof(const Message& message, const FieldDescriptor* field) const; template - const T& GetRawSplit(const Message& message, - const FieldDescriptor* field) const; + T* MutableRawNonOneof(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 - 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)); - } - + inline Type* MutableRaw(Message* message, const FieldDescriptor* field) const; template const Type& DefaultRaw(const FieldDescriptor* field) const; const Message* GetDefaultMessageInstance(const FieldDescriptor* field) const; - const uint32_t* GetHasBits(const Message& message) const; + inline 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; @@ -1151,8 +1136,9 @@ class PROTOBUF_EXPORT Reflection final { inline bool IsInlined(const FieldDescriptor* field) const; - bool HasBit(const Message& message, const FieldDescriptor* field) const; - void SetBit(Message* message, const FieldDescriptor* field) const; + inline bool HasBit(const Message& message, + const FieldDescriptor* field) const; + inline 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; @@ -1202,7 +1188,8 @@ class PROTOBUF_EXPORT Reflection final { const FieldDescriptor* field) const; inline void SetOneofCase(Message* message, const FieldDescriptor* field) const; - void ClearOneofField(Message* message, const FieldDescriptor* field) const; + inline void ClearOneofField(Message* message, + const FieldDescriptor* field) const; template inline const Type& GetField(const Message& message, @@ -1558,44 +1545,20 @@ class RawMessageBase : public Message { } // namespace internal -template -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); + if (!schema_.IsSplit(field)) { + return internal::GetConstRefAtOffset(message, field_offset); + } + const void* split = GetSplitField(&message); + if (internal::SplitFieldHasExtraIndirectionStatic(field)) { + return **internal::GetConstPointerAtOffset(split, field_offset); + } + return *internal::GetConstPointerAtOffset(split, field_offset); } template