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
diff --git a/BUILD.bazel b/BUILD.bazel
index 23efee4..5951297 100644
--- a/BUILD.bazel
+++ b/BUILD.bazel
@@ -224,7 +224,6 @@
cc_library(
name = "protobuf",
copts = COPTS,
- include_prefix = "google/protobuf/io",
linkopts = LINK_OPTS,
visibility = ["//visibility:public"],
deps = [
diff --git a/cmake/tests.cmake b/cmake/tests.cmake
index 489ca65..044af48 100644
--- a/cmake/tests.cmake
+++ b/cmake/tests.cmake
@@ -62,6 +62,7 @@
${protobuf_test_files}
${compiler_test_files}
${annotation_test_util_srcs}
+ ${editions_test_files}
${io_test_files}
${util_test_files}
${stubs_test_files}
diff --git a/src/google/protobuf/BUILD.bazel b/src/google/protobuf/BUILD.bazel
index 8961ca6..f85e88b 100644
--- a/src/google/protobuf/BUILD.bazel
+++ b/src/google/protobuf/BUILD.bazel
@@ -162,6 +162,7 @@
copts = COPTS,
includes = ["wkt"],
linkopts = LINK_OPTS,
+ strip_include_prefix = "/src",
visibility = ["//pkg:__pkg__"],
deps = [":protobuf_nowkt"],
)
@@ -198,7 +199,7 @@
"port_def.inc",
"port_undef.inc",
],
- include_prefix = "google/protobuf",
+ strip_include_prefix = "/src",
visibility = [
"//:__subpackages__",
"//src/google/protobuf:__subpackages__",
@@ -212,7 +213,7 @@
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 @@
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(
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(
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(
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 @@
"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 @@
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 @@
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 @@
"-Wno-error",
],
}),
- include_prefix = "google/protobuf",
linkopts = LINK_OPTS,
+ strip_include_prefix = "/src",
visibility = [
"//:__pkg__",
"//pkg:__pkg__",
@@ -506,8 +507,8 @@
"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_library(
name = "protobuf",
copts = COPTS,
- include_prefix = "google/protobuf",
linkopts = LINK_OPTS,
+ strip_include_prefix = "/src",
visibility = [
"//:__pkg__",
"//pkg:__pkg__",
@@ -573,14 +574,15 @@
"**/*.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 @@
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",
@@ -750,6 +752,22 @@
)
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"],
strip_import_prefix = "/src",
diff --git a/src/google/protobuf/compiler/BUILD.bazel b/src/google/protobuf/compiler/BUILD.bazel
index 273dae0..f98c317 100644
--- a/src/google/protobuf/compiler/BUILD.bazel
+++ b/src/google/protobuf/compiler/BUILD.bazel
@@ -42,7 +42,7 @@
"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 @@
"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 @@
"versions_suffix.h",
],
copts = COPTS,
- include_prefix = "google/protobuf/compiler",
+ strip_include_prefix = "/src",
visibility = [
"//src/google/protobuf/compiler:__subpackages__",
],
@@ -107,7 +107,7 @@
"zip_writer.h",
],
copts = COPTS,
- include_prefix = "google/protobuf/compiler",
+ strip_include_prefix = "/src",
visibility = ["//visibility:public"],
deps = [
":code_generator",
@@ -133,6 +133,7 @@
"main.cc",
],
copts = COPTS,
+ strip_include_prefix = "/src",
visibility = [
"//:__pkg__",
"//pkg:__pkg__",
@@ -154,6 +155,23 @@
],
)
+# 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 @@
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",
diff --git a/src/google/protobuf/compiler/allowlists/BUILD.bazel b/src/google/protobuf/compiler/allowlists/BUILD.bazel
index 470181f..e6671c0 100644
--- a/src/google/protobuf/compiler/allowlists/BUILD.bazel
+++ b/src/google/protobuf/compiler/allowlists/BUILD.bazel
@@ -7,7 +7,7 @@
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 @@
],
hdrs = ["allowlists.h"],
copts = COPTS,
- include_prefix = "google/protobuf/compiler/allowlists",
+ strip_include_prefix = "/src",
visibility = ["//src/google/protobuf:__subpackages__"],
deps = [
":allowlist",
diff --git a/src/google/protobuf/compiler/cpp/BUILD.bazel b/src/google/protobuf/compiler/cpp/BUILD.bazel
index 8ca37b4..fb168b0 100644
--- a/src/google/protobuf/compiler/cpp/BUILD.bazel
+++ b/src/google/protobuf/compiler/cpp/BUILD.bazel
@@ -11,7 +11,7 @@
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 @@
"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 @@
"tracker.h",
],
copts = COPTS,
- include_prefix = "google/protobuf/compiler/cpp",
+ strip_include_prefix = "/src",
visibility = [
"//pkg:__pkg__",
"//src/google/protobuf/compiler:__pkg__",
diff --git a/src/google/protobuf/compiler/csharp/BUILD.bazel b/src/google/protobuf/compiler/csharp/BUILD.bazel
index 414dd0f..a182bc2 100644
--- a/src/google/protobuf/compiler/csharp/BUILD.bazel
+++ b/src/google/protobuf/compiler/csharp/BUILD.bazel
@@ -11,7 +11,7 @@
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 @@
"//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__",
diff --git a/src/google/protobuf/compiler/java/BUILD.bazel b/src/google/protobuf/compiler/java/BUILD.bazel
index a9461d0..8ca67c1 100644
--- a/src/google/protobuf/compiler/java/BUILD.bazel
+++ b/src/google/protobuf/compiler/java/BUILD.bazel
@@ -10,7 +10,7 @@
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 @@
"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 @@
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 @@
"string_field_lite.h",
],
copts = COPTS,
- include_prefix = "google/protobuf/compiler/java",
+ strip_include_prefix = "/src",
visibility = [
"//pkg:__pkg__",
"//src/google/protobuf/compiler:__pkg__",
diff --git a/src/google/protobuf/compiler/main_no_generators.cc b/src/google/protobuf/compiler/main_no_generators.cc
new file mode 100644
index 0000000..83a44e8
--- /dev/null
+++ b/src/google/protobuf/compiler/main_no_generators.cc
@@ -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);
+}
diff --git a/src/google/protobuf/compiler/objectivec/BUILD.bazel b/src/google/protobuf/compiler/objectivec/BUILD.bazel
index 5ab3381..a3a6fcf 100644
--- a/src/google/protobuf/compiler/objectivec/BUILD.bazel
+++ b/src/google/protobuf/compiler/objectivec/BUILD.bazel
@@ -10,7 +10,7 @@
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 @@
"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 @@
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 @@
"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__",
diff --git a/src/google/protobuf/compiler/php/BUILD.bazel b/src/google/protobuf/compiler/php/BUILD.bazel
index f814a03..2a9746d 100644
--- a/src/google/protobuf/compiler/php/BUILD.bazel
+++ b/src/google/protobuf/compiler/php/BUILD.bazel
@@ -11,7 +11,7 @@
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 @@
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__",
diff --git a/src/google/protobuf/compiler/python/BUILD.bazel b/src/google/protobuf/compiler/python/BUILD.bazel
index 64b5808..e9501f2 100644
--- a/src/google/protobuf/compiler/python/BUILD.bazel
+++ b/src/google/protobuf/compiler/python/BUILD.bazel
@@ -19,7 +19,7 @@
"pyi_generator.h",
],
copts = COPTS,
- include_prefix = "google/protobuf/compiler/python",
+ strip_include_prefix = "/src",
visibility = [
"//pkg:__pkg__",
"//src/google/protobuf/compiler:__pkg__",
diff --git a/src/google/protobuf/compiler/ruby/BUILD.bazel b/src/google/protobuf/compiler/ruby/BUILD.bazel
index d01764c..62afc3c 100644
--- a/src/google/protobuf/compiler/ruby/BUILD.bazel
+++ b/src/google/protobuf/compiler/ruby/BUILD.bazel
@@ -11,7 +11,7 @@
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__",
diff --git a/src/google/protobuf/compiler/rust/BUILD.bazel b/src/google/protobuf/compiler/rust/BUILD.bazel
index 1429b9b..9939c2c 100644
--- a/src/google/protobuf/compiler/rust/BUILD.bazel
+++ b/src/google/protobuf/compiler/rust/BUILD.bazel
@@ -10,7 +10,7 @@
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 @@
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 @@
"accessors/accessors.h",
],
copts = COPTS,
- include_prefix = "google/protobuf/compiler/rust",
+ strip_include_prefix = "/src",
deps = [
":context",
":naming",
@@ -78,7 +78,7 @@
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 @@
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 @@
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 @@
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",
diff --git a/src/google/protobuf/editions/BUILD b/src/google/protobuf/editions/BUILD
index 04e1967..0fa11a8 100644
--- a/src/google/protobuf/editions/BUILD
+++ b/src/google/protobuf/editions/BUILD
@@ -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",
diff --git a/src/google/protobuf/editions/defaults.bzl b/src/google/protobuf/editions/defaults.bzl
new file mode 100644
index 0000000..865efaf
--- /dev/null
+++ b/src/google/protobuf/editions/defaults.bzl
@@ -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,
+)
diff --git a/src/google/protobuf/editions/defaults_test.cc b/src/google/protobuf/editions/defaults_test.cc
new file mode 100644
index 0000000..24c66ec
--- /dev/null
+++ b/src/google/protobuf/editions/defaults_test.cc
@@ -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
diff --git a/src/google/protobuf/editions/internal_defaults_escape.cc b/src/google/protobuf/editions/internal_defaults_escape.cc
new file mode 100644
index 0000000..4c1aa46
--- /dev/null
+++ b/src/google/protobuf/editions/internal_defaults_escape.cc
@@ -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;
+}
diff --git a/src/google/protobuf/io/BUILD.bazel b/src/google/protobuf/io/BUILD.bazel
index 0578742..a5c44e2 100644
--- a/src/google/protobuf/io/BUILD.bazel
+++ b/src/google/protobuf/io/BUILD.bazel
@@ -23,7 +23,7 @@
"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 @@
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 @@
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 @@
"tokenizer.h",
],
copts = COPTS,
- include_prefix = "google/protobuf/io",
+ strip_include_prefix = "/src",
deps = [
":io",
"//src/google/protobuf/stubs",
@@ -134,7 +134,7 @@
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 @@
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__",
diff --git a/src/google/protobuf/stubs/BUILD.bazel b/src/google/protobuf/stubs/BUILD.bazel
index 740e43e..f89f34a 100644
--- a/src/google/protobuf/stubs/BUILD.bazel
+++ b/src/google/protobuf/stubs/BUILD.bazel
@@ -22,8 +22,8 @@
"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 @@
hdrs = [
],
copts = COPTS,
- include_prefix = "google/protobuf/stubs",
+ strip_include_prefix = "/src",
textual_hdrs = [
"callback.h",
"common.h",
diff --git a/src/google/protobuf/testing/BUILD.bazel b/src/google/protobuf/testing/BUILD.bazel
index 572c1f9..ab3e979 100644
--- a/src/google/protobuf/testing/BUILD.bazel
+++ b/src/google/protobuf/testing/BUILD.bazel
@@ -19,8 +19,8 @@
"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",