Update C++ compiler to prefix enum and messages defined with no package name to avoid C include collisions.

PiperOrigin-RevId: 489023142
pull/13171/head
Protobuf Team Bot 2 years ago committed by Copybara-Service
parent d3ec4b63c9
commit 0184441169
  1. 19
      protos_generator/gen_enums.cc
  2. 7
      protos_generator/gen_utils.cc
  3. 3
      protos_generator/gen_utils.h
  4. 19
      protos_generator/tests/BUILD
  5. 10
      protos_generator/tests/no_package.proto
  6. 11
      protos_generator/tests/no_package_enum_user.proto

@ -27,6 +27,7 @@
#include "google/protobuf/descriptor.pb.h"
#include "google/protobuf/descriptor.h"
#include "protos_generator/gen_utils.h"
namespace protos_generator {
@ -53,12 +54,22 @@ std::string EnumTypeName(const protobuf::EnumDescriptor* enum_descriptor) {
// enums types with no package name are prefixed with protos_ to prevent
// conflicts with generated C headers.
if (enum_descriptor->file()->package().empty()) {
return absl::StrCat("protos_", ToCIdent(enum_descriptor->name()));
return absl::StrCat(kNoPackageNamePrefix,
ToCIdent(enum_descriptor->name()));
}
return ToCIdent(enum_descriptor->name());
} else {
return ToCIdent(
absl::StrCat(containing_type->name(), "_", enum_descriptor->name()));
// Since the enum is in global name space (no package), it will have the
// same classified name as the C header include, to prevent collision
// rename as above.
if (containing_type->file()->package().empty()) {
return ToCIdent(absl::StrCat(containing_type->name(), "_",
kNoPackageNamePrefix,
enum_descriptor->name()));
} else {
return ToCIdent(
absl::StrCat(containing_type->name(), "_", enum_descriptor->name()));
}
}
}
@ -73,7 +84,7 @@ std::string EnumValueSymbolInNameSpace(
// protos enum values with no package name are prefixed with protos_ to
// prevent conflicts with generated C headers.
if (desc->file()->package().empty()) {
return absl::StrCat("protos_", ToCIdent(value->name()));
return absl::StrCat(kNoPackageNamePrefix, ToCIdent(value->name()));
}
return ToCIdent(value->name());
}

@ -73,6 +73,13 @@ std::string QualifiedFileLevelSymbol(const protobuf::FileDescriptor* file,
std::string ClassName(const protobuf::Descriptor* descriptor) {
const protobuf::Descriptor* parent = descriptor->containing_type();
std::string res;
// Classes in global namespace without package names are prefixed
// by protos_ to avoid collision with C compiler structs defined in
// proto.upb.h.
if ((parent && parent->file()->package().empty()) ||
descriptor->file()->package().empty()) {
res = std::string(kNoPackageNamePrefix);
}
if (parent) res += ClassName(parent) + "_";
absl::StrAppend(&res, descriptor->name());
return ::upbc::ResolveKeywordConflict(res);

@ -30,6 +30,7 @@
#include "google/protobuf/descriptor.pb.h"
#include "absl/container/flat_hash_map.h"
#include "absl/strings/string_view.h"
#include "google/protobuf/compiler/code_generator.h"
#include "google/protobuf/compiler/plugin.h"
#include "google/protobuf/descriptor.h"
@ -76,6 +77,8 @@ std::string MessageCProxyType(const protobuf::FieldDescriptor* field,
std::string MessageProxyType(const protobuf::FieldDescriptor* field,
bool is_const);
inline constexpr absl::string_view kNoPackageNamePrefix = "protos_";
} // namespace protos_generator
#endif // UPB_PROTOS_GENERATOR_GEN_UTILS_H_

@ -59,6 +59,14 @@ proto_library(
],
)
proto_library(
name = "no_package_enum_user_proto",
srcs = [
"no_package_enum_user.proto",
],
deps = [":no_package_proto"],
)
upb_proto_library(
name = "test_model_upb_proto",
visibility = [
@ -78,7 +86,16 @@ upb_cc_proto_library(
upb_cc_proto_library(
name = "no_package_upb_cc_proto",
deps = [":no_package_proto"],
deps = [
":no_package_proto",
],
)
upb_cc_proto_library(
name = "no_package_enum_user_upb_cc_proto",
deps = [
":no_package_enum_user_proto",
],
)
cc_proto_library(

@ -6,3 +6,13 @@ enum EnumWithNoPackage {
CELSIUS = 1;
FAHRENHEIT = 2;
}
message MessageWithEnumUpbTest {
enum EnumWithNoPackageInMessage {
UNKNOWN = 0;
AB_1 = 1;
CD_2 = 2;
EF_3 = 3;
GH_4 = 4;
}
}

@ -0,0 +1,11 @@
syntax = "proto2";
package protos_generator.tests;
import "protos_generator/tests/no_package.proto";
// option java_multiple_files = true;
message MyMessage {
optional MessageWithEnumUpbTest my_type = 1;
}
Loading…
Cancel
Save