Commit 2e66a61b authored by Thomas Van Lenten's avatar Thomas Van Lenten

Support GenerateAll().

- Expect calls on GenerateAll() and not Generate().
- Parse the prefix validation file once, and then check all the files.
parent b97a4a53
...@@ -99,26 +99,26 @@ CORE_PROTO_FILES+=( ...@@ -99,26 +99,26 @@ CORE_PROTO_FILES+=(
src/google/protobuf/descriptor.proto src/google/protobuf/descriptor.proto
) )
compile_proto() { compile_protos() {
src/protoc \ src/protoc \
--objc_out="${OUTPUT_DIR}/google/protobuf" \ --objc_out="${OUTPUT_DIR}/google/protobuf" \
--proto_path=src/google/protobuf/ \ --proto_path=src/google/protobuf/ \
--proto_path=src \ --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 for a_proto in "${CORE_PROTO_FILES[@]}" ; do
compile_proto "${a_proto}" compile_protos "${a_proto}"
done done
OBJC_PROTO_FILES=( # Objective C specific testing protos.
objectivec/Tests/unittest_cycle.proto compile_protos \
objectivec/Tests/unittest_runtime_proto2.proto --proto_path="objectivec/Tests" \
objectivec/Tests/unittest_runtime_proto3.proto objectivec/Tests/unittest_cycle.proto \
objectivec/Tests/unittest_objc.proto objectivec/Tests/unittest_runtime_proto2.proto \
objectivec/Tests/unittest_runtime_proto3.proto \
objectivec/Tests/unittest_objc.proto \
objectivec/Tests/unittest_objc_startup.proto objectivec/Tests/unittest_objc_startup.proto
)
for a_proto in "${OBJC_PROTO_FILES[@]}" ; do
compile_proto --proto_path="objectivec/Tests" "${a_proto}"
done
...@@ -45,9 +45,21 @@ ObjectiveCGenerator::ObjectiveCGenerator() {} ...@@ -45,9 +45,21 @@ ObjectiveCGenerator::ObjectiveCGenerator() {}
ObjectiveCGenerator::~ObjectiveCGenerator() {} ObjectiveCGenerator::~ObjectiveCGenerator() {}
bool ObjectiveCGenerator::HasGenerateAll() const {
return true;
}
bool ObjectiveCGenerator::Generate(const FileDescriptor* file, bool ObjectiveCGenerator::Generate(const FileDescriptor* file,
const string& parameter, 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<const FileDescriptor*>& files,
const string& parameter,
GeneratorContext* context,
string* error) const { string* error) const {
// ----------------------------------------------------------------- // -----------------------------------------------------------------
// Parse generator options. These options are passed to the compiler using the // Parse generator options. These options are passed to the compiler using the
...@@ -117,19 +129,21 @@ bool ObjectiveCGenerator::Generate(const FileDescriptor* file, ...@@ -117,19 +129,21 @@ bool ObjectiveCGenerator::Generate(const FileDescriptor* file,
// ----------------------------------------------------------------- // -----------------------------------------------------------------
// Validate the objc prefix/package pairing. // Validate the objc prefix/package pairings.
if (!ValidateObjCClassPrefix(file, generation_options, error)) { if (!ValidateObjCClassPrefixes(files, generation_options, error)) {
// *error will have been filled in. // *error will have been filled in.
return false; return false;
} }
for (int i = 0; i < files.size(); i++) {
const FileDescriptor* file = files[i];
FileGenerator file_generator(file, generation_options); FileGenerator file_generator(file, generation_options);
string filepath = FilePath(file); string filepath = FilePath(file);
// Generate header. // Generate header.
{ {
scoped_ptr<io::ZeroCopyOutputStream> output( scoped_ptr<io::ZeroCopyOutputStream> output(
output_directory->Open(filepath + ".pbobjc.h")); context->Open(filepath + ".pbobjc.h"));
io::Printer printer(output.get(), '$'); io::Printer printer(output.get(), '$');
file_generator.GenerateHeader(&printer); file_generator.GenerateHeader(&printer);
} }
...@@ -137,10 +151,11 @@ bool ObjectiveCGenerator::Generate(const FileDescriptor* file, ...@@ -137,10 +151,11 @@ bool ObjectiveCGenerator::Generate(const FileDescriptor* file,
// Generate m file. // Generate m file.
{ {
scoped_ptr<io::ZeroCopyOutputStream> output( scoped_ptr<io::ZeroCopyOutputStream> output(
output_directory->Open(filepath + ".pbobjc.m")); context->Open(filepath + ".pbobjc.m"));
io::Printer printer(output.get(), '$'); io::Printer printer(output.get(), '$');
file_generator.GenerateSource(&printer); file_generator.GenerateSource(&printer);
} }
}
return true; return true;
} }
......
...@@ -47,8 +47,15 @@ class LIBPROTOC_EXPORT ObjectiveCGenerator : public CodeGenerator { ...@@ -47,8 +47,15 @@ class LIBPROTOC_EXPORT ObjectiveCGenerator : public CodeGenerator {
~ObjectiveCGenerator(); ~ObjectiveCGenerator();
// implements CodeGenerator ---------------------------------------- // implements CodeGenerator ----------------------------------------
bool Generate(const FileDescriptor* file, const string& parameter, bool HasGenerateAll() const;
OutputDirectory* output_directory, string* error) const; bool Generate(const FileDescriptor* file,
const string& parameter,
GeneratorContext* context,
string* error) const;
bool GenerateAll(const vector<const FileDescriptor*>& files,
const string& parameter,
GeneratorContext* context,
string* error) const;
private: private:
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ObjectiveCGenerator); GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ObjectiveCGenerator);
......
...@@ -980,10 +980,10 @@ bool LoadExpectedPackagePrefixes(const Options &generation_options, ...@@ -980,10 +980,10 @@ bool LoadExpectedPackagePrefixes(const Options &generation_options,
generation_options.expected_prefixes_path, &collector, out_error); generation_options.expected_prefixes_path, &collector, out_error);
} }
} // namespace bool ValidateObjCClassPrefix(
const FileDescriptor* file,
bool ValidateObjCClassPrefix(const FileDescriptor* file, const string& expected_prefixes_path,
const Options& generation_options, const map<string, string>& expected_package_prefixes,
string* out_error) { string* out_error) {
const string prefix = file->options().objc_class_prefix(); const string prefix = file->options().objc_class_prefix();
const string package = file->package(); const string package = file->package();
...@@ -991,17 +991,9 @@ bool ValidateObjCClassPrefix(const FileDescriptor* file, ...@@ -991,17 +991,9 @@ bool ValidateObjCClassPrefix(const FileDescriptor* file,
// NOTE: src/google/protobuf/compiler/plugin.cc makes use of cerr for some // 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. // 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<string, string> 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 // Check: Error - See if there was an expected prefix for the package and
// report if it doesn't match (wrong or missing). // report if it doesn't match (wrong or missing).
map<string, string>::iterator package_match = map<string, string>::const_iterator package_match =
expected_package_prefixes.find(package); expected_package_prefixes.find(package);
if (package_match != expected_package_prefixes.end()) { if (package_match != expected_package_prefixes.end()) {
// There was an entry, and... // There was an entry, and...
...@@ -1050,7 +1042,7 @@ bool ValidateObjCClassPrefix(const FileDescriptor* file, ...@@ -1050,7 +1042,7 @@ bool ValidateObjCClassPrefix(const FileDescriptor* file,
// Look for any other package that uses the same prefix. // Look for any other package that uses the same prefix.
string other_package_for_prefix; string other_package_for_prefix;
for (map<string, string>::iterator i = expected_package_prefixes.begin(); for (map<string, string>::const_iterator i = expected_package_prefixes.begin();
i != expected_package_prefixes.end(); ++i) { i != expected_package_prefixes.end(); ++i) {
if (i->second == prefix) { if (i->second == prefix) {
other_package_for_prefix = i->first; other_package_for_prefix = i->first;
...@@ -1068,7 +1060,7 @@ bool ValidateObjCClassPrefix(const FileDescriptor* file, ...@@ -1068,7 +1060,7 @@ bool ValidateObjCClassPrefix(const FileDescriptor* file,
<< "protoc:0: warning: File '" << file->name() << "' has no " << "protoc:0: warning: File '" << file->name() << "' has no "
<< "package. Consider adding a new package to the proto and adding '" << "package. Consider adding a new package to the proto and adding '"
<< "new.package = " << prefix << "' to the expected prefixes file (" << "new.package = " << prefix << "' to the expected prefixes file ("
<< generation_options.expected_prefixes_path << ")." << endl; << expected_prefixes_path << ")." << endl;
cerr.flush(); cerr.flush();
} else { } else {
// ... another package has declared the same prefix. // ... another package has declared the same prefix.
...@@ -1078,7 +1070,7 @@ bool ValidateObjCClassPrefix(const FileDescriptor* file, ...@@ -1078,7 +1070,7 @@ bool ValidateObjCClassPrefix(const FileDescriptor* file,
<< prefix << "' as its prefix. Consider either adding a new package " << prefix << "' as its prefix. Consider either adding a new package "
<< "to the proto, or reusing one of the packages already using this " << "to the proto, or reusing one of the packages already using this "
<< "prefix in the expected prefixes file (" << "prefix in the expected prefixes file ("
<< generation_options.expected_prefixes_path << ")." << endl; << expected_prefixes_path << ")." << endl;
cerr.flush(); cerr.flush();
} }
return true; return true;
...@@ -1094,7 +1086,7 @@ bool ValidateObjCClassPrefix(const FileDescriptor* file, ...@@ -1094,7 +1086,7 @@ bool ValidateObjCClassPrefix(const FileDescriptor* file,
"'; that prefix is already used for 'package " + "'; that prefix is already used for 'package " +
other_package_for_prefix + ";'. It can only be reused by listing " + other_package_for_prefix + ";'. It can only be reused by listing " +
"it in the expected file (" + "it in the expected file (" +
generation_options.expected_prefixes_path + ")."; expected_prefixes_path + ").";
return false; // Only report first usage of the prefix. return false; // Only report first usage of the prefix.
} }
...@@ -1105,13 +1097,39 @@ bool ValidateObjCClassPrefix(const FileDescriptor* file, ...@@ -1105,13 +1097,39 @@ bool ValidateObjCClassPrefix(const FileDescriptor* file,
<< "protoc:0: warning: Found unexpected 'option objc_class_prefix = \"" << "protoc:0: warning: Found unexpected 'option objc_class_prefix = \""
<< prefix << "\";' in '" << file->name() << "';" << prefix << "\";' in '" << file->name() << "';"
<< " consider adding it to the expected prefixes file (" << " consider adding it to the expected prefixes file ("
<< generation_options.expected_prefixes_path << ")." << endl; << expected_prefixes_path << ")." << endl;
cerr.flush(); cerr.flush();
} }
return true; return true;
} }
} // namespace
bool ValidateObjCClassPrefixes(const vector<const FileDescriptor*>& files,
const Options& generation_options,
string* out_error) {
// Load the expected package prefixes, if available, to validate against.
map<string, string> 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() { }
TextFormatDecodeData::~TextFormatDecodeData() { } TextFormatDecodeData::~TextFormatDecodeData() { }
......
...@@ -185,10 +185,10 @@ string ProtobufFrameworkImportSymbol(const string& framework_name); ...@@ -185,10 +185,10 @@ string ProtobufFrameworkImportSymbol(const string& framework_name);
// Checks if the file is one of the proto's bundled with the library. // Checks if the file is one of the proto's bundled with the library.
bool IsProtobufLibraryBundledProtoFile(const FileDescriptor* file); bool IsProtobufLibraryBundledProtoFile(const FileDescriptor* file);
// Checks the prefix for a given file and outputs any warnings needed, if // 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 and the result is // there are flat out errors, then out_error is filled in with the first error
// false. // and the result is false.
bool ValidateObjCClassPrefix(const FileDescriptor* file, bool ValidateObjCClassPrefixes(const vector<const FileDescriptor*>& files,
const Options& generation_options, const Options& generation_options,
string* out_error); string* out_error);
......
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