diff options
Diffstat (limited to 'src/google/protobuf/compiler/objectivec/objectivec_file.cc')
-rw-r--r-- | src/google/protobuf/compiler/objectivec/objectivec_file.cc | 171 |
1 files changed, 135 insertions, 36 deletions
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_file.cc b/src/google/protobuf/compiler/objectivec/objectivec_file.cc index ed4fc6a3..ccf5fbb4 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_file.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_file.cc @@ -50,6 +50,80 @@ const int32 GOOGLE_PROTOBUF_OBJC_GEN_VERSION = 30001; namespace compiler { namespace objectivec { +namespace { + +class ImportWriter { + public: + ImportWriter() {} + + void AddFile(const FileGenerator* file); + void Print(io::Printer *printer) const; + + private: + vector<string> protobuf_framework_imports_; + vector<string> protobuf_non_framework_imports_; + vector<string> other_imports_; +}; + +void ImportWriter::AddFile(const FileGenerator* file) { + const FileDescriptor* file_descriptor = file->Descriptor(); + const string extension(".pbobjc.h"); + if (IsProtobufLibraryBundledProtoFile(file_descriptor)) { + protobuf_framework_imports_.push_back( + FilePathBasename(file_descriptor) + extension); + protobuf_non_framework_imports_.push_back(file->Path() + extension); + } else { + other_imports_.push_back(file->Path() + extension); + } +} + +void ImportWriter::Print(io::Printer *printer) const { + assert(protobuf_non_framework_imports_.size() == + protobuf_framework_imports_.size()); + + if (protobuf_framework_imports_.size() > 0) { + const string framework_name(ProtobufLibraryFrameworkName); + const string cpp_symbol(ProtobufFrameworkImportSymbol(framework_name)); + + printer->Print( + "#if $cpp_symbol$\n", + "cpp_symbol", cpp_symbol); + for (vector<string>::const_iterator iter = protobuf_framework_imports_.begin(); + iter != protobuf_framework_imports_.end(); ++iter) { + printer->Print( + " #import <$framework_name$/$header$>\n", + "framework_name", framework_name, + "header", *iter); + } + printer->Print( + "#else\n"); + for (vector<string>::const_iterator iter = protobuf_non_framework_imports_.begin(); + iter != protobuf_non_framework_imports_.end(); ++iter) { + printer->Print( + " #import \"$header$\"\n", + "header", *iter); + } + printer->Print( + "#endif\n"); + + if (other_imports_.size() > 0) { + printer->Print("\n"); + } + } + + if (other_imports_.size() > 0) { + for (vector<string>::const_iterator iter = other_imports_.begin(); + iter != other_imports_.end(); ++iter) { + printer->Print( + " #import \"$header$\"\n", + "header", *iter); + } + } +} + +} // namespace + + FileGenerator::FileGenerator(const FileDescriptor *file, const Options& options) : file_(file), root_class_name_(FileClassName(file)), @@ -82,15 +156,7 @@ FileGenerator::~FileGenerator() { } void FileGenerator::GenerateHeader(io::Printer *printer) { - printer->Print( - "// Generated by the protocol buffer compiler. DO NOT EDIT!\n" - "// source: $filename$\n" - "\n", - "filename", file_->name()); - - printer->Print( - "#import \"GPBProtocolBuffers.h\"\n" - "\n"); + PrintFilePreamble(printer, "GPBProtocolBuffers.h"); // Add some verification that the generated code matches the source the // code is being compiled with. @@ -102,14 +168,18 @@ void FileGenerator::GenerateHeader(io::Printer *printer) { "protoc_gen_objc_version", SimpleItoa(GOOGLE_PROTOBUF_OBJC_GEN_VERSION)); - const vector<FileGenerator *> &dependency_generators = DependencyGenerators(); - for (vector<FileGenerator *>::const_iterator iter = - dependency_generators.begin(); - iter != dependency_generators.end(); ++iter) { - if ((*iter)->IsPublicDependency()) { - printer->Print("#import \"$header$.pbobjc.h\"\n", - "header", (*iter)->Path()); + // #import any headers for "public imports" in the proto file. + { + ImportWriter import_writer; + const vector<FileGenerator *> &dependency_generators = DependencyGenerators(); + for (vector<FileGenerator *>::const_iterator iter = + dependency_generators.begin(); + iter != dependency_generators.end(); ++iter) { + if ((*iter)->IsPublicDependency()) { + import_writer.AddFile(*iter); + } } + import_writer.Print(printer); } printer->Print( @@ -198,27 +268,30 @@ void FileGenerator::GenerateHeader(io::Printer *printer) { } void FileGenerator::GenerateSource(io::Printer *printer) { - printer->Print( - "// Generated by the protocol buffer compiler. DO NOT EDIT!\n" - "// source: $filename$\n" - "\n", - "filename", file_->name()); + // #import the runtime support. + PrintFilePreamble(printer, "GPBProtocolBuffers_RuntimeSupport.h"); - string header_file = Path() + ".pbobjc.h"; - printer->Print( - "#import \"GPBProtocolBuffers_RuntimeSupport.h\"\n" - "#import \"$header_file$\"\n", - "header_file", header_file); - const vector<FileGenerator *> &dependency_generators = - DependencyGenerators(); - for (vector<FileGenerator *>::const_iterator iter = - dependency_generators.begin(); - iter != dependency_generators.end(); ++iter) { - if (!(*iter)->IsPublicDependency()) { - printer->Print("#import \"$header$.pbobjc.h\"\n", - "header", (*iter)->Path()); + { + ImportWriter import_writer; + + // #import the header for this proto file. + import_writer.AddFile(this); + + // #import the headers for anything that a plain dependency of this proto + // file (that means they were just an include, not a "public" include). + const vector<FileGenerator *> &dependency_generators = + DependencyGenerators(); + for (vector<FileGenerator *>::const_iterator iter = + dependency_generators.begin(); + iter != dependency_generators.end(); ++iter) { + if (!(*iter)->IsPublicDependency()) { + import_writer.AddFile(*iter); + } } + + import_writer.Print(printer); } + printer->Print( "// @@protoc_insertion_point(imports)\n" "\n" @@ -356,8 +429,6 @@ void FileGenerator::GenerateSource(io::Printer *printer) { "// @@protoc_insertion_point(global_scope)\n"); } -const string FileGenerator::Path() const { return FilePath(file_); } - const vector<FileGenerator *> &FileGenerator::DependencyGenerators() { if (file_->dependency_count() != dependency_generators_.size()) { set<string> public_import_names; @@ -376,6 +447,34 @@ const vector<FileGenerator *> &FileGenerator::DependencyGenerators() { return dependency_generators_; } +void FileGenerator::PrintFilePreamble( + io::Printer* printer, const string& header_to_import) const { + printer->Print( + "// Generated by the protocol buffer compiler. DO NOT EDIT!\n" + "// source: $filename$\n" + "\n", + "filename", file_->name()); + + const string framework_name(ProtobufLibraryFrameworkName); + const string cpp_symbol(ProtobufFrameworkImportSymbol(framework_name)); + printer->Print( + "// 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" + "#if $cpp_symbol$\n" + " #import <$framework_name$/$header$>\n" + "#else\n" + " #import \"$header$\"\n" + "#endif\n" + "\n", + "cpp_symbol", cpp_symbol, + "header", header_to_import, + "framework_name", framework_name); +} + } // namespace objectivec } // namespace compiler } // namespace protobuf |