Separate MiniTable code generator into a separate library target.

This will allow it to be linked into other code generators.

PiperOrigin-RevId: 599171495
pull/15460/head
Joshua Haberman 2024-01-17 07:48:21 -08:00 committed by Copybara-Service
parent 12e6af88e9
commit 50d0421170
5 changed files with 201 additions and 122 deletions

View File

@ -287,9 +287,10 @@ proto_lang_toolchain(
visibility = ["//visibility:public"],
)
bootstrap_cc_binary(
name = "protoc-gen-upb_minitable",
bootstrap_cc_library(
name = "protoc-gen-upb_minitable_lib",
srcs = ["protoc-gen-upb_minitable.cc"],
hdrs = ["protoc-gen-upb_minitable.h"],
bootstrap_deps = [
":common",
":file_layout",
@ -300,7 +301,7 @@ bootstrap_cc_binary(
"//upb/reflection:reflection",
],
copts = UPB_DEFAULT_CPPOPTS,
visibility = ["//visibility:public"],
visibility = ["//upb:friends"],
deps = [
"//upb:base",
"//upb:mem",
@ -315,6 +316,25 @@ bootstrap_cc_binary(
],
)
bootstrap_cc_binary(
name = "protoc-gen-upb_minitable",
srcs = ["protoc-gen-upb_minitable-main.cc"],
bootstrap_deps = [
":file_layout",
":common",
":plugin",
":protoc-gen-upb_minitable_lib",
],
copts = UPB_DEFAULT_CPPOPTS,
visibility = ["//visibility:public"],
deps = [
"//upb:base",
"//upb:port",
"@com_google_absl//absl/log:absl_check",
"@com_google_absl//absl/log:absl_log",
],
)
proto_lang_toolchain(
name = "protoc-gen-upb_minitable_toolchain",
command_line = "--upb_minitable_out=$(OUT)",

View File

@ -26,7 +26,7 @@ _extra_proto_path = "-I$$(dirname $(location @com_google_protobuf//:descriptor_p
def _upbc(generator, stage):
return _upbc_base + generator + _stages[stage]
def bootstrap_cc_library(name, visibility, deps, bootstrap_deps, **kwargs):
def bootstrap_cc_library(name, visibility, deps = [], bootstrap_deps = [], **kwargs):
for stage in _stages:
stage_visibility = visibility if stage == "" else ["//upb_generator:__pkg__"]
native.cc_library(
@ -36,7 +36,7 @@ def bootstrap_cc_library(name, visibility, deps, bootstrap_deps, **kwargs):
**kwargs
)
def bootstrap_cc_binary(name, deps, bootstrap_deps, **kwargs):
def bootstrap_cc_binary(name, deps = [], bootstrap_deps = [], **kwargs):
for stage in _stages:
native.cc_binary(
name = name + stage,

View File

@ -0,0 +1,78 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2023 Google LLC. 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 <string>
#include <vector>
#include "absl/log/absl_log.h"
#include "upb/base/status.hpp"
#include "upb/base/string_view.h"
#include "upb_generator/common.h"
#include "upb_generator/file_layout.h"
#include "upb_generator/plugin.h"
#include "upb_generator/protoc-gen-upb_minitable.h"
// Must be last.
#include "upb/port/def.inc"
namespace upb {
namespace generator {
std::string SourceFilename(upb::FileDefPtr file) {
return StripExtension(file.name()) + ".upb_minitable.c";
}
absl::string_view ToStringView(upb_StringView str) {
return absl::string_view(str.data, str.size);
}
void GenerateFile(const DefPoolPair& pools, upb::FileDefPtr file,
Plugin* plugin) {
Output h_output;
WriteMiniTableHeader(pools, file, h_output);
plugin->AddOutputFile(MiniTableHeaderFilename(file), h_output.output());
Output c_output;
WriteMiniTableSource(pools, file, c_output);
plugin->AddOutputFile(SourceFilename(file), c_output.output());
}
bool ParseOptions(Plugin* plugin) {
const auto param = ParseGeneratorParameter(plugin->parameter());
if (!param.empty()) {
plugin->SetError(absl::Substitute("Unknown parameter: $0", param[0].first));
return false;
}
return true;
}
int PluginMain(int argc, char** argv) {
DefPoolPair pools;
Plugin plugin;
if (!ParseOptions(&plugin)) return 0;
plugin.GenerateFilesRaw(
[&](const UPB_DESC(FileDescriptorProto) * file_proto, bool generate) {
upb::Status status;
upb::FileDefPtr file = pools.AddFile(file_proto, &status);
if (!file) {
absl::string_view name =
ToStringView(UPB_DESC(FileDescriptorProto_name)(file_proto));
ABSL_LOG(FATAL) << "Couldn't add file " << name
<< " to DefPool: " << status.error_message();
}
if (generate) GenerateFile(pools, file, &plugin);
});
return 0;
}
} // namespace generator
} // namespace upb
int main(int argc, char** argv) {
return upb::generator::PluginMain(argc, argv);
}

View File

@ -18,13 +18,10 @@
#include <vector>
#include "absl/log/absl_check.h"
#include "absl/log/absl_log.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "absl/strings/substitute.h"
#include "upb/base/descriptor_constants.h"
#include "upb/base/status.hpp"
#include "upb/base/string_view.h"
#include "upb/mini_table/enum.h"
#include "upb/mini_table/field.h"
#include "upb/mini_table/message.h"
@ -32,7 +29,6 @@
#include "upb/wire/types.h"
#include "upb_generator/common.h"
#include "upb_generator/file_layout.h"
#include "upb_generator/plugin.h"
// Must be last.
#include "upb/port/def.inc"
@ -60,10 +56,6 @@ inline std::vector<upb::FieldDefPtr> FieldHotnessOrder(
return fields;
}
std::string SourceFilename(upb::FileDefPtr file) {
return StripExtension(file.name()) + ".upb_minitable.c";
}
std::string ExtensionIdentBase(upb::FieldDefPtr ext) {
UPB_ASSERT(ext.is_extension());
std::string ext_scope;
@ -82,69 +74,6 @@ const char* kEnumsInit = "enums_layout";
const char* kExtensionsInit = "extensions_layout";
const char* kMessagesInit = "messages_layout";
void WriteHeader(const DefPoolPair& pools, upb::FileDefPtr file,
Output& output) {
EmitFileWarning(file.name(), output);
output(
"#ifndef $0_UPB_MINITABLE_H_\n"
"#define $0_UPB_MINITABLE_H_\n\n"
"#include \"upb/generated_code_support.h\"\n",
ToPreproc(file.name()));
for (int i = 0; i < file.public_dependency_count(); i++) {
if (i == 0) {
output("/* Public Imports. */\n");
}
output("#include \"$0\"\n",
MiniTableHeaderFilename(file.public_dependency(i)));
if (i == file.public_dependency_count() - 1) {
output("\n");
}
}
output(
"\n"
"// Must be last.\n"
"#include \"upb/port/def.inc\"\n"
"\n"
"#ifdef __cplusplus\n"
"extern \"C\" {\n"
"#endif\n"
"\n");
const std::vector<upb::MessageDefPtr> this_file_messages =
SortedMessages(file);
const std::vector<upb::FieldDefPtr> this_file_exts = SortedExtensions(file);
for (auto message : this_file_messages) {
output("extern const upb_MiniTable $0;\n", MessageInitName(message));
}
for (auto ext : this_file_exts) {
output("extern const upb_MiniTableExtension $0;\n", ExtensionLayout(ext));
}
output("\n");
std::vector<upb::EnumDefPtr> this_file_enums =
SortedEnums(file, kClosedEnums);
for (const auto enumdesc : this_file_enums) {
output("extern const upb_MiniTableEnum $0;\n", EnumInit(enumdesc));
}
output("extern const upb_MiniTableFile $0;\n\n", FileLayoutName(file));
output(
"#ifdef __cplusplus\n"
"} /* extern \"C\" */\n"
"#endif\n"
"\n"
"#include \"upb/port/undef.inc\"\n"
"\n"
"#endif /* $0_UPB_MINITABLE_H_ */\n",
ToPreproc(file.name()));
}
typedef std::pair<std::string, uint64_t> TableEntry;
uint32_t GetWireTypeForField(upb::FieldDefPtr field) {
@ -598,6 +527,71 @@ int WriteExtensions(const DefPoolPair& pools, upb::FileDefPtr file,
return exts.size();
}
} // namespace
void WriteMiniTableHeader(const DefPoolPair& pools, upb::FileDefPtr file,
Output& output) {
EmitFileWarning(file.name(), output);
output(
"#ifndef $0_UPB_MINITABLE_H_\n"
"#define $0_UPB_MINITABLE_H_\n\n"
"#include \"upb/generated_code_support.h\"\n",
ToPreproc(file.name()));
for (int i = 0; i < file.public_dependency_count(); i++) {
if (i == 0) {
output("/* Public Imports. */\n");
}
output("#include \"$0\"\n",
MiniTableHeaderFilename(file.public_dependency(i)));
if (i == file.public_dependency_count() - 1) {
output("\n");
}
}
output(
"\n"
"// Must be last.\n"
"#include \"upb/port/def.inc\"\n"
"\n"
"#ifdef __cplusplus\n"
"extern \"C\" {\n"
"#endif\n"
"\n");
const std::vector<upb::MessageDefPtr> this_file_messages =
SortedMessages(file);
const std::vector<upb::FieldDefPtr> this_file_exts = SortedExtensions(file);
for (auto message : this_file_messages) {
output("extern const upb_MiniTable $0;\n", MessageInitName(message));
}
for (auto ext : this_file_exts) {
output("extern const upb_MiniTableExtension $0;\n", ExtensionLayout(ext));
}
output("\n");
std::vector<upb::EnumDefPtr> this_file_enums =
SortedEnums(file, kClosedEnums);
for (const auto enumdesc : this_file_enums) {
output("extern const upb_MiniTableEnum $0;\n", EnumInit(enumdesc));
}
output("extern const upb_MiniTableFile $0;\n\n", FileLayoutName(file));
output(
"#ifdef __cplusplus\n"
"} /* extern \"C\" */\n"
"#endif\n"
"\n"
"#include \"upb/port/undef.inc\"\n"
"\n"
"#endif /* $0_UPB_MINITABLE_H_ */\n",
ToPreproc(file.name()));
}
void WriteMiniTableSource(const DefPoolPair& pools, upb::FileDefPtr file,
Output& output) {
EmitFileWarning(file.name(), output);
@ -635,51 +629,5 @@ void WriteMiniTableSource(const DefPoolPair& pools, upb::FileDefPtr file,
output("\n");
}
void GenerateFile(const DefPoolPair& pools, upb::FileDefPtr file,
Plugin* plugin) {
Output h_output;
WriteHeader(pools, file, h_output);
plugin->AddOutputFile(MiniTableHeaderFilename(file), h_output.output());
Output c_output;
WriteMiniTableSource(pools, file, c_output);
plugin->AddOutputFile(SourceFilename(file), c_output.output());
}
bool ParseOptions(Plugin* plugin) {
const auto param = ParseGeneratorParameter(plugin->parameter());
if (!param.empty()) {
plugin->SetError(absl::Substitute("Unknown parameter: $0", param[0].first));
return false;
}
return true;
}
absl::string_view ToStringView(upb_StringView str) {
return absl::string_view(str.data, str.size);
}
} // namespace
} // namespace generator
} // namespace upb
int main(int argc, char** argv) {
upb::generator::DefPoolPair pools;
upb::generator::Plugin plugin;
if (!upb::generator::ParseOptions(&plugin)) return 0;
plugin.GenerateFilesRaw([&](const UPB_DESC(FileDescriptorProto) * file_proto,
bool generate) {
upb::Status status;
upb::FileDefPtr file = pools.AddFile(file_proto, &status);
if (!file) {
absl::string_view name = upb::generator::ToStringView(
UPB_DESC(FileDescriptorProto_name)(file_proto));
ABSL_LOG(FATAL) << "Couldn't add file " << name
<< " to DefPool: " << status.error_message();
}
if (generate) upb::generator::GenerateFile(pools, file, &plugin);
});
return 0;
}

View File

@ -0,0 +1,33 @@
// Protocol Buffers - Google's data interchange format
// Copyright 2023 Google LLC. 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 <string.h>
#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <map>
#include <string>
#include <utility>
#include <vector>
#include "upb_generator/common.h"
#include "upb_generator/file_layout.h"
#include "upb_generator/plugin.h"
namespace upb {
namespace generator {
void WriteMiniTableSource(const DefPoolPair& pools, upb::FileDefPtr file,
Output& output);
void WriteMiniTableHeader(const DefPoolPair& pools, upb::FileDefPtr file,
Output& output);
} // namespace generator
} // namespace upb