diff options
Diffstat (limited to 'src/google/protobuf/compiler/plugin.cc')
-rw-r--r-- | src/google/protobuf/compiler/plugin.cc | 138 |
1 files changed, 72 insertions, 66 deletions
diff --git a/src/google/protobuf/compiler/plugin.cc b/src/google/protobuf/compiler/plugin.cc index 2bebf1f3..9c1c757c 100644 --- a/src/google/protobuf/compiler/plugin.cc +++ b/src/google/protobuf/compiler/plugin.cc @@ -36,14 +36,7 @@ #include <set> #ifdef _WIN32 -#include <io.h> #include <fcntl.h> -#ifndef STDIN_FILENO -#define STDIN_FILENO 0 -#endif -#ifndef STDOUT_FILENO -#define STDOUT_FILENO 1 -#endif #else #include <unistd.h> #endif @@ -52,19 +45,29 @@ #include <google/protobuf/stubs/common.h> #include <google/protobuf/compiler/plugin.pb.h> #include <google/protobuf/compiler/code_generator.h> -#include <google/protobuf/descriptor.h> #include <google/protobuf/io/zero_copy_stream_impl.h> +#include <google/protobuf/descriptor.h> +#include <google/protobuf/stubs/io_win32.h> namespace google { namespace protobuf { namespace compiler { +#if defined(_WIN32) +// DO NOT include <io.h>, instead create functions in io_win32.{h,cc} and import +// them like we do below. +using google::protobuf::internal::win32::setmode; +#endif + class GeneratorResponseContext : public GeneratorContext { public: - GeneratorResponseContext(CodeGeneratorResponse* response, - const vector<const FileDescriptor*>& parsed_files) - : response_(response), + GeneratorResponseContext( + const Version& compiler_version, + CodeGeneratorResponse* response, + const std::vector<const FileDescriptor*>& parsed_files) + : compiler_version_(compiler_version), + response_(response), parsed_files_(parsed_files) {} virtual ~GeneratorResponseContext() {} @@ -84,15 +87,62 @@ class GeneratorResponseContext : public GeneratorContext { return new io::StringOutputStream(file->mutable_content()); } - void ListParsedFiles(vector<const FileDescriptor*>* output) { + void ListParsedFiles(std::vector<const FileDescriptor*>* output) { *output = parsed_files_; } + void GetCompilerVersion(Version* version) const { + *version = compiler_version_; + } + private: + Version compiler_version_; CodeGeneratorResponse* response_; - const vector<const FileDescriptor*>& parsed_files_; + const std::vector<const FileDescriptor*>& parsed_files_; }; +bool GenerateCode(const CodeGeneratorRequest& request, + const CodeGenerator& generator, CodeGeneratorResponse* response, + string* error_msg) { + DescriptorPool pool; + for (int i = 0; i < request.proto_file_size(); i++) { + const FileDescriptor* file = pool.BuildFile(request.proto_file(i)); + if (file == NULL) { + // BuildFile() already wrote an error message. + return false; + } + } + + std::vector<const FileDescriptor*> parsed_files; + for (int i = 0; i < request.file_to_generate_size(); i++) { + parsed_files.push_back(pool.FindFileByName(request.file_to_generate(i))); + if (parsed_files.back() == NULL) { + *error_msg = "protoc asked plugin to generate a file but " + "did not provide a descriptor for the file: " + + request.file_to_generate(i); + return false; + } + } + + GeneratorResponseContext context( + request.compiler_version(), response, parsed_files); + + + string error; + bool succeeded = generator.GenerateAll( + parsed_files, request.parameter(), &context, &error); + + if (!succeeded && error.empty()) { + error = "Code generator returned false but provided no error " + "description."; + } + if (!error.empty()) { + response->set_error(error); + } + + return true; +} + int PluginMain(int argc, char* argv[], const CodeGenerator* generator) { if (argc > 1) { @@ -101,8 +151,8 @@ int PluginMain(int argc, char* argv[], const CodeGenerator* generator) { } #ifdef _WIN32 - _setmode(STDIN_FILENO, _O_BINARY); - _setmode(STDOUT_FILENO, _O_BINARY); + setmode(STDIN_FILENO, _O_BINARY); + setmode(STDOUT_FILENO, _O_BINARY); #endif CodeGeneratorRequest request; @@ -112,62 +162,18 @@ int PluginMain(int argc, char* argv[], const CodeGenerator* generator) { return 1; } - DescriptorPool pool; - for (int i = 0; i < request.proto_file_size(); i++) { - const FileDescriptor* file = pool.BuildFile(request.proto_file(i)); - if (file == NULL) { - // BuildFile() already wrote an error message. - return 1; - } - } - - vector<const FileDescriptor*> parsed_files; - for (int i = 0; i < request.file_to_generate_size(); i++) { - parsed_files.push_back(pool.FindFileByName(request.file_to_generate(i))); - if (parsed_files.back() == NULL) { - std::cerr << argv[0] << ": protoc asked plugin to generate a file but " - "did not provide a descriptor for the file: " - << request.file_to_generate(i) << std::endl; - return 1; - } - } - + string error_msg; CodeGeneratorResponse response; - GeneratorResponseContext context(&response, parsed_files); - - if (generator->HasGenerateAll()) { - string error; - bool succeeded = generator->GenerateAll( - parsed_files, request.parameter(), &context, &error); - if (!succeeded && error.empty()) { - error = "Code generator returned false but provided no error " - "description."; - } - if (!error.empty()) { - response.set_error(error); + if (GenerateCode(request, *generator, &response, &error_msg)) { + if (!response.SerializeToFileDescriptor(STDOUT_FILENO)) { + std::cerr << argv[0] << ": Error writing to stdout." << std::endl; + return 1; } } else { - for (int i = 0; i < parsed_files.size(); i++) { - const FileDescriptor* file = parsed_files[i]; - - string error; - bool succeeded = generator->Generate( - file, request.parameter(), &context, &error); - - if (!succeeded && error.empty()) { - error = "Code generator returned false but provided no error " - "description."; - } - if (!error.empty()) { - response.set_error(file->name() + ": " + error); - break; - } + if (!error_msg.empty()) { + std::cerr << argv[0] << ": " << error_msg << std::endl; } - } - - if (!response.SerializeToFileDescriptor(STDOUT_FILENO)) { - std::cerr << argv[0] << ": Error writing to stdout." << std::endl; return 1; } |