Start conversion to use Printer::Emit()

Move ImportWriter over and some of FileGenerator.

PiperOrigin-RevId: 544690162
pull/13189/head
Thomas Van Lenten 2 years ago committed by Copybara-Service
parent d063281036
commit 70b0769073
  1. 238
      src/google/protobuf/compiler/objectivec/file.cc
  2. 105
      src/google/protobuf/compiler/objectivec/import_writer.cc

@ -32,10 +32,8 @@
#include <algorithm>
#include <functional>
#include <iostream>
#include <iterator>
#include <memory>
#include <sstream>
#include <string>
#include <vector>
@ -50,12 +48,10 @@
#include "google/protobuf/compiler/objectivec/message.h"
#include "google/protobuf/compiler/objectivec/names.h"
#include "google/protobuf/descriptor.h"
#include "google/protobuf/descriptor.pb.h"
#include "google/protobuf/descriptor_legacy.h"
#include "google/protobuf/io/printer.h"
// NOTE: src/google/protobuf/compiler/plugin.cc makes use of cerr for some
// error cases, so it seems to be ok to use as a back door for errors.
namespace google {
namespace protobuf {
namespace compiler {
@ -130,6 +126,23 @@ void MakeDescriptors(
}
}
void EmitSourceFwdDecls(const absl::btree_set<std::string>& fwd_decls,
io::Printer* p) {
if (fwd_decls.empty()) {
return;
}
p->Emit({{"fwd_decls", absl::StrJoin(fwd_decls, "\n")}},
R"objc(
#pragma mark - Objective-C Class declarations
// Forward declarations of Objective-C classes that we can use as
// static values in struct initializers.
// We don't use [Foo class] because it is not a static value.
$fwd_decls$
)objc");
p->Emit("\n");
}
} // namespace
const FileGenerator::CommonState::MinDepsEntry&
@ -354,19 +367,7 @@ void FileGenerator::GenerateSource(io::Printer* p) const {
}
GenerateFile(p, GeneratedFileType::kSource, file_options, [&] {
if (!fwd_decls.empty()) {
p->Print(
// clang-format off
"#pragma mark - Objective-C Class declarations\n"
"// Forward declarations of Objective-C classes that we can use as\n"
"// static values in struct initializers.\n"
"// We don't use [Foo class] because it is not a static value.\n"
"$fwd_decls$\n"
"\n",
// clang-format on
"fwd_decls", absl::StrJoin(fwd_decls, "\n"));
}
EmitSourceFwdDecls(fwd_decls, p);
PrintRootImplementation(p, deps_with_extensions);
PrintFileDescription(p);
@ -404,19 +405,7 @@ void FileGenerator::GenerateGlobalSource(io::Printer* p) const {
}
GenerateFile(p, GeneratedFileType::kSource, file_options, [&] {
if (!fwd_decls.empty()) {
p->Print(
// clang-format off
"#pragma mark - Objective-C Class declarations\n"
"// Forward declarations of Objective-C classes that we can use as\n"
"// static values in struct initializers.\n"
"// We don't use [Foo class] because it is not a static value.\n"
"$fwd_decls$\n"
"\n",
// clang-format on
"fwd_decls", absl::StrJoin(fwd_decls, "\n"));
}
EmitSourceFwdDecls(fwd_decls, p);
PrintRootImplementation(p, deps_with_extensions);
});
}
@ -448,19 +437,7 @@ void FileGenerator::GenerateSourceForMessage(int idx, io::Printer* p) const {
}
GenerateFile(p, GeneratedFileType::kSource, file_options, [&] {
if (!fwd_decls.empty()) {
p->Print(
// clang-format off
"#pragma mark - Objective-C Class declarations\n"
"// Forward declarations of Objective-C classes that we can use as\n"
"// static values in struct initializers.\n"
"// We don't use [Foo class] because it is not a static value.\n"
"$fwd_decls$\n"
"\n",
// clang-format on
"fwd_decls", absl::StrJoin(fwd_decls, "\n"));
}
EmitSourceFwdDecls(fwd_decls, p);
PrintFileDescription(p);
generator->GenerateSource(p);
});
@ -523,69 +500,84 @@ void FileGenerator::GenerateFile(io::Printer* p, GeneratedFileType file_type,
import_writer.AddFile(dep, header_extension);
}
p->Print(
"// Generated by the protocol buffer compiler. DO NOT EDIT!\n"
"// $clangfmt$ off\n"
"// source: $filename$\n"
"\n",
"filename", file_->name(), "clangfmt", "clang-format");
import_writer.PrintRuntimeImports(
p, /* default_cpp_symbol = */ !is_bundled_proto_);
// Some things for all Emit() calls to have access too.
auto vars = p->WithVars({
{// Avoid the directive within the template strings as the tool would
// then honor the directives within the generators sources.
"clangfmt", "clang-format"},
{"root_class_name", root_class_name_},
});
p->Print("\n");
p->Emit(
{
{"filename", file_->name()},
{"google_protobuf_objc_version", GOOGLE_PROTOBUF_OBJC_VERSION},
{"runtime_imports",
[&] {
import_writer.PrintRuntimeImports(
p, /* default_cpp_symbol = */ !is_bundled_proto_);
}},
{"extra_system_imports",
[&] {
if (file_options.extra_system_headers.empty()) {
return;
}
for (const auto& system_header :
file_options.extra_system_headers) {
p->Emit({{"header", system_header}},
R"objc(
#import <$header$>
)objc");
}
p->Emit("\n");
}},
{"file_imports", [&] { import_writer.PrintFileImports(p); }},
{"extra_warnings",
[&] {
for (const auto& warning : file_options.ignored_warnings) {
p->Emit({{"warning", warning}},
R"objc(
#pragma clang diagnostic ignored "-W$warning$"
)objc");
}
}},
},
R"objc(
// Generated by the protocol buffer compiler. DO NOT EDIT!
// $clangfmt$ off
// source: $filename$
$runtime_imports$
#if GOOGLE_PROTOBUF_OBJC_VERSION < $google_protobuf_objc_version$
#error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources.
#endif
#if $google_protobuf_objc_version$ < GOOGLE_PROTOBUF_OBJC_MIN_SUPPORTED_VERSION
#error This file was generated by an older version of protoc which is incompatible with your Protocol Buffer library sources.
#endif
$extra_system_imports$
$file_imports$
// @@protoc_insertion_point(imports)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
$extra_warnings$
)objc");
p->Emit("\n");
// Add some verification that the generated code matches the source the
// code is being compiled with.
// NOTE: This captures the raw numeric values at the time the generator was
// compiled, since that will be the versions for the ObjC runtime at that
// time. The constants in the generated code will then get their values at
// compile time (so checking against the headers being used to compile).
p->Print(
// clang-format off
"#if GOOGLE_PROTOBUF_OBJC_VERSION < $google_protobuf_objc_version$\n"
"#error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources.\n"
"#endif\n"
"#if $google_protobuf_objc_version$ < GOOGLE_PROTOBUF_OBJC_MIN_SUPPORTED_VERSION\n"
"#error This file was generated by an older version of protoc which is incompatible with your Protocol Buffer library sources.\n"
"#endif\n"
"\n",
// clang-format on
"google_protobuf_objc_version",
absl::StrCat(GOOGLE_PROTOBUF_OBJC_VERSION));
if (!file_options.extra_system_headers.empty()) {
for (const auto& system_header : file_options.extra_system_headers) {
p->Print("#import <$header$>\n", "header", system_header);
}
p->Print("\n");
}
body();
import_writer.PrintFileImports(p);
p->Emit("\n");
// clang-format off
p->Print(
"// @@protoc_insertion_point(imports)\n"
"\n"
"#pragma clang diagnostic push\n"
"#pragma clang diagnostic ignored \"-Wdeprecated-declarations\"\n");
// clang-format on
for (const auto& warning : file_options.ignored_warnings) {
p->Print("#pragma clang diagnostic ignored \"-W$warning$\"\n", "warning",
warning);
}
p->Print("\n");
p->Emit(R"objc(
#pragma clang diagnostic pop
body();
// @@protoc_insertion_point(global_scope)
p->Print(
"\n"
"#pragma clang diagnostic pop\n"
"\n"
"// @@protoc_insertion_point(global_scope)\n"
"\n"
"// $clangfmt$ on\n",
"clangfmt", "clang-format");
// $clangfmt$ on
)objc");
}
void FileGenerator::PrintRootImplementation(
@ -697,38 +689,36 @@ void FileGenerator::PrintFileDescription(io::Printer* p) const {
}
const std::string objc_prefix(FileClassPrefix(file_));
absl::flat_hash_map<absl::string_view, std::string> vars;
vars["file_description_name"] = file_description_name_;
vars["package_value"] = file_->package().empty()
? "NULL"
: absl::StrCat("\"", file_->package(), "\"");
std::string syntax;
switch (FileDescriptorLegacy(file_).syntax()) {
case FileDescriptorLegacy::Syntax::SYNTAX_UNKNOWN:
vars["syntax"] = "GPBFileSyntaxUnknown";
syntax = "GPBFileSyntaxUnknown";
break;
case FileDescriptorLegacy::Syntax::SYNTAX_PROTO2:
vars["syntax"] = "GPBFileSyntaxProto2";
syntax = "GPBFileSyntaxProto2";
break;
case FileDescriptorLegacy::Syntax::SYNTAX_PROTO3:
vars["syntax"] = "GPBFileSyntaxProto3";
syntax = "GPBFileSyntaxProto3";
break;
}
if (objc_prefix.empty() && !file_->options().has_objc_class_prefix()) {
vars["prefix_value"] = "NULL";
} else {
vars["prefix_value"] = absl::StrCat("\"", objc_prefix, "\"");
}
// clang-format off
p->Print(
vars,
"static GPBFileDescription $file_description_name$ = {\n"
" .package = $package_value$,\n"
" .prefix = $prefix_value$,\n"
" .syntax = $syntax$\n"
"};\n"
"\n");
// clang-format on
p->Emit({{"file_description_name", file_description_name_},
{"package_value", file_->package().empty()
? "NULL"
: absl::StrCat("\"", file_->package(), "\"")},
{"prefix_value",
objc_prefix.empty() && !file_->options().has_objc_class_prefix()
? "NULL"
: absl::StrCat("\"", objc_prefix, "\"")},
{"syntax", syntax}},
R"objc(
static GPBFileDescription $file_description_name$ = {
.package = $package_value$,
.prefix = $prefix_value$,
.syntax = $syntax$
};
)objc");
p->Emit("\n");
}
} // namespace objectivec

@ -180,20 +180,18 @@ std::string ImportWriter::ModuleForFile(const FileDescriptor* file) {
}
void ImportWriter::PrintFileImports(io::Printer* p) const {
if (!other_framework_imports_.empty()) {
for (const auto& header : other_framework_imports_) {
p->Print("#import <$header$>\n", "header", header);
}
for (const auto& header : other_framework_imports_) {
p->Emit({{"header", header}},
R"objc(
#import <$header$>
)objc");
}
if (!other_imports_.empty()) {
if (!other_framework_imports_.empty()) {
p->Print("\n");
}
for (const auto& header : other_imports_) {
p->Print("#import \"$header$\"\n", "header", header);
}
for (const auto& header : other_imports_) {
p->Emit({{"header", header}},
R"objc(
#import "$header$"
)objc");
}
}
@ -202,8 +200,10 @@ void ImportWriter::PrintRuntimeImports(io::Printer* p,
// Given an override, use that.
if (!runtime_import_prefix_.empty()) {
for (const auto& header : protobuf_imports_) {
p->Print("#import \"$import_prefix$/$header$\"\n", "header", header,
"import_prefix", runtime_import_prefix_);
p->Emit({{"import_prefix", runtime_import_prefix_}, {"header", header}},
R"objc(
#import "$import_prefix$/$header$"
)objc");
}
return;
}
@ -212,37 +212,60 @@ void ImportWriter::PrintRuntimeImports(io::Printer* p,
if (for_bundled_proto_) {
ABSL_DCHECK(!default_cpp_symbol);
for (const auto& header : protobuf_imports_) {
p->Print("#import \"$header$\"\n", "header", header);
p->Emit({{"header", header}},
R"objc(
#import "$header$"
)objc");
}
return;
}
const std::string cpp_symbol(
ProtobufFrameworkImportSymbol(ProtobufLibraryFrameworkName));
if (default_cpp_symbol) {
p->Print(
// clang-format off
"// This CPP symbol can be defined to use imports that match up to the framework\n"
"// imports needed when using CocoaPods.\n"
"#if !defined($cpp_symbol$)\n"
" #define $cpp_symbol$ 0\n"
"#endif\n"
"\n",
// clang-format on
"cpp_symbol", cpp_symbol);
}
p->Print("#if $cpp_symbol$\n", "cpp_symbol", cpp_symbol);
for (const auto& header : protobuf_imports_) {
p->Print(" #import <$framework_name$/$header$>\n", "framework_name",
ProtobufLibraryFrameworkName, "header", header);
}
p->Print("#else\n");
for (const auto& header : protobuf_imports_) {
p->Print(" #import \"$header$\"\n", "header", header);
}
p->Print("#endif\n");
p->Emit(
{
{"cpp_symbol",
ProtobufFrameworkImportSymbol(ProtobufLibraryFrameworkName)},
{"maybe_default_cpp_symbol",
[&] {
if (default_cpp_symbol) {
p->Emit(
R"objc(
// This CPP symbol can be defined to use imports that match up to the framework
// imports needed when using CocoaPods.
#if !defined($cpp_symbol$)
#define $cpp_symbol$ 0
#endif
)objc");
}
}},
{"framework_name", ProtobufLibraryFrameworkName},
{"framework_imports",
[&] {
for (const auto& header : protobuf_imports_) {
p->Emit({{"header", header}},
R"objc(
#import <$framework_name$/$header$>
)objc");
}
}},
{"raw_imports",
[&] {
for (const auto& header : protobuf_imports_) {
p->Emit({{"header", header}},
R"objc(
#import "$header$"
)objc");
}
}},
},
R"objc(
$maybe_default_cpp_symbol$
#if $cpp_symbol$
$framework_imports$
#else
$raw_imports$
#endif
)objc");
}
void ImportWriter::ParseFrameworkMappings() {

Loading…
Cancel
Save