Do proper const propagation on the `msg` accessors.

PiperOrigin-RevId: 553482114
pull/13675/head^2
Protobuf Team Bot 2 years ago committed by Copybara-Service
parent 8687124a99
commit c4549993da
  1. 109
      protos/protos.h
  2. 5
      protos/repeated_field.h
  3. 9
      protos_generator/gen_accessors.cc
  4. 43
      protos_generator/gen_messages.cc

@ -98,6 +98,21 @@ class Ptr final {
Proxy<T> p_;
};
namespace internal {
struct PrivateAccess {
template <typename T>
static auto* GetInternalMsg(T&& message) {
return message->msg();
}
};
template <typename T>
auto* GetInternalMsg(T&& message) {
return PrivateAccess::GetInternalMsg(std::forward<T>(message));
}
} // namespace internal
inline absl::string_view UpbStrToStringView(upb_StringView str) {
return absl::string_view(str.data, str.size);
}
@ -119,37 +134,43 @@ typename T::Proxy CreateMessage(::protos::Arena& arena) {
template <typename T>
typename T::Proxy CloneMessage(Ptr<T> message, upb::Arena& arena) {
return typename T::Proxy(
upb_Message_DeepClone(message->msg(), T::minitable(), arena.ptr()),
arena.ptr());
return
typename T::Proxy(upb_Message_DeepClone(internal::GetInternalMsg(message),
T::minitable(), arena.ptr()),
arena.ptr());
}
template <typename T>
void DeepCopy(Ptr<const T> source_message, Ptr<T> target_message) {
static_assert(!std::is_const_v<T>);
upb_Message_DeepCopy(
target_message->msg(), source_message->msg(), T::minitable(),
internal::GetInternalMsg(target_message),
internal::GetInternalMsg(source_message), T::minitable(),
static_cast<upb_Arena*>(target_message->GetInternalArena()));
}
template <typename T>
void DeepCopy(Ptr<const T> source_message, T* target_message) {
static_assert(!std::is_const_v<T>);
DeepCopy(source_message, protos::Ptr(target_message));
}
template <typename T>
void DeepCopy(const T* source_message, Ptr<T> target_message) {
static_assert(!std::is_const_v<T>);
DeepCopy(protos::Ptr(source_message), target_message);
}
template <typename T>
void DeepCopy(const T* source_message, T* target_message) {
static_assert(!std::is_const_v<T>);
DeepCopy(protos::Ptr(source_message), protos::Ptr(target_message));
}
template <typename T>
void ClearMessage(Ptr<T> message) {
static_assert(!std::is_const_v<T>, "");
upb_Message_Clear(message->msg(), T::minitable());
upb_Message_Clear(internal::GetInternalMsg(message), T::minitable());
}
template <typename T>
@ -231,16 +252,6 @@ class ExtensionIdentifier : public ExtensionMiniTableProvider {
: ExtensionMiniTableProvider(mini_table_ext) {}
};
template <typename T>
void* GetInternalMsg(const T* message) {
return message->msg();
}
template <typename T>
void* GetInternalMsg(Ptr<T> message) {
return message->msg();
}
template <typename T>
upb_Arena* GetArena(Ptr<T> message) {
return static_cast<upb_Arena*>(message->GetInternalArena());
@ -311,8 +322,8 @@ using EnableIfMutableProto = std::enable_if_t<!std::is_const<T>::value>;
template <typename T, typename Extendee, typename Extension,
typename = EnableIfProtosClass<T>>
bool HasExtension(
const Ptr<T>& message,
ABSL_MUST_USE_RESULT bool HasExtension(
Ptr<T> message,
const ::protos::internal::ExtensionIdentifier<Extendee, Extension>& id) {
return ::protos::internal::HasExtensionOrUnknown(
::protos::internal::GetInternalMsg(message), id.mini_table_ext());
@ -320,7 +331,7 @@ bool HasExtension(
template <typename T, typename Extendee, typename Extension,
typename = EnableIfProtosClass<T>>
bool HasExtension(
ABSL_MUST_USE_RESULT bool HasExtension(
const T* message,
const ::protos::internal::ExtensionIdentifier<Extendee, Extension>& id) {
return HasExtension(protos::Ptr(message), id);
@ -329,10 +340,10 @@ bool HasExtension(
template <typename T, typename Extendee, typename Extension,
typename = EnableIfProtosClass<T>, typename = EnableIfMutableProto<T>>
void ClearExtension(
const Ptr<T>& message,
Ptr<T> message,
const ::protos::internal::ExtensionIdentifier<Extendee, Extension>& id) {
static_assert(!std::is_const_v<T>, "");
_upb_Message_ClearExtensionField(::protos::internal::GetInternalMsg(message),
_upb_Message_ClearExtensionField(internal::GetInternalMsg(message),
id.mini_table_ext());
}
@ -347,12 +358,13 @@ void ClearExtension(
template <typename T, typename Extendee, typename Extension,
typename = EnableIfProtosClass<T>, typename = EnableIfMutableProto<T>>
absl::Status SetExtension(
const Ptr<T>& message,
Ptr<T> message,
const ::protos::internal::ExtensionIdentifier<Extendee, Extension>& id,
Extension& value) {
static_assert(!std::is_const_v<T>);
auto* message_arena = static_cast<upb_Arena*>(message->GetInternalArena());
upb_Message_Extension* msg_ext = _upb_Message_GetOrCreateExtension(
message->msg(), id.mini_table_ext(), message_arena);
internal::GetInternalMsg(message), id.mini_table_ext(), message_arena);
if (!msg_ext) {
return MessageAllocationError();
}
@ -360,7 +372,7 @@ absl::Status SetExtension(
if (message_arena != extension_arena) {
upb_Arena_Fuse(message_arena, extension_arena);
}
msg_ext->data.ptr = ::protos::internal::GetInternalMsg(&value);
msg_ext->data.ptr = internal::GetInternalMsg(&value);
return absl::OkStatus();
}
@ -376,11 +388,12 @@ absl::Status SetExtension(
template <typename T, typename Extendee, typename Extension,
typename = EnableIfProtosClass<T>>
absl::StatusOr<Ptr<const Extension>> GetExtension(
const Ptr<T>& message,
Ptr<T> message,
const ::protos::internal::ExtensionIdentifier<Extendee, Extension>& id) {
// TODO(b/294089233): Fix const correctness issues.
const upb_Message_Extension* ext = ::protos::internal::GetOrPromoteExtension(
::protos::internal::GetInternalMsg(message), id.mini_table_ext(),
::protos::internal::GetArena(message));
const_cast<upb_Message*>(internal::GetInternalMsg(message)),
id.mini_table_ext(), ::protos::internal::GetArena(message));
if (!ext) {
return ExtensionNotFoundError(id.mini_table_ext()->field.number);
}
@ -397,21 +410,28 @@ absl::StatusOr<Ptr<const Extension>> GetExtension(
}
template <typename T>
bool Parse(Ptr<T>& message, absl::string_view bytes) {
upb_Message_Clear(message->msg(), ::protos::internal::GetMiniTable(message));
ABSL_MUST_USE_RESULT bool Parse(Ptr<T> message, absl::string_view bytes) {
static_assert(!std::is_const_v<T>);
upb_Message_Clear(internal::GetInternalMsg(message),
::protos::internal::GetMiniTable(message));
auto* arena = static_cast<upb_Arena*>(message->GetInternalArena());
return upb_Decode(bytes.data(), bytes.size(), message->msg(),
return upb_Decode(bytes.data(), bytes.size(),
internal::GetInternalMsg(message),
::protos::internal::GetMiniTable(message),
/* extreg= */ nullptr, /* options= */ 0,
arena) == kUpb_DecodeStatus_Ok;
}
template <typename T>
bool Parse(Ptr<T>& message, absl::string_view bytes,
const ::protos::ExtensionRegistry& extension_registry) {
upb_Message_Clear(message->msg(), ::protos::internal::GetMiniTable(message));
ABSL_MUST_USE_RESULT bool Parse(
Ptr<T> message, absl::string_view bytes,
const ::protos::ExtensionRegistry& extension_registry) {
static_assert(!std::is_const_v<T>);
upb_Message_Clear(internal::GetInternalMsg(message),
::protos::internal::GetMiniTable(message));
auto* arena = static_cast<upb_Arena*>(message->GetInternalArena());
return upb_Decode(bytes.data(), bytes.size(), message->msg(),
return upb_Decode(bytes.data(), bytes.size(),
internal::GetInternalMsg(message),
::protos::internal::GetMiniTable(message),
/* extreg= */
::protos::internal::GetUpbExtensions(extension_registry),
@ -419,16 +439,21 @@ bool Parse(Ptr<T>& message, absl::string_view bytes,
}
template <typename T>
bool Parse(T* message, absl::string_view bytes,
const ::protos::ExtensionRegistry& extension_registry) {
ABSL_MUST_USE_RESULT bool Parse(
T* message, absl::string_view bytes,
const ::protos::ExtensionRegistry& extension_registry) {
static_assert(!std::is_const_v<T>);
return Parse(protos::Ptr(message, bytes, extension_registry));
}
template <typename T>
bool Parse(T* message, absl::string_view bytes) {
upb_Message_Clear(message->msg(), ::protos::internal::GetMiniTable(message));
ABSL_MUST_USE_RESULT bool Parse(T* message, absl::string_view bytes) {
static_assert(!std::is_const_v<T>);
upb_Message_Clear(internal::GetInternalMsg(message),
::protos::internal::GetMiniTable(message));
auto* arena = static_cast<upb_Arena*>(message->GetInternalArena());
return upb_Decode(bytes.data(), bytes.size(), message->msg(),
return upb_Decode(bytes.data(), bytes.size(),
internal::GetInternalMsg(message),
::protos::internal::GetMiniTable(message),
/* extreg= */ nullptr, /* options= */ 0,
arena) == kUpb_DecodeStatus_Ok;
@ -469,16 +494,16 @@ template <typename T>
absl::StatusOr<absl::string_view> Serialize(const T* message, upb::Arena& arena,
int options = 0) {
return ::protos::internal::Serialize(
message->msg(), ::protos::internal::GetMiniTable(message), arena.ptr(),
options);
internal::GetInternalMsg(message),
::protos::internal::GetMiniTable(message), arena.ptr(), options);
}
template <typename T>
absl::StatusOr<absl::string_view> Serialize(Ptr<T> message, upb::Arena& arena,
int options = 0) {
return ::protos::internal::Serialize(
message->msg(), ::protos::internal::GetMiniTable(message), arena.ptr(),
options);
internal::GetInternalMsg(message),
::protos::internal::GetMiniTable(message), arena.ptr(), options);
}
} // namespace protos

@ -134,7 +134,8 @@ class RepeatedFieldProxy
void push_back(const T& t) {
upb_MessageValue message_value;
message_value.msg_val = upb_Message_DeepClone(
GetInternalMsg(&t), ::protos::internal::GetMiniTable(&t), this->arena_);
PrivateAccess::GetInternalMsg(&t), ::protos::internal::GetMiniTable(&t),
this->arena_);
upb_Array_Append(this->arr_, message_value, this->arena_);
}
@ -143,7 +144,7 @@ class RepeatedFieldProxy
typename = std::enable_if_t<b>>
void push_back(T&& msg) {
upb_MessageValue message_value;
message_value.msg_val = GetInternalMsg(&msg);
message_value.msg_val = PrivateAccess::GetInternalMsg(&msg);
upb_Arena_Fuse(GetArena(&msg), this->arena_);
upb_Array_Append(this->arr_, message_value, this->arena_);
T moved_msg = std::move(msg);

@ -312,7 +312,9 @@ void WriteMapAccessorDefinitions(const protobuf::Descriptor* message,
output(
R"cc(
bool $0::set_$1($2 key, $3 value) {
upb_Message* clone = upb_Message_DeepClone(value->msg(), &$9, arena_);
upb_Message* clone = upb_Message_DeepClone(
::protos::internal::PrivateAccess::GetInternalMsg(value), &$9,
arena_);
$6return $4_$8_set(msg_, $7, ($5*)clone, arena_);
}
)cc",
@ -324,7 +326,9 @@ void WriteMapAccessorDefinitions(const protobuf::Descriptor* message,
output(
R"cc(
bool $0::set_$1($2 key, $3 value) {
upb_Message* clone = upb_Message_DeepClone(value->msg(), &$9, arena_);
upb_Message* clone = upb_Message_DeepClone(
::protos::internal::PrivateAccess::GetInternalMsg(value), &$9,
arena_);
$6return $4_$8_set(msg_, $7, ($5*)clone, arena_);
}
)cc",
@ -484,7 +488,6 @@ void WriteUsingAccessorsInHeader(const protobuf::Descriptor* desc,
output("using $0Access::$1_NOT_SET;\n", class_name,
absl::AsciiStrToUpper(oneof->name()));
}
output("using $0Access::msg;\n", class_name);
}
void WriteOneofAccessorsInHeader(const protobuf::Descriptor* desc,

@ -127,13 +127,10 @@ void WriteModelAccessDeclaration(const protobuf::Descriptor* descriptor,
output(
R"cc(
private:
void* msg() const { return msg_; }
friend class $2;
friend class $0Proxy;
friend class $0CProxy;
friend void* ::protos::internal::GetInternalMsg<$2>(const $2* message);
friend void* ::protos::internal::GetInternalMsg<$2>(::protos::Ptr<$2> message);
friend struct ::protos::internal::PrivateAccess;
$1* msg_;
upb_Arena* arena_;
)cc",
@ -159,20 +156,11 @@ void WriteModelPublicDeclaration(
$0();
$0(const $0& from);
inline $0& operator=(const $3& from) {
arena_ = owned_arena_.ptr();
msg_ = ($2*)upb_Message_DeepClone(from.msg_, &$1, arena_);
return *this;
}
$0& operator=(const $3& from);
$0(const CProxy& from);
$0(const Proxy& from);
inline $0& operator=(const CProxy& from) {
arena_ = owned_arena_.ptr();
msg_ = ($2*)upb_Message_DeepClone(
::protos::internal::GetInternalMsg(&from), &$1, arena_);
return *this;
}
$0& operator=(const CProxy& from);
$0($0&& m)
: Access(absl::exchange(m.msg_, nullptr),
absl::exchange(m.arena_, nullptr)),
@ -212,12 +200,16 @@ void WriteModelPublicDeclaration(
output(
R"cc(
private:
const void* msg() const { return msg_; }
void* msg() { return msg_; }
$0(upb_Message* msg, upb_Arena* arena) : $0Access() {
msg_ = ($1*)msg;
arena_ = owned_arena_.ptr();
upb_Arena_Fuse(arena_, arena);
}
::protos::Arena owned_arena_;
friend struct ::protos::internal::PrivateAccess;
friend Proxy;
friend CProxy;
friend absl::StatusOr<$2>(::protos::Parse<$2>(absl::string_view bytes,
@ -269,10 +261,13 @@ void WriteModelProxyDeclaration(const protobuf::Descriptor* descriptor,
output(
R"cc(
private:
void* msg() const { return msg_; }
$0Proxy(void* msg, upb_Arena* arena) : internal::$0Access(($1*)msg, arena) {}
friend $0::Proxy(::protos::CreateMessage<$0>(::protos::Arena& arena));
friend $0::Proxy(::protos::internal::CreateMessageProxy<$0>(
upb_Message*, upb_Arena*));
friend struct ::protos::internal::PrivateAccess;
friend class RepeatedFieldProxy;
friend class $0CProxy;
friend class $0Access;
@ -287,6 +282,7 @@ void WriteModelProxyDeclaration(const protobuf::Descriptor* descriptor,
friend upb_Arena* ::protos::internal::GetArena<$2>(::protos::Ptr<$2> message);
friend $0Proxy(::protos::CloneMessage(::protos::Ptr<$2> message,
::upb::Arena& arena));
static void Rebind($0Proxy& lhs, const $0Proxy& rhs) {
lhs.msg_ = rhs.msg_;
lhs.arena_ = rhs.arena_;
@ -320,9 +316,13 @@ void WriteModelCProxyDeclaration(const protobuf::Descriptor* descriptor,
output(
R"cc(
private:
using AsNonConst = $0Proxy;
const void* msg() const { return msg_; }
$0CProxy(void* msg, upb_Arena* arena) : internal::$0Access(($1*)msg, arena){};
friend $0::CProxy(::protos::internal::CreateMessage<$0>(
upb_Message* msg, upb_Arena* arena));
friend struct ::protos::internal::PrivateAccess;
friend class RepeatedFieldProxy;
friend class ::protos::Ptr<$0>;
friend class ::protos::Ptr<const $0>;
@ -375,6 +375,17 @@ void WriteMessageImplementation(
arena_ = m.arena_;
msg_ = ($1*)::protos::internal::GetInternalMsg(&m);
}
$0& $0::operator=(const $3& from) {
arena_ = owned_arena_.ptr();
msg_ = ($1*)upb_Message_DeepClone(from.msg_, &$2, arena_);
return *this;
}
$0& $0::operator=(const CProxy& from) {
arena_ = owned_arena_.ptr();
msg_ = ($1*)upb_Message_DeepClone(
::protos::internal::GetInternalMsg(&from), &$2, arena_);
return *this;
}
)cc",
ClassName(descriptor), MessageName(descriptor),
::upbc::MessageInit(descriptor->full_name()),

Loading…
Cancel
Save