Fix a bug where message-level extension identifier should also be generated in the source file.

PiperOrigin-RevId: 513687688
pull/13171/head
Protobuf Team Bot 2 years ago committed by Copybara-Service
parent 74905292da
commit ccdfaf7ea3
  1. 1
      protos/BUILD
  2. 9
      protos/protos.h
  3. 1
      protos_generator/BUILD
  4. 15
      protos_generator/gen_extensions.cc
  5. 2
      protos_generator/gen_messages.cc
  6. 13
      protos_generator/tests/test_generated.cc
  7. 3
      protos_generator/tests/test_model.proto

@ -41,7 +41,6 @@ cc_library(
copts = UPB_DEFAULT_CPPOPTS, copts = UPB_DEFAULT_CPPOPTS,
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
deps = [ deps = [
"//:message_accessors",
"//:mini_table", "//:mini_table",
"//:upb", "//:upb",
"@com_google_absl//absl/status", "@com_google_absl//absl/status",

@ -29,6 +29,7 @@
#define UPB_PROTOS_PROTOS_H_ #define UPB_PROTOS_PROTOS_H_
#include <type_traits> #include <type_traits>
#include <vector>
#include "absl/status/status.h" #include "absl/status/status.h"
#include "absl/status/statusor.h" #include "absl/status/statusor.h"
@ -159,7 +160,8 @@ typename T::CProxy CreateMessage(upb_Message* msg) {
class ExtensionMiniTableProvider { class ExtensionMiniTableProvider {
public: public:
ExtensionMiniTableProvider(const upb_MiniTableExtension* mini_table_ext) constexpr explicit ExtensionMiniTableProvider(
const upb_MiniTableExtension* mini_table_ext)
: mini_table_ext_(mini_table_ext) {} : mini_table_ext_(mini_table_ext) {}
const upb_MiniTableExtension* mini_table_ext() const { const upb_MiniTableExtension* mini_table_ext() const {
return mini_table_ext_; return mini_table_ext_;
@ -183,7 +185,8 @@ class ExtensionIdentifier : public ExtensionMiniTableProvider {
using Extension = ExtensionType; using Extension = ExtensionType;
using Extendee = ExtendeeType; using Extendee = ExtendeeType;
ExtensionIdentifier(const upb_MiniTableExtension* mini_table_ext) constexpr explicit ExtensionIdentifier(
const upb_MiniTableExtension* mini_table_ext)
: ExtensionMiniTableProvider(mini_table_ext) {} : ExtensionMiniTableProvider(mini_table_ext) {}
}; };
@ -219,7 +222,7 @@ absl::StatusOr<absl::string_view> Serialize(const upb_Message* message,
class ExtensionRegistry { class ExtensionRegistry {
public: public:
ExtensionRegistry( ExtensionRegistry(
const std::vector<const ::protos::internal::ExtensionMiniTableProvider*> const std::vector<const ::protos::internal::ExtensionMiniTableProvider*>&
extensions, extensions,
const upb::Arena& arena) const upb::Arena& arena)
: registry_(upb_ExtensionRegistry_New(arena.ptr())) { : registry_(upb_ExtensionRegistry_New(arena.ptr())) {

@ -69,7 +69,6 @@ cc_library(
"//upbc:file_layout", "//upbc:file_layout",
"//upbc:keywords", "//upbc:keywords",
"//upbc:names", "//upbc:names",
"//upbc:plugin",
"@com_google_absl//absl/container:flat_hash_map", "@com_google_absl//absl/container:flat_hash_map",
"@com_google_absl//absl/container:flat_hash_set", "@com_google_absl//absl/container:flat_hash_set",
"@com_google_absl//absl/log:absl_check", "@com_google_absl//absl/log:absl_check",

@ -53,14 +53,15 @@ void WriteExtensionIdentifierHeader(const protobuf::FieldDescriptor* ext,
std::string mini_table_name = std::string mini_table_name =
absl::StrCat(ExtensionIdentifierBase(ext), "_", ext->name(), "_ext"); absl::StrCat(ExtensionIdentifierBase(ext), "_", ext->name(), "_ext");
if (ext->extension_scope()) { if (ext->extension_scope()) {
output(R"cc( output(
static ::protos::internal::ExtensionIdentifier<$0, $1> $2; R"cc(
)cc", static const ::protos::internal::ExtensionIdentifier<$0, $1> $2;
ContainingTypeName(ext), CppTypeParameterName(ext), ext->name()); )cc",
ContainingTypeName(ext), CppTypeParameterName(ext), ext->name());
} else { } else {
output( output(
R"cc( R"cc(
extern ::protos::internal::ExtensionIdentifier<$0, $1> $2; extern const ::protos::internal::ExtensionIdentifier<$0, $1> $2;
)cc", )cc",
ContainingTypeName(ext), CppTypeParameterName(ext), ext->name()); ContainingTypeName(ext), CppTypeParameterName(ext), ext->name());
} }
@ -83,14 +84,14 @@ void WriteExtensionIdentifier(const protobuf::FieldDescriptor* ext,
if (ext->extension_scope()) { if (ext->extension_scope()) {
output( output(
R"cc( R"cc(
::protos::internal::ExtensionIdentifier<$0, $3> $4::$2(&$1); constexpr ::protos::internal::ExtensionIdentifier<$0, $3> $4::$2(&$1);
)cc", )cc",
ContainingTypeName(ext), mini_table_name, ext->name(), ContainingTypeName(ext), mini_table_name, ext->name(),
CppTypeParameterName(ext), ClassName(ext->extension_scope())); CppTypeParameterName(ext), ClassName(ext->extension_scope()));
} else { } else {
output( output(
R"cc( R"cc(
::protos::internal::ExtensionIdentifier<$0, $3> $2(&$1); constexpr ::protos::internal::ExtensionIdentifier<$0, $3> $2(&$1);
)cc", )cc",
ContainingTypeName(ext), mini_table_name, ext->name(), ContainingTypeName(ext), mini_table_name, ext->name(),
CppTypeParameterName(ext)); CppTypeParameterName(ext));

@ -350,6 +350,8 @@ void WriteMessageImplementation(
} }
)cc", )cc",
ClassName(descriptor)); ClassName(descriptor));
WriteExtensionIdentifiersImplementation(descriptor, file_exts, output);
} }
} }

@ -598,14 +598,25 @@ TEST(CppGeneratedCode, ParseWithExtensionRegistry) {
ThemeExtension extension1; ThemeExtension extension1;
extension1.set_ext_name("Hello World"); extension1.set_ext_name("Hello World");
EXPECT_EQ(true, ::protos::SetExtension(model, theme, extension1).ok()); EXPECT_EQ(true, ::protos::SetExtension(model, theme, extension1).ok());
EXPECT_EQ(true, ::protos::SetExtension(model, ThemeExtension::theme_extension,
extension1)
.ok());
::upb::Arena arena; ::upb::Arena arena;
auto bytes = ::protos::Serialize(model, arena); auto bytes = ::protos::Serialize(model, arena);
EXPECT_EQ(true, bytes.ok()); EXPECT_EQ(true, bytes.ok());
::protos::ExtensionRegistry extensions({&theme, &other_ext}, arena); ::protos::ExtensionRegistry extensions(
{&theme, &other_ext, &ThemeExtension::theme_extension}, arena);
TestModel parsed_model = TestModel parsed_model =
::protos::Parse<TestModel>(bytes.value(), extensions).value(); ::protos::Parse<TestModel>(bytes.value(), extensions).value();
EXPECT_EQ("Test123", parsed_model.str1()); EXPECT_EQ("Test123", parsed_model.str1());
EXPECT_EQ(true, ::protos::GetExtension(parsed_model, theme).ok()); EXPECT_EQ(true, ::protos::GetExtension(parsed_model, theme).ok());
EXPECT_EQ(true, ::protos::GetExtension(parsed_model,
ThemeExtension::theme_extension)
.ok());
EXPECT_EQ("Hello World", ::protos::GetExtension(
parsed_model, ThemeExtension::theme_extension)
.value()
->ext_name());
} }
TEST(CppGeneratedCode, NameCollisions) { TEST(CppGeneratedCode, NameCollisions) {

@ -119,6 +119,9 @@ enum PrimaryColors {
// TestModel extension. // TestModel extension.
message ThemeExtension { message ThemeExtension {
extend TestModel {
optional ThemeExtension theme_extension = 12003;
}
optional string ext_name = 1; optional string ext_name = 1;
optional bool ext_bool = 2; optional bool ext_bool = 2;
} }

Loading…
Cancel
Save