Fixed layering check violations once and for all in upb bootstrapping.

Our bootstrapping setup compiles multiple versions of the generated code for `descriptor.proto` and `plugin.proto`, one for each stage of the bootstrap.  For source files (`.c`), we can always select the correct version of the file in the BUILD rules, but for header files we need to make sure the correct stage's file is always selected via `#include`.

Previously we used `cc_library(includes=[])` to make it appear as though our bootstrapped headers had the same names as the "real" headers. This allowed a lot of the code to be agnostic to whether a bootstrap header was being used, which simplified things because we did not have to change the code performing the `#include`.

Unfortunately, due to build system limitations, this sometimes led to the incorrect header getting included. This should not have been possible, because we had a clean BUILD graph that should have removed all ambiguity about which header should be available. But in non-sandboxed builds, the compiler was able to find headers that were not actually in `deps=[]`, and worse it preferred those headers over the headers that actually were in `deps=[]`. This led to unintended results and errors about layering check violations.

This CL fixes the problem by removing all use of `includes=[]`.  We now spell a full pathname to all bootstrap headers, so this class of errors is no longer possible.  Unfortunately this adds some complexity, as we have to hard-code these full paths in several places.

A nice improvement in this CL is that `bootstrap_upb_proto_library()` can now only be used for bootstrapping; it only exposes the `descriptor_bootstrap.h` / `plugin_bootstrap.h` files.  Anyone wanting to use the normal `net/proto2/proto/descriptor.upb.h` file should depend on `//net/proto2/proto:descriptor_upb_c_proto` target instead.

PiperOrigin-RevId: 664953196
pull/17837/head
Joshua Haberman 7 months ago committed by Copybara-Service
parent 979931cc02
commit eab1fa2765
  1. 1
      benchmarks/BUILD
  2. 2
      python/BUILD.bazel
  3. 21
      src/google/protobuf/BUILD.bazel
  4. 14
      src/google/protobuf/compiler/BUILD.bazel
  5. 11
      upb/BUILD
  6. 2
      upb/bazel/amalgamate.py
  7. 4
      upb/cmake/BUILD.bazel
  8. 5
      upb/port/def.inc
  9. 4
      upb/reflection/BUILD
  10. 12
      upb/reflection/common.h
  11. 19
      upb/reflection/descriptor_bootstrap.h
  12. 2
      upb/reflection/field_def.c
  13. 2
      upb/reflection/stage0/google/protobuf/descriptor.upb.c
  14. 8
      upb/util/BUILD
  15. 13
      upb_generator/BUILD
  16. 84
      upb_generator/bootstrap_compiler.bzl
  17. 30
      upb_generator/common.cc
  18. 4
      upb_generator/common.h
  19. 14
      upb_generator/file_layout.h
  20. 17
      upb_generator/plugin.h
  21. 19
      upb_generator/plugin_bootstrap.h
  22. 46
      upb_generator/protoc-gen-upb.cc
  23. 9
      upb_generator/protoc-gen-upb_minitable-main.cc
  24. 12
      upb_generator/protoc-gen-upb_minitable.cc
  25. 3
      upb_generator/protoc-gen-upb_minitable.h
  26. 2
      upb_generator/protoc-gen-upbdefs.cc
  27. 4
      upb_generator/stage0/google/protobuf/compiler/plugin.upb.c

@ -74,7 +74,6 @@ cc_test(
"//:protobuf", "//:protobuf",
"//src/google/protobuf/json", "//src/google/protobuf/json",
"//upb:base", "//upb:base",
"//upb:descriptor_upb_proto",
"//upb:json", "//upb:json",
"//upb:mem", "//upb:mem",
"//upb:reflection", "//upb:reflection",

@ -191,9 +191,9 @@ py_extension(
], ],
target_compatible_with = select(_message_target_compatible_with), target_compatible_with = select(_message_target_compatible_with),
deps = [ deps = [
"//src/google/protobuf:descriptor_upb_reflection_proto",
"//third_party/utf8_range", "//third_party/utf8_range",
"//upb:base", "//upb:base",
"//upb:descriptor_upb_proto_reflection",
"//upb:eps_copy_input_stream", "//upb:eps_copy_input_stream",
"//upb:message", "//upb:message",
"//upb:message_compare", "//upb:message_compare",

@ -6,6 +6,9 @@ load("@rules_cc//cc:defs.bzl", "cc_library", "cc_test")
load("@rules_pkg//pkg:mappings.bzl", "pkg_files", "strip_prefix") load("@rules_pkg//pkg:mappings.bzl", "pkg_files", "strip_prefix")
load("//bazel:cc_proto_library.bzl", "cc_proto_library") load("//bazel:cc_proto_library.bzl", "cc_proto_library")
load("//bazel:proto_library.bzl", "proto_library") load("//bazel:proto_library.bzl", "proto_library")
load("//bazel:upb_c_proto_library.bzl", "upb_c_proto_library")
load("//bazel:upb_minitable_proto_library.bzl", "upb_minitable_proto_library")
load("//bazel:upb_proto_reflection_library.bzl", "upb_proto_reflection_library")
load("//build_defs:cpp_opts.bzl", "COPTS", "LINK_OPTS") load("//build_defs:cpp_opts.bzl", "COPTS", "LINK_OPTS")
load("//upb/cmake:build_defs.bzl", "staleness_test") load("//upb/cmake:build_defs.bzl", "staleness_test")
@ -223,6 +226,24 @@ proto_library(
], ],
) )
upb_c_proto_library(
name = "descriptor_upb_c_proto",
visibility = ["//:__subpackages__"],
deps = [":descriptor_proto"],
)
upb_minitable_proto_library(
name = "descriptor_upb_minitable_proto",
visibility = ["//:__subpackages__"],
deps = [":descriptor_proto"],
)
upb_proto_reflection_library(
name = "descriptor_upb_reflection_proto",
visibility = ["//:__subpackages__"],
deps = [":descriptor_proto"],
)
proto_library( proto_library(
name = "cpp_features_proto", name = "cpp_features_proto",
srcs = ["cpp_features.proto"], srcs = ["cpp_features.proto"],

@ -11,6 +11,8 @@ load(
) )
load("//bazel:cc_proto_library.bzl", "cc_proto_library") load("//bazel:cc_proto_library.bzl", "cc_proto_library")
load("//bazel:proto_library.bzl", "proto_library") load("//bazel:proto_library.bzl", "proto_library")
load("//bazel:upb_c_proto_library.bzl", "upb_c_proto_library")
load("//bazel:upb_proto_reflection_library.bzl", "upb_proto_reflection_library")
load("//build_defs:arch_tests.bzl", "aarch64_test", "x86_64_test") load("//build_defs:arch_tests.bzl", "aarch64_test", "x86_64_test")
load("//build_defs:cpp_opts.bzl", "COPTS") load("//build_defs:cpp_opts.bzl", "COPTS")
load("test_plugin_injection.bzl", "inject_plugin_paths") load("test_plugin_injection.bzl", "inject_plugin_paths")
@ -32,6 +34,18 @@ cc_proto_library(
deps = [":plugin_proto"], deps = [":plugin_proto"],
) )
upb_c_proto_library(
name = "plugin_upb_c_proto",
visibility = ["//upb_generator:__subpackages__"],
deps = [":plugin_proto"],
)
upb_proto_reflection_library(
name = "plugin_upb_reflection_proto",
visibility = ["//upb_generator:__subpackages__"],
deps = [":plugin_proto"],
)
cc_library( cc_library(
name = "importer", name = "importer",
srcs = [ srcs = [

@ -261,7 +261,6 @@ upb_amalgamation(
], ],
libs = [ libs = [
":base", ":base",
":descriptor_upb_minitable_proto",
":descriptor_upb_proto", ":descriptor_upb_proto",
":eps_copy_input_stream", ":eps_copy_input_stream",
":generated_code_support__only_for_generated_code_do_not_use__i_give_permission_to_break_me", ":generated_code_support__only_for_generated_code_do_not_use__i_give_permission_to_break_me",
@ -276,6 +275,8 @@ upb_amalgamation(
":reflection", ":reflection",
":wire", ":wire",
":wire_reader", ":wire_reader",
"//src/google/protobuf:descriptor_upb_c_proto",
"//src/google/protobuf:descriptor_upb_minitable_proto",
"//upb/base:internal", "//upb/base:internal",
"//upb/hash:hash", "//upb/hash:hash",
"//upb/lex:lex", "//upb/lex:lex",
@ -307,8 +308,6 @@ upb_amalgamation(
], ],
libs = [ libs = [
":base", ":base",
":descriptor_upb_minitable_proto",
":descriptor_upb_proto_reflection",
":descriptor_upb_proto", ":descriptor_upb_proto",
":eps_copy_input_stream", ":eps_copy_input_stream",
":generated_code_support__only_for_generated_code_do_not_use__i_give_permission_to_break_me", ":generated_code_support__only_for_generated_code_do_not_use__i_give_permission_to_break_me",
@ -324,6 +323,9 @@ upb_amalgamation(
":reflection", ":reflection",
":wire", ":wire",
":wire_reader", ":wire_reader",
"//src/google/protobuf:descriptor_upb_c_proto",
"//src/google/protobuf:descriptor_upb_minitable_proto",
"//src/google/protobuf:descriptor_upb_reflection_proto",
"//upb/base:internal", "//upb/base:internal",
"//upb/hash:hash", "//upb/hash:hash",
"//upb/lex:lex", "//upb/lex:lex",
@ -356,7 +358,6 @@ upb_amalgamation(
], ],
libs = [ libs = [
":base", ":base",
":descriptor_upb_minitable_proto",
":descriptor_upb_proto", ":descriptor_upb_proto",
":eps_copy_input_stream", ":eps_copy_input_stream",
":generated_code_support__only_for_generated_code_do_not_use__i_give_permission_to_break_me", ":generated_code_support__only_for_generated_code_do_not_use__i_give_permission_to_break_me",
@ -372,6 +373,8 @@ upb_amalgamation(
":reflection", ":reflection",
":wire", ":wire",
":wire_reader", ":wire_reader",
"//src/google/protobuf:descriptor_upb_c_proto",
"//src/google/protobuf:descriptor_upb_minitable_proto",
"//upb/base:internal", "//upb/base:internal",
"//upb/hash:hash", "//upb/hash:hash",
"//upb/lex:lex", "//upb/lex:lex",

@ -106,6 +106,8 @@ class Amalgamator:
if include.endswith("hpp"): if include.endswith("hpp"):
# Skip, we don't support the amalgamation from C++. # Skip, we don't support the amalgamation from C++.
return True return True
if re.search(r"stage\d/", include):
return True
elif include in self.included: elif include in self.included:
return True return True
else: else:

@ -47,8 +47,8 @@ genrule(
genrule( genrule(
name = "copy_protos", name = "copy_protos",
srcs = [ srcs = [
"//upb:descriptor_upb_proto", "//src/google/protobuf:descriptor_upb_c_proto",
"//upb:descriptor_upb_minitable_proto", "//src/google/protobuf:descriptor_upb_minitable_proto",
], ],
outs = [ outs = [
"generated-in/google/protobuf/descriptor.upb.h", "generated-in/google/protobuf/descriptor.upb.h",

@ -338,10 +338,11 @@ void __asan_unpoison_memory_region(void const volatile *addr, size_t size);
// #define UPB_IS_GOOGLE3 // #define UPB_IS_GOOGLE3
// end:google_only // end:google_only
#if defined(UPB_IS_GOOGLE3) && !defined(UPB_BOOTSTRAP_STAGE0) #if defined(UPB_IS_GOOGLE3) && \
(!defined(UPB_BOOTSTRAP_STAGE) || UPB_BOOTSTRAP_STAGE != 0)
#define UPB_DESC(sym) proto2_##sym #define UPB_DESC(sym) proto2_##sym
#define UPB_DESC_MINITABLE(sym) &proto2__##sym##_msg_init #define UPB_DESC_MINITABLE(sym) &proto2__##sym##_msg_init
#elif defined(UPB_BOOTSTRAP_STAGE0) #elif defined(UPB_BOOTSTRAP_STAGE) && UPB_BOOTSTRAP_STAGE == 0
#define UPB_DESC(sym) google_protobuf_##sym #define UPB_DESC(sym) google_protobuf_##sym
#define UPB_DESC_MINITABLE(sym) google__protobuf__##sym##_msg_init() #define UPB_DESC_MINITABLE(sym) google__protobuf__##sym##_msg_init()
#else #else

@ -29,9 +29,7 @@ load(
bootstrap_upb_proto_library( bootstrap_upb_proto_library(
name = "descriptor_upb_proto", name = "descriptor_upb_proto",
base_dir = "", bootstrap_hdr = "descriptor_bootstrap.h",
# TODO: Export 'net/proto2/proto/descriptor.upb.h' and remove "-layering_check".
features = ["-layering_check"],
google3_src_files = ["net/proto2/proto/descriptor.proto"], google3_src_files = ["net/proto2/proto/descriptor.proto"],
google3_src_rules = ["//net/proto2/proto:descriptor_proto_source"], google3_src_rules = ["//net/proto2/proto:descriptor_proto_source"],
oss_src_files = ["google/protobuf/descriptor.proto"], oss_src_files = ["google/protobuf/descriptor.proto"],

@ -12,17 +12,7 @@
#ifndef UPB_REFLECTION_COMMON_H_ #ifndef UPB_REFLECTION_COMMON_H_
#define UPB_REFLECTION_COMMON_H_ #define UPB_REFLECTION_COMMON_H_
// begin:google_only #include "upb/reflection/descriptor_bootstrap.h" // IWYU pragma: export
// #ifndef UPB_BOOTSTRAP_STAGE0
// #include "net/proto2/proto/descriptor.upb.h"
// #else
// #include "google/protobuf/descriptor.upb.h"
// #endif
// end:google_only
// begin:github_only
#include "google/protobuf/descriptor.upb.h"
// end:github_only
typedef enum { typedef enum {
kUpb_Syntax_Proto2 = 2, kUpb_Syntax_Proto2 = 2,

@ -0,0 +1,19 @@
#ifndef THIRD_PARTY_UPB_UPB_REFLECTION_DESCRIPTOR_BOOTSTRAP_H_
#define THIRD_PARTY_UPB_UPB_REFLECTION_DESCRIPTOR_BOOTSTRAP_H_
// IWYU pragma: begin_exports
#if defined(UPB_BOOTSTRAP_STAGE) && UPB_BOOTSTRAP_STAGE == 0
// This header is checked in.
#include "upb/reflection/stage0/google/protobuf/descriptor.upb.h"
#elif UPB_BOOTSTRAP_STAGE == 1
// This header is generated at build time by the bootstrapping process.
#include "upb/reflection/stage1/google/protobuf/descriptor.upb.h"
#else
// This is the normal header, generated by upb_c_proto_library().
#include "google/protobuf/descriptor.upb.h"
#endif
// IWYU pragma: end_exports
#endif // THIRD_PARTY_UPB_UPB_REFLECTION_DESCRIPTOR_BOOTSTRAP_H_

@ -591,7 +591,7 @@ static bool _upb_FieldDef_InferLegacyFeatures(
} }
// begin:google_only // begin:google_only
// #ifndef UPB_BOOTSTRAP_STAGE0 // #if UPB_BOOTSTRAP_STAGE != 0
// if (syntax == kUpb_Syntax_Proto3 && // if (syntax == kUpb_Syntax_Proto3 &&
// UPB_DESC(FieldOptions_has_enforce_utf8)(options) && // UPB_DESC(FieldOptions_has_enforce_utf8)(options) &&
// !UPB_DESC(FieldOptions_enforce_utf8)(options)) { // !UPB_DESC(FieldOptions_enforce_utf8)(options)) {

@ -1,6 +1,6 @@
#include <stddef.h> #include <stddef.h>
#include "upb/generated_code_support.h" #include "upb/generated_code_support.h"
#include "google/protobuf/descriptor.upb.h" #include "upb/reflection/descriptor_bootstrap.h"
static upb_Arena* upb_BootstrapArena() { static upb_Arena* upb_BootstrapArena() {
static upb_Arena* arena = NULL; static upb_Arena* arena = NULL;

@ -18,8 +18,8 @@ cc_library(
hdrs = ["def_to_proto.h"], hdrs = ["def_to_proto.h"],
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
deps = [ deps = [
"//src/google/protobuf:descriptor_upb_c_proto",
"//upb:base", "//upb:base",
"//upb:descriptor_upb_proto",
"//upb:port", "//upb:port",
"//upb:reflection", "//upb:reflection",
"//upb/reflection:internal", "//upb/reflection:internal",
@ -52,9 +52,9 @@ cc_library(
deps = [ deps = [
":def_to_proto", ":def_to_proto",
"//:protobuf", "//:protobuf",
"//src/google/protobuf:descriptor_upb_c_proto",
"//src/google/protobuf/util:differencer", "//src/google/protobuf/util:differencer",
"//upb:base", "//upb:base",
"//upb:descriptor_upb_proto",
"//upb:mem", "//upb:mem",
"//upb/reflection:internal", "//upb/reflection:internal",
"@com_google_googletest//:gtest", "@com_google_googletest//:gtest",
@ -72,10 +72,10 @@ cc_test(
":def_to_proto_test_upb_proto", ":def_to_proto_test_upb_proto",
":def_to_proto_test_upb_proto_reflection", ":def_to_proto_test_upb_proto_reflection",
"//:protobuf", "//:protobuf",
"//src/google/protobuf:descriptor_upb_c_proto",
"//src/google/protobuf:descriptor_upb_reflection_proto",
"//src/google/protobuf/util:differencer", "//src/google/protobuf/util:differencer",
"//upb:base", "//upb:base",
"//upb:descriptor_upb_proto",
"//upb:descriptor_upb_proto_reflection",
"//upb:mem", "//upb:mem",
"//upb:reflection", "//upb:reflection",
"//upb/test:parse_text_proto", "//upb/test:parse_text_proto",

@ -59,9 +59,7 @@ upb_minitable_proto_library(
bootstrap_upb_proto_library( bootstrap_upb_proto_library(
name = "plugin_upb_proto", name = "plugin_upb_proto",
base_dir = "", bootstrap_hdr = "plugin_bootstrap.h",
# TODO: Export 'net/proto2/proto/descriptor.upb.h' and remove "-layering_check".
features = ["-layering_check"],
google3_src_files = [ google3_src_files = [
"net/proto2/compiler/proto/profile.proto", "net/proto2/compiler/proto/profile.proto",
"third_party/protobuf/compiler/plugin.proto", "third_party/protobuf/compiler/plugin.proto",
@ -234,10 +232,10 @@ cc_library(
deps = [ deps = [
":code_generator_request_upb_proto", ":code_generator_request_upb_proto",
":code_generator_request_upb_proto_reflection", ":code_generator_request_upb_proto_reflection",
":plugin_upb_proto", "//src/google/protobuf:descriptor_upb_c_proto",
":plugin_upb_proto_reflection", "//src/google/protobuf/compiler:plugin_upb_c_proto",
"//src/google/protobuf/compiler:plugin_upb_reflection_proto",
"//upb:base", "//upb:base",
"//upb:descriptor_upb_proto",
"//upb:json", "//upb:json",
"//upb:mem", "//upb:mem",
"//upb:message", "//upb:message",
@ -281,6 +279,7 @@ bootstrap_cc_library(
"//upb:mini_table", "//upb:mini_table",
"//upb:port", "//upb:port",
"//upb:wire_reader", "//upb:wire_reader",
"@com_google_absl//absl/base:core_headers",
"@com_google_absl//absl/container:flat_hash_map", "@com_google_absl//absl/container:flat_hash_map",
"@com_google_absl//absl/container:flat_hash_set", "@com_google_absl//absl/container:flat_hash_set",
"@com_google_absl//absl/log:absl_check", "@com_google_absl//absl/log:absl_check",
@ -400,7 +399,7 @@ cc_library(
":common", ":common",
":file_layout", ":file_layout",
":plugin", ":plugin",
"//upb:descriptor_upb_proto", "//src/google/protobuf:descriptor_upb_c_proto",
"//upb:reflection", "//upb:reflection",
"//upb/util:def_to_proto", "//upb/util:def_to_proto",
], ],

@ -51,38 +51,38 @@ def bootstrap_cc_binary(name, deps = [], bootstrap_deps = [], **kwargs):
**kwargs **kwargs
) )
def _generated_srcs_for_suffix(prefix, srcs, suffix): def _generated_file(proto, stage, generator, suffix):
return [prefix + "/" + src[:-len(".proto")] + suffix for src in srcs] stripped = proto[:-len(".proto")]
return "{}/{}.{}.{}".format(stage, stripped, generator, suffix)
def _generated_srcs_for_generator(prefix, srcs, generator): def _generated_files(protos, stage, generator, suffix):
ret = _generated_srcs_for_suffix(prefix, srcs, ".{}.h".format(generator)) return [_generated_file(proto, stage, generator, suffix) for proto in protos]
if generator != "upb" or prefix.endswith("stage0"): def _generated_hdrs_and_srcs(protos, stage, generator):
ret += _generated_srcs_for_suffix(prefix, srcs, ".{}.c".format(generator)) ret = _generated_files(protos, stage, generator, "h")
if generator != "upb" or stage == "stage0":
ret += _generated_files(protos, stage, generator, "c")
return ret return ret
def _generated_srcs(prefix, srcs): def _stage0_proto_staleness_test(name, src_files, src_rules, strip_prefix):
return _generated_srcs_for_generator(prefix, srcs, "upb")
def _stage0_proto_staleness_test(name, base_dir, src_files, src_rules, strip_prefix):
native.genrule( native.genrule(
name = name + "_generate_bootstrap", name = name + "_generate_bootstrap",
srcs = src_rules, srcs = src_rules,
outs = _generated_srcs("bootstrap_generated_sources/" + base_dir + "stage0", src_files), outs = ["bootstrap_generated_sources/" + f for f in _generated_hdrs_and_srcs(src_files, "stage0", "upb")],
tools = [_protoc, _upbc("upb", 0)], tools = [_protoc, _upbc("upb", 0)],
cmd = cmd =
"$(location " + _protoc + ") " + "$(location " + _protoc + ") " +
"-I$(GENDIR)/" + strip_prefix + " " + _extra_proto_path + "-I$(GENDIR)/" + strip_prefix + " " + _extra_proto_path +
"--plugin=protoc-gen-upb=$(location " + _upbc("upb", 0) + ") " + "--plugin=protoc-gen-upb=$(location " + _upbc("upb", 0) + ") " +
"--upb_out=bootstrap_upb:$(@D)/bootstrap_generated_sources/" + base_dir + "stage0 " + "--upb_out=bootstrap_stage=0:$(@D)/bootstrap_generated_sources/stage0 " +
" ".join(src_files), " ".join(src_files),
) )
staleness_test( staleness_test(
name = name + "_stage0_staleness_test", name = name + "_stage0_staleness_test",
outs = _generated_srcs(base_dir + "stage0", src_files), outs = _generated_hdrs_and_srcs(src_files, "stage0", "upb"),
generated_pattern = "bootstrap_generated_sources/%s", generated_pattern = "bootstrap_generated_sources/%s",
target_files = native.glob([base_dir + "stage0/**"]), target_files = native.glob(["stage0/**"]),
# To avoid skew problems for descriptor.proto/pluging.proto between # To avoid skew problems for descriptor.proto/pluging.proto between
# GitHub repos. It's not critical that the checked-in protos are up to # GitHub repos. It's not critical that the checked-in protos are up to
# date for every change, they just needs to be complete enough to have # date for every change, they just needs to be complete enough to have
@ -90,15 +90,15 @@ def _stage0_proto_staleness_test(name, base_dir, src_files, src_rules, strip_pre
tags = ["manual"], tags = ["manual"],
) )
def _generate_stage1_proto(name, base_dir, src_files, src_rules, generator, kwargs): def _generate_stage1_proto(name, src_files, src_rules, generator, kwargs):
native.genrule( native.genrule(
name = "gen_{}_{}_stage1".format(name, generator), name = "gen_{}_{}_stage1".format(name, generator),
srcs = src_rules, srcs = src_rules,
outs = _generated_srcs_for_generator(base_dir + "stage1", src_files, generator), outs = _generated_hdrs_and_srcs(src_files, "stage1", generator),
cmd = "$(location " + _protoc + ") " + cmd = "$(location " + _protoc + ") " +
"--plugin=protoc-gen-" + generator + "--plugin=protoc-gen-" + generator +
"=$(location " + _upbc(generator, 0) + ") " + _extra_proto_path + "=$(location " + _upbc(generator, 0) + ") " + _extra_proto_path +
"--" + generator + "_out=$(RULEDIR)/" + base_dir + "stage1 " + "--" + generator + "_out=bootstrap_stage=1:$(RULEDIR)/stage1 " +
" ".join(src_files), " ".join(src_files),
visibility = ["//upb_generator:__pkg__"], visibility = ["//upb_generator:__pkg__"],
tools = [ tools = [
@ -109,7 +109,7 @@ def _generate_stage1_proto(name, base_dir, src_files, src_rules, generator, kwar
) )
# begin:github_only # begin:github_only
def _cmake_staleness_test(name, base_dir, src_files, proto_lib_deps, **kwargs): def _cmake_staleness_test(name, src_files, proto_lib_deps, **kwargs):
upb_minitable_proto_library( upb_minitable_proto_library(
name = name + "_minitable", name = name + "_minitable",
deps = proto_lib_deps, deps = proto_lib_deps,
@ -117,15 +117,15 @@ def _cmake_staleness_test(name, base_dir, src_files, proto_lib_deps, **kwargs):
) )
# Copy the final gencode for staleness comparison # Copy the final gencode for staleness comparison
files = _generated_srcs("cmake" + base_dir, src_files) + \ files = _generated_hdrs_and_srcs(src_files, "cmake", "upb") + \
_generated_srcs_for_generator("cmake" + base_dir, src_files, "upb_minitable") _generated_hdrs_and_srcs(src_files, "cmake", "upb_minitable")
genrule = 0 genrule = 0
for src in files: for src in files:
genrule += 1 genrule += 1
native.genrule( native.genrule(
name = name + "_copy_gencode_%d" % genrule, name = name + "_copy_gencode_%d" % genrule,
outs = ["generated_sources/" + src], outs = ["generated_sources/" + src],
srcs = [name, name + "_minitable"], srcs = [name + "_upb_proto", name + "_minitable"],
cmd = """ cmd = """
mkdir -p $(@D) mkdir -p $(@D)
for src in $(SRCS); do for src in $(SRCS); do
@ -148,7 +148,7 @@ def _cmake_staleness_test(name, base_dir, src_files, proto_lib_deps, **kwargs):
def bootstrap_upb_proto_library( def bootstrap_upb_proto_library(
name, name,
base_dir, bootstrap_hdr,
google3_src_files, google3_src_files,
google3_src_rules, google3_src_rules,
oss_src_files, oss_src_files,
@ -162,7 +162,6 @@ def bootstrap_upb_proto_library(
Args: Args:
name: Name of this rule. This name will resolve to a upb_proto_library(). name: Name of this rule. This name will resolve to a upb_proto_library().
base_dir: The directory that all generated files should be placed under.
google3_src_files: Google3 filenames of .proto files that should be built by this rule. google3_src_files: Google3 filenames of .proto files that should be built by this rule.
The names should be relative to the depot base. The names should be relative to the depot base.
google3_src_rules: Target names of the Blaze rules that will provide these filenames. google3_src_rules: Target names of the Blaze rules that will provide these filenames.
@ -177,17 +176,15 @@ def bootstrap_upb_proto_library(
**kwargs: Other arguments that will be passed through to cc_library(), genrule(), and **kwargs: Other arguments that will be passed through to cc_library(), genrule(), and
upb_proto_library(). upb_proto_library().
""" """
_stage0_proto_staleness_test(name, base_dir, oss_src_files, oss_src_rules, oss_strip_prefix) _stage0_proto_staleness_test(name, oss_src_files, oss_src_rules, oss_strip_prefix)
# stage0 uses checked-in protos, and has no MiniTable. # stage0 uses checked-in protos, and has no MiniTable.
native.cc_library( native.cc_library(
name = name + "_stage0", name = name + "_stage0",
srcs = _generated_srcs_for_suffix(base_dir + "stage0", oss_src_files, ".upb.c"), srcs = _generated_hdrs_and_srcs(oss_src_files, "stage0", "upb"),
hdrs = _generated_srcs_for_suffix(base_dir + "stage0", oss_src_files, ".upb.h"), hdrs = [bootstrap_hdr],
includes = [base_dir + "stage0"],
visibility = ["//upb_generator:__pkg__"], visibility = ["//upb_generator:__pkg__"],
# This macro signals to the runtime that it must use OSS APIs for descriptor.proto/plugin.proto. defines = ["UPB_BOOTSTRAP_STAGE=0"],
defines = ["UPB_BOOTSTRAP_STAGE0"],
deps = [ deps = [
"//upb:generated_code_support__only_for_generated_code_do_not_use__i_give_permission_to_break_me", "//upb:generated_code_support__only_for_generated_code_do_not_use__i_give_permission_to_break_me",
"//upb:mini_table", "//upb:mini_table",
@ -199,41 +196,48 @@ def bootstrap_upb_proto_library(
src_rules = google3_src_rules if _is_google3 else oss_src_rules src_rules = google3_src_rules if _is_google3 else oss_src_rules
# Generate stage1 protos (C API and MiniTables) using stage0 compiler. # Generate stage1 protos (C API and MiniTables) using stage0 compiler.
_generate_stage1_proto(name, base_dir, src_files, src_rules, "upb", kwargs) _generate_stage1_proto(name, src_files, src_rules, "upb", kwargs)
_generate_stage1_proto(name, base_dir, src_files, src_rules, "upb_minitable", kwargs) _generate_stage1_proto(name, src_files, src_rules, "upb_minitable", kwargs)
native.cc_library( native.cc_library(
name = name + "_minitable_stage1", name = name + "_minitable_stage1",
srcs = _generated_srcs_for_suffix(base_dir + "stage1", src_files, ".upb_minitable.c"), srcs = _generated_files(src_files, "stage1", "upb_minitable", "c"),
hdrs = _generated_srcs_for_suffix(base_dir + "stage1", src_files, ".upb_minitable.h"), hdrs = _generated_files(src_files, "stage1", "upb_minitable", "h"),
includes = [base_dir + "stage1"],
visibility = ["//upb_generator:__pkg__"], visibility = ["//upb_generator:__pkg__"],
defines = ["UPB_BOOTSTRAP_STAGE=1"],
deps = [ deps = [
"//upb:generated_code_support__only_for_generated_code_do_not_use__i_give_permission_to_break_me", "//upb:generated_code_support__only_for_generated_code_do_not_use__i_give_permission_to_break_me",
] + [dep + "_stage1" for dep in deps], ] + [dep + "_minitable_stage1" for dep in deps],
**kwargs **kwargs
) )
native.cc_library( native.cc_library(
name = name + "_stage1", name = name + "_stage1",
hdrs = _generated_srcs_for_suffix(base_dir + "stage1", src_files, ".upb.h"), srcs = _generated_files(src_files, "stage1", "upb", "h"),
includes = [base_dir + "stage1"], hdrs = [bootstrap_hdr],
visibility = ["//upb_generator:__pkg__"], visibility = ["//upb_generator:__pkg__"],
defines = ["UPB_BOOTSTRAP_STAGE=1"],
deps = [ deps = [
"//upb:generated_code_support__only_for_generated_code_do_not_use__i_give_permission_to_break_me", "//upb:generated_code_support__only_for_generated_code_do_not_use__i_give_permission_to_break_me",
":" + name + "_minitable_stage1", ":" + name + "_minitable_stage1",
] + [dep + "_stage1" for dep in deps], ] + [dep + "_minitable_stage1" for dep in deps],
**kwargs **kwargs
) )
# The final protos are generated via normal upb_proto_library(). # The final protos are generated via normal upb_proto_library().
upb_proto_library( upb_proto_library(
name = name, name = name + "_upb_proto",
deps = proto_lib_deps, deps = proto_lib_deps,
**kwargs
)
native.cc_library(
name = name,
hdrs = [bootstrap_hdr],
deps = [name + "_upb_proto"],
visibility = visibility, visibility = visibility,
**kwargs **kwargs
) )
# begin:github_only # begin:github_only
_cmake_staleness_test(name, base_dir, src_files, proto_lib_deps, **kwargs) _cmake_staleness_test(name, src_files, proto_lib_deps, **kwargs)
# end:github_only # end:github_only

@ -75,12 +75,36 @@ std::string FileLayoutName(upb::FileDefPtr file) {
return ToCIdent(file.name()) + "_upb_file_layout"; return ToCIdent(file.name()) + "_upb_file_layout";
} }
std::string CApiHeaderFilename(upb::FileDefPtr file) { bool HasFilename(upb::FileDefPtr file, absl::string_view filename) {
return file.name() == filename;
}
bool IsDescriptorProto(upb::FileDefPtr file) {
return HasFilename(file, "net/proto2/proto/descriptor.proto") ||
HasFilename(file, "google/protobuf/descriptor.proto");
}
std::string CApiHeaderFilename(upb::FileDefPtr file, bool bootstrap) {
if (bootstrap) {
if (IsDescriptorProto(file)) {
return "upb/reflection/descriptor_bootstrap.h";
} else {
return "upb_generator/plugin_bootstrap.h";
}
}
return StripExtension(file.name()) + ".upb.h"; return StripExtension(file.name()) + ".upb.h";
} }
std::string MiniTableHeaderFilename(upb::FileDefPtr file) { std::string MiniTableHeaderFilename(upb::FileDefPtr file, bool bootstrap) {
return StripExtension(file.name()) + ".upb_minitable.h"; std::string base;
if (bootstrap) {
if (IsDescriptorProto(file)) {
base = "upb/reflection/stage1/";
} else {
base = "upb_generator/stage1/";
}
}
return base + StripExtension(file.name()) + ".upb_minitable.h";
} }
std::string EnumInit(upb::EnumDefPtr descriptor) { std::string EnumInit(upb::EnumDefPtr descriptor) {

@ -66,8 +66,8 @@ PROTOC_EXPORT std::string MessageInit(absl::string_view full_name);
std::string MessageInitName(upb::MessageDefPtr descriptor); std::string MessageInitName(upb::MessageDefPtr descriptor);
std::string MessageName(upb::MessageDefPtr descriptor); std::string MessageName(upb::MessageDefPtr descriptor);
std::string FileLayoutName(upb::FileDefPtr file); std::string FileLayoutName(upb::FileDefPtr file);
std::string MiniTableHeaderFilename(upb::FileDefPtr file); std::string MiniTableHeaderFilename(upb::FileDefPtr file, bool bootstrap);
std::string CApiHeaderFilename(upb::FileDefPtr file); std::string CApiHeaderFilename(upb::FileDefPtr file, bool bootstrap);
std::string PadPrefix(absl::string_view tag); std::string PadPrefix(absl::string_view tag);
std::string EnumInit(upb::EnumDefPtr descriptor); std::string EnumInit(upb::EnumDefPtr descriptor);

@ -9,24 +9,14 @@
#define UPB_GENERATOR_FILE_LAYOUT_H #define UPB_GENERATOR_FILE_LAYOUT_H
#include <string> #include <string>
#include <vector>
// begin:google_only
// #ifndef UPB_BOOTSTRAP_STAGE0
// #include "google/protobuf/descriptor.upb.h"
// #else
// #include "google/protobuf/descriptor.upb.h"
// #endif
// end:google_only
// begin:github_only
#include "google/protobuf/descriptor.upb.h"
// end:github_only
#include "absl/container/flat_hash_map.h" #include "absl/container/flat_hash_map.h"
#include "upb/base/status.hpp" #include "upb/base/status.hpp"
#include "upb/mini_descriptor/decode.h" #include "upb/mini_descriptor/decode.h"
#include "upb/reflection/def.h" #include "upb/reflection/def.h"
#include "upb/reflection/def.hpp" #include "upb/reflection/def.hpp"
#include "upb/reflection/descriptor_bootstrap.h"
// Must be last // Must be last
#include "upb/port/def.inc" #include "upb/port/def.inc"

@ -17,26 +17,13 @@
#include <io.h> #include <io.h>
#endif #endif
// begin:google_only
// #ifndef UPB_BOOTSTRAP_STAGE0
// #include "google/protobuf/descriptor.upb.h"
// #include "google/protobuf/compiler/plugin.upb.h"
// #else
// #include "google/protobuf/compiler/plugin.upb.h"
// #include "google/protobuf/descriptor.upb.h"
// #endif
// end:google_only
// begin:github_only
#include "google/protobuf/compiler/plugin.upb.h"
#include "google/protobuf/descriptor.upb.h"
// end:github_only
#include "absl/container/flat_hash_set.h" #include "absl/container/flat_hash_set.h"
#include "absl/log/absl_log.h" #include "absl/log/absl_log.h"
#include "absl/strings/str_split.h" #include "absl/strings/str_split.h"
#include "absl/strings/string_view.h" #include "absl/strings/string_view.h"
#include "upb/reflection/def.hpp" #include "upb/reflection/def.hpp"
#include "upb/reflection/descriptor_bootstrap.h"
#include "upb_generator/plugin_bootstrap.h"
// Must be last. // Must be last.
#include "upb/port/def.inc" #include "upb/port/def.inc"

@ -0,0 +1,19 @@
#ifndef THIRD_PARTY_UPB_UPB_GENERATOR_PLUGIN_BOOTSTRAP_H_
#define THIRD_PARTY_UPB_UPB_GENERATOR_PLUGIN_BOOTSTRAP_H_
// IWYU pragma: begin_exports
#if defined(UPB_BOOTSTRAP_STAGE) && UPB_BOOTSTRAP_STAGE == 0
// This header is checked in.
#include "upb_generator/stage0/google/protobuf/compiler/plugin.upb.h"
#elif UPB_BOOTSTRAP_STAGE == 1
// This header is generated at build time by the bootstrapping process.
#include "upb_generator/stage1/google/protobuf/compiler/plugin.upb.h"
#else
// This is the normal header, generated by upb_c_proto_library().
#include "google/protobuf/compiler/plugin.upb.h"
#endif
// IWYU pragma: end_exports
#endif // THIRD_PARTY_UPB_UPB_GENERATOR_PLUGIN_BOOTSTRAP_H_

@ -6,6 +6,7 @@
// https://developers.google.com/open-source/licenses/bsd // https://developers.google.com/open-source/licenses/bsd
#include <algorithm> #include <algorithm>
#include <cassert>
#include <cmath> #include <cmath>
#include <cstddef> #include <cstddef>
#include <cstdint> #include <cstdint>
@ -17,10 +18,12 @@
#include <utility> #include <utility>
#include <vector> #include <vector>
#include "absl/base/macros.h"
#include "absl/log/absl_check.h" #include "absl/log/absl_check.h"
#include "absl/log/absl_log.h" #include "absl/log/absl_log.h"
#include "absl/strings/escaping.h" #include "absl/strings/escaping.h"
#include "absl/strings/match.h" #include "absl/strings/match.h"
#include "absl/strings/numbers.h"
#include "absl/strings/str_cat.h" #include "absl/strings/str_cat.h"
#include "absl/strings/str_replace.h" #include "absl/strings/str_replace.h"
#include "absl/strings/string_view.h" #include "absl/strings/string_view.h"
@ -31,7 +34,6 @@
#include "upb/base/string_view.h" #include "upb/base/string_view.h"
#include "upb/mini_table/field.h" #include "upb/mini_table/field.h"
#include "upb/reflection/def.hpp" #include "upb/reflection/def.hpp"
#include "upb/wire/types.h"
#include "upb_generator/common.h" #include "upb_generator/common.h"
#include "upb_generator/file_layout.h" #include "upb_generator/file_layout.h"
#include "upb_generator/names.h" #include "upb_generator/names.h"
@ -45,7 +47,7 @@ namespace generator {
namespace { namespace {
struct Options { struct Options {
bool bootstrap = false; int bootstrap_stage = -1; // -1 means not bootstrapped.
bool strip_nonfunctional_codegen = false; bool strip_nonfunctional_codegen = false;
}; };
@ -55,7 +57,7 @@ std::string SourceFilename(upb::FileDefPtr file) {
std::string MessageMiniTableRef(upb::MessageDefPtr descriptor, std::string MessageMiniTableRef(upb::MessageDefPtr descriptor,
const Options& options) { const Options& options) {
if (options.bootstrap) { if (options.bootstrap_stage == 0) {
return absl::StrCat(MessageInitName(descriptor), "()"); return absl::StrCat(MessageInitName(descriptor), "()");
} else { } else {
return absl::StrCat("&", MessageInitName(descriptor)); return absl::StrCat("&", MessageInitName(descriptor));
@ -68,7 +70,7 @@ std::string EnumInitName(upb::EnumDefPtr descriptor) {
std::string EnumMiniTableRef(upb::EnumDefPtr descriptor, std::string EnumMiniTableRef(upb::EnumDefPtr descriptor,
const Options& options) { const Options& options) {
if (options.bootstrap) { if (options.bootstrap_stage == 0) {
return absl::StrCat(EnumInitName(descriptor), "()"); return absl::StrCat(EnumInitName(descriptor), "()");
} else { } else {
return absl::StrCat("&", EnumInitName(descriptor)); return absl::StrCat("&", EnumInitName(descriptor));
@ -887,21 +889,26 @@ void WriteHeader(const DefPoolPair& pools, upb::FileDefPtr file,
if (i == 0) { if (i == 0) {
output("/* Public Imports. */\n"); output("/* Public Imports. */\n");
} }
output("#include \"$0\"\n", CApiHeaderFilename(file.public_dependency(i))); output("#include \"$0\"\n",
CApiHeaderFilename(file.public_dependency(i),
options.bootstrap_stage >= 0));
} }
if (file.public_dependency_count() > 0) { if (file.public_dependency_count() > 0) {
output("\n"); output("\n");
} }
if (!options.bootstrap) { if (options.bootstrap_stage != 0) {
output("#include \"$0\"\n\n", MiniTableHeaderFilename(file)); output("#include \"$0\"\n\n",
MiniTableHeaderFilename(file, options.bootstrap_stage >= 0));
for (int i = 0; i < file.dependency_count(); i++) { for (int i = 0; i < file.dependency_count(); i++) {
if (options.strip_nonfunctional_codegen && if (options.strip_nonfunctional_codegen &&
google::protobuf::compiler::IsKnownFeatureProto(file.dependency(i).name())) { google::protobuf::compiler::IsKnownFeatureProto(file.dependency(i).name())) {
// Strip feature imports for editions codegen tests. // Strip feature imports for editions codegen tests.
continue; continue;
} }
output("#include \"$0\"\n", MiniTableHeaderFilename(file.dependency(i))); output("#include \"$0\"\n",
MiniTableHeaderFilename(file.dependency(i),
options.bootstrap_stage >= 0));
} }
output("\n"); output("\n");
} }
@ -915,7 +922,7 @@ void WriteHeader(const DefPoolPair& pools, upb::FileDefPtr file,
"#endif\n" "#endif\n"
"\n"); "\n");
if (options.bootstrap) { if (options.bootstrap_stage == 0) {
for (auto message : this_file_messages) { for (auto message : this_file_messages) {
output("extern const upb_MiniTable* $0();\n", MessageInitName(message)); output("extern const upb_MiniTable* $0();\n", MessageInitName(message));
} }
@ -1005,7 +1012,7 @@ std::string FieldInitializer(upb::FieldDefPtr field,
const upb_MiniTableField* field64, const upb_MiniTableField* field64,
const upb_MiniTableField* field32, const upb_MiniTableField* field32,
const Options& options) { const Options& options) {
if (options.bootstrap) { if (options.bootstrap_stage == 0) {
ABSL_CHECK(!field.is_extension()); ABSL_CHECK(!field.is_extension());
return absl::Substitute( return absl::Substitute(
"*upb_MiniTable_FindFieldByNumber($0, $1)", "*upb_MiniTable_FindFieldByNumber($0, $1)",
@ -1034,7 +1041,7 @@ std::string FieldInitializerStrong(const DefPoolPair& pools,
upb::FieldDefPtr field, upb::FieldDefPtr field,
const Options& options) { const Options& options) {
std::string ret = FieldInitializer(pools, field, options); std::string ret = FieldInitializer(pools, field, options);
if (!options.bootstrap && field.IsSubMessage()) { if (options.bootstrap_stage != 0 && field.IsSubMessage()) {
ret += ";\n" + StrongReference(field); ret += ";\n" + StrongReference(field);
} }
return ret; return ret;
@ -1109,14 +1116,16 @@ void WriteMiniDescriptorSource(const DefPoolPair& pools, upb::FileDefPtr file,
"#include <stddef.h>\n" "#include <stddef.h>\n"
"#include \"upb/generated_code_support.h\"\n" "#include \"upb/generated_code_support.h\"\n"
"#include \"$0\"\n\n", "#include \"$0\"\n\n",
CApiHeaderFilename(file)); CApiHeaderFilename(file, options.bootstrap_stage >= 0));
for (int i = 0; i < file.dependency_count(); i++) { for (int i = 0; i < file.dependency_count(); i++) {
if (options.strip_nonfunctional_codegen && if (options.strip_nonfunctional_codegen &&
google::protobuf::compiler::IsKnownFeatureProto(file.dependency(i).name())) { google::protobuf::compiler::IsKnownFeatureProto(file.dependency(i).name())) {
continue; continue;
} }
output("#include \"$0\"\n", CApiHeaderFilename(file.dependency(i))); output(
"#include \"$0\"\n",
CApiHeaderFilename(file.dependency(i), options.bootstrap_stage >= 0));
} }
output( output(
@ -1143,9 +1152,9 @@ void GenerateFile(const DefPoolPair& pools, upb::FileDefPtr file,
const Options& options, Plugin* plugin) { const Options& options, Plugin* plugin) {
Output h_output; Output h_output;
WriteHeader(pools, file, options, h_output); WriteHeader(pools, file, options, h_output);
plugin->AddOutputFile(CApiHeaderFilename(file), h_output.output()); plugin->AddOutputFile(CApiHeaderFilename(file, false), h_output.output());
if (options.bootstrap) { if (options.bootstrap_stage == 0) {
Output c_output; Output c_output;
WriteMiniDescriptorSource(pools, file, options, c_output); WriteMiniDescriptorSource(pools, file, options, c_output);
plugin->AddOutputFile(SourceFilename(file), c_output.output()); plugin->AddOutputFile(SourceFilename(file), c_output.output());
@ -1161,8 +1170,11 @@ void GenerateFile(const DefPoolPair& pools, upb::FileDefPtr file,
bool ParseOptions(Plugin* plugin, Options* options) { bool ParseOptions(Plugin* plugin, Options* options) {
for (const auto& pair : ParseGeneratorParameter(plugin->parameter())) { for (const auto& pair : ParseGeneratorParameter(plugin->parameter())) {
if (pair.first == "bootstrap_upb") { if (pair.first == "bootstrap_stage") {
options->bootstrap = true; if (!absl::SimpleAtoi(pair.second, &options->bootstrap_stage)) {
plugin->SetError(absl::Substitute("Bad stage: $0", pair.second));
return false;
}
} else if (pair.first == "experimental_strip_nonfunctional_codegen") { } else if (pair.first == "experimental_strip_nonfunctional_codegen") {
options->strip_nonfunctional_codegen = true; options->strip_nonfunctional_codegen = true;
} else { } else {

@ -35,8 +35,9 @@ absl::string_view ToStringView(upb_StringView str) {
void GenerateFile(const DefPoolPair& pools, upb::FileDefPtr file, void GenerateFile(const DefPoolPair& pools, upb::FileDefPtr file,
const MiniTableOptions& options, Plugin* plugin) { const MiniTableOptions& options, Plugin* plugin) {
Output h_output; Output h_output;
WriteMiniTableHeader(pools, file, h_output); WriteMiniTableHeader(pools, file, options, h_output);
plugin->AddOutputFile(MiniTableHeaderFilename(file), h_output.output()); plugin->AddOutputFile(MiniTableHeaderFilename(file, false),
h_output.output());
Output c_output; Output c_output;
WriteMiniTableSource(pools, file, options, c_output); WriteMiniTableSource(pools, file, options, c_output);
@ -49,7 +50,9 @@ void GenerateFile(const DefPoolPair& pools, upb::FileDefPtr file,
bool ParseOptions(MiniTableOptions* options, Plugin* plugin) { bool ParseOptions(MiniTableOptions* options, Plugin* plugin) {
for (const auto& pair : ParseGeneratorParameter(plugin->parameter())) { for (const auto& pair : ParseGeneratorParameter(plugin->parameter())) {
if (pair.first == "experimental_strip_nonfunctional_codegen") { if (pair.first == "bootstrap_stage") {
options->bootstrap = true;
} else if (pair.first == "experimental_strip_nonfunctional_codegen") {
options->strip_nonfunctional_codegen = true; options->strip_nonfunctional_codegen = true;
} else if (pair.first == "one_output_per_message") { } else if (pair.first == "one_output_per_message") {
options->one_output_per_message = true; options->one_output_per_message = true;

@ -488,7 +488,7 @@ void WriteExtension(const DefPoolPair& pools, upb::FieldDefPtr ext,
} // namespace } // namespace
void WriteMiniTableHeader(const DefPoolPair& pools, upb::FileDefPtr file, void WriteMiniTableHeader(const DefPoolPair& pools, upb::FileDefPtr file,
Output& output) { const MiniTableOptions& options, Output& output) {
EmitFileWarning(file.name(), output); EmitFileWarning(file.name(), output);
output( output(
"#ifndef $0_UPB_MINITABLE_H_\n" "#ifndef $0_UPB_MINITABLE_H_\n"
@ -500,8 +500,9 @@ void WriteMiniTableHeader(const DefPoolPair& pools, upb::FileDefPtr file,
if (i == 0) { if (i == 0) {
output("/* Public Imports. */\n"); output("/* Public Imports. */\n");
} }
output("#include \"$0\"\n", output(
MiniTableHeaderFilename(file.public_dependency(i))); "#include \"$0\"\n",
MiniTableHeaderFilename(file.public_dependency(i), options.bootstrap));
if (i == file.public_dependency_count() - 1) { if (i == file.public_dependency_count() - 1) {
output("\n"); output("\n");
} }
@ -560,7 +561,7 @@ void WriteMiniTableSourceIncludes(upb::FileDefPtr file,
"#include <stddef.h>\n" "#include <stddef.h>\n"
"#include \"upb/generated_code_support.h\"\n" "#include \"upb/generated_code_support.h\"\n"
"#include \"$0\"\n", "#include \"$0\"\n",
MiniTableHeaderFilename(file)); MiniTableHeaderFilename(file, options.bootstrap));
for (int i = 0; i < file.dependency_count(); i++) { for (int i = 0; i < file.dependency_count(); i++) {
if (options.strip_nonfunctional_codegen && if (options.strip_nonfunctional_codegen &&
@ -568,7 +569,8 @@ void WriteMiniTableSourceIncludes(upb::FileDefPtr file,
// Strip feature imports for editions codegen tests. // Strip feature imports for editions codegen tests.
continue; continue;
} }
output("#include \"$0\"\n", MiniTableHeaderFilename(file.dependency(i))); output("#include \"$0\"\n",
MiniTableHeaderFilename(file.dependency(i), options.bootstrap));
} }
output( output(

@ -25,6 +25,7 @@ namespace upb {
namespace generator { namespace generator {
struct MiniTableOptions { struct MiniTableOptions {
bool bootstrap = false;
bool one_output_per_message = false; bool one_output_per_message = false;
bool strip_nonfunctional_codegen = false; bool strip_nonfunctional_codegen = false;
}; };
@ -36,7 +37,7 @@ void WriteMiniTableMultipleSources(const DefPoolPair& pools,
const MiniTableOptions& options, const MiniTableOptions& options,
Plugin* plugin); Plugin* plugin);
void WriteMiniTableHeader(const DefPoolPair& pools, upb::FileDefPtr file, void WriteMiniTableHeader(const DefPoolPair& pools, upb::FileDefPtr file,
Output& output); const MiniTableOptions& options, Output& output);
} // namespace generator } // namespace generator
} // namespace upb } // namespace upb

@ -84,7 +84,7 @@ void WriteDefSource(upb::FileDefPtr file, const Options& options,
output("#include \"upb/reflection/def.h\"\n"); output("#include \"upb/reflection/def.h\"\n");
output("#include \"$0\"\n", DefHeaderFilename(file)); output("#include \"$0\"\n", DefHeaderFilename(file));
output("#include \"$0\"\n", MiniTableHeaderFilename(file)); output("#include \"$0\"\n", MiniTableHeaderFilename(file, false));
output("\n"); output("\n");
for (int i = 0; i < file.dependency_count(); i++) { for (int i = 0; i < file.dependency_count(); i++) {

@ -1,8 +1,8 @@
#include <stddef.h> #include <stddef.h>
#include "upb/generated_code_support.h" #include "upb/generated_code_support.h"
#include "google/protobuf/compiler/plugin.upb.h" #include "upb_generator/plugin_bootstrap.h"
#include "google/protobuf/descriptor.upb.h" #include "upb/reflection/descriptor_bootstrap.h"
static upb_Arena* upb_BootstrapArena() { static upb_Arena* upb_BootstrapArena() {
static upb_Arena* arena = NULL; static upb_Arena* arena = NULL;
if (!arena) arena = upb_Arena_New(); if (!arena) arena = upb_Arena_New();

Loading…
Cancel
Save