Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(66)

Side by Side Diff: third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc

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

Powered by Google App Engine
This is Rietveld 408576698