|
|
|
@ -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
|
|
|
|
|