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

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

Issue 2495533002: third_party/protobuf: Update to HEAD (83d681ee2c) (Closed)
Patch Set: Make chrome settings proto generated file a component Created 4 years 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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698