From 2e66a61b540b7858c1cd1910c5efa58d72907b54 Mon Sep 17 00:00:00 2001 From: Thomas Van Lenten Date: Wed, 24 Aug 2016 17:29:05 -0400 Subject: Support GenerateAll(). - Expect calls on GenerateAll() and not Generate(). - Parse the prefix validation file once, and then check all the files. --- objectivec/DevTools/compile_testing_protos.sh | 26 +++++----- .../compiler/objectivec/objectivec_generator.cc | 51 +++++++++++++------- .../compiler/objectivec/objectivec_generator.h | 11 ++++- .../compiler/objectivec/objectivec_helpers.cc | 56 ++++++++++++++-------- .../compiler/objectivec/objectivec_helpers.h | 12 ++--- 5 files changed, 98 insertions(+), 58 deletions(-) diff --git a/objectivec/DevTools/compile_testing_protos.sh b/objectivec/DevTools/compile_testing_protos.sh index 82953130..9a6b7bf2 100755 --- a/objectivec/DevTools/compile_testing_protos.sh +++ b/objectivec/DevTools/compile_testing_protos.sh @@ -99,26 +99,26 @@ CORE_PROTO_FILES+=( src/google/protobuf/descriptor.proto ) -compile_proto() { +compile_protos() { src/protoc \ --objc_out="${OUTPUT_DIR}/google/protobuf" \ --proto_path=src/google/protobuf/ \ --proto_path=src \ - $* + "$@" } +# Note: there is overlap in package.Message names between some of the test +# files, so they can't be generated all at once. This works because the overlap +# isn't linked into a single binary. for a_proto in "${CORE_PROTO_FILES[@]}" ; do - compile_proto "${a_proto}" + compile_protos "${a_proto}" done -OBJC_PROTO_FILES=( - objectivec/Tests/unittest_cycle.proto - objectivec/Tests/unittest_runtime_proto2.proto - objectivec/Tests/unittest_runtime_proto3.proto - objectivec/Tests/unittest_objc.proto +# Objective C specific testing protos. +compile_protos \ + --proto_path="objectivec/Tests" \ + objectivec/Tests/unittest_cycle.proto \ + objectivec/Tests/unittest_runtime_proto2.proto \ + objectivec/Tests/unittest_runtime_proto3.proto \ + objectivec/Tests/unittest_objc.proto \ objectivec/Tests/unittest_objc_startup.proto -) - -for a_proto in "${OBJC_PROTO_FILES[@]}" ; do - compile_proto --proto_path="objectivec/Tests" "${a_proto}" -done diff --git a/src/google/protobuf/compiler/objectivec/objectivec_generator.cc b/src/google/protobuf/compiler/objectivec/objectivec_generator.cc index a0b6d6cb..36407467 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_generator.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_generator.cc @@ -45,10 +45,22 @@ ObjectiveCGenerator::ObjectiveCGenerator() {} ObjectiveCGenerator::~ObjectiveCGenerator() {} +bool ObjectiveCGenerator::HasGenerateAll() const { + return true; +} + bool ObjectiveCGenerator::Generate(const FileDescriptor* file, const string& parameter, - OutputDirectory* output_directory, + GeneratorContext* context, string* error) const { + *error = "Unimplemented Generate() method. Call GenerateAll() instead."; + return false; +} + +bool ObjectiveCGenerator::GenerateAll(const vector& files, + const string& parameter, + GeneratorContext* context, + string* error) const { // ----------------------------------------------------------------- // Parse generator options. These options are passed to the compiler using the // --objc_opt flag. The options are passed as a comma separated list of @@ -117,29 +129,32 @@ bool ObjectiveCGenerator::Generate(const FileDescriptor* file, // ----------------------------------------------------------------- - // Validate the objc prefix/package pairing. - if (!ValidateObjCClassPrefix(file, generation_options, error)) { + // Validate the objc prefix/package pairings. + if (!ValidateObjCClassPrefixes(files, generation_options, error)) { // *error will have been filled in. return false; } - FileGenerator file_generator(file, generation_options); - string filepath = FilePath(file); + for (int i = 0; i < files.size(); i++) { + const FileDescriptor* file = files[i]; + FileGenerator file_generator(file, generation_options); + string filepath = FilePath(file); - // Generate header. - { - scoped_ptr output( - output_directory->Open(filepath + ".pbobjc.h")); - io::Printer printer(output.get(), '$'); - file_generator.GenerateHeader(&printer); - } + // Generate header. + { + scoped_ptr output( + context->Open(filepath + ".pbobjc.h")); + io::Printer printer(output.get(), '$'); + file_generator.GenerateHeader(&printer); + } - // Generate m file. - { - scoped_ptr output( - output_directory->Open(filepath + ".pbobjc.m")); - io::Printer printer(output.get(), '$'); - file_generator.GenerateSource(&printer); + // Generate m file. + { + scoped_ptr output( + context->Open(filepath + ".pbobjc.m")); + io::Printer printer(output.get(), '$'); + file_generator.GenerateSource(&printer); + } } return true; diff --git a/src/google/protobuf/compiler/objectivec/objectivec_generator.h b/src/google/protobuf/compiler/objectivec/objectivec_generator.h index 09266b04..9d801d51 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_generator.h +++ b/src/google/protobuf/compiler/objectivec/objectivec_generator.h @@ -47,8 +47,15 @@ class LIBPROTOC_EXPORT ObjectiveCGenerator : public CodeGenerator { ~ObjectiveCGenerator(); // implements CodeGenerator ---------------------------------------- - bool Generate(const FileDescriptor* file, const string& parameter, - OutputDirectory* output_directory, string* error) const; + bool HasGenerateAll() const; + bool Generate(const FileDescriptor* file, + const string& parameter, + GeneratorContext* context, + string* error) const; + bool GenerateAll(const vector& files, + const string& parameter, + GeneratorContext* context, + string* error) const; private: GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ObjectiveCGenerator); diff --git a/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc b/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc index 009d57f9..847be983 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc @@ -980,28 +980,20 @@ bool LoadExpectedPackagePrefixes(const Options &generation_options, generation_options.expected_prefixes_path, &collector, out_error); } -} // namespace - -bool ValidateObjCClassPrefix(const FileDescriptor* file, - const Options& generation_options, - string* out_error) { +bool ValidateObjCClassPrefix( + const FileDescriptor* file, + const string& expected_prefixes_path, + const map& expected_package_prefixes, + string* out_error) { const string prefix = file->options().objc_class_prefix(); const string package = file->package(); // 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 warnings. - // Load any expected package prefixes to validate against those. - map expected_package_prefixes; - if (!LoadExpectedPackagePrefixes(generation_options, - &expected_package_prefixes, - out_error)) { - return false; - } - // Check: Error - See if there was an expected prefix for the package and // report if it doesn't match (wrong or missing). - map::iterator package_match = + map::const_iterator package_match = expected_package_prefixes.find(package); if (package_match != expected_package_prefixes.end()) { // There was an entry, and... @@ -1050,7 +1042,7 @@ bool ValidateObjCClassPrefix(const FileDescriptor* file, // Look for any other package that uses the same prefix. string other_package_for_prefix; - for (map::iterator i = expected_package_prefixes.begin(); + for (map::const_iterator i = expected_package_prefixes.begin(); i != expected_package_prefixes.end(); ++i) { if (i->second == prefix) { other_package_for_prefix = i->first; @@ -1068,7 +1060,7 @@ bool ValidateObjCClassPrefix(const FileDescriptor* file, << "protoc:0: warning: File '" << file->name() << "' has no " << "package. Consider adding a new package to the proto and adding '" << "new.package = " << prefix << "' to the expected prefixes file (" - << generation_options.expected_prefixes_path << ")." << endl; + << expected_prefixes_path << ")." << endl; cerr.flush(); } else { // ... another package has declared the same prefix. @@ -1078,7 +1070,7 @@ bool ValidateObjCClassPrefix(const FileDescriptor* file, << prefix << "' as its prefix. Consider either adding a new package " << "to the proto, or reusing one of the packages already using this " << "prefix in the expected prefixes file (" - << generation_options.expected_prefixes_path << ")." << endl; + << expected_prefixes_path << ")." << endl; cerr.flush(); } return true; @@ -1094,7 +1086,7 @@ bool ValidateObjCClassPrefix(const FileDescriptor* file, "'; that prefix is already used for 'package " + other_package_for_prefix + ";'. It can only be reused by listing " + "it in the expected file (" + - generation_options.expected_prefixes_path + ")."; + expected_prefixes_path + ")."; return false; // Only report first usage of the prefix. } @@ -1105,13 +1097,39 @@ bool ValidateObjCClassPrefix(const FileDescriptor* file, << "protoc:0: warning: Found unexpected 'option objc_class_prefix = \"" << prefix << "\";' in '" << file->name() << "';" << " consider adding it to the expected prefixes file (" - << generation_options.expected_prefixes_path << ")." << endl; + << expected_prefixes_path << ")." << endl; cerr.flush(); } return true; } +} // namespace + +bool ValidateObjCClassPrefixes(const vector& files, + const Options& generation_options, + string* out_error) { + // Load the expected package prefixes, if available, to validate against. + map expected_package_prefixes; + if (!LoadExpectedPackagePrefixes(generation_options, + &expected_package_prefixes, + out_error)) { + return false; + } + + for (int i = 0; i < files.size(); i++) { + bool is_valid = + ValidateObjCClassPrefix(files[i], + generation_options.expected_prefixes_path, + expected_package_prefixes, + out_error); + if (!is_valid) { + return false; + } + } + return true; +} + TextFormatDecodeData::TextFormatDecodeData() { } TextFormatDecodeData::~TextFormatDecodeData() { } diff --git a/src/google/protobuf/compiler/objectivec/objectivec_helpers.h b/src/google/protobuf/compiler/objectivec/objectivec_helpers.h index 344723a6..b05983df 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_helpers.h +++ b/src/google/protobuf/compiler/objectivec/objectivec_helpers.h @@ -185,12 +185,12 @@ string ProtobufFrameworkImportSymbol(const string& framework_name); // Checks if the file is one of the proto's bundled with the library. bool IsProtobufLibraryBundledProtoFile(const FileDescriptor* file); -// Checks the prefix for a given file and outputs any warnings needed, if -// there are flat out errors, then out_error is filled in and the result is -// false. -bool ValidateObjCClassPrefix(const FileDescriptor* file, - const Options& generation_options, - string* out_error); +// Checks the prefix for the given files and outputs any warnings as needed. If +// there are flat out errors, then out_error is filled in with the first error +// and the result is false. +bool ValidateObjCClassPrefixes(const vector& files, + const Options& generation_options, + string* out_error); // Generate decode data needed for ObjC's GPBDecodeTextFormatName() to transform // the input into the expected output. -- cgit v1.2.3