Fix Serialize failing for Proxy/CProxy.
Refactor minitable access.
PiperOrigin-RevId: 542895074
diff --git a/protos/protos.h b/protos/protos.h
index 809e964..2e2fae9 100644
--- a/protos/protos.h
+++ b/protos/protos.h
@@ -199,12 +199,12 @@
};
template <typename T>
-void* GetInternalMsg(const T& message) {
- return message.msg();
+void* GetInternalMsg(const T* message) {
+ return message->msg();
}
template <typename T>
-void* GetInternalMsg(const Ptr<T>& message) {
+void* GetInternalMsg(Ptr<T> message) {
return message->msg();
}
@@ -214,10 +214,20 @@
}
template <typename T>
-upb_Arena* GetArena(const Ptr<T>& message) {
+upb_Arena* GetArena(Ptr<T> message) {
return static_cast<upb_Arena*>(message->GetInternalArena());
}
+template <typename T>
+const upb_MiniTable* GetMiniTable(const T*) {
+ return T::minitable();
+}
+
+template <typename T>
+const upb_MiniTable* GetMiniTable(Ptr<T>) {
+ return T::minitable();
+}
+
upb_ExtensionRegistry* GetUpbExtensions(
const ExtensionRegistry& extension_registry);
@@ -328,7 +338,7 @@
if (message_arena != extension_arena) {
upb_Arena_Fuse(message_arena, extension_arena);
}
- msg_ext->data.ptr = ::protos::internal::GetInternalMsg(value);
+ msg_ext->data.ptr = ::protos::internal::GetInternalMsg(&value);
return absl::OkStatus();
}
@@ -362,7 +372,7 @@
template <typename T>
bool Parse(T& message, absl::string_view bytes) {
- upb_Message_Clear(message.msg(), T::minitable());
+ upb_Message_Clear(message.msg(), ::protos::internal::GetMiniTable(&message));
auto* arena = static_cast<upb_Arena*>(message.GetInternalArena());
return upb_Decode(bytes.data(), bytes.size(), message.msg(), T::minitable(),
/* extreg= */ nullptr, /* options= */ 0,
@@ -372,9 +382,10 @@
template <typename T>
bool Parse(T& message, absl::string_view bytes,
const ::protos::ExtensionRegistry& extension_registry) {
- upb_Message_Clear(message.msg(), T::minitable());
+ upb_Message_Clear(message.msg(), ::protos::internal::GetMiniTable(message));
auto* arena = static_cast<upb_Arena*>(message.GetInternalArena());
- return upb_Decode(bytes.data(), bytes.size(), message.msg(), T::minitable(),
+ return upb_Decode(bytes.data(), bytes.size(), message.msg(),
+ ::protos::internal::GetMiniTable(message),
/* extreg= */
::protos::internal::GetUpbExtensions(extension_registry),
/* options= */ 0, arena) == kUpb_DecodeStatus_Ok;
@@ -382,9 +393,10 @@
template <typename T>
bool Parse(Ptr<T>& message, absl::string_view bytes) {
- upb_Message_Clear(message->msg(), T::minitable());
+ upb_Message_Clear(message->msg(), ::protos::internal::GetMiniTable(message));
auto* arena = static_cast<upb_Arena*>(message->GetInternalArena());
- return upb_Decode(bytes.data(), bytes.size(), message->msg(), T::minitable(),
+ return upb_Decode(bytes.data(), bytes.size(), message->msg(),
+ ::protos::internal::GetMiniTable(message),
/* extreg= */ nullptr, /* options= */ 0,
arena) == kUpb_DecodeStatus_Ok;
}
@@ -392,60 +404,32 @@
template <typename T>
bool Parse(Ptr<T>& message, absl::string_view bytes,
const ::protos::ExtensionRegistry& extension_registry) {
- upb_Message_Clear(message->msg(), T::minitable());
+ upb_Message_Clear(message->msg(), ::protos::internal::GetMiniTable(message));
auto* arena = static_cast<upb_Arena*>(message->GetInternalArena());
- return upb_Decode(bytes.data(), bytes.size(), message->msg(), T::minitable(),
+ return upb_Decode(bytes.data(), bytes.size(), message->msg(),
+ ::protos::internal::GetMiniTable(message),
/* extreg= */
::protos::internal::GetUpbExtensions(extension_registry),
/* options= */ 0, arena) == kUpb_DecodeStatus_Ok;
}
template <typename T>
-bool Parse(std::unique_ptr<T>& message, absl::string_view bytes) {
- upb_Message_Clear(message->msg(), T::minitable());
+bool Parse(T* message, absl::string_view bytes) {
+ upb_Message_Clear(message->msg(), ::protos::internal::GetMiniTable(message));
auto* arena = static_cast<upb_Arena*>(message->GetInternalArena());
- return upb_Decode(bytes.data(), bytes.size(), message->msg(), T::minitable(),
+ return upb_Decode(bytes.data(), bytes.size(), message->msg(),
+ ::protos::internal::GetMiniTable(message),
/* extreg= */ nullptr, /* options= */ 0,
arena) == kUpb_DecodeStatus_Ok;
}
template <typename T>
-bool Parse(std::unique_ptr<T>& message, absl::string_view bytes,
- const ::protos::ExtensionRegistry& extension_registry) {
- upb_Message_Clear(message->msg(), T::minitable());
- auto* arena = static_cast<upb_Arena*>(message->GetInternalArena());
- return upb_Decode(bytes.data(), bytes.size(), message->msg(), T::minitable(),
- /* extreg= */
- ::protos::internal::GetUpbExtensions(extension_registry),
- /* options= */ 0, arena) == kUpb_DecodeStatus_Ok;
-}
-
-template <typename T>
-bool Parse(std::shared_ptr<T>& message, absl::string_view bytes) {
- upb_Message_Clear(message->msg(), T::minitable());
- auto* arena = static_cast<upb_Arena*>(message->GetInternalArena());
- return upb_Decode(bytes.data(), bytes.size(), message->msg(), T::minitable(),
- /* extreg= */ nullptr, /* options= */ 0,
- arena) == kUpb_DecodeStatus_Ok;
-}
-
-template <typename T>
-bool Parse(std::shared_ptr<T>& message, absl::string_view bytes,
- const ::protos::ExtensionRegistry& extension_registry) {
- upb_Message_Clear(message->msg(), T::minitable());
- auto* arena = static_cast<upb_Arena*>(message->GetInternalArena());
- return upb_Decode(bytes.data(), bytes.size(), message->msg(), T::minitable(),
- /* extreg= */
- ::protos::internal::GetUpbExtensions(extension_registry),
- /* options= */ 0, arena) == kUpb_DecodeStatus_Ok;
-}
-
-template <typename T>
absl::StatusOr<T> Parse(absl::string_view bytes, int options = 0) {
T message;
auto* arena = static_cast<upb_Arena*>(message.GetInternalArena());
upb_DecodeStatus status =
- upb_Decode(bytes.data(), bytes.size(), message.msg(), T::minitable(),
+ upb_Decode(bytes.data(), bytes.size(), message.msg(),
+ ::protos::internal::GetMiniTable(&message),
/* extreg= */ nullptr, /* options= */ 0, arena);
if (status == kUpb_DecodeStatus_Ok) {
return message;
@@ -460,7 +444,8 @@
T message;
auto* arena = static_cast<upb_Arena*>(message.GetInternalArena());
upb_DecodeStatus status =
- upb_Decode(bytes.data(), bytes.size(), message.msg(), T::minitable(),
+ upb_Decode(bytes.data(), bytes.size(), message.msg(),
+ ::protos::internal::GetMiniTable(&message),
::protos::internal::GetUpbExtensions(extension_registry),
/* options= */ 0, arena);
if (status == kUpb_DecodeStatus_Ok) {
@@ -470,34 +455,19 @@
}
template <typename T>
-absl::StatusOr<absl::string_view> Serialize(const T& message, upb::Arena& arena,
+absl::StatusOr<absl::string_view> Serialize(const T* message, upb::Arena& arena,
int options = 0) {
return ::protos::internal::Serialize(
- ::protos::internal::GetInternalMsg(message), T::minitable(), arena.ptr(),
+ message->msg(), ::protos::internal::GetMiniTable(message), arena.ptr(),
options);
}
template <typename T>
-absl::StatusOr<absl::string_view> Serialize(std::unique_ptr<T>& message,
- upb::Arena& arena,
- int options = 0) {
- return ::protos::internal::Serialize(message->msg(), T::minitable(),
- arena.ptr(), options);
-}
-
-template <typename T>
-absl::StatusOr<absl::string_view> Serialize(std::shared_ptr<T>& message,
- upb::Arena& arena,
- int options = 0) {
- return ::protos::internal::Serialize(message->msg(), T::minitable(),
- 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(), T::minitable(),
- arena.ptr(), options);
+ return ::protos::internal::Serialize(
+ message->msg(), ::protos::internal::GetMiniTable(message), arena.ptr(),
+ options);
}
} // namespace protos
diff --git a/protos/repeated_field.h b/protos/repeated_field.h
index a040e50..3bdb20d 100644
--- a/protos/repeated_field.h
+++ b/protos/repeated_field.h
@@ -145,8 +145,8 @@
typename = std::enable_if_t<b>>
void push_back(const T& t) {
upb_MessageValue message_value;
- message_value.msg_val =
- upb_Message_DeepClone(GetInternalMsg(t), T::minitable(), this->arena_);
+ message_value.msg_val = upb_Message_DeepClone(
+ GetInternalMsg(&t), ::protos::internal::GetMiniTable(&t), this->arena_);
upb_Array_Append(this->arr_, message_value, this->arena_);
}
@@ -155,7 +155,7 @@
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 = GetInternalMsg(&msg);
upb_Arena_Fuse(GetArena(msg), this->arena_);
upb_Array_Append(this->arr_, message_value, this->arena_);
T moved_msg = std::move(msg);
diff --git a/protos_generator/gen_messages.cc b/protos_generator/gen_messages.cc
index 3fb5d4d..6396c07 100644
--- a/protos_generator/gen_messages.cc
+++ b/protos_generator/gen_messages.cc
@@ -31,6 +31,7 @@
#include <vector>
#include "google/protobuf/descriptor.pb.h"
+#include "absl/strings/str_cat.h"
#include "google/protobuf/descriptor.h"
#include "protos_generator/gen_accessors.h"
#include "protos_generator/gen_enums.h"
@@ -127,9 +128,8 @@
friend class $2;
friend class $0Proxy;
friend class $0CProxy;
- friend void* ::protos::internal::GetInternalMsg<$2>(const $2& message);
- friend void* ::protos::internal::GetInternalMsg<$2>(
- const ::protos::Ptr<$2>& message);
+ friend void* ::protos::internal::GetInternalMsg<$2>(const $2* message);
+ friend void* ::protos::internal::GetInternalMsg<$2>(::protos::Ptr<$2> message);
$1* msg_;
upb_Arena* arena_;
)cc",
@@ -166,7 +166,7 @@
inline $0& operator=(const CProxy& from) {
arena_ = owned_arena_.ptr();
msg_ = ($2*)upb_Message_DeepClone(
- ::protos::internal::GetInternalMsg(from), &$1, arena_);
+ ::protos::internal::GetInternalMsg(&from), &$1, arena_);
return *this;
}
$0($0&& m)
@@ -223,8 +223,7 @@
const ::protos::ExtensionRegistry& extension_registry,
int options));
friend upb_Arena* ::protos::internal::GetArena<$0>(const $0& message);
- friend upb_Arena* ::protos::internal::GetArena<$0>(
- const ::protos::Ptr<$0>& message);
+ friend upb_Arena* ::protos::internal::GetArena<$0>(::protos::Ptr<$0> message);
friend $0(::protos::internal::MoveMessage<$0>(upb_Message* msg,
upb_Arena* arena));
)cc",
@@ -271,9 +270,13 @@
friend class $0Access;
friend class ::protos::Ptr<$0>;
friend class ::protos::Ptr<const $0>;
+ static const upb_MiniTable* minitable() { return $0::minitable(); }
+ friend const upb_MiniTable* ::protos::internal::GetMiniTable<$0Proxy>(
+ const $0Proxy* message);
+ friend const upb_MiniTable* ::protos::internal::GetMiniTable<$0Proxy>(
+ ::protos::Ptr<$0Proxy> message);
friend upb_Arena* ::protos::internal::GetArena<$2>(const $2& message);
- friend upb_Arena* ::protos::internal::GetArena<$2>(
- const ::protos::Ptr<$2>& message);
+ 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) {
@@ -313,6 +316,12 @@
friend class RepeatedFieldProxy;
friend class ::protos::Ptr<$0>;
friend class ::protos::Ptr<const $0>;
+ static const upb_MiniTable* minitable() { return $0::minitable(); }
+ friend const upb_MiniTable* ::protos::internal::GetMiniTable<$0CProxy>(
+ const $0CProxy* message);
+ friend const upb_MiniTable* ::protos::internal::GetMiniTable<$0CProxy>(
+ ::protos::Ptr<$0CProxy> message);
+
static void Rebind($0CProxy& lhs, const $0CProxy& rhs) {
lhs.msg_ = rhs.msg_;
lhs.arena_ = rhs.arena_;
@@ -349,12 +358,12 @@
$0::$0(const CProxy& from) : $0Access() {
arena_ = owned_arena_.ptr();
msg_ = ($1*)upb_Message_DeepClone(
- ::protos::internal::GetInternalMsg(from), &$2, arena_);
+ ::protos::internal::GetInternalMsg(&from), &$2, arena_);
}
$0::$0(const Proxy& from) : $0(static_cast<const CProxy&>(from)) {}
internal::$0CProxy::$0CProxy($0Proxy m) : $0Access() {
arena_ = m.arena_;
- msg_ = ($1*)::protos::internal::GetInternalMsg(m);
+ msg_ = ($1*)::protos::internal::GetInternalMsg(&m);
}
)cc",
ClassName(descriptor), MessageName(descriptor),
diff --git a/protos_generator/tests/BUILD b/protos_generator/tests/BUILD
index 82cbf55..5e66184 100644
--- a/protos_generator/tests/BUILD
+++ b/protos_generator/tests/BUILD
@@ -147,6 +147,8 @@
":test_model_upb_proto",
":naming_conflict_upb_cc_proto",
"@com_google_googletest//:gtest_main",
+ "@com_google_absl//absl/status:statusor",
+ "@com_google_absl//absl/strings",
"//:upb",
"//protos",
"//protos:repeated_field",
diff --git a/protos_generator/tests/test_generated.cc b/protos_generator/tests/test_generated.cc
index b2866b6..fd117a1 100644
--- a/protos_generator/tests/test_generated.cc
+++ b/protos_generator/tests/test_generated.cc
@@ -28,12 +28,15 @@
#include <utility>
#include "gtest/gtest.h"
+#include "absl/status/statusor.h"
+#include "absl/strings/string_view.h"
#include "protos/protos.h"
#include "protos/repeated_field.h"
#include "protos/repeated_field_iterator.h"
#include "protos_generator/tests/child_model.upb.proto.h"
#include "protos_generator/tests/no_package.upb.proto.h"
#include "protos_generator/tests/test_model.upb.proto.h"
+#include "upb/upb.hpp"
using ::protos_generator::test::protos::ChildModel1;
using ::protos_generator::test::protos::other_ext;
@@ -712,7 +715,20 @@
TestModel model;
model.set_str1("Hello World");
::upb::Arena arena;
- absl::StatusOr<absl::string_view> bytes = ::protos::Serialize(model, arena);
+ absl::StatusOr<absl::string_view> bytes = ::protos::Serialize(&model, arena);
+ EXPECT_EQ(true, bytes.ok());
+ TestModel parsed_model = ::protos::Parse<TestModel>(bytes.value()).value();
+ EXPECT_EQ("Hello World", parsed_model.str1());
+}
+
+TEST(CppGeneratedCode, SerializeProxyUsingArena) {
+ ::upb::Arena message_arena;
+ TestModel::Proxy model_proxy =
+ ::protos::CreateMessage<TestModel>(message_arena);
+ model_proxy.set_str1("Hello World");
+ ::upb::Arena arena;
+ absl::StatusOr<absl::string_view> bytes =
+ ::protos::Serialize(&model_proxy, arena);
EXPECT_EQ(true, bytes.ok());
TestModel parsed_model = ::protos::Parse<TestModel>(bytes.value()).value();
EXPECT_EQ("Hello World", parsed_model.str1());
@@ -736,7 +752,7 @@
extension1.set_ext_name("Hello World");
EXPECT_EQ(true, ::protos::SetExtension(model, theme, extension1).ok());
::upb::Arena arena;
- auto bytes = ::protos::Serialize(model, arena);
+ auto bytes = ::protos::Serialize(&model, arena);
EXPECT_EQ(true, bytes.ok());
TestModel parsed_model = ::protos::Parse<TestModel>(bytes.value()).value();
EXPECT_EQ("Test123", parsed_model.str1());
@@ -751,7 +767,7 @@
extension1.set_ext_name("Hello World");
EXPECT_EQ(true, ::protos::SetExtension(model, theme, extension1).ok());
::upb::Arena arena;
- auto bytes = ::protos::Serialize(model, arena);
+ auto bytes = ::protos::Serialize(&model, arena);
EXPECT_EQ(true, bytes.ok());
::protos::Ptr<TestModel> parsed_model =
::protos::CreateMessage<TestModel>(arena);
@@ -771,7 +787,7 @@
extension1)
.ok());
::upb::Arena arena;
- auto bytes = ::protos::Serialize(model, arena);
+ auto bytes = ::protos::Serialize(&model, arena);
EXPECT_EQ(true, bytes.ok());
::protos::ExtensionRegistry extensions(
{&theme, &other_ext, &ThemeExtension::theme_extension}, arena);
@@ -799,15 +815,15 @@
TEST(CppGeneratedCode, SharedPointer) {
std::shared_ptr<TestModel> model = std::make_shared<TestModel>();
::upb::Arena arena;
- auto bytes = protos::Serialize(model, arena);
- EXPECT_TRUE(protos::Parse(model, bytes.value()));
+ auto bytes = protos::Serialize(model.get(), arena);
+ EXPECT_TRUE(protos::Parse(model.get(), bytes.value()));
}
TEST(CppGeneratedCode, UniquePointer) {
auto model = std::make_unique<TestModel>();
::upb::Arena arena;
- auto bytes = protos::Serialize(model, arena);
- EXPECT_TRUE(protos::Parse(model, bytes.value()));
+ auto bytes = protos::Serialize(model.get(), arena);
+ EXPECT_TRUE(protos::Parse(model.get(), bytes.value()));
}
TEST(CppGeneratedCode, Assignment) {