Commit 78a6d310 authored by Thomas Van Lenten's avatar Thomas Van Lenten

Speed up ObjC Generation with large dependency trees

Don't create FileGenerators for each dep. FileGenerators will deeply create all
the message, enum, and field generators; but those aren't needed when doing
the imports for dependencies. Instead directly generate the imports off the
FileDescriptors so no extra objects are created. The only other use was when
chaining together the *Roots for the file extension registry, but that also
can be generate off the name of the FileDescriptor directly.
parent e721ce66
......@@ -59,7 +59,6 @@ namespace objectivec {
FileGenerator::FileGenerator(const FileDescriptor *file, const Options& options)
: file_(file),
root_class_name_(FileClassName(file)),
is_public_dep_(false),
options_(options) {
for (int i = 0; i < file_->enum_type_count(); i++) {
EnumGenerator *generator = new EnumGenerator(file_->enum_type(i));
......@@ -78,8 +77,6 @@ FileGenerator::FileGenerator(const FileDescriptor *file, const Options& options)
}
FileGenerator::~FileGenerator() {
STLDeleteContainerPointers(dependency_generators_.begin(),
dependency_generators_.end());
STLDeleteContainerPointers(enum_generators_.begin(), enum_generators_.end());
STLDeleteContainerPointers(message_generators_.begin(),
message_generators_.end());
......@@ -105,14 +102,9 @@ void FileGenerator::GenerateHeader(io::Printer *printer) {
ImportWriter import_writer(
options_.generate_for_named_framework,
options_.named_framework_to_proto_path_mappings_path);
const vector<FileGenerator *> &dependency_generators = DependencyGenerators();
const string header_extension(kHeaderExtension);
for (vector<FileGenerator *>::const_iterator iter =
dependency_generators.begin();
iter != dependency_generators.end(); ++iter) {
if ((*iter)->IsPublicDependency()) {
import_writer.AddFile((*iter)->file_, header_extension);
}
for (int i = 0; i < file_->public_dependency_count(); i++) {
import_writer.AddFile(file_->public_dependency(i), header_extension);
}
import_writer.Print(printer);
}
......@@ -223,13 +215,15 @@ void FileGenerator::GenerateSource(io::Printer *printer) {
// #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)->file_, header_extension);
set<string> public_import_names;
for (int i = 0; i < file_->public_dependency_count(); i++) {
public_import_names.insert(file_->public_dependency(i)->name());
}
for (int i = 0; i < file_->dependency_count(); i++) {
const FileDescriptor *dep = file_->dependency(i);
bool public_import = (public_import_names.count(dep->name()) != 0);
if (!public_import) {
import_writer.AddFile(dep, header_extension);
}
}
......@@ -321,14 +315,11 @@ void FileGenerator::GenerateSource(io::Printer *printer) {
"}\n");
}
const vector<FileGenerator *> &dependency_generators =
DependencyGenerators();
for (vector<FileGenerator *>::const_iterator iter =
dependency_generators.begin();
iter != dependency_generators.end(); ++iter) {
for (int i = 0; i < file_->dependency_count(); i++) {
const string root_class_name(FileClassName(file_->dependency(i)));
printer->Print(
"[registry addExtensions:[$dependency$ extensionRegistry]];\n",
"dependency", (*iter)->RootClassName());
"dependency", root_class_name);
}
printer->Outdent();
......@@ -393,24 +384,6 @@ void FileGenerator::GenerateSource(io::Printer *printer) {
"// @@protoc_insertion_point(global_scope)\n");
}
const vector<FileGenerator *> &FileGenerator::DependencyGenerators() {
if (file_->dependency_count() != dependency_generators_.size()) {
set<string> public_import_names;
for (int i = 0; i < file_->public_dependency_count(); i++) {
public_import_names.insert(file_->public_dependency(i)->name());
}
for (int i = 0; i < file_->dependency_count(); i++) {
FileGenerator *generator =
new FileGenerator(file_->dependency(i), options_);
const string& name = file_->dependency(i)->name();
bool public_import = (public_import_names.count(name) != 0);
generator->SetIsPublicDependency(public_import);
dependency_generators_.push_back(generator);
}
}
return dependency_generators_;
}
// Helper to print the import of the runtime support at the top of generated
// files. This currently only supports the runtime coming from a framework
// as defined by the official CocoaPod.
......
......@@ -63,29 +63,16 @@ class FileGenerator {
const string& RootClassName() const { return root_class_name_; }
bool IsPublicDependency() const { return is_public_dep_; }
protected:
void SetIsPublicDependency(bool is_public_dep) {
is_public_dep_ = is_public_dep;
}
private:
const FileDescriptor* file_;
string root_class_name_;
// Access this field through the DependencyGenerators accessor call below.
// Do not reference it directly.
vector<FileGenerator*> dependency_generators_;
vector<EnumGenerator*> enum_generators_;
vector<MessageGenerator*> message_generators_;
vector<ExtensionGenerator*> extension_generators_;
bool is_public_dep_;
const Options options_;
const vector<FileGenerator*>& DependencyGenerators();
void PrintFileRuntimePreamble(
io::Printer* printer, const string& header_to_import) const;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment