mirror of
https://github.com/protocolbuffers/protobuf
synced 2026-08-26 02:23:14 -04:00
Expand embed_edition_defaults encoding to byte types.
While there is support for base64, it requires a runtime cost to decode back into the bytes, so adding support to write out either hex or decimal byte values to the encoding. This allows the values to be directly used for datatypes that are more "byte buffer" than a "string". Also make the rule's implementation return the output file via the default file provider. PiperOrigin-RevId: 786338818
This commit is contained in:
parent
c81a0c2467
commit
b09d551636
6 changed files with 119 additions and 2 deletions
|
|
@ -74,6 +74,26 @@ embed_edition_defaults(
|
|||
template = "defaults_test_embedded_base64.h.template",
|
||||
)
|
||||
|
||||
embed_edition_defaults(
|
||||
name = "embed_test_defaults_decimal_array",
|
||||
testonly = True,
|
||||
defaults = ":test_defaults_2023",
|
||||
encoding = "decimal_array",
|
||||
output = "defaults_test_embedded_decimal_array.h",
|
||||
placeholder = "DEFAULTS_VALUE",
|
||||
template = "defaults_test_embedded_decimal_array.h.template",
|
||||
)
|
||||
|
||||
embed_edition_defaults(
|
||||
name = "embed_test_defaults_hex_array",
|
||||
testonly = True,
|
||||
defaults = ":test_defaults_2023",
|
||||
encoding = "hex_array",
|
||||
output = "defaults_test_embedded_hex_array.h",
|
||||
placeholder = "DEFAULTS_VALUE",
|
||||
template = "defaults_test_embedded_hex_array.h.template",
|
||||
)
|
||||
|
||||
cc_binary(
|
||||
name = "internal_defaults_escape",
|
||||
srcs = ["internal_defaults_escape.cc"],
|
||||
|
|
@ -94,6 +114,8 @@ cc_library(
|
|||
hdrs = [
|
||||
"defaults_test_embedded.h",
|
||||
"defaults_test_embedded_base64.h",
|
||||
"defaults_test_embedded_decimal_array.h",
|
||||
"defaults_test_embedded_hex_array.h",
|
||||
],
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -78,6 +78,8 @@ def _embed_edition_defaults_impl(ctx):
|
|||
inputs = [ctx.file.defaults, ctx.file.template],
|
||||
)
|
||||
|
||||
return DefaultInfo(files = depset([ctx.outputs.output]))
|
||||
|
||||
embed_edition_defaults = rule(
|
||||
doc = "genrule to embed edition defaults binary data into a template file.",
|
||||
attrs = {
|
||||
|
|
@ -103,8 +105,8 @@ embed_edition_defaults = rule(
|
|||
),
|
||||
"encoding": attr.string(
|
||||
default = "octal",
|
||||
values = ["octal", "base64"],
|
||||
doc = "The encoding format to use for the binary data (octal or base64)",
|
||||
values = ["octal", "base64", "decimal_array", "hex_array"],
|
||||
doc = "The encoding format to use for the binary data (octal, base64, decimal_array, hex_array)",
|
||||
),
|
||||
"_escape": attr.label(
|
||||
default = "//editions:internal_defaults_escape",
|
||||
|
|
|
|||
|
|
@ -16,6 +16,8 @@
|
|||
#include "google/protobuf/cpp_features.pb.h"
|
||||
#include "editions/defaults_test_embedded.h"
|
||||
#include "editions/defaults_test_embedded_base64.h"
|
||||
#include "editions/defaults_test_embedded_decimal_array.h"
|
||||
#include "editions/defaults_test_embedded_hex_array.h"
|
||||
#include "google/protobuf/extension_set.h"
|
||||
#include "google/protobuf/message.h"
|
||||
#include "google/protobuf/test_textproto.h"
|
||||
|
|
@ -188,6 +190,48 @@ TEST(DefaultsTest, EmbeddedBase64) {
|
|||
pb::VALUE3);
|
||||
}
|
||||
|
||||
TEST(DefaultsTest, EmbeddedDecimalArray) {
|
||||
FeatureSetDefaults defaults;
|
||||
ASSERT_TRUE(defaults.ParseFromArray(kDefaultTestEmbeddedDecimalArray.data(),
|
||||
kDefaultTestEmbeddedDecimalArray.size()))
|
||||
<< "Could not parse embedded data";
|
||||
ASSERT_EQ(defaults.defaults().size(), 3);
|
||||
ASSERT_EQ(defaults.minimum_edition(), EDITION_2023);
|
||||
ASSERT_EQ(defaults.maximum_edition(), EDITION_2023);
|
||||
|
||||
EXPECT_EQ(defaults.defaults()[0].edition(), EDITION_LEGACY);
|
||||
EXPECT_EQ(defaults.defaults()[1].edition(), EDITION_PROTO3);
|
||||
EXPECT_EQ(defaults.defaults()[2].edition(), EDITION_2023);
|
||||
EXPECT_EQ(defaults.defaults()[2].overridable_features().field_presence(),
|
||||
FeatureSet::EXPLICIT);
|
||||
EXPECT_EQ(defaults.defaults()[2]
|
||||
.overridable_features()
|
||||
.GetExtension(pb::test)
|
||||
.file_feature(),
|
||||
pb::VALUE3);
|
||||
}
|
||||
|
||||
TEST(DefaultsTest, EmbeddedHexArray) {
|
||||
FeatureSetDefaults defaults;
|
||||
ASSERT_TRUE(defaults.ParseFromArray(kDefaultTestEmbeddedHexArray.data(),
|
||||
kDefaultTestEmbeddedHexArray.size()))
|
||||
<< "Could not parse embedded data";
|
||||
ASSERT_EQ(defaults.defaults().size(), 3);
|
||||
ASSERT_EQ(defaults.minimum_edition(), EDITION_2023);
|
||||
ASSERT_EQ(defaults.maximum_edition(), EDITION_2023);
|
||||
|
||||
EXPECT_EQ(defaults.defaults()[0].edition(), EDITION_LEGACY);
|
||||
EXPECT_EQ(defaults.defaults()[1].edition(), EDITION_PROTO3);
|
||||
EXPECT_EQ(defaults.defaults()[2].edition(), EDITION_2023);
|
||||
EXPECT_EQ(defaults.defaults()[2].overridable_features().field_presence(),
|
||||
FeatureSet::EXPLICIT);
|
||||
EXPECT_EQ(defaults.defaults()[2]
|
||||
.overridable_features()
|
||||
.GetExtension(pb::test)
|
||||
.file_feature(),
|
||||
pb::VALUE3);
|
||||
}
|
||||
|
||||
// Lock down that overridable defaults never change in released editions. After
|
||||
// an edition has been released these tests should never need to be touched.
|
||||
class OverridableDefaultsTest : public ::testing::Test {
|
||||
|
|
|
|||
11
editions/defaults_test_embedded_decimal_array.h.template
Normal file
11
editions/defaults_test_embedded_decimal_array.h.template
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
#ifndef THIRD_PARTY_PROTOBUF_EDITIONS_DEFAULTS_TEST_EMBEDDED_DECIMAL_ARRAY_H_
|
||||
#define THIRD_PARTY_PROTOBUF_EDITIONS_DEFAULTS_TEST_EMBEDDED_DECIMAL_ARRAY_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
// Normally something like this would go into a .cc file, but using a header to
|
||||
// simplify things.
|
||||
static const std::vector<uint8_t> kDefaultTestEmbeddedDecimalArray = { DEFAULTS_VALUE };
|
||||
|
||||
#endif // THIRD_PARTY_PROTOBUF_EDITIONS_DEFAULTS_TEST_EMBEDDED_DECIMAL_ARRAY_H_
|
||||
13
editions/defaults_test_embedded_hex_array.h.template
Normal file
13
editions/defaults_test_embedded_hex_array.h.template
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
#ifndef THIRD_PARTY_PROTOBUF_EDITIONS_DEFAULTS_TEST_EMBEDDED_HEX_ARRAY_H_
|
||||
#define THIRD_PARTY_PROTOBUF_EDITIONS_DEFAULTS_TEST_EMBEDDED_HEX_ARRAY_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
// Normally something like this would go into a .cc file, but using a header to
|
||||
// simplify things.
|
||||
static const std::vector<uint8_t> kDefaultTestEmbeddedHexArray = {
|
||||
DEFAULTS_VALUE
|
||||
};
|
||||
|
||||
#endif // THIRD_PARTY_PROTOBUF_EDITIONS_DEFAULTS_TEST_EMBEDDED_HEX_ARRAY_H_
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
|
@ -14,6 +15,8 @@
|
|||
#include "absl/flags/parse.h"
|
||||
#include "absl/log/absl_log.h"
|
||||
#include "absl/strings/escaping.h"
|
||||
#include "absl/strings/str_cat.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
|
||||
#if defined(_WIN32)
|
||||
#include "google/protobuf/io/io_win32.h"
|
||||
|
|
@ -58,6 +61,28 @@ int defaults_escape(const std::string& defaults_path,
|
|||
content = absl::Base64Escape(content);
|
||||
} else if (encoding == "octal") {
|
||||
content = absl::CEscape(content);
|
||||
} else if (encoding == "decimal_array") {
|
||||
std::string encoded;
|
||||
bool first = true;
|
||||
for (uint8_t c : content) {
|
||||
if (first) {
|
||||
first = false;
|
||||
absl::StrAppend(&encoded, c);
|
||||
} else {
|
||||
absl::StrAppend(&encoded, ", ", c);
|
||||
}
|
||||
}
|
||||
content = encoded;
|
||||
} else if (encoding == "hex_array") {
|
||||
std::string encoded = {};
|
||||
size_t count = 0;
|
||||
for (uint8_t c : content) {
|
||||
absl::string_view prefix =
|
||||
(count % 12 != 0) ? ", 0x" : (count == 0 ? " 0x" : ",\n 0x");
|
||||
absl::StrAppend(&encoded, prefix, absl::Hex(c, absl::kZeroPad2));
|
||||
++count;
|
||||
}
|
||||
content = encoded;
|
||||
} else {
|
||||
ABSL_LOG(FATAL) << "Unknown encoding: " << encoding;
|
||||
return 1;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue