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,
visibility = ["//visibility:public"],
deps = [
"//:message_accessors",
"//:mini_table",
"//:upb",
"@com_google_absl//absl/status",

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

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

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

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

@ -598,14 +598,25 @@ TEST(CppGeneratedCode, ParseWithExtensionRegistry) {
ThemeExtension extension1;
extension1.set_ext_name("Hello World");
EXPECT_EQ(true, ::protos::SetExtension(model, theme, extension1).ok());
EXPECT_EQ(true, ::protos::SetExtension(model, ThemeExtension::theme_extension,
extension1)
.ok());
::upb::Arena arena;
auto bytes = ::protos::Serialize(model, arena);
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 =
::protos::Parse<TestModel>(bytes.value(), extensions).value();
EXPECT_EQ("Test123", parsed_model.str1());
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) {

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

Loading…
Cancel
Save