Open-source editions Bazel rules for embedding defaults.

These utilities provide a way to embed a FeatureSetDefaults message into generators or runtimes that need to implement feature resolution.  They use protoc to handle the tricky reflection-based algorithm over feature protos, leaving only simple merges to be implemented in other languages.  See docs/design/editions/editions-life-of-a-featureset.md for more information.

PiperOrigin-RevId: 574554333
pull/14430/head
Mike Kruskal 1 year ago committed by Copybara-Service
parent 536066eb52
commit 898d8fa1fd
  1. 1
      BUILD.bazel
  2. 1
      cmake/tests.cmake
  3. 46
      src/google/protobuf/BUILD.bazel
  4. 28
      src/google/protobuf/compiler/BUILD.bazel
  5. 4
      src/google/protobuf/compiler/allowlists/BUILD.bazel
  6. 6
      src/google/protobuf/compiler/cpp/BUILD.bazel
  7. 4
      src/google/protobuf/compiler/csharp/BUILD.bazel
  8. 8
      src/google/protobuf/compiler/java/BUILD.bazel
  9. 36
      src/google/protobuf/compiler/main_no_generators.cc
  10. 8
      src/google/protobuf/compiler/objectivec/BUILD.bazel
  11. 4
      src/google/protobuf/compiler/php/BUILD.bazel
  12. 2
      src/google/protobuf/compiler/python/BUILD.bazel
  13. 2
      src/google/protobuf/compiler/ruby/BUILD.bazel
  14. 14
      src/google/protobuf/compiler/rust/BUILD.bazel
  15. 84
      src/google/protobuf/editions/BUILD
  16. 112
      src/google/protobuf/editions/defaults.bzl
  17. 145
      src/google/protobuf/editions/defaults_test.cc
  18. 35
      src/google/protobuf/editions/internal_defaults_escape.cc
  19. 12
      src/google/protobuf/io/BUILD.bazel
  20. 4
      src/google/protobuf/stubs/BUILD.bazel
  21. 2
      src/google/protobuf/testing/BUILD.bazel

@ -224,7 +224,6 @@ alias(
cc_library(
name = "protobuf",
copts = COPTS,
include_prefix = "google/protobuf/io",
linkopts = LINK_OPTS,
visibility = ["//visibility:public"],
deps = [

@ -62,6 +62,7 @@ set(tests_files
${protobuf_test_files}
${compiler_test_files}
${annotation_test_util_srcs}
${editions_test_files}
${io_test_files}
${util_test_files}
${stubs_test_files}

@ -162,6 +162,7 @@ cc_library(
copts = COPTS,
includes = ["wkt"],
linkopts = LINK_OPTS,
strip_include_prefix = "/src",
visibility = ["//pkg:__pkg__"],
deps = [":protobuf_nowkt"],
)
@ -198,7 +199,7 @@ cc_library(
"port_def.inc",
"port_undef.inc",
],
include_prefix = "google/protobuf",
strip_include_prefix = "/src",
visibility = [
"//:__subpackages__",
"//src/google/protobuf:__subpackages__",
@ -212,7 +213,7 @@ cc_library(
name = "varint_shuffle",
hdrs = ["varint_shuffle.h"],
copts = COPTS,
include_prefix = "google/protobuf",
strip_include_prefix = "/src",
visibility = [
"//:__subpackages__",
"//src/google/protobuf:__subpackages__",
@ -248,7 +249,7 @@ cc_library(
name = "arena_align",
srcs = ["arena_align.cc"],
hdrs = ["arena_align.h"],
include_prefix = "google/protobuf",
strip_include_prefix = "/src",
visibility = [
"//:__subpackages__",
"//src/google/protobuf:__subpackages__",
@ -264,7 +265,7 @@ cc_library(
cc_library(
name = "arena_cleanup",
hdrs = ["arena_cleanup.h"],
include_prefix = "google/protobuf",
strip_include_prefix = "/src",
visibility = [
"//:__subpackages__",
"//src/google/protobuf:__subpackages__",
@ -278,7 +279,7 @@ cc_library(
cc_library(
name = "arena_allocation_policy",
hdrs = ["arena_allocation_policy.h"],
include_prefix = "google/protobuf",
strip_include_prefix = "/src",
visibility = [
"//:__subpackages__",
"//src/google/protobuf:__subpackages__",
@ -291,7 +292,7 @@ cc_library(
cc_library(
name = "string_block",
hdrs = ["string_block.h"],
include_prefix = "google/protobuf",
strip_include_prefix = "/src",
deps = [
":arena_align",
"@com_google_absl//absl/base:core_headers",
@ -320,7 +321,7 @@ cc_library(
"serial_arena.h",
"thread_safe_arena.h",
],
include_prefix = "google/protobuf",
strip_include_prefix = "/src",
visibility = [
"//:__subpackages__",
"//src/google/protobuf:__subpackages__",
@ -343,7 +344,7 @@ cc_library(
name = "internal_visibility",
hdrs = ["internal_visibility.h"],
copts = COPTS,
include_prefix = "google/protobuf",
strip_include_prefix = "/src",
visibility = [
"//:__subpackages__",
"//src/google/protobuf:__subpackages__",
@ -355,7 +356,7 @@ cc_library(
testonly = 1,
hdrs = ["internal_visibility_for_testing.h"],
copts = COPTS,
include_prefix = "google/protobuf",
strip_include_prefix = "/src",
visibility = [
"//:__subpackages__",
"//src/google/protobuf:__subpackages__",
@ -419,8 +420,8 @@ cc_library(
"-Wno-error",
],
}),
include_prefix = "google/protobuf",
linkopts = LINK_OPTS,
strip_include_prefix = "/src",
visibility = [
"//:__pkg__",
"//pkg:__pkg__",
@ -506,8 +507,8 @@ cc_library(
"wire_format.h",
],
copts = COPTS,
include_prefix = "google/protobuf",
linkopts = LINK_OPTS,
strip_include_prefix = "/src",
visibility = [
"//:__pkg__",
"//pkg:__pkg__",
@ -549,8 +550,8 @@ cc_test(
cc_library(
name = "protobuf",
copts = COPTS,
include_prefix = "google/protobuf",
linkopts = LINK_OPTS,
strip_include_prefix = "/src",
visibility = [
"//:__pkg__",
"//pkg:__pkg__",
@ -573,14 +574,15 @@ cc_library(
"**/*.h",
"**/*.inc",
]),
strip_include_prefix = "/src",
)
cc_library(
name = "descriptor_legacy",
hdrs = ["descriptor_legacy.h"],
copts = COPTS,
include_prefix = "google/protobuf",
linkopts = LINK_OPTS,
strip_include_prefix = "/src",
visibility = ["//:__subpackages__"],
deps = [
":port_def",
@ -593,8 +595,8 @@ cc_library(
name = "descriptor_visitor",
hdrs = ["descriptor_visitor.h"],
copts = COPTS,
include_prefix = "google/protobuf",
linkopts = LINK_OPTS,
strip_include_prefix = "/src",
visibility = ["//:__subpackages__"],
deps = [
":port_def",
@ -749,6 +751,22 @@ proto_library(
],
)
proto_library(
name = "unittest_features_proto",
srcs = ["unittest_features.proto"],
strip_import_prefix = "/src",
visibility = ["//src/google/protobuf:__subpackages__"],
deps = [
":descriptor_proto",
],
)
cc_proto_library(
name = "unittest_features_cc_proto",
visibility = ["//src/google/protobuf:__subpackages__"],
deps = [":unittest_features_proto"],
)
proto_library(
name = "generic_test_protos",
srcs = [":test_proto_srcs"],

@ -42,7 +42,7 @@ cc_library(
"parser.h",
],
copts = COPTS,
include_prefix = "google/protobuf/compiler",
strip_include_prefix = "/src",
visibility = ["//visibility:public"],
deps = [
"//src/google/protobuf:protobuf_nowkt",
@ -66,7 +66,7 @@ cc_library(
"scc.h",
],
copts = COPTS,
include_prefix = "google/protobuf/compiler",
strip_include_prefix = "/src",
visibility = ["//visibility:public"],
deps = [
"//src/google/protobuf:protobuf_nowkt",
@ -87,7 +87,7 @@ cc_library(
"versions_suffix.h",
],
copts = COPTS,
include_prefix = "google/protobuf/compiler",
strip_include_prefix = "/src",
visibility = [
"//src/google/protobuf/compiler:__subpackages__",
],
@ -107,7 +107,7 @@ cc_library(
"zip_writer.h",
],
copts = COPTS,
include_prefix = "google/protobuf/compiler",
strip_include_prefix = "/src",
visibility = ["//visibility:public"],
deps = [
":code_generator",
@ -133,6 +133,7 @@ cc_library(
"main.cc",
],
copts = COPTS,
strip_include_prefix = "/src",
visibility = [
"//:__pkg__",
"//pkg:__pkg__",
@ -154,6 +155,23 @@ cc_library(
],
)
# This is a build of the protobuf compiler without code generators.
cc_binary(
name = "protoc_minimal",
srcs = [
"main_no_generators.cc",
],
copts = COPTS,
visibility = [
"//src/google/protobuf:__subpackages__",
],
deps = [
":command_line_interface",
"//src/google/protobuf:port_def",
"@com_google_absl//absl/log:initialize",
],
)
# Note: this is an alias for now. In the future, this rule will become the
# cc_binary for protoc, and //:protoc will become an alias.
alias(
@ -397,7 +415,7 @@ cc_library(
name = "retention",
srcs = ["retention.cc"],
hdrs = ["retention.h"],
include_prefix = "google/protobuf/compiler",
strip_include_prefix = "/src",
visibility = ["//src/google/protobuf:__subpackages__"],
deps = [
"//src/google/protobuf:protobuf_nowkt",

@ -7,7 +7,7 @@ cc_library(
name = "allowlist",
hdrs = ["allowlist.h"],
copts = COPTS,
include_prefix = "google/protobuf/compiler/allowlists",
strip_include_prefix = "/src",
deps = [
"//src/google/protobuf/stubs",
"@com_google_absl//absl/algorithm:container",
@ -28,7 +28,7 @@ cc_library(
],
hdrs = ["allowlists.h"],
copts = COPTS,
include_prefix = "google/protobuf/compiler/allowlists",
strip_include_prefix = "/src",
visibility = ["//src/google/protobuf:__subpackages__"],
deps = [
":allowlist",

@ -11,7 +11,7 @@ cc_library(
name = "names",
hdrs = ["names.h"],
copts = COPTS,
include_prefix = "google/protobuf/compiler/cpp",
strip_include_prefix = "/src",
visibility = ["//visibility:public"],
deps = [
":names_internal",
@ -32,7 +32,7 @@ cc_library(
"options.h",
],
copts = COPTS,
include_prefix = "google/protobuf/compiler/cpp",
strip_include_prefix = "/src",
visibility = [
"//pkg:__pkg__",
"//src/google/protobuf/compiler/rust:__subpackages__",
@ -79,7 +79,7 @@ cc_library(
"tracker.h",
],
copts = COPTS,
include_prefix = "google/protobuf/compiler/cpp",
strip_include_prefix = "/src",
visibility = [
"//pkg:__pkg__",
"//src/google/protobuf/compiler:__pkg__",

@ -11,7 +11,7 @@ cc_library(
srcs = ["names.cc"],
hdrs = ["names.h"],
copts = COPTS,
include_prefix = "google/protobuf/compiler/csharp",
strip_include_prefix = "/src",
visibility = ["//visibility:public"],
deps = [
"//src/google/protobuf:protobuf_nowkt",
@ -62,7 +62,7 @@ cc_library(
"//build_defs:config_msvc": [],
"//conditions:default": ["-Wno-overloaded-virtual"],
}),
include_prefix = "google/protobuf/compiler/csharp",
strip_include_prefix = "/src",
visibility = [
"//pkg:__pkg__",
"//src/google/protobuf/compiler:__pkg__",

@ -10,7 +10,7 @@ cc_library(
name = "names",
hdrs = ["names.h"],
copts = COPTS,
include_prefix = "google/protobuf/compiler/java",
strip_include_prefix = "/src",
visibility = ["//visibility:public"],
deps = [
":names_internal",
@ -33,7 +33,7 @@ cc_library(
"options.h",
],
copts = COPTS,
include_prefix = "google/protobuf/compiler/java",
strip_include_prefix = "/src",
visibility = ["//pkg:__pkg__"],
deps = [
":java_features_bootstrap",
@ -48,7 +48,7 @@ cc_library(
name = "java_features_bootstrap",
srcs = ["java_features.pb.cc"],
hdrs = ["java_features.pb.h"],
include_prefix = "google/protobuf/compiler/java",
strip_include_prefix = "/src",
deps = [
"//src/google/protobuf:arena",
"//src/google/protobuf:protobuf_nowkt",
@ -119,7 +119,7 @@ cc_library(
"string_field_lite.h",
],
copts = COPTS,
include_prefix = "google/protobuf/compiler/java",
strip_include_prefix = "/src",
visibility = [
"//pkg:__pkg__",
"//src/google/protobuf/compiler:__pkg__",

@ -0,0 +1,36 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd
#include "google/protobuf/compiler/command_line_interface.h"
#include "absl/log/initialize.h"
// Must be included last.
#include "google/protobuf/port_def.inc"
namespace google {
namespace protobuf {
namespace compiler {
// This is a version of protoc that has no built-in code generators.
// See go/protobuf-toolchain-protoc
int ProtocMain(int argc, char* argv[]) {
absl::InitializeLog();
CommandLineInterface cli;
cli.AllowPlugins("protoc-");
return cli.Run(argc, argv);
}
} // namespace compiler
} // namespace protobuf
} // namespace google
int main(int argc, char* argv[]) {
return google::protobuf::compiler::ProtocMain(argc, argv);
}

@ -10,7 +10,7 @@ cc_library(
name = "names",
hdrs = ["names.h"],
copts = COPTS,
include_prefix = "google/protobuf/compiler/objectivec",
strip_include_prefix = "/src",
visibility = ["//visibility:public"],
deps = [
":names_internal",
@ -27,7 +27,7 @@ cc_library(
"nsobject_methods.h",
],
copts = COPTS,
include_prefix = "google/protobuf/compiler/objectivec",
strip_include_prefix = "/src",
visibility = ["//pkg:__pkg__"],
deps = [
":line_consumer",
@ -43,7 +43,7 @@ cc_library(
srcs = ["line_consumer.cc"],
hdrs = ["line_consumer.h"],
copts = COPTS,
include_prefix = "google/protobuf/compiler/objectivec",
strip_include_prefix = "/src",
visibility = ["//pkg:__pkg__"],
deps = [
"//src/google/protobuf:protobuf_nowkt",
@ -87,7 +87,7 @@ cc_library(
"text_format_decode_data.h",
],
copts = COPTS,
include_prefix = "google/protobuf/compiler/objectivec",
strip_include_prefix = "/src",
visibility = [
"//pkg:__pkg__",
"//src/google/protobuf/compiler:__pkg__",

@ -11,7 +11,7 @@ cc_library(
srcs = ["names.cc"],
hdrs = ["names.h"],
copts = COPTS,
include_prefix = "google/protobuf/compiler/php",
strip_include_prefix = "/src",
visibility = ["//visibility:public"],
deps = [
"//src/google/protobuf:protobuf_nowkt",
@ -25,7 +25,7 @@ cc_library(
srcs = ["php_generator.cc"],
hdrs = ["php_generator.h"],
copts = COPTS,
include_prefix = "google/protobuf/compiler/php",
strip_include_prefix = "/src",
visibility = [
"//pkg:__pkg__",
"//src/google/protobuf/compiler:__pkg__",

@ -19,7 +19,7 @@ cc_library(
"pyi_generator.h",
],
copts = COPTS,
include_prefix = "google/protobuf/compiler/python",
strip_include_prefix = "/src",
visibility = [
"//pkg:__pkg__",
"//src/google/protobuf/compiler:__pkg__",

@ -11,7 +11,7 @@ cc_library(
srcs = ["ruby_generator.cc"],
hdrs = ["ruby_generator.h"],
copts = COPTS,
include_prefix = "google/protobuf/compiler/ruby",
strip_include_prefix = "/src",
visibility = [
"//pkg:__pkg__",
"//src/google/protobuf/compiler:__pkg__",

@ -10,7 +10,7 @@ cc_library(
srcs = ["generator.cc"],
hdrs = ["generator.h"],
copts = COPTS,
include_prefix = "google/protobuf/compiler/rust",
strip_include_prefix = "/src",
visibility = [
"//pkg:__pkg__",
"//src/google/protobuf/compiler:__pkg__",
@ -34,7 +34,7 @@ cc_library(
srcs = ["message.cc"],
hdrs = ["message.h"],
copts = COPTS,
include_prefix = "google/protobuf/compiler/rust",
strip_include_prefix = "/src",
deps = [
":accessors",
":context",
@ -62,7 +62,7 @@ cc_library(
"accessors/accessors.h",
],
copts = COPTS,
include_prefix = "google/protobuf/compiler/rust",
strip_include_prefix = "/src",
deps = [
":context",
":naming",
@ -78,7 +78,7 @@ cc_library(
srcs = ["context.cc"],
hdrs = ["context.h"],
copts = COPTS,
include_prefix = "google/protobuf/compiler/rust",
strip_include_prefix = "/src",
deps = [
"//src/google/protobuf/compiler:code_generator",
"//src/google/protobuf/io:printer",
@ -96,7 +96,7 @@ cc_library(
srcs = ["naming.cc"],
hdrs = ["naming.h"],
copts = COPTS,
include_prefix = "google/protobuf/compiler/rust",
strip_include_prefix = "/src",
deps = [
":context",
"//src/google/protobuf:protobuf_nowkt",
@ -110,7 +110,7 @@ cc_library(
srcs = ["oneof.cc"],
hdrs = ["oneof.h"],
copts = COPTS,
include_prefix = "google/protobuf/compiler/rust",
strip_include_prefix = "/src",
deps = [
":context",
":naming",
@ -124,7 +124,7 @@ cc_library(
name = "relative_path",
srcs = ["relative_path.cc"],
hdrs = ["relative_path.h"],
include_prefix = "google/protobuf/compiler/rust",
strip_include_prefix = "/src",
deps = [
"@com_google_absl//absl/algorithm:container",
"@com_google_absl//absl/log:absl_check",

@ -1,4 +1,88 @@
load("@rules_cc//cc:defs.bzl", "cc_proto_library")
load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
load(":defaults.bzl", "compile_edition_defaults", "embed_edition_defaults")
bzl_library(
name = "defaults",
srcs = ["defaults.bzl"],
visibility = ["//visibility:public"],
)
compile_edition_defaults(
name = "test_defaults_2023",
testonly = True,
srcs = ["//src/google/protobuf:unittest_features_proto"],
maximum_edition = "2023",
minimum_edition = "2023",
)
compile_edition_defaults(
name = "test_defaults_future",
testonly = True,
srcs = ["//src/google/protobuf:unittest_features_proto"],
maximum_edition = "99997_TEST_ONLY",
minimum_edition = "2023",
)
compile_edition_defaults(
name = "test_defaults_far_future",
testonly = True,
srcs = ["//src/google/protobuf:unittest_features_proto"],
maximum_edition = "99999_TEST_ONLY",
minimum_edition = "99997_TEST_ONLY",
)
embed_edition_defaults(
name = "embed_test_defaults",
testonly = True,
defaults = ":test_defaults_2023",
output = "defaults_test_embedded.h",
placeholder = "DEFAULTS_VALUE",
template = "defaults_test_embedded.h.template",
)
cc_binary(
name = "internal_defaults_escape",
srcs = ["internal_defaults_escape.cc"],
# This needs to be public for users of embed_edition_defaults.
visibility = ["//visibility:public"],
deps = [
"//src/google/protobuf",
"@com_google_absl//absl/strings",
],
)
cc_library(
name = "defaults_test_embedded",
hdrs = [
"defaults_test_embedded.h",
],
strip_include_prefix = "/src",
)
cc_test(
name = "defaults_test",
srcs = ["defaults_test.cc"],
data = [
":test_defaults_2023",
":test_defaults_far_future",
":test_defaults_future",
],
deps = [
":defaults_test_embedded",
"//src/google/protobuf",
"//src/google/protobuf:unittest_features_cc_proto",
"//src/google/protobuf/stubs",
"//src/google/protobuf/testing",
"@bazel_tools//tools/cpp/runfiles",
"@com_google_absl//absl/memory",
"@com_google_absl//absl/status",
"@com_google_absl//absl/status:statusor",
"@com_google_absl//absl/strings",
"@com_google_absl//absl/strings:string_view",
"@com_google_googletest//:gtest_main",
],
)
proto_library(
name = "test_messages_proto2_proto",

@ -0,0 +1,112 @@
# Protocol Buffers - Google's data interchange format
# Copyright 2023 Google Inc. All rights reserved.
#
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file or at
# https://developers.google.com/open-source/licenses/bsd
"""
Provide a rule for generating the intermediate feature set defaults used for feature resolution.
See go/life-of-a-featureset for more information.
"""
def _compile_edition_defaults_impl(ctx):
out_file = ctx.actions.declare_file(ctx.outputs.output.basename)
sources = []
paths = []
for src in ctx.attr.srcs:
sources.extend(src[ProtoInfo].transitive_sources.to_list())
paths.extend(src[ProtoInfo].transitive_proto_path.to_list())
args = ctx.actions.args()
args.add("--experimental_edition_defaults_out", out_file)
args.add("--experimental_edition_defaults_minimum", ctx.attr.minimum_edition)
args.add("--experimental_edition_defaults_maximum", ctx.attr.maximum_edition)
for p in paths:
args.add("--proto_path", p)
for source in sources:
args.add(source)
ctx.actions.run(
outputs = [out_file],
inputs = sources,
executable = ctx.executable._protoc,
arguments = [args],
progress_message = "Generating edition defaults",
)
compile_edition_defaults = rule(
attrs = {
"srcs": attr.label_list(
mandatory = True,
allow_rules = ["proto_library"],
providers = [ProtoInfo],
),
"minimum_edition": attr.string(mandatory = True),
"maximum_edition": attr.string(mandatory = True),
"_protoc": attr.label(
default = "//src/google/protobuf/compiler:protoc_minimal",
executable = True,
cfg = "exec",
),
},
implementation = _compile_edition_defaults_impl,
outputs = {
"output": "%{name}.binpb",
},
)
def _embed_edition_defaults_impl(ctx):
ctx.actions.run_shell(
outputs = [ctx.outputs.output],
inputs = [ctx.file.defaults, ctx.file.template],
tools = [ctx.executable._escape],
command = """
DEFAULTS_RAW=$({escape} < {defaults})
# Windows requires extra escaping.
DEFAULTS_ESCAPED=$(echo $DEFAULTS_RAW | sed 's/\\\\/\\\\\\\\/g' ||
echo $DEFAULTS_RAW | sed 's/\\\\\\\\/\\\\\\\\\\\\\\\\/g')
cp -f {template} {output}
# MacOS requires a backup file.
sed -i.bak \"s|{placeholder}|$DEFAULTS_ESCAPED|g\" {output}
""".format(
escape = ctx.executable._escape.path,
defaults = ctx.file.defaults.path,
template = ctx.file.template.path,
output = ctx.outputs.output.path,
placeholder = ctx.attr.placeholder,
),
)
embed_edition_defaults = rule(
doc = "genrule to embed edition defaults binary data into a template file using octal C-style escaping.",
attrs = {
"defaults": attr.label(
mandatory = True,
allow_single_file = True,
allow_rules = ["compile_edition_defaults"],
providers = [ProtoInfo],
doc = "The compile_edition_defaults rule to embed",
),
"output": attr.output(
mandatory = True,
doc = "The name of the output file",
),
"template": attr.label(
mandatory = True,
allow_single_file = True,
doc = "The template to use for generating the output file",
),
"placeholder": attr.string(
mandatory = True,
doc = "The placeholder to replace with a serialized string in the template",
),
"_escape": attr.label(
default = "//src/google/protobuf/editions:internal_defaults_escape",
executable = True,
cfg = "exec",
),
},
implementation = _embed_edition_defaults_impl,
)

@ -0,0 +1,145 @@
#include <string>
#include "tools/cpp/runfiles/runfiles.h"
#include "google/protobuf/testing/file.h"
#include "google/protobuf/testing/file.h"
#include "google/protobuf/descriptor.pb.h"
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "absl/memory/memory.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "google/protobuf/editions/defaults_test_embedded.h"
#include "google/protobuf/unittest_features.pb.h"
#include "google/protobuf/stubs/status_macros.h"
// Must be included last.
#include "google/protobuf/port_def.inc"
#define ASSERT_OK(x) ASSERT_TRUE(x.ok()) << x.status().message();
namespace google {
namespace protobuf {
namespace {
absl::StatusOr<FeatureSetDefaults> ReadDefaults(absl::string_view name) {
auto runfiles = absl::WrapUnique(bazel::tools::cpp::runfiles::Runfiles::CreateForTest());
std::string file = runfiles->Rlocation(absl::StrCat(
"com_google_protobuf/src/google/protobuf/editions/",
name, ".binpb"));
std::string data;
RETURN_IF_ERROR(File::GetContents(file, &data, true));
FeatureSetDefaults defaults;
if (!defaults.ParseFromString(data)) {
return absl::InternalError("Could not parse edition defaults!");
}
return defaults;
}
TEST(DefaultsTest, Check2023) {
auto defaults = ReadDefaults("test_defaults_2023");
ASSERT_OK(defaults);
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);
}
TEST(DefaultsTest, CheckFuture) {
auto defaults = ReadDefaults("test_defaults_future");
ASSERT_OK(defaults);
ASSERT_EQ(defaults->defaults().size(), 4);
ASSERT_EQ(defaults->minimum_edition(), EDITION_2023);
ASSERT_EQ(defaults->maximum_edition(), EDITION_99997_TEST_ONLY);
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);
EXPECT_EQ(defaults->defaults()[3].edition(), EDITION_99997_TEST_ONLY);
EXPECT_EQ(defaults->defaults()[3].features().field_presence(),
FeatureSet::EXPLICIT);
EXPECT_EQ(defaults->defaults()[3]
.features()
.GetExtension(pb::test)
.int_file_feature(),
2);
}
TEST(DefaultsTest, CheckFarFuture) {
auto defaults = ReadDefaults("test_defaults_far_future");
ASSERT_OK(defaults);
ASSERT_EQ(defaults->defaults().size(), 5);
ASSERT_EQ(defaults->minimum_edition(), EDITION_99997_TEST_ONLY);
ASSERT_EQ(defaults->maximum_edition(), EDITION_99999_TEST_ONLY);
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);
EXPECT_EQ(defaults->defaults()[3].edition(), EDITION_99997_TEST_ONLY);
EXPECT_EQ(defaults->defaults()[3].features().field_presence(),
FeatureSet::EXPLICIT);
EXPECT_EQ(defaults->defaults()[3]
.features()
.GetExtension(pb::test)
.int_file_feature(),
2);
EXPECT_EQ(defaults->defaults()[4].edition(), EDITION_99998_TEST_ONLY);
EXPECT_EQ(defaults->defaults()[4].features().field_presence(),
FeatureSet::EXPLICIT);
EXPECT_EQ(defaults->defaults()[4]
.features()
.GetExtension(pb::test)
.int_file_feature(),
3);
}
TEST(DefaultsTest, Embedded) {
FeatureSetDefaults defaults;
ASSERT_TRUE(defaults.ParseFromArray(DEFAULTS_TEST_EMBEDDED,
sizeof(DEFAULTS_TEST_EMBEDDED) - 1))
<< "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_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

@ -0,0 +1,35 @@
#include <iostream>
#include <string>
#ifdef _WIN32
#include <fcntl.h>
#else
#include <unistd.h>
#endif
#include "google/protobuf/descriptor.pb.h"
#include "absl/strings/escaping.h"
#if defined(_WIN32)
#include "google/protobuf/io/io_win32.h"
// DO NOT include <io.h>, instead create functions in io_win32.{h,cc} and import
// them like we do below.
using google::protobuf::io::win32::setmode;
#endif
int main(int argc, char *argv[]) {
#ifdef _WIN32
setmode(STDIN_FILENO, _O_BINARY);
setmode(STDOUT_FILENO, _O_BINARY);
#endif
google::protobuf::FeatureSetDefaults defaults;
if (!defaults.ParseFromFileDescriptor(STDIN_FILENO)) {
std::cerr << argv[0] << ": unable to parse edition defaults." << std::endl;
return 1;
}
std::string output;
defaults.SerializeToString(&output);
std::cout << absl::CEscape(output);
return 0;
}

@ -23,7 +23,7 @@ cc_library(
"zero_copy_stream_impl_lite.h",
],
copts = COPTS,
include_prefix = "google/protobuf/io",
strip_include_prefix = "/src",
deps = [
":io_win32",
"//src/google/protobuf:arena",
@ -39,7 +39,7 @@ cc_library(
testonly = 1,
hdrs = ["test_zero_copy_stream.h"],
copts = COPTS,
include_prefix = "google/protobuf/io",
strip_include_prefix = "/src",
deps = [
":io",
"//src/google/protobuf/stubs",
@ -90,7 +90,7 @@ cc_library(
srcs = ["printer.cc"],
hdrs = ["printer.h"],
copts = COPTS,
include_prefix = "google/protobuf/io",
strip_include_prefix = "/src",
deps = [
":zero_copy_sink",
"//src/google/protobuf/stubs",
@ -119,7 +119,7 @@ cc_library(
"tokenizer.h",
],
copts = COPTS,
include_prefix = "google/protobuf/io",
strip_include_prefix = "/src",
deps = [
":io",
"//src/google/protobuf/stubs",
@ -134,7 +134,7 @@ cc_library(
srcs = ["gzip_stream.cc"],
hdrs = ["gzip_stream.h"],
copts = COPTS,
include_prefix = "google/protobuf/io",
strip_include_prefix = "/src",
deps = [
":io",
"//src/google/protobuf/stubs",
@ -151,7 +151,7 @@ cc_library(
srcs = ["io_win32.cc"],
hdrs = ["io_win32.h"],
copts = COPTS,
include_prefix = "google/protobuf/io",
strip_include_prefix = "/src",
visibility = [
"//pkg:__pkg__",
"//src/google/protobuf/compiler:__pkg__",

@ -22,8 +22,8 @@ cc_library(
"status_macros.h",
],
copts = COPTS,
include_prefix = "google/protobuf/stubs",
linkopts = LINK_OPTS,
strip_include_prefix = "/src",
deps = [
"//src/google/protobuf:port_def",
"@com_google_absl//absl/log:absl_log",
@ -40,7 +40,7 @@ cc_library(
hdrs = [
],
copts = COPTS,
include_prefix = "google/protobuf/stubs",
strip_include_prefix = "/src",
textual_hdrs = [
"callback.h",
"common.h",

@ -19,8 +19,8 @@ cc_library(
"googletest.h",
],
copts = COPTS,
include_prefix = "google/protobuf/testing",
linkopts = LINK_OPTS,
strip_include_prefix = "/src",
deps = [
"//:protobuf_lite", # for ShutdownProtobufLibrary
"//src/google/protobuf/io",

Loading…
Cancel
Save