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
// 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 @@ static Type* AllocIfDefault(const FieldDescriptor* field, Type*& ptr,
return ptr;
}
template <class Type>
Type* Reflection::MutableRawNonOneof(Message* message,
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,
void* Reflection::MutableRawNonOneofImpl(Message* message,
const FieldDescriptor* field) const {
const uint32_t field_offset = schema_.GetFieldOffset(field);
if (!schema_.IsSplit(field)) {
return GetPointerAtOffset<Type>(message, field_offset);
if (PROTOBUF_PREDICT_FALSE(schema_.IsSplit(field))) {
return MutableRawSplitImpl(message, field);
}
PrepareSplitMessageForWrite(message);
void** split = MutableSplitField(message);
if (SplitFieldHasExtraIndirection(field)) {
return AllocIfDefault(field,
*GetPointerAtOffset<Type*>(*split, field_offset),
message->GetArena());
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);
}
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 {

@ -1105,19 +1105,34 @@ class PROTOBUF_EXPORT Reflection final {
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 @@ 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 <typename Type>
inline const Type& GetField(const Message& message,
@ -1546,21 +1559,45 @@ class RawMessageBase : public Message {
} // namespace internal
template <typename Type>
const Type& Reflection::GetRaw(const Message& message,
const Type& Reflection::GetRawSplit(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);
}
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 {

Loading…
Cancel
Save