Generate extension and k[FieldName]FieldNumber as constexpr int(s).

PiperOrigin-RevId: 632173946
pull/16768/head
Protobuf Team Bot 2024-05-09 09:24:33 -07:00 committed by Copybara-Service
parent 13caa08692
commit dbc2baf5bd
2 changed files with 59 additions and 0 deletions

View File

@ -7,11 +7,14 @@
#include "protos_generator/gen_messages.h"
#include <cstddef>
#include <string>
#include <vector>
#include "google/protobuf/descriptor.pb.h"
#include "absl/strings/ascii.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "google/protobuf/descriptor.h"
#include "protos_generator/gen_accessors.h"
#include "protos_generator/gen_enums.h"
@ -120,6 +123,55 @@ void WriteModelAccessDeclaration(const protobuf::Descriptor* descriptor,
output("};\n");
}
std::string UnderscoresToCamelCase(absl::string_view input,
bool cap_next_letter) {
std::string result;
for (size_t i = 0; i < input.size(); i++) {
if (absl::ascii_islower(input[i])) {
if (cap_next_letter) {
result += absl::ascii_toupper(input[i]);
} else {
result += input[i];
}
cap_next_letter = false;
} else if (absl::ascii_isupper(input[i])) {
// Capital letters are left as-is.
result += input[i];
cap_next_letter = false;
} else if (absl::ascii_isdigit(input[i])) {
result += input[i];
cap_next_letter = true;
} else {
cap_next_letter = true;
}
}
return result;
}
std::string FieldConstantName(const protobuf::FieldDescriptor* field) {
std::string field_name = UnderscoresToCamelCase(field->name(), true);
std::string result = absl::StrCat("k", field_name, "FieldNumber");
if (!field->is_extension() &&
field->containing_type()->FindFieldByCamelcaseName(
field->camelcase_name()) != field) {
// This field's camelcase name is not unique, add field number to make it
// unique.
absl::StrAppend(&result, "_", field->number());
}
return result;
}
void WriteConstFieldNumbers(Output& output,
const protobuf::Descriptor* descriptor) {
for (auto field : FieldRange(descriptor)) {
output("static constexpr ::uint32_t $0 = $1;\n", FieldConstantName(field),
field->number());
}
output("\n\n");
}
void WriteModelPublicDeclaration(
const protobuf::Descriptor* descriptor,
const std::vector<const protobuf::FieldDescriptor*>& file_exts,
@ -178,6 +230,7 @@ void WriteModelPublicDeclaration(
)cc",
ClassName(descriptor));
output("\n");
WriteConstFieldNumbers(output, descriptor);
output(
R"cc(
private:

View File

@ -9,6 +9,7 @@
#include <limits>
#include <memory>
#include <string>
#include <type_traits>
#include <utility>
#include <vector>
@ -1134,6 +1135,11 @@ TEST(CppGeneratedCode, HasExtensionAndRegistry) {
EXPECT_TRUE(::protos::HasExtension(&parsed_model, theme));
}
TEST(CppGeneratedCode, FieldNumberConstants) {
static_assert(TestModel::kChildMapFieldNumber == 225);
EXPECT_EQ(225, TestModel::kChildMapFieldNumber);
}
// TODO : Add BUILD rule to test failures below.
#ifdef TEST_CLEAR_MESSAGE_FAILURE
TEST(CppGeneratedCode, ClearConstMessageShouldFail) {