Allow base64 encoding of embedded edition defaults.

PiperOrigin-RevId: 610570515
pull/15942/head
Mike Kruskal 2024-02-26 16:58:16 -08:00 committed by Copybara-Service
parent 4dc2c07025
commit f66d876a10
5 changed files with 75 additions and 3 deletions

View File

@ -44,6 +44,16 @@ embed_edition_defaults(
template = "defaults_test_embedded.h.template",
)
embed_edition_defaults(
name = "embed_test_defaults_base64",
testonly = True,
defaults = ":test_defaults_2023",
encoding = "base64",
output = "defaults_test_embedded_base64.h",
placeholder = "DEFAULTS_VALUE",
template = "defaults_test_embedded_base64.h.template",
)
cc_binary(
name = "internal_defaults_escape",
srcs = ["internal_defaults_escape.cc"],
@ -51,6 +61,9 @@ cc_binary(
visibility = ["//visibility:public"],
deps = [
"//src/google/protobuf",
"@com_google_absl//absl/flags:flag",
"@com_google_absl//absl/flags:parse",
"@com_google_absl//absl/log:absl_log",
"@com_google_absl//absl/strings",
],
)
@ -59,6 +72,7 @@ cc_library(
name = "defaults_test_embedded",
hdrs = [
"defaults_test_embedded.h",
"defaults_test_embedded_base64.h",
],
strip_include_prefix = "/src",
)

View File

@ -58,12 +58,18 @@ compile_edition_defaults = rule(
)
def _embed_edition_defaults_impl(ctx):
if ctx.attr.encoding == "base64":
args = "--encoding=base64"
elif ctx.attr.encoding == "octal":
args = "--encoding=octal"
else:
fail("Unknown encoding %s" % ctx.attr.encoding)
ctx.actions.run_shell(
outputs = [ctx.outputs.output],
inputs = [ctx.file.defaults, ctx.file.template],
tools = [ctx.executable._escape],
command = """
DEFAULTS_RAW=$({escape} < {defaults})
DEFAULTS_RAW=$({escape} {args} < {defaults})
# Windows requires extra escaping.
DEFAULTS_ESCAPED=$(echo $DEFAULTS_RAW | sed 's/\\\\/\\\\\\\\/g' ||
echo $DEFAULTS_RAW | sed 's/\\\\\\\\/\\\\\\\\\\\\\\\\/g')
@ -72,6 +78,7 @@ def _embed_edition_defaults_impl(ctx):
sed -i.bak \"s|{placeholder}|$DEFAULTS_ESCAPED|g\" {output}
""".format(
escape = ctx.executable._escape.path,
args = args,
defaults = ctx.file.defaults.path,
template = ctx.file.template.path,
output = ctx.outputs.output.path,
@ -80,7 +87,7 @@ def _embed_edition_defaults_impl(ctx):
)
embed_edition_defaults = rule(
doc = "genrule to embed edition defaults binary data into a template file using octal C-style escaping.",
doc = "genrule to embed edition defaults binary data into a template file.",
attrs = {
"defaults": attr.label(
mandatory = True,
@ -102,6 +109,11 @@ embed_edition_defaults = rule(
mandatory = True,
doc = "The placeholder to replace with a serialized string in the template",
),
"encoding": attr.string(
default = "octal",
values = ["octal", "base64"],
doc = "The encoding format to use for the binary data (octal or base64)",
),
"_escape": attr.label(
default = "//src/google/protobuf/editions:internal_defaults_escape",
executable = True,

View File

@ -9,9 +9,11 @@
#include "absl/memory/memory.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/escaping.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "google/protobuf/editions/defaults_test_embedded.h"
#include "google/protobuf/editions/defaults_test_embedded_base64.h"
#include "google/protobuf/unittest_features.pb.h"
#include "google/protobuf/stubs/status_macros.h"
@ -140,6 +142,30 @@ TEST(DefaultsTest, Embedded) {
1);
}
TEST(DefaultsTest, EmbeddedBase64) {
FeatureSetDefaults defaults;
std::string data;
ASSERT_TRUE(absl::Base64Unescape(
absl::string_view{DEFAULTS_TEST_EMBEDDED_BASE64,
sizeof(DEFAULTS_TEST_EMBEDDED_BASE64) - 1},
&data));
ASSERT_TRUE(defaults.ParseFromString(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_PROTO2);
EXPECT_EQ(defaults.defaults()[1].edition(), EDITION_PROTO3);
EXPECT_EQ(defaults.defaults()[2].edition(), EDITION_2023);
EXPECT_EQ(defaults.defaults()[2].features().field_presence(),
FeatureSet::EXPLICIT);
EXPECT_EQ(defaults.defaults()[2]
.features()
.GetExtension(pb::test)
.int_file_feature(),
1);
}
} // namespace
} // namespace protobuf
} // namespace google

View File

@ -0,0 +1,6 @@
#ifndef THIRD_PARTY_PROTOBUF_EDITIONS_DEFAULTS_TEST_EMBEDDED_BASE64_H_
#define THIRD_PARTY_PROTOBUF_EDITIONS_DEFAULTS_TEST_EMBEDDED_BASE64_H_
#define DEFAULTS_TEST_EMBEDDED_BASE64 "DEFAULTS_VALUE"
#endif // THIRD_PARTY_PROTOBUF_EDITIONS_DEFAULTS_TEST_EMBEDDED_BASE64_H_

View File

@ -8,6 +8,9 @@
#endif
#include "google/protobuf/descriptor.pb.h"
#include "absl/flags/flag.h"
#include "absl/flags/parse.h"
#include "absl/log/absl_log.h"
#include "absl/strings/escaping.h"
#if defined(_WIN32)
@ -18,7 +21,11 @@
using google::protobuf::io::win32::setmode;
#endif
ABSL_FLAG(std::string, encoding, "octal",
"The encoding to use for the output.");
int main(int argc, char *argv[]) {
absl::ParseCommandLine(argc, argv);
#ifdef _WIN32
setmode(STDIN_FILENO, _O_BINARY);
setmode(STDOUT_FILENO, _O_BINARY);
@ -30,6 +37,13 @@ int main(int argc, char *argv[]) {
}
std::string output;
defaults.SerializeToString(&output);
std::cout << absl::CEscape(output);
std::string encoding = absl::GetFlag(FLAGS_encoding);
if (encoding == "base64") {
std::cout << absl::Base64Escape(output);
} else if (encoding == "octal") {
std::cout << absl::CEscape(output);
} else {
ABSL_LOG(FATAL) << "Unknown encoding: " << encoding;
}
return 0;
}