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

PiperOrigin-RevId: 591330894
pull/15101/head
Protobuf Team Bot 12 months ago committed by Copybara-Service
parent 14dd8e9ee0
commit 481c4fede5
  1. 56
      src/google/protobuf/generated_message_reflection.cc
  2. 69
      src/google/protobuf/message.h

@ -2659,20 +2659,6 @@ const FieldDescriptor* Reflection::FindKnownExtensionByNumber(
// These simple template accessors obtain pointers (or references) to // These simple template accessors obtain pointers (or references) to
// the given field. // 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 { void Reflection::PrepareSplitMessageForWrite(Message* message) const {
ABSL_DCHECK_NE(message, schema_.default_instance_); ABSL_DCHECK_NE(message, schema_.default_instance_);
void** split = MutableSplitField(message); void** split = MutableSplitField(message);
@ -2705,38 +2691,42 @@ static Type* AllocIfDefault(const FieldDescriptor* field, Type*& ptr,
return ptr; return ptr;
} }
template <class Type> void* Reflection::MutableRawSplitImpl(Message* message,
Type* Reflection::MutableRawNonOneof(Message* message,
const FieldDescriptor* field) const { const FieldDescriptor* field) const {
ABSL_DCHECK(!schema_.InRealOneof(field)) << "Field = " << field->full_name();
const uint32_t field_offset = schema_.GetFieldOffsetNonOneof(field); const uint32_t field_offset = schema_.GetFieldOffsetNonOneof(field);
if (!schema_.IsSplit(field)) {
return GetPointerAtOffset<Type>(message, field_offset);
}
PrepareSplitMessageForWrite(message); PrepareSplitMessageForWrite(message);
void** split = MutableSplitField(message); void** split = MutableSplitField(message);
if (SplitFieldHasExtraIndirection(field)) { if (SplitFieldHasExtraIndirection(field)) {
return AllocIfDefault(field, return AllocIfDefault(field,
*GetPointerAtOffset<Type*>(*split, field_offset), *GetPointerAtOffset<void*>(*split, field_offset),
message->GetArena()); message->GetArena());
} }
return GetPointerAtOffset<Type>(*split, field_offset); return GetPointerAtOffset<void>(*split, field_offset);
} }
template <typename Type> void* Reflection::MutableRawNonOneofImpl(Message* message,
Type* Reflection::MutableRaw(Message* message,
const FieldDescriptor* field) const { const FieldDescriptor* field) const {
const uint32_t field_offset = schema_.GetFieldOffset(field); if (PROTOBUF_PREDICT_FALSE(schema_.IsSplit(field))) {
if (!schema_.IsSplit(field)) { return MutableRawSplitImpl(message, field);
return GetPointerAtOffset<Type>(message, field_offset);
} }
PrepareSplitMessageForWrite(message);
void** split = MutableSplitField(message); const uint32_t field_offset = schema_.GetFieldOffsetNonOneof(field);
if (SplitFieldHasExtraIndirection(field)) { return GetPointerAtOffset<void>(message, field_offset);
return AllocIfDefault(field, }
*GetPointerAtOffset<Type*>(*split, field_offset),
message->GetArena()); void* Reflection::MutableRawImpl(Message* message,
const FieldDescriptor* field) const {
if (PROTOBUF_PREDICT_TRUE(!schema_.InRealOneof(field))) {
return MutableRawNonOneofImpl(message, field);
} }
return GetPointerAtOffset<Type>(*split, field_offset);
// Oneof fields are not split.
ABSL_DCHECK(!schema_.IsSplit(field));
const uint32_t field_offset = schema_.GetFieldOffset(field);
return GetPointerAtOffset<void>(message, field_offset);
} }
const uint32_t* Reflection::GetHasBits(const Message& message) const { const uint32_t* Reflection::GetHasBits(const Message& message) const {

@ -1105,19 +1105,34 @@ class PROTOBUF_EXPORT Reflection final {
const T& GetRawNonOneof(const Message& message, const T& GetRawNonOneof(const Message& message,
const FieldDescriptor* field) const; const FieldDescriptor* field) const;
template <class T> template <class T>
T* MutableRawNonOneof(Message* message, const FieldDescriptor* field) const; const T& GetRawSplit(const Message& message,
const FieldDescriptor* field) const;
template <typename Type> template <typename Type>
const Type& GetRaw(const Message& message, const Type& GetRaw(const Message& message,
const FieldDescriptor* field) const; 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> 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> template <typename Type>
const Type& DefaultRaw(const FieldDescriptor* field) const; const Type& DefaultRaw(const FieldDescriptor* field) const;
const Message* GetDefaultMessageInstance(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; inline uint32_t* MutableHasBits(Message* message) const;
uint32_t GetOneofCase(const Message& message, uint32_t GetOneofCase(const Message& message,
const OneofDescriptor* oneof_descriptor) const; const OneofDescriptor* oneof_descriptor) const;
@ -1136,9 +1151,8 @@ class PROTOBUF_EXPORT Reflection final {
inline bool IsInlined(const FieldDescriptor* field) const; inline bool IsInlined(const FieldDescriptor* field) const;
inline bool HasBit(const Message& message, bool HasBit(const Message& message, const FieldDescriptor* field) const;
const FieldDescriptor* field) const; void SetBit(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 ClearBit(Message* message, const FieldDescriptor* field) const;
inline void SwapBit(Message* message1, Message* message2, inline void SwapBit(Message* message1, Message* message2,
const FieldDescriptor* field) const; const FieldDescriptor* field) const;
@ -1188,8 +1202,7 @@ class PROTOBUF_EXPORT Reflection final {
const FieldDescriptor* field) const; const FieldDescriptor* field) const;
inline void SetOneofCase(Message* message, inline void SetOneofCase(Message* message,
const FieldDescriptor* field) const; const FieldDescriptor* field) const;
inline void ClearOneofField(Message* message, void ClearOneofField(Message* message, const FieldDescriptor* field) const;
const FieldDescriptor* field) const;
template <typename Type> template <typename Type>
inline const Type& GetField(const Message& message, inline const Type& GetField(const Message& message,
@ -1546,21 +1559,45 @@ class RawMessageBase : public Message {
} // namespace internal } // namespace internal
template <typename Type> template <typename Type>
const Type& Reflection::GetRaw(const Message& message, const Type& Reflection::GetRawSplit(const Message& message,
const FieldDescriptor* field) const { const FieldDescriptor* field) const {
ABSL_DCHECK(!schema_.InRealOneof(field) || HasOneofField(message, field)) ABSL_DCHECK(!schema_.InRealOneof(field)) << "Field = " << field->full_name();
<< "Field = " << field->full_name();
const uint32_t field_offset = schema_.GetFieldOffset(field);
if (!schema_.IsSplit(field)) {
return internal::GetConstRefAtOffset<Type>(message, field_offset);
}
const void* split = GetSplitField(&message); const void* split = GetSplitField(&message);
const uint32_t field_offset = schema_.GetFieldOffsetNonOneof(field);
if (internal::SplitFieldHasExtraIndirectionStatic<Type>(field)) { if (internal::SplitFieldHasExtraIndirectionStatic<Type>(field)) {
return **internal::GetConstPointerAtOffset<Type*>(split, field_offset); return **internal::GetConstPointerAtOffset<Type*>(split, field_offset);
} }
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> template <typename T>
RepeatedFieldRef<T> Reflection::GetRepeatedFieldRef( RepeatedFieldRef<T> Reflection::GetRepeatedFieldRef(
const Message& message, const FieldDescriptor* field) const { const Message& message, const FieldDescriptor* field) const {

Loading…
Cancel
Save