| OLD | NEW |
| 1 // Protocol Buffers - Google's data interchange format | 1 // Protocol Buffers - Google's data interchange format |
| 2 // Copyright 2008 Google Inc. All rights reserved. | 2 // Copyright 2008 Google Inc. All rights reserved. |
| 3 // https://developers.google.com/protocol-buffers/ | 3 // https://developers.google.com/protocol-buffers/ |
| 4 // | 4 // |
| 5 // Redistribution and use in source and binary forms, with or without | 5 // Redistribution and use in source and binary forms, with or without |
| 6 // modification, are permitted provided that the following conditions are | 6 // modification, are permitted provided that the following conditions are |
| 7 // met: | 7 // met: |
| 8 // | 8 // |
| 9 // * Redistributions of source code must retain the above copyright | 9 // * Redistributions of source code must retain the above copyright |
| 10 // notice, this list of conditions and the following disclaimer. | 10 // notice, this list of conditions and the following disclaimer. |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 43 #include <io.h> | 43 #include <io.h> |
| 44 #include <direct.h> | 44 #include <direct.h> |
| 45 #else | 45 #else |
| 46 #include <unistd.h> | 46 #include <unistd.h> |
| 47 #endif | 47 #endif |
| 48 #include <errno.h> | 48 #include <errno.h> |
| 49 #include <fstream> | 49 #include <fstream> |
| 50 #include <iostream> | 50 #include <iostream> |
| 51 #include <ctype.h> | 51 #include <ctype.h> |
| 52 | 52 |
| 53 #ifdef GOOGLE_PROTOBUF_ARCH_SPARC | |
| 54 #include <limits.h> //For PATH_MAX | 53 #include <limits.h> //For PATH_MAX |
| 55 #endif | |
| 56 | 54 |
| 57 #include <memory> | 55 #include <memory> |
| 58 #ifndef _SHARED_PTR_H | 56 #ifndef _SHARED_PTR_H |
| 59 #include <google/protobuf/stubs/shared_ptr.h> | 57 #include <google/protobuf/stubs/shared_ptr.h> |
| 60 #endif | 58 #endif |
| 61 | 59 |
| 62 #ifdef __APPLE__ | 60 #ifdef __APPLE__ |
| 63 #include <mach-o/dyld.h> | 61 #include <mach-o/dyld.h> |
| 64 #endif | 62 #endif |
| 65 | 63 |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 168 return true; | 166 return true; |
| 169 } | 167 } |
| 170 } | 168 } |
| 171 | 169 |
| 172 // Try to create the parent directory of the given file, creating the parent's | 170 // Try to create the parent directory of the given file, creating the parent's |
| 173 // parent if necessary, and so on. The full file name is actually | 171 // parent if necessary, and so on. The full file name is actually |
| 174 // (prefix + filename), but we assume |prefix| already exists and only create | 172 // (prefix + filename), but we assume |prefix| already exists and only create |
| 175 // directories listed in |filename|. | 173 // directories listed in |filename|. |
| 176 bool TryCreateParentDirectory(const string& prefix, const string& filename) { | 174 bool TryCreateParentDirectory(const string& prefix, const string& filename) { |
| 177 // Recursively create parent directories to the output file. | 175 // Recursively create parent directories to the output file. |
| 178 vector<string> parts = Split(filename, "/", true); | 176 std::vector<string> parts = |
| 177 Split(filename, "/", true); |
| 179 string path_so_far = prefix; | 178 string path_so_far = prefix; |
| 180 for (int i = 0; i < parts.size() - 1; i++) { | 179 for (int i = 0; i < parts.size() - 1; i++) { |
| 181 path_so_far += parts[i]; | 180 path_so_far += parts[i]; |
| 182 if (mkdir(path_so_far.c_str(), 0777) != 0) { | 181 if (mkdir(path_so_far.c_str(), 0777) != 0) { |
| 183 if (errno != EEXIST) { | 182 if (errno != EEXIST) { |
| 184 std::cerr << filename << ": while trying to create directory " | 183 std::cerr << filename << ": while trying to create directory " |
| 185 << path_so_far << ": " << strerror(errno) << std::endl; | 184 << path_so_far << ": " << strerror(errno) << std::endl; |
| 186 return false; | 185 return false; |
| 187 } | 186 } |
| 188 } | 187 } |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 257 pos = path.find_last_of("/\\"); | 256 pos = path.find_last_of("/\\"); |
| 258 if (pos == string::npos || pos == 0) { | 257 if (pos == string::npos || pos == 0) { |
| 259 return; | 258 return; |
| 260 } | 259 } |
| 261 path = path.substr(0, pos); | 260 path = path.substr(0, pos); |
| 262 if (IsInstalledProtoPath(path + "/include")) { | 261 if (IsInstalledProtoPath(path + "/include")) { |
| 263 paths->push_back(pair<string, string>("", path + "/include")); | 262 paths->push_back(pair<string, string>("", path + "/include")); |
| 264 return; | 263 return; |
| 265 } | 264 } |
| 266 } | 265 } |
| 266 |
| 267 string PluginName(const string& plugin_prefix, const string& directive) { |
| 268 // Assuming the directive starts with "--" and ends with "_out" or "_opt", |
| 269 // strip the "--" and "_out/_opt" and add the plugin prefix. |
| 270 return plugin_prefix + "gen-" + directive.substr(2, directive.size() - 6); |
| 271 } |
| 267 } // namespace | 272 } // namespace |
| 268 | 273 |
| 269 // A MultiFileErrorCollector that prints errors to stderr. | 274 // A MultiFileErrorCollector that prints errors to stderr. |
| 270 class CommandLineInterface::ErrorPrinter : public MultiFileErrorCollector, | 275 class CommandLineInterface::ErrorPrinter : public MultiFileErrorCollector, |
| 271 public io::ErrorCollector { | 276 public io::ErrorCollector { |
| 272 public: | 277 public: |
| 273 ErrorPrinter(ErrorFormat format, DiskSourceTree *tree = NULL) | 278 ErrorPrinter(ErrorFormat format, DiskSourceTree *tree = NULL) |
| 274 : format_(format), tree_(tree) {} | 279 : format_(format), tree_(tree) {} |
| 275 ~ErrorPrinter() {} | 280 ~ErrorPrinter() {} |
| 276 | 281 |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 333 const ErrorFormat format_; | 338 const ErrorFormat format_; |
| 334 DiskSourceTree *tree_; | 339 DiskSourceTree *tree_; |
| 335 }; | 340 }; |
| 336 | 341 |
| 337 // ------------------------------------------------------------------- | 342 // ------------------------------------------------------------------- |
| 338 | 343 |
| 339 // A GeneratorContext implementation that buffers files in memory, then dumps | 344 // A GeneratorContext implementation that buffers files in memory, then dumps |
| 340 // them all to disk on demand. | 345 // them all to disk on demand. |
| 341 class CommandLineInterface::GeneratorContextImpl : public GeneratorContext { | 346 class CommandLineInterface::GeneratorContextImpl : public GeneratorContext { |
| 342 public: | 347 public: |
| 343 GeneratorContextImpl(const vector<const FileDescriptor*>& parsed_files); | 348 GeneratorContextImpl(const std::vector<const FileDescriptor*>& parsed_files); |
| 344 ~GeneratorContextImpl(); | 349 ~GeneratorContextImpl(); |
| 345 | 350 |
| 346 // Write all files in the directory to disk at the given output location, | 351 // Write all files in the directory to disk at the given output location, |
| 347 // which must end in a '/'. | 352 // which must end in a '/'. |
| 348 bool WriteAllToDisk(const string& prefix); | 353 bool WriteAllToDisk(const string& prefix); |
| 349 | 354 |
| 350 // Write the contents of this directory to a ZIP-format archive with the | 355 // Write the contents of this directory to a ZIP-format archive with the |
| 351 // given name. | 356 // given name. |
| 352 bool WriteAllToZip(const string& filename); | 357 bool WriteAllToZip(const string& filename); |
| 353 | 358 |
| 354 // Add a boilerplate META-INF/MANIFEST.MF file as required by the Java JAR | 359 // Add a boilerplate META-INF/MANIFEST.MF file as required by the Java JAR |
| 355 // format, unless one has already been written. | 360 // format, unless one has already been written. |
| 356 void AddJarManifest(); | 361 void AddJarManifest(); |
| 357 | 362 |
| 358 // Get name of all output files. | 363 // Get name of all output files. |
| 359 void GetOutputFilenames(vector<string>* output_filenames); | 364 void GetOutputFilenames(std::vector<string>* output_filenames); |
| 360 | 365 |
| 361 // implements GeneratorContext -------------------------------------- | 366 // implements GeneratorContext -------------------------------------- |
| 362 io::ZeroCopyOutputStream* Open(const string& filename); | 367 io::ZeroCopyOutputStream* Open(const string& filename); |
| 363 io::ZeroCopyOutputStream* OpenForAppend(const string& filename); | 368 io::ZeroCopyOutputStream* OpenForAppend(const string& filename); |
| 364 io::ZeroCopyOutputStream* OpenForInsert( | 369 io::ZeroCopyOutputStream* OpenForInsert( |
| 365 const string& filename, const string& insertion_point); | 370 const string& filename, const string& insertion_point); |
| 366 void ListParsedFiles(vector<const FileDescriptor*>* output) { | 371 void ListParsedFiles(std::vector<const FileDescriptor*>* output) { |
| 367 *output = parsed_files_; | 372 *output = parsed_files_; |
| 368 } | 373 } |
| 369 | 374 |
| 370 private: | 375 private: |
| 371 friend class MemoryOutputStream; | 376 friend class MemoryOutputStream; |
| 372 | 377 |
| 373 // map instead of hash_map so that files are written in order (good when | 378 // map instead of hash_map so that files are written in order (good when |
| 374 // writing zips). | 379 // writing zips). |
| 375 map<string, string*> files_; | 380 std::map<string, string*> files_; |
| 376 const vector<const FileDescriptor*>& parsed_files_; | 381 const std::vector<const FileDescriptor*>& parsed_files_; |
| 377 bool had_error_; | 382 bool had_error_; |
| 378 }; | 383 }; |
| 379 | 384 |
| 380 class CommandLineInterface::MemoryOutputStream | 385 class CommandLineInterface::MemoryOutputStream |
| 381 : public io::ZeroCopyOutputStream { | 386 : public io::ZeroCopyOutputStream { |
| 382 public: | 387 public: |
| 383 MemoryOutputStream(GeneratorContextImpl* directory, const string& filename, | 388 MemoryOutputStream(GeneratorContextImpl* directory, const string& filename, |
| 384 bool append_mode); | 389 bool append_mode); |
| 385 MemoryOutputStream(GeneratorContextImpl* directory, const string& filename, | 390 MemoryOutputStream(GeneratorContextImpl* directory, const string& filename, |
| 386 const string& insertion_point); | 391 const string& insertion_point); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 403 // Whether we should append the output stream to the existing file. | 408 // Whether we should append the output stream to the existing file. |
| 404 bool append_mode_; | 409 bool append_mode_; |
| 405 | 410 |
| 406 // StringOutputStream writing to data_. | 411 // StringOutputStream writing to data_. |
| 407 google::protobuf::scoped_ptr<io::StringOutputStream> inner_; | 412 google::protobuf::scoped_ptr<io::StringOutputStream> inner_; |
| 408 }; | 413 }; |
| 409 | 414 |
| 410 // ------------------------------------------------------------------- | 415 // ------------------------------------------------------------------- |
| 411 | 416 |
| 412 CommandLineInterface::GeneratorContextImpl::GeneratorContextImpl( | 417 CommandLineInterface::GeneratorContextImpl::GeneratorContextImpl( |
| 413 const vector<const FileDescriptor*>& parsed_files) | 418 const std::vector<const FileDescriptor*>& parsed_files) |
| 414 : parsed_files_(parsed_files), | 419 : parsed_files_(parsed_files), |
| 415 had_error_(false) { | 420 had_error_(false) { |
| 416 } | 421 } |
| 417 | 422 |
| 418 CommandLineInterface::GeneratorContextImpl::~GeneratorContextImpl() { | 423 CommandLineInterface::GeneratorContextImpl::~GeneratorContextImpl() { |
| 419 STLDeleteValues(&files_); | 424 STLDeleteValues(&files_); |
| 420 } | 425 } |
| 421 | 426 |
| 422 bool CommandLineInterface::GeneratorContextImpl::WriteAllToDisk( | 427 bool CommandLineInterface::GeneratorContextImpl::WriteAllToDisk( |
| 423 const string& prefix) { | 428 const string& prefix) { |
| 424 if (had_error_) { | 429 if (had_error_) { |
| 425 return false; | 430 return false; |
| 426 } | 431 } |
| 427 | 432 |
| 428 if (!VerifyDirectoryExists(prefix)) { | 433 if (!VerifyDirectoryExists(prefix)) { |
| 429 return false; | 434 return false; |
| 430 } | 435 } |
| 431 | 436 |
| 432 for (map<string, string*>::const_iterator iter = files_.begin(); | 437 for (std::map<string, string*>::const_iterator iter = files_.begin(); |
| 433 iter != files_.end(); ++iter) { | 438 iter != files_.end(); ++iter) { |
| 434 const string& relative_filename = iter->first; | 439 const string& relative_filename = iter->first; |
| 435 const char* data = iter->second->data(); | 440 const char* data = iter->second->data(); |
| 436 int size = iter->second->size(); | 441 int size = iter->second->size(); |
| 437 | 442 |
| 438 if (!TryCreateParentDirectory(prefix, relative_filename)) { | 443 if (!TryCreateParentDirectory(prefix, relative_filename)) { |
| 439 return false; | 444 return false; |
| 440 } | 445 } |
| 441 string filename = prefix + relative_filename; | 446 string filename = prefix + relative_filename; |
| 442 | 447 |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 510 if (file_descriptor < 0) { | 515 if (file_descriptor < 0) { |
| 511 int error = errno; | 516 int error = errno; |
| 512 std::cerr << filename << ": " << strerror(error); | 517 std::cerr << filename << ": " << strerror(error); |
| 513 return false; | 518 return false; |
| 514 } | 519 } |
| 515 | 520 |
| 516 // Create the ZipWriter | 521 // Create the ZipWriter |
| 517 io::FileOutputStream stream(file_descriptor); | 522 io::FileOutputStream stream(file_descriptor); |
| 518 ZipWriter zip_writer(&stream); | 523 ZipWriter zip_writer(&stream); |
| 519 | 524 |
| 520 for (map<string, string*>::const_iterator iter = files_.begin(); | 525 for (std::map<string, string*>::const_iterator iter = files_.begin(); |
| 521 iter != files_.end(); ++iter) { | 526 iter != files_.end(); ++iter) { |
| 522 zip_writer.Write(iter->first, *iter->second); | 527 zip_writer.Write(iter->first, *iter->second); |
| 523 } | 528 } |
| 524 | 529 |
| 525 zip_writer.WriteDirectory(); | 530 zip_writer.WriteDirectory(); |
| 526 | 531 |
| 527 if (stream.GetErrno() != 0) { | 532 if (stream.GetErrno() != 0) { |
| 528 std::cerr << filename << ": " << strerror(stream.GetErrno()) << std::endl; | 533 std::cerr << filename << ": " << strerror(stream.GetErrno()) << std::endl; |
| 529 } | 534 } |
| 530 | 535 |
| 531 if (!stream.Close()) { | 536 if (!stream.Close()) { |
| 532 std::cerr << filename << ": " << strerror(stream.GetErrno()) << std::endl; | 537 std::cerr << filename << ": " << strerror(stream.GetErrno()) << std::endl; |
| 533 } | 538 } |
| 534 | 539 |
| 535 return true; | 540 return true; |
| 536 } | 541 } |
| 537 | 542 |
| 538 void CommandLineInterface::GeneratorContextImpl::AddJarManifest() { | 543 void CommandLineInterface::GeneratorContextImpl::AddJarManifest() { |
| 539 string** map_slot = &files_["META-INF/MANIFEST.MF"]; | 544 string** map_slot = &files_["META-INF/MANIFEST.MF"]; |
| 540 if (*map_slot == NULL) { | 545 if (*map_slot == NULL) { |
| 541 *map_slot = new string( | 546 *map_slot = new string( |
| 542 "Manifest-Version: 1.0\n" | 547 "Manifest-Version: 1.0\n" |
| 543 "Created-By: 1.6.0 (protoc)\n" | 548 "Created-By: 1.6.0 (protoc)\n" |
| 544 "\n"); | 549 "\n"); |
| 545 } | 550 } |
| 546 } | 551 } |
| 547 | 552 |
| 548 void CommandLineInterface::GeneratorContextImpl::GetOutputFilenames( | 553 void CommandLineInterface::GeneratorContextImpl::GetOutputFilenames( |
| 549 vector<string>* output_filenames) { | 554 std::vector<string>* output_filenames) { |
| 550 for (map<string, string*>::iterator iter = files_.begin(); | 555 for (std::map<string, string*>::iterator iter = files_.begin(); |
| 551 iter != files_.end(); ++iter) { | 556 iter != files_.end(); ++iter) { |
| 552 output_filenames->push_back(iter->first); | 557 output_filenames->push_back(iter->first); |
| 553 } | 558 } |
| 554 } | 559 } |
| 555 | 560 |
| 556 io::ZeroCopyOutputStream* CommandLineInterface::GeneratorContextImpl::Open( | 561 io::ZeroCopyOutputStream* CommandLineInterface::GeneratorContextImpl::Open( |
| 557 const string& filename) { | 562 const string& filename) { |
| 558 return new MemoryOutputStream(this, filename, false); | 563 return new MemoryOutputStream(this, filename, false); |
| 559 } | 564 } |
| 560 | 565 |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 607 directory_->had_error_ = true; | 612 directory_->had_error_ = true; |
| 608 } | 613 } |
| 609 return; | 614 return; |
| 610 } | 615 } |
| 611 | 616 |
| 612 *map_slot = new string; | 617 *map_slot = new string; |
| 613 (*map_slot)->swap(data_); | 618 (*map_slot)->swap(data_); |
| 614 } else { | 619 } else { |
| 615 // This was an OpenForInsert(). | 620 // This was an OpenForInsert(). |
| 616 | 621 |
| 617 // If the data doens't end with a clean line break, add one. | 622 // If the data doesn't end with a clean line break, add one. |
| 618 if (!data_.empty() && data_[data_.size() - 1] != '\n') { | 623 if (!data_.empty() && data_[data_.size() - 1] != '\n') { |
| 619 data_.push_back('\n'); | 624 data_.push_back('\n'); |
| 620 } | 625 } |
| 621 | 626 |
| 622 // Find the file we are going to insert into. | 627 // Find the file we are going to insert into. |
| 623 if (*map_slot == NULL) { | 628 if (*map_slot == NULL) { |
| 624 std::cerr << filename_ | 629 std::cerr << filename_ |
| 625 << ": Tried to insert into file that doesn't exist." | 630 << ": Tried to insert into file that doesn't exist." |
| 626 << std::endl; | 631 << std::endl; |
| 627 directory_->had_error_ = true; | 632 directory_->had_error_ = true; |
| 628 return; | 633 return; |
| 629 } | 634 } |
| 630 string* target = *map_slot; | 635 string* target = *map_slot; |
| 631 | 636 |
| 632 // Find the insertion point. | 637 // Find the insertion point. |
| 633 string magic_string = strings::Substitute( | 638 string magic_string = strings::Substitute( |
| 634 "@@protoc_insertion_point($0)", insertion_point_); | 639 "@@protoc_insertion_point($0)", insertion_point_); |
| 635 string::size_type pos = target->find(magic_string); | 640 string::size_type pos = target->find(magic_string); |
| 636 | 641 |
| 637 if (pos == string::npos) { | 642 if (pos == string::npos) { |
| 638 std::cerr << filename_ << ": insertion point \"" << insertion_point_ | 643 std::cerr << filename_ << ": insertion point \"" << insertion_point_ |
| 639 << "\" not found." << std::endl; | 644 << "\" not found." << std::endl; |
| 640 directory_->had_error_ = true; | 645 directory_->had_error_ = true; |
| 641 return; | 646 return; |
| 642 } | 647 } |
| 643 | 648 |
| 644 // Seek backwards to the beginning of the line, which is where we will | 649 if ((pos > 3) && (target->substr(pos - 3, 2) == "/*")) { |
| 645 // insert the data. Note that this has the effect of pushing the insertion | 650 // Support for inline "/* @@protoc_insertion_point() */" |
| 646 // point down, so the data is inserted before it. This is intentional | 651 pos = pos - 3; |
| 647 // because it means that multiple insertions at the same point will end | |
| 648 // up in the expected order in the final output. | |
| 649 pos = target->find_last_of('\n', pos); | |
| 650 if (pos == string::npos) { | |
| 651 // Insertion point is on the first line. | |
| 652 pos = 0; | |
| 653 } else { | 652 } else { |
| 654 // Advance to character after '\n'. | 653 // Seek backwards to the beginning of the line, which is where we will |
| 655 ++pos; | 654 // insert the data. Note that this has the effect of pushing the |
| 655 // insertion point down, so the data is inserted before it. This is |
| 656 // intentional because it means that multiple insertions at the same point |
| 657 // will end up in the expected order in the final output. |
| 658 pos = target->find_last_of('\n', pos); |
| 659 if (pos == string::npos) { |
| 660 // Insertion point is on the first line. |
| 661 pos = 0; |
| 662 } else { |
| 663 // Advance to character after '\n'. |
| 664 ++pos; |
| 665 } |
| 656 } | 666 } |
| 657 | 667 |
| 658 // Extract indent. | 668 // Extract indent. |
| 659 string indent_(*target, pos, target->find_first_not_of(" \t", pos) - pos); | 669 string indent_(*target, pos, target->find_first_not_of(" \t", pos) - pos); |
| 660 | 670 |
| 661 if (indent_.empty()) { | 671 if (indent_.empty()) { |
| 662 // No indent. This makes things easier. | 672 // No indent. This makes things easier. |
| 663 target->insert(pos, data_); | 673 target->insert(pos, data_); |
| 664 } else { | 674 } else { |
| 665 // Calculate how much space we need. | 675 // Calculate how much space we need. |
| (...skipping 28 matching lines...) Expand all Loading... |
| 694 } | 704 } |
| 695 } | 705 } |
| 696 } | 706 } |
| 697 | 707 |
| 698 // =================================================================== | 708 // =================================================================== |
| 699 | 709 |
| 700 CommandLineInterface::CommandLineInterface() | 710 CommandLineInterface::CommandLineInterface() |
| 701 : mode_(MODE_COMPILE), | 711 : mode_(MODE_COMPILE), |
| 702 print_mode_(PRINT_NONE), | 712 print_mode_(PRINT_NONE), |
| 703 error_format_(ERROR_FORMAT_GCC), | 713 error_format_(ERROR_FORMAT_GCC), |
| 714 direct_dependencies_explicitly_set_(false), |
| 704 imports_in_descriptor_set_(false), | 715 imports_in_descriptor_set_(false), |
| 705 source_info_in_descriptor_set_(false), | 716 source_info_in_descriptor_set_(false), |
| 706 disallow_services_(false), | 717 disallow_services_(false), |
| 707 inputs_are_proto_path_relative_(false) {} | 718 inputs_are_proto_path_relative_(false) {} |
| 708 CommandLineInterface::~CommandLineInterface() {} | 719 CommandLineInterface::~CommandLineInterface() {} |
| 709 | 720 |
| 710 void CommandLineInterface::RegisterGenerator(const string& flag_name, | 721 void CommandLineInterface::RegisterGenerator(const string& flag_name, |
| 711 CodeGenerator* generator, | 722 CodeGenerator* generator, |
| 712 const string& help_text) { | 723 const string& help_text) { |
| 713 GeneratorInfo info; | 724 GeneratorInfo info; |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 757 if (!inputs_are_proto_path_relative_) { | 768 if (!inputs_are_proto_path_relative_) { |
| 758 if (!MakeInputsBeProtoPathRelative(&source_tree)) { | 769 if (!MakeInputsBeProtoPathRelative(&source_tree)) { |
| 759 return 1; | 770 return 1; |
| 760 } | 771 } |
| 761 } | 772 } |
| 762 | 773 |
| 763 // Allocate the Importer. | 774 // Allocate the Importer. |
| 764 ErrorPrinter error_collector(error_format_, &source_tree); | 775 ErrorPrinter error_collector(error_format_, &source_tree); |
| 765 Importer importer(&source_tree, &error_collector); | 776 Importer importer(&source_tree, &error_collector); |
| 766 | 777 |
| 767 vector<const FileDescriptor*> parsed_files; | 778 std::vector<const FileDescriptor*> parsed_files; |
| 768 | 779 |
| 769 // Parse each file. | 780 // Parse each file. |
| 770 for (int i = 0; i < input_files_.size(); i++) { | 781 for (int i = 0; i < input_files_.size(); i++) { |
| 771 // Import the file. | 782 // Import the file. |
| 772 importer.AddUnusedImportTrackFile(input_files_[i]); | 783 importer.AddUnusedImportTrackFile(input_files_[i]); |
| 773 const FileDescriptor* parsed_file = importer.Import(input_files_[i]); | 784 const FileDescriptor* parsed_file = importer.Import(input_files_[i]); |
| 774 importer.ClearUnusedImportTrackFiles(); | 785 importer.ClearUnusedImportTrackFiles(); |
| 775 if (parsed_file == NULL) return 1; | 786 if (parsed_file == NULL) return 1; |
| 776 parsed_files.push_back(parsed_file); | 787 parsed_files.push_back(parsed_file); |
| 777 | 788 |
| 778 // Enforce --disallow_services. | 789 // Enforce --disallow_services. |
| 779 if (disallow_services_ && parsed_file->service_count() > 0) { | 790 if (disallow_services_ && parsed_file->service_count() > 0) { |
| 780 cerr << parsed_file->name() << ": This file contains services, but " | 791 cerr << parsed_file->name() << ": This file contains services, but " |
| 781 "--disallow_services was used." << endl; | 792 "--disallow_services was used." << endl; |
| 782 return 1; | 793 return 1; |
| 783 } | 794 } |
| 795 |
| 796 // Enforce --direct_dependencies |
| 797 if (direct_dependencies_explicitly_set_) { |
| 798 bool indirect_imports = false; |
| 799 for (int i = 0; i < parsed_file->dependency_count(); i++) { |
| 800 if (direct_dependencies_.find(parsed_file->dependency(i)->name()) == |
| 801 direct_dependencies_.end()) { |
| 802 indirect_imports = true; |
| 803 cerr << parsed_file->name() |
| 804 << ": File is imported but not declared in " |
| 805 << "--direct_dependencies: " |
| 806 << parsed_file->dependency(i)->name() << std::endl; |
| 807 } |
| 808 } |
| 809 if (indirect_imports) { |
| 810 return 1; |
| 811 } |
| 812 } |
| 784 } | 813 } |
| 785 | 814 |
| 786 // We construct a separate GeneratorContext for each output location. Note | 815 // We construct a separate GeneratorContext for each output location. Note |
| 787 // that two code generators may output to the same location, in which case | 816 // that two code generators may output to the same location, in which case |
| 788 // they should share a single GeneratorContext so that OpenForInsert() works. | 817 // they should share a single GeneratorContext so that OpenForInsert() works. |
| 789 GeneratorContextMap output_directories; | 818 GeneratorContextMap output_directories; |
| 790 | 819 |
| 791 // Generate output. | 820 // Generate output. |
| 792 if (mode_ == MODE_COMPILE) { | 821 if (mode_ == MODE_COMPILE) { |
| 793 for (int i = 0; i < output_directives_.size(); i++) { | 822 for (int i = 0; i < output_directives_.size(); i++) { |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 887 | 916 |
| 888 return 0; | 917 return 0; |
| 889 } | 918 } |
| 890 | 919 |
| 891 void CommandLineInterface::Clear() { | 920 void CommandLineInterface::Clear() { |
| 892 // Clear all members that are set by Run(). Note that we must not clear | 921 // Clear all members that are set by Run(). Note that we must not clear |
| 893 // members which are set by other methods before Run() is called. | 922 // members which are set by other methods before Run() is called. |
| 894 executable_name_.clear(); | 923 executable_name_.clear(); |
| 895 proto_path_.clear(); | 924 proto_path_.clear(); |
| 896 input_files_.clear(); | 925 input_files_.clear(); |
| 926 direct_dependencies_.clear(); |
| 897 output_directives_.clear(); | 927 output_directives_.clear(); |
| 898 codec_type_.clear(); | 928 codec_type_.clear(); |
| 899 descriptor_set_name_.clear(); | 929 descriptor_set_name_.clear(); |
| 900 dependency_out_name_.clear(); | 930 dependency_out_name_.clear(); |
| 901 | 931 |
| 902 mode_ = MODE_COMPILE; | 932 mode_ = MODE_COMPILE; |
| 903 print_mode_ = PRINT_NONE; | 933 print_mode_ = PRINT_NONE; |
| 904 imports_in_descriptor_set_ = false; | 934 imports_in_descriptor_set_ = false; |
| 905 source_info_in_descriptor_set_ = false; | 935 source_info_in_descriptor_set_ = false; |
| 906 disallow_services_ = false; | 936 disallow_services_ = false; |
| 937 direct_dependencies_explicitly_set_ = false; |
| 907 } | 938 } |
| 908 | 939 |
| 909 bool CommandLineInterface::MakeInputsBeProtoPathRelative( | 940 bool CommandLineInterface::MakeInputsBeProtoPathRelative( |
| 910 DiskSourceTree* source_tree) { | 941 DiskSourceTree* source_tree) { |
| 911 for (int i = 0; i < input_files_.size(); i++) { | 942 for (int i = 0; i < input_files_.size(); i++) { |
| 912 string virtual_file, shadowing_disk_file; | 943 string virtual_file, shadowing_disk_file; |
| 913 switch (source_tree->DiskFileToVirtualFile( | 944 switch (source_tree->DiskFileToVirtualFile( |
| 914 input_files_[i], &virtual_file, &shadowing_disk_file)) { | 945 input_files_[i], &virtual_file, &shadowing_disk_file)) { |
| 915 case DiskSourceTree::SUCCESS: | 946 case DiskSourceTree::SUCCESS: |
| 916 input_files_[i] = virtual_file; | 947 input_files_[i] = virtual_file; |
| (...skipping 30 matching lines...) Expand all Loading... |
| 947 } | 978 } |
| 948 | 979 |
| 949 return true; | 980 return true; |
| 950 } | 981 } |
| 951 | 982 |
| 952 | 983 |
| 953 CommandLineInterface::ParseArgumentStatus | 984 CommandLineInterface::ParseArgumentStatus |
| 954 CommandLineInterface::ParseArguments(int argc, const char* const argv[]) { | 985 CommandLineInterface::ParseArguments(int argc, const char* const argv[]) { |
| 955 executable_name_ = argv[0]; | 986 executable_name_ = argv[0]; |
| 956 | 987 |
| 957 vector<string> arguments; | 988 std::vector<string> arguments; |
| 958 for (int i = 1; i < argc; ++i) { | 989 for (int i = 1; i < argc; ++i) { |
| 959 arguments.push_back(argv[i]); | 990 arguments.push_back(argv[i]); |
| 960 } | 991 } |
| 961 | 992 |
| 962 // Iterate through all arguments and parse them. | 993 // Iterate through all arguments and parse them. |
| 963 for (int i = 0; i < arguments.size(); ++i) { | 994 for (int i = 0; i < arguments.size(); ++i) { |
| 964 string name, value; | 995 string name, value; |
| 965 | 996 |
| 966 if (ParseArgument(arguments[i].c_str(), &name, &value)) { | 997 if (ParseArgument(arguments[i].c_str(), &name, &value)) { |
| 967 // Returned true => Use the next argument as the flag value. | 998 // Returned true => Use the next argument as the flag value. |
| 968 if (i + 1 == arguments.size() || arguments[i + 1][0] == '-') { | 999 if (i + 1 == arguments.size() || arguments[i + 1][0] == '-') { |
| 969 std::cerr << "Missing value for flag: " << name << std::endl; | 1000 std::cerr << "Missing value for flag: " << name << std::endl; |
| 970 if (name == "--decode") { | 1001 if (name == "--decode") { |
| 971 std::cerr << "To decode an unknown message, use --decode_raw." | 1002 std::cerr << "To decode an unknown message, use --decode_raw." |
| 972 << std::endl; | 1003 << std::endl; |
| 973 } | 1004 } |
| 974 return PARSE_ARGUMENT_FAIL; | 1005 return PARSE_ARGUMENT_FAIL; |
| 975 } else { | 1006 } else { |
| 976 ++i; | 1007 ++i; |
| 977 value = arguments[i]; | 1008 value = arguments[i]; |
| 978 } | 1009 } |
| 979 } | 1010 } |
| 980 | 1011 |
| 981 ParseArgumentStatus status = InterpretArgument(name, value); | 1012 ParseArgumentStatus status = InterpretArgument(name, value); |
| 982 if (status != PARSE_ARGUMENT_DONE_AND_CONTINUE) | 1013 if (status != PARSE_ARGUMENT_DONE_AND_CONTINUE) |
| 983 return status; | 1014 return status; |
| 984 } | 1015 } |
| 985 | 1016 |
| 1017 // Make sure each plugin option has a matching plugin output. |
| 1018 for (map<string, string>::const_iterator i = plugin_parameters_.begin(); |
| 1019 i != plugin_parameters_.end(); ++i) { |
| 1020 if (plugins_.find(i->first) == plugins_.end()) { |
| 1021 std::cerr << "Unknown flag: " |
| 1022 // strip prefix + "gen-" and add back "_opt" |
| 1023 << "--" + i->first.substr(plugin_prefix_.size() + 4) + "_opt" |
| 1024 << std::endl; |
| 1025 return PARSE_ARGUMENT_FAIL; |
| 1026 } |
| 1027 } |
| 1028 |
| 986 // If no --proto_path was given, use the current working directory. | 1029 // If no --proto_path was given, use the current working directory. |
| 987 if (proto_path_.empty()) { | 1030 if (proto_path_.empty()) { |
| 988 // Don't use make_pair as the old/default standard library on Solaris | 1031 // Don't use make_pair as the old/default standard library on Solaris |
| 989 // doesn't support it without explicit template parameters, which are | 1032 // doesn't support it without explicit template parameters, which are |
| 990 // incompatible with C++0x's make_pair. | 1033 // incompatible with C++0x's make_pair. |
| 991 proto_path_.push_back(pair<string, string>("", ".")); | 1034 proto_path_.push_back(std::pair<string, string>("", ".")); |
| 992 } | 1035 } |
| 993 | 1036 |
| 994 // Check some errror cases. | 1037 // Check some errror cases. |
| 995 bool decoding_raw = (mode_ == MODE_DECODE) && codec_type_.empty(); | 1038 bool decoding_raw = (mode_ == MODE_DECODE) && codec_type_.empty(); |
| 996 if (decoding_raw && !input_files_.empty()) { | 1039 if (decoding_raw && !input_files_.empty()) { |
| 997 std::cerr << "When using --decode_raw, no input files should be given." | 1040 std::cerr << "When using --decode_raw, no input files should be given." |
| 998 << std::endl; | 1041 << std::endl; |
| 999 return PARSE_ARGUMENT_FAIL; | 1042 return PARSE_ARGUMENT_FAIL; |
| 1000 } else if (!decoding_raw && input_files_.empty()) { | 1043 } else if (!decoding_raw && input_files_.empty()) { |
| 1001 std::cerr << "Missing input file." << std::endl; | 1044 std::cerr << "Missing input file." << std::endl; |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1104 "input so the program is going to die now." << std::endl; | 1147 "input so the program is going to die now." << std::endl; |
| 1105 return PARSE_ARGUMENT_FAIL; | 1148 return PARSE_ARGUMENT_FAIL; |
| 1106 } | 1149 } |
| 1107 | 1150 |
| 1108 input_files_.push_back(value); | 1151 input_files_.push_back(value); |
| 1109 | 1152 |
| 1110 } else if (name == "-I" || name == "--proto_path") { | 1153 } else if (name == "-I" || name == "--proto_path") { |
| 1111 // Java's -classpath (and some other languages) delimits path components | 1154 // Java's -classpath (and some other languages) delimits path components |
| 1112 // with colons. Let's accept that syntax too just to make things more | 1155 // with colons. Let's accept that syntax too just to make things more |
| 1113 // intuitive. | 1156 // intuitive. |
| 1114 vector<string> parts = Split( | 1157 std::vector<string> parts = Split( |
| 1115 value, kPathSeparator, true); | 1158 value, kPathSeparator, true); |
| 1116 | 1159 |
| 1117 for (int i = 0; i < parts.size(); i++) { | 1160 for (int i = 0; i < parts.size(); i++) { |
| 1118 string virtual_path; | 1161 string virtual_path; |
| 1119 string disk_path; | 1162 string disk_path; |
| 1120 | 1163 |
| 1121 string::size_type equals_pos = parts[i].find_first_of('='); | 1164 string::size_type equals_pos = parts[i].find_first_of('='); |
| 1122 if (equals_pos == string::npos) { | 1165 if (equals_pos == string::npos) { |
| 1123 virtual_path = ""; | 1166 virtual_path = ""; |
| 1124 disk_path = parts[i]; | 1167 disk_path = parts[i]; |
| 1125 } else { | 1168 } else { |
| 1126 virtual_path = parts[i].substr(0, equals_pos); | 1169 virtual_path = parts[i].substr(0, equals_pos); |
| 1127 disk_path = parts[i].substr(equals_pos + 1); | 1170 disk_path = parts[i].substr(equals_pos + 1); |
| 1128 } | 1171 } |
| 1129 | 1172 |
| 1130 if (disk_path.empty()) { | 1173 if (disk_path.empty()) { |
| 1131 std::cerr | 1174 std::cerr |
| 1132 << "--proto_path passed empty directory name. (Use \".\" for " | 1175 << "--proto_path passed empty directory name. (Use \".\" for " |
| 1133 "current directory.)" << std::endl; | 1176 "current directory.)" << std::endl; |
| 1134 return PARSE_ARGUMENT_FAIL; | 1177 return PARSE_ARGUMENT_FAIL; |
| 1135 } | 1178 } |
| 1136 | 1179 |
| 1137 // Make sure disk path exists, warn otherwise. | 1180 // Make sure disk path exists, warn otherwise. |
| 1138 if (access(disk_path.c_str(), F_OK) < 0) { | 1181 if (access(disk_path.c_str(), F_OK) < 0) { |
| 1139 std::cerr << disk_path << ": warning: directory does not exist." | 1182 // Try the original path; it may have just happed to have a '=' in it. |
| 1140 << std::endl; | 1183 if (access(parts[i].c_str(), F_OK) < 0) { |
| 1184 cerr << disk_path << ": warning: directory does not exist." << endl; |
| 1185 } else { |
| 1186 virtual_path = ""; |
| 1187 disk_path = parts[i]; |
| 1188 } |
| 1141 } | 1189 } |
| 1142 | 1190 |
| 1143 // Don't use make_pair as the old/default standard library on Solaris | 1191 // Don't use make_pair as the old/default standard library on Solaris |
| 1144 // doesn't support it without explicit template parameters, which are | 1192 // doesn't support it without explicit template parameters, which are |
| 1145 // incompatible with C++0x's make_pair. | 1193 // incompatible with C++0x's make_pair. |
| 1146 proto_path_.push_back(pair<string, string>(virtual_path, disk_path)); | 1194 proto_path_.push_back(std::pair<string, string>(virtual_path, disk_path)); |
| 1147 } | 1195 } |
| 1148 | 1196 |
| 1197 } else if (name == "--direct_dependencies") { |
| 1198 if (direct_dependencies_explicitly_set_) { |
| 1199 std::cerr << name << " may only be passed once. To specify multiple " |
| 1200 "direct dependencies, pass them all as a single " |
| 1201 "parameter separated by ':'." |
| 1202 << std::endl; |
| 1203 return PARSE_ARGUMENT_FAIL; |
| 1204 } |
| 1205 |
| 1206 direct_dependencies_explicitly_set_ = true; |
| 1207 std::vector<string> direct = Split( |
| 1208 value, ":", true); |
| 1209 GOOGLE_DCHECK(direct_dependencies_.empty()); |
| 1210 direct_dependencies_.insert(direct.begin(), direct.end()); |
| 1211 |
| 1149 } else if (name == "-o" || name == "--descriptor_set_out") { | 1212 } else if (name == "-o" || name == "--descriptor_set_out") { |
| 1150 if (!descriptor_set_name_.empty()) { | 1213 if (!descriptor_set_name_.empty()) { |
| 1151 std::cerr << name << " may only be passed once." << std::endl; | 1214 std::cerr << name << " may only be passed once." << std::endl; |
| 1152 return PARSE_ARGUMENT_FAIL; | 1215 return PARSE_ARGUMENT_FAIL; |
| 1153 } | 1216 } |
| 1154 if (value.empty()) { | 1217 if (value.empty()) { |
| 1155 std::cerr << name << " requires a non-empty value." << std::endl; | 1218 std::cerr << name << " requires a non-empty value." << std::endl; |
| 1156 return PARSE_ARGUMENT_FAIL; | 1219 return PARSE_ARGUMENT_FAIL; |
| 1157 } | 1220 } |
| 1158 if (mode_ != MODE_COMPILE) { | 1221 if (mode_ != MODE_COMPILE) { |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1286 mode_ = MODE_PRINT; | 1349 mode_ = MODE_PRINT; |
| 1287 print_mode_ = PRINT_FREE_FIELDS; | 1350 print_mode_ = PRINT_FREE_FIELDS; |
| 1288 } else { | 1351 } else { |
| 1289 // Some other flag. Look it up in the generators list. | 1352 // Some other flag. Look it up in the generators list. |
| 1290 const GeneratorInfo* generator_info = | 1353 const GeneratorInfo* generator_info = |
| 1291 FindOrNull(generators_by_flag_name_, name); | 1354 FindOrNull(generators_by_flag_name_, name); |
| 1292 if (generator_info == NULL && | 1355 if (generator_info == NULL && |
| 1293 (plugin_prefix_.empty() || !HasSuffixString(name, "_out"))) { | 1356 (plugin_prefix_.empty() || !HasSuffixString(name, "_out"))) { |
| 1294 // Check if it's a generator option flag. | 1357 // Check if it's a generator option flag. |
| 1295 generator_info = FindOrNull(generators_by_option_name_, name); | 1358 generator_info = FindOrNull(generators_by_option_name_, name); |
| 1296 if (generator_info == NULL) { | 1359 if (generator_info != NULL) { |
| 1297 std::cerr << "Unknown flag: " << name << std::endl; | |
| 1298 return PARSE_ARGUMENT_FAIL; | |
| 1299 } else { | |
| 1300 string* parameters = &generator_parameters_[generator_info->flag_name]; | 1360 string* parameters = &generator_parameters_[generator_info->flag_name]; |
| 1301 if (!parameters->empty()) { | 1361 if (!parameters->empty()) { |
| 1302 parameters->append(","); | 1362 parameters->append(","); |
| 1303 } | 1363 } |
| 1304 parameters->append(value); | 1364 parameters->append(value); |
| 1365 } else if (HasPrefixString(name, "--") && HasSuffixString(name, "_opt")) { |
| 1366 string* parameters = |
| 1367 &plugin_parameters_[PluginName(plugin_prefix_, name)]; |
| 1368 if (!parameters->empty()) { |
| 1369 parameters->append(","); |
| 1370 } |
| 1371 parameters->append(value); |
| 1372 } else { |
| 1373 std::cerr << "Unknown flag: " << name << std::endl; |
| 1374 return PARSE_ARGUMENT_FAIL; |
| 1305 } | 1375 } |
| 1306 } else { | 1376 } else { |
| 1307 // It's an output flag. Add it to the output directives. | 1377 // It's an output flag. Add it to the output directives. |
| 1308 if (mode_ != MODE_COMPILE) { | 1378 if (mode_ != MODE_COMPILE) { |
| 1309 std::cerr << "Cannot use --encode, --decode or print .proto info and " | 1379 std::cerr << "Cannot use --encode, --decode or print .proto info and " |
| 1310 "generate code at the same time." << std::endl; | 1380 "generate code at the same time." << std::endl; |
| 1311 return PARSE_ARGUMENT_FAIL; | 1381 return PARSE_ARGUMENT_FAIL; |
| 1312 } | 1382 } |
| 1313 | 1383 |
| 1314 OutputDirective directive; | 1384 OutputDirective directive; |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1402 // FIXME(kenton): If the text is long enough it will wrap, which is ugly, | 1472 // FIXME(kenton): If the text is long enough it will wrap, which is ugly, |
| 1403 // but fixing this nicely (e.g. splitting on spaces) is probably more | 1473 // but fixing this nicely (e.g. splitting on spaces) is probably more |
| 1404 // trouble than it's worth. | 1474 // trouble than it's worth. |
| 1405 std::cerr << " " << iter->first << "=OUT_DIR " | 1475 std::cerr << " " << iter->first << "=OUT_DIR " |
| 1406 << string(19 - iter->first.size(), ' ') // Spaces for alignment. | 1476 << string(19 - iter->first.size(), ' ') // Spaces for alignment. |
| 1407 << iter->second.help_text << std::endl; | 1477 << iter->second.help_text << std::endl; |
| 1408 } | 1478 } |
| 1409 } | 1479 } |
| 1410 | 1480 |
| 1411 bool CommandLineInterface::GenerateOutput( | 1481 bool CommandLineInterface::GenerateOutput( |
| 1412 const vector<const FileDescriptor*>& parsed_files, | 1482 const std::vector<const FileDescriptor*>& parsed_files, |
| 1413 const OutputDirective& output_directive, | 1483 const OutputDirective& output_directive, |
| 1414 GeneratorContext* generator_context) { | 1484 GeneratorContext* generator_context) { |
| 1415 // Call the generator. | 1485 // Call the generator. |
| 1416 string error; | 1486 string error; |
| 1417 if (output_directive.generator == NULL) { | 1487 if (output_directive.generator == NULL) { |
| 1418 // This is a plugin. | 1488 // This is a plugin. |
| 1419 GOOGLE_CHECK(HasPrefixString(output_directive.name, "--") && | 1489 GOOGLE_CHECK(HasPrefixString(output_directive.name, "--") && |
| 1420 HasSuffixString(output_directive.name, "_out")) | 1490 HasSuffixString(output_directive.name, "_out")) |
| 1421 << "Bad name for plugin generator: " << output_directive.name; | 1491 << "Bad name for plugin generator: " << output_directive.name; |
| 1422 | 1492 |
| 1423 // Strip the "--" and "_out" and add the plugin prefix. | 1493 string plugin_name = PluginName(plugin_prefix_ , output_directive.name); |
| 1424 string plugin_name = plugin_prefix_ + "gen-" + | 1494 string parameters = output_directive.parameter; |
| 1425 output_directive.name.substr(2, output_directive.name.size() - 6); | 1495 if (!plugin_parameters_[plugin_name].empty()) { |
| 1426 | 1496 if (!parameters.empty()) { |
| 1497 parameters.append(","); |
| 1498 } |
| 1499 parameters.append(plugin_parameters_[plugin_name]); |
| 1500 } |
| 1427 if (!GeneratePluginOutput(parsed_files, plugin_name, | 1501 if (!GeneratePluginOutput(parsed_files, plugin_name, |
| 1428 output_directive.parameter, | 1502 parameters, |
| 1429 generator_context, &error)) { | 1503 generator_context, &error)) { |
| 1430 std::cerr << output_directive.name << ": " << error << std::endl; | 1504 std::cerr << output_directive.name << ": " << error << std::endl; |
| 1431 return false; | 1505 return false; |
| 1432 } | 1506 } |
| 1433 } else { | 1507 } else { |
| 1434 // Regular generator. | 1508 // Regular generator. |
| 1435 string parameters = output_directive.parameter; | 1509 string parameters = output_directive.parameter; |
| 1436 if (!generator_parameters_[output_directive.name].empty()) { | 1510 if (!generator_parameters_[output_directive.name].empty()) { |
| 1437 if (!parameters.empty()) { | 1511 if (!parameters.empty()) { |
| 1438 parameters.append(","); | 1512 parameters.append(","); |
| 1439 } | 1513 } |
| 1440 parameters.append(generator_parameters_[output_directive.name]); | 1514 parameters.append(generator_parameters_[output_directive.name]); |
| 1441 } | 1515 } |
| 1442 if (output_directive.generator->HasGenerateAll()) { | 1516 if (!output_directive.generator->GenerateAll( |
| 1443 if (!output_directive.generator->GenerateAll( | 1517 parsed_files, parameters, generator_context, &error)) { |
| 1444 parsed_files, parameters, generator_context, &error)) { | 1518 // Generator returned an error. |
| 1445 // Generator returned an error. | 1519 std::cerr << output_directive.name << ": " << error << std::endl; |
| 1446 std::cerr << output_directive.name << ": " | 1520 return false; |
| 1447 << ": " << error << std::endl; | |
| 1448 return false; | |
| 1449 } | |
| 1450 } else { | |
| 1451 for (int i = 0; i < parsed_files.size(); i++) { | |
| 1452 if (!output_directive.generator->Generate(parsed_files[i], parameters, | |
| 1453 generator_context, &error)) { | |
| 1454 // Generator returned an error. | |
| 1455 std::cerr << output_directive.name << ": " << parsed_files[i]->name() | |
| 1456 << ": " << error << std::endl; | |
| 1457 return false; | |
| 1458 } | |
| 1459 } | |
| 1460 } | 1521 } |
| 1461 } | 1522 } |
| 1462 | 1523 |
| 1463 return true; | 1524 return true; |
| 1464 } | 1525 } |
| 1465 | 1526 |
| 1466 bool CommandLineInterface::GenerateDependencyManifestFile( | 1527 bool CommandLineInterface::GenerateDependencyManifestFile( |
| 1467 const vector<const FileDescriptor*>& parsed_files, | 1528 const std::vector<const FileDescriptor*>& parsed_files, |
| 1468 const GeneratorContextMap& output_directories, | 1529 const GeneratorContextMap& output_directories, |
| 1469 DiskSourceTree* source_tree) { | 1530 DiskSourceTree* source_tree) { |
| 1470 FileDescriptorSet file_set; | 1531 FileDescriptorSet file_set; |
| 1471 | 1532 |
| 1472 set<const FileDescriptor*> already_seen; | 1533 std::set<const FileDescriptor*> already_seen; |
| 1473 for (int i = 0; i < parsed_files.size(); i++) { | 1534 for (int i = 0; i < parsed_files.size(); i++) { |
| 1474 GetTransitiveDependencies(parsed_files[i], | 1535 GetTransitiveDependencies(parsed_files[i], |
| 1475 false, | 1536 false, |
| 1476 false, | 1537 false, |
| 1477 &already_seen, | 1538 &already_seen, |
| 1478 file_set.mutable_file()); | 1539 file_set.mutable_file()); |
| 1479 } | 1540 } |
| 1480 | 1541 |
| 1481 vector<string> output_filenames; | 1542 std::vector<string> output_filenames; |
| 1482 for (GeneratorContextMap::const_iterator iter = output_directories.begin(); | 1543 for (GeneratorContextMap::const_iterator iter = output_directories.begin(); |
| 1483 iter != output_directories.end(); ++iter) { | 1544 iter != output_directories.end(); ++iter) { |
| 1484 const string& location = iter->first; | 1545 const string& location = iter->first; |
| 1485 GeneratorContextImpl* directory = iter->second; | 1546 GeneratorContextImpl* directory = iter->second; |
| 1486 vector<string> relative_output_filenames; | 1547 std::vector<string> relative_output_filenames; |
| 1487 directory->GetOutputFilenames(&relative_output_filenames); | 1548 directory->GetOutputFilenames(&relative_output_filenames); |
| 1488 for (int i = 0; i < relative_output_filenames.size(); i++) { | 1549 for (int i = 0; i < relative_output_filenames.size(); i++) { |
| 1489 string output_filename = location + relative_output_filenames[i]; | 1550 string output_filename = location + relative_output_filenames[i]; |
| 1490 if (output_filename.compare(0, 2, "./") == 0) { | 1551 if (output_filename.compare(0, 2, "./") == 0) { |
| 1491 output_filename = output_filename.substr(2); | 1552 output_filename = output_filename.substr(2); |
| 1492 } | 1553 } |
| 1493 output_filenames.push_back(output_filename); | 1554 output_filenames.push_back(output_filename); |
| 1494 } | 1555 } |
| 1495 } | 1556 } |
| 1496 | 1557 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1529 std::cerr << "Unable to identify path for file " << virtual_file | 1590 std::cerr << "Unable to identify path for file " << virtual_file |
| 1530 << std::endl; | 1591 << std::endl; |
| 1531 return false; | 1592 return false; |
| 1532 } | 1593 } |
| 1533 } | 1594 } |
| 1534 | 1595 |
| 1535 return true; | 1596 return true; |
| 1536 } | 1597 } |
| 1537 | 1598 |
| 1538 bool CommandLineInterface::GeneratePluginOutput( | 1599 bool CommandLineInterface::GeneratePluginOutput( |
| 1539 const vector<const FileDescriptor*>& parsed_files, | 1600 const std::vector<const FileDescriptor*>& parsed_files, |
| 1540 const string& plugin_name, | 1601 const string& plugin_name, |
| 1541 const string& parameter, | 1602 const string& parameter, |
| 1542 GeneratorContext* generator_context, | 1603 GeneratorContext* generator_context, |
| 1543 string* error) { | 1604 string* error) { |
| 1544 CodeGeneratorRequest request; | 1605 CodeGeneratorRequest request; |
| 1545 CodeGeneratorResponse response; | 1606 CodeGeneratorResponse response; |
| 1546 | 1607 |
| 1547 // Build the request. | 1608 // Build the request. |
| 1548 if (!parameter.empty()) { | 1609 if (!parameter.empty()) { |
| 1549 request.set_parameter(parameter); | 1610 request.set_parameter(parameter); |
| 1550 } | 1611 } |
| 1551 | 1612 |
| 1552 set<const FileDescriptor*> already_seen; | 1613 std::set<const FileDescriptor*> already_seen; |
| 1553 for (int i = 0; i < parsed_files.size(); i++) { | 1614 for (int i = 0; i < parsed_files.size(); i++) { |
| 1554 request.add_file_to_generate(parsed_files[i]->name()); | 1615 request.add_file_to_generate(parsed_files[i]->name()); |
| 1555 GetTransitiveDependencies(parsed_files[i], | 1616 GetTransitiveDependencies(parsed_files[i], |
| 1556 true, // Include json_name for plugins. | 1617 true, // Include json_name for plugins. |
| 1557 true, // Include source code info. | 1618 true, // Include source code info. |
| 1558 &already_seen, request.mutable_proto_file()); | 1619 &already_seen, request.mutable_proto_file()); |
| 1559 } | 1620 } |
| 1560 | 1621 |
| 1622 google::protobuf::compiler::Version* version = |
| 1623 request.mutable_compiler_version(); |
| 1624 version->set_major(GOOGLE_PROTOBUF_VERSION / 1000000); |
| 1625 version->set_minor(GOOGLE_PROTOBUF_VERSION / 1000 % 1000); |
| 1626 version->set_patch(GOOGLE_PROTOBUF_VERSION % 1000); |
| 1627 version->set_suffix(GOOGLE_PROTOBUF_VERSION_SUFFIX); |
| 1628 |
| 1561 // Invoke the plugin. | 1629 // Invoke the plugin. |
| 1562 Subprocess subprocess; | 1630 Subprocess subprocess; |
| 1563 | 1631 |
| 1564 if (plugins_.count(plugin_name) > 0) { | 1632 if (plugins_.count(plugin_name) > 0) { |
| 1565 subprocess.Start(plugins_[plugin_name], Subprocess::EXACT_NAME); | 1633 subprocess.Start(plugins_[plugin_name], Subprocess::EXACT_NAME); |
| 1566 } else { | 1634 } else { |
| 1567 subprocess.Start(plugin_name, Subprocess::SEARCH_PATH); | 1635 subprocess.Start(plugin_name, Subprocess::SEARCH_PATH); |
| 1568 } | 1636 } |
| 1569 | 1637 |
| 1570 string communicate_error; | 1638 string communicate_error; |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1672 if (!TextFormat::Print(*message, &out)) { | 1740 if (!TextFormat::Print(*message, &out)) { |
| 1673 std::cerr << "output: I/O error." << std::endl; | 1741 std::cerr << "output: I/O error." << std::endl; |
| 1674 return false; | 1742 return false; |
| 1675 } | 1743 } |
| 1676 } | 1744 } |
| 1677 | 1745 |
| 1678 return true; | 1746 return true; |
| 1679 } | 1747 } |
| 1680 | 1748 |
| 1681 bool CommandLineInterface::WriteDescriptorSet( | 1749 bool CommandLineInterface::WriteDescriptorSet( |
| 1682 const vector<const FileDescriptor*> parsed_files) { | 1750 const std::vector<const FileDescriptor*> parsed_files) { |
| 1683 FileDescriptorSet file_set; | 1751 FileDescriptorSet file_set; |
| 1684 | 1752 |
| 1685 if (imports_in_descriptor_set_) { | 1753 if (imports_in_descriptor_set_) { |
| 1686 set<const FileDescriptor*> already_seen; | 1754 std::set<const FileDescriptor*> already_seen; |
| 1687 for (int i = 0; i < parsed_files.size(); i++) { | 1755 for (int i = 0; i < parsed_files.size(); i++) { |
| 1688 GetTransitiveDependencies(parsed_files[i], | 1756 GetTransitiveDependencies(parsed_files[i], |
| 1689 true, // Include json_name | 1757 true, // Include json_name |
| 1690 source_info_in_descriptor_set_, | 1758 source_info_in_descriptor_set_, |
| 1691 &already_seen, file_set.mutable_file()); | 1759 &already_seen, file_set.mutable_file()); |
| 1692 } | 1760 } |
| 1693 } else { | 1761 } else { |
| 1694 set<const FileDescriptor*> already_seen; | 1762 std::set<const FileDescriptor*> already_seen; |
| 1695 for (int i = 0; i < parsed_files.size(); i++) { | 1763 for (int i = 0; i < parsed_files.size(); i++) { |
| 1696 if (!already_seen.insert(parsed_files[i]).second) { | 1764 if (!already_seen.insert(parsed_files[i]).second) { |
| 1697 continue; | 1765 continue; |
| 1698 } | 1766 } |
| 1699 FileDescriptorProto* file_proto = file_set.add_file(); | 1767 FileDescriptorProto* file_proto = file_set.add_file(); |
| 1700 parsed_files[i]->CopyTo(file_proto); | 1768 parsed_files[i]->CopyTo(file_proto); |
| 1701 parsed_files[i]->CopyJsonNameTo(file_proto); | 1769 parsed_files[i]->CopyJsonNameTo(file_proto); |
| 1702 if (source_info_in_descriptor_set_) { | 1770 if (source_info_in_descriptor_set_) { |
| 1703 parsed_files[i]->CopySourceCodeInfoTo(file_proto); | 1771 parsed_files[i]->CopySourceCodeInfoTo(file_proto); |
| 1704 } | 1772 } |
| (...skipping 24 matching lines...) Expand all Loading... |
| 1729 return false; | 1797 return false; |
| 1730 } | 1798 } |
| 1731 | 1799 |
| 1732 return true; | 1800 return true; |
| 1733 } | 1801 } |
| 1734 | 1802 |
| 1735 void CommandLineInterface::GetTransitiveDependencies( | 1803 void CommandLineInterface::GetTransitiveDependencies( |
| 1736 const FileDescriptor* file, | 1804 const FileDescriptor* file, |
| 1737 bool include_json_name, | 1805 bool include_json_name, |
| 1738 bool include_source_code_info, | 1806 bool include_source_code_info, |
| 1739 set<const FileDescriptor*>* already_seen, | 1807 std::set<const FileDescriptor*>* already_seen, |
| 1740 RepeatedPtrField<FileDescriptorProto>* output) { | 1808 RepeatedPtrField<FileDescriptorProto>* output) { |
| 1741 if (!already_seen->insert(file).second) { | 1809 if (!already_seen->insert(file).second) { |
| 1742 // Already saw this file. Skip. | 1810 // Already saw this file. Skip. |
| 1743 return; | 1811 return; |
| 1744 } | 1812 } |
| 1745 | 1813 |
| 1746 // Add all dependencies. | 1814 // Add all dependencies. |
| 1747 for (int i = 0; i < file->dependency_count(); i++) { | 1815 for (int i = 0; i < file->dependency_count(); i++) { |
| 1748 GetTransitiveDependencies(file->dependency(i), | 1816 GetTransitiveDependencies(file->dependency(i), |
| 1749 include_json_name, | 1817 include_json_name, |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1788 // message NestedBaz {} | 1856 // message NestedBaz {} |
| 1789 // } | 1857 // } |
| 1790 // } | 1858 // } |
| 1791 // | 1859 // |
| 1792 // In this case, Bar, Quz and NestedBaz will be added into the nested types. | 1860 // In this case, Bar, Quz and NestedBaz will be added into the nested types. |
| 1793 // Since free field numbers of group types will not be printed, this makes sure | 1861 // Since free field numbers of group types will not be printed, this makes sure |
| 1794 // the nested message types in groups will not be dropped. The nested_messages | 1862 // the nested message types in groups will not be dropped. The nested_messages |
| 1795 // parameter will contain the direct children (when groups are ignored in the | 1863 // parameter will contain the direct children (when groups are ignored in the |
| 1796 // tree) of the given descriptor for the caller to traverse. The declaration | 1864 // tree) of the given descriptor for the caller to traverse. The declaration |
| 1797 // order of the nested messages is also preserved. | 1865 // order of the nested messages is also preserved. |
| 1798 typedef pair<int, int> FieldRange; | 1866 typedef std::pair<int, int> FieldRange; |
| 1799 void GatherOccupiedFieldRanges(const Descriptor* descriptor, | 1867 void GatherOccupiedFieldRanges( |
| 1800 set<FieldRange>* ranges, | 1868 const Descriptor* descriptor, std::set<FieldRange>* ranges, |
| 1801 vector<const Descriptor*>* nested_messages) { | 1869 std::vector<const Descriptor*>* nested_messages) { |
| 1802 set<const Descriptor*> groups; | 1870 std::set<const Descriptor*> groups; |
| 1803 for (int i = 0; i < descriptor->field_count(); ++i) { | 1871 for (int i = 0; i < descriptor->field_count(); ++i) { |
| 1804 const FieldDescriptor* fd = descriptor->field(i); | 1872 const FieldDescriptor* fd = descriptor->field(i); |
| 1805 ranges->insert(FieldRange(fd->number(), fd->number() + 1)); | 1873 ranges->insert(FieldRange(fd->number(), fd->number() + 1)); |
| 1806 if (fd->type() == FieldDescriptor::TYPE_GROUP) { | 1874 if (fd->type() == FieldDescriptor::TYPE_GROUP) { |
| 1807 groups.insert(fd->message_type()); | 1875 groups.insert(fd->message_type()); |
| 1808 } | 1876 } |
| 1809 } | 1877 } |
| 1810 for (int i = 0; i < descriptor->extension_range_count(); ++i) { | 1878 for (int i = 0; i < descriptor->extension_range_count(); ++i) { |
| 1811 ranges->insert(FieldRange(descriptor->extension_range(i)->start, | 1879 ranges->insert(FieldRange(descriptor->extension_range(i)->start, |
| 1812 descriptor->extension_range(i)->end)); | 1880 descriptor->extension_range(i)->end)); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1824 } else { | 1892 } else { |
| 1825 nested_messages->push_back(nested_desc); | 1893 nested_messages->push_back(nested_desc); |
| 1826 } | 1894 } |
| 1827 } | 1895 } |
| 1828 } | 1896 } |
| 1829 | 1897 |
| 1830 // Utility function for PrintFreeFieldNumbers. | 1898 // Utility function for PrintFreeFieldNumbers. |
| 1831 // Actually prints the formatted free field numbers for given message name and | 1899 // Actually prints the formatted free field numbers for given message name and |
| 1832 // occupied ranges. | 1900 // occupied ranges. |
| 1833 void FormatFreeFieldNumbers(const string& name, | 1901 void FormatFreeFieldNumbers(const string& name, |
| 1834 const set<FieldRange>& ranges) { | 1902 const std::set<FieldRange>& ranges) { |
| 1835 string output; | 1903 string output; |
| 1836 StringAppendF(&output, "%-35s free:", name.c_str()); | 1904 StringAppendF(&output, "%-35s free:", name.c_str()); |
| 1837 int next_free_number = 1; | 1905 int next_free_number = 1; |
| 1838 for (set<FieldRange>::const_iterator i = ranges.begin(); | 1906 for (std::set<FieldRange>::const_iterator i = ranges.begin(); |
| 1839 i != ranges.end(); ++i) { | 1907 i != ranges.end(); ++i) { |
| 1840 // This happens when groups re-use parent field numbers, in which | 1908 // This happens when groups re-use parent field numbers, in which |
| 1841 // case we skip the FieldRange entirely. | 1909 // case we skip the FieldRange entirely. |
| 1842 if (next_free_number >= i->second) continue; | 1910 if (next_free_number >= i->second) continue; |
| 1843 | 1911 |
| 1844 if (next_free_number < i->first) { | 1912 if (next_free_number < i->first) { |
| 1845 if (next_free_number + 1 == i->first) { | 1913 if (next_free_number + 1 == i->first) { |
| 1846 // Singleton | 1914 // Singleton |
| 1847 StringAppendF(&output, " %d", next_free_number); | 1915 StringAppendF(&output, " %d", next_free_number); |
| 1848 } else { | 1916 } else { |
| 1849 // Range | 1917 // Range |
| 1850 StringAppendF(&output, " %d-%d", next_free_number, i->first - 1); | 1918 StringAppendF(&output, " %d-%d", next_free_number, i->first - 1); |
| 1851 } | 1919 } |
| 1852 } | 1920 } |
| 1853 next_free_number = i->second; | 1921 next_free_number = i->second; |
| 1854 } | 1922 } |
| 1855 if (next_free_number <= FieldDescriptor::kMaxNumber) { | 1923 if (next_free_number <= FieldDescriptor::kMaxNumber) { |
| 1856 StringAppendF(&output, " %d-INF", next_free_number); | 1924 StringAppendF(&output, " %d-INF", next_free_number); |
| 1857 } | 1925 } |
| 1858 std::cout << output << std::endl; | 1926 std::cout << output << std::endl; |
| 1859 } | 1927 } |
| 1860 | 1928 |
| 1861 } // namespace | 1929 } // namespace |
| 1862 | 1930 |
| 1863 void CommandLineInterface::PrintFreeFieldNumbers( | 1931 void CommandLineInterface::PrintFreeFieldNumbers( |
| 1864 const Descriptor* descriptor) { | 1932 const Descriptor* descriptor) { |
| 1865 set<FieldRange> ranges; | 1933 std::set<FieldRange> ranges; |
| 1866 vector<const Descriptor*> nested_messages; | 1934 std::vector<const Descriptor*> nested_messages; |
| 1867 GatherOccupiedFieldRanges(descriptor, &ranges, &nested_messages); | 1935 GatherOccupiedFieldRanges(descriptor, &ranges, &nested_messages); |
| 1868 | 1936 |
| 1869 for (int i = 0; i < nested_messages.size(); ++i) { | 1937 for (int i = 0; i < nested_messages.size(); ++i) { |
| 1870 PrintFreeFieldNumbers(nested_messages[i]); | 1938 PrintFreeFieldNumbers(nested_messages[i]); |
| 1871 } | 1939 } |
| 1872 FormatFreeFieldNumbers(descriptor->full_name(), ranges); | 1940 FormatFreeFieldNumbers(descriptor->full_name(), ranges); |
| 1873 } | 1941 } |
| 1874 | 1942 |
| 1875 | 1943 |
| 1876 | 1944 |
| 1877 } // namespace compiler | 1945 } // namespace compiler |
| 1878 } // namespace protobuf | 1946 } // namespace protobuf |
| 1879 } // namespace google | 1947 } // namespace google |
| OLD | NEW |