diff --git a/protos/protos.h b/protos/protos.h index bcf930c170..7b4f423acf 100644 --- a/protos/protos.h +++ b/protos/protos.h @@ -358,6 +358,15 @@ bool Parse(T& message, absl::string_view bytes) { arena) == kUpb_DecodeStatus_Ok; } +template <typename T> +bool Parse(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::unique_ptr<T>& message, absl::string_view bytes) { _upb_Message_Clear(message->msg(), T::minitable()); @@ -430,8 +439,7 @@ absl::StatusOr<absl::string_view> Serialize(std::shared_ptr<T>& message, } template <typename T> -absl::StatusOr<absl::string_view> Serialize(Ptr<const T> message, - upb::Arena& arena, +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); diff --git a/protos_generator/tests/BUILD b/protos_generator/tests/BUILD index 995f556432..f5a5fb9c47 100644 --- a/protos_generator/tests/BUILD +++ b/protos_generator/tests/BUILD @@ -131,5 +131,6 @@ cc_test( ":test_model_upb_proto", "@com_google_googletest//:gtest_main", "//:upb", + "//protos", ], ) diff --git a/protos_generator/tests/test_generated.cc b/protos_generator/tests/test_generated.cc index 416d9f466c..d6ca24a00b 100644 --- a/protos_generator/tests/test_generated.cc +++ b/protos_generator/tests/test_generated.cc @@ -26,10 +26,10 @@ #include <limits> #include "gtest/gtest.h" +#include "protos/protos.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/string_view.h" using ::protos_generator::test::protos::ChildModel1; using ::protos_generator::test::protos::other_ext; @@ -559,6 +559,23 @@ TEST(CppGeneratedCode, Parse) { EXPECT_EQ(false, ::protos::GetExtension(parsed_model, theme).ok()); } +TEST(CppGeneratedCode, ParseIntoPtrToModel) { + TestModel model; + model.set_str1("Test123"); + ThemeExtension extension1; + extension1.set_ext_name("Hello World"); + EXPECT_EQ(true, ::protos::SetExtension(model, theme, extension1).ok()); + ::upb::Arena arena; + auto bytes = ::protos::Serialize(model, arena); + EXPECT_EQ(true, bytes.ok()); + ::protos::Ptr<TestModel> parsed_model = + ::protos::CreateMessage<TestModel>(arena); + EXPECT_TRUE(::protos::Parse(parsed_model, bytes.value())); + EXPECT_EQ("Test123", parsed_model->str1()); + // Should not return an extension since we did not pass ExtensionRegistry. + EXPECT_EQ(false, ::protos::GetExtension(parsed_model, theme).ok()); +} + TEST(CppGeneratedCode, ParseWithExtensionRegistry) { TestModel model; model.set_str1("Test123");