| Index: third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc
|
| diff --git a/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc b/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc
|
| index e88718615aa8873c92bb47bb3b991397c8ec495d..b9293c97de1238bb212aedf6e9aa756b62624da9 100644
|
| --- a/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc
|
| +++ b/third_party/protobuf/src/google/protobuf/compiler/command_line_interface.cc
|
| @@ -1,6 +1,6 @@
|
| // Protocol Buffers - Google's data interchange format
|
| // Copyright 2008 Google Inc. All rights reserved.
|
| -// https://developers.google.com/protocol-buffers/
|
| +// http://code.google.com/p/protobuf/
|
| //
|
| // Redistribution and use in source and binary forms, with or without
|
| // modification, are permitted provided that the following conditions are
|
| @@ -48,17 +48,9 @@
|
| #include <iostream>
|
| #include <ctype.h>
|
|
|
| -#include <memory>
|
| -#ifndef _SHARED_PTR_H
|
| -#include <google/protobuf/stubs/shared_ptr.h>
|
| -#endif
|
| -
|
| -#ifdef __APPLE__
|
| -#include <mach-o/dyld.h>
|
| -#endif
|
| +#include <google/protobuf/stubs/hash.h>
|
|
|
| #include <google/protobuf/stubs/common.h>
|
| -#include <google/protobuf/stubs/stringprintf.h>
|
| #include <google/protobuf/compiler/importer.h>
|
| #include <google/protobuf/compiler/code_generator.h>
|
| #include <google/protobuf/compiler/plugin.pb.h>
|
| @@ -72,7 +64,7 @@
|
| #include <google/protobuf/io/printer.h>
|
| #include <google/protobuf/stubs/strutil.h>
|
| #include <google/protobuf/stubs/substitute.h>
|
| -#include <google/protobuf/stubs/map_util.h>
|
| +#include <google/protobuf/stubs/map-util.h>
|
| #include <google/protobuf/stubs/stl_util.h>
|
|
|
|
|
| @@ -155,7 +147,7 @@ bool VerifyDirectoryExists(const string& path) {
|
| if (path.empty()) return true;
|
|
|
| if (access(path.c_str(), F_OK) == -1) {
|
| - std::cerr << path << ": " << strerror(errno) << std::endl;
|
| + cerr << path << ": " << strerror(errno) << endl;
|
| return false;
|
| } else {
|
| return true;
|
| @@ -168,14 +160,15 @@ bool VerifyDirectoryExists(const string& path) {
|
| // directories listed in |filename|.
|
| bool TryCreateParentDirectory(const string& prefix, const string& filename) {
|
| // Recursively create parent directories to the output file.
|
| - vector<string> parts = Split(filename, "/", true);
|
| + vector<string> parts;
|
| + SplitStringUsing(filename, "/", &parts);
|
| string path_so_far = prefix;
|
| for (int i = 0; i < parts.size() - 1; i++) {
|
| path_so_far += parts[i];
|
| if (mkdir(path_so_far.c_str(), 0777) != 0) {
|
| if (errno != EEXIST) {
|
| - std::cerr << filename << ": while trying to create directory "
|
| - << path_so_far << ": " << strerror(errno) << std::endl;
|
| + cerr << filename << ": while trying to create directory "
|
| + << path_so_far << ": " << strerror(errno) << endl;
|
| return false;
|
| }
|
| }
|
| @@ -185,78 +178,6 @@ bool TryCreateParentDirectory(const string& prefix, const string& filename) {
|
| return true;
|
| }
|
|
|
| -// Get the absolute path of this protoc binary.
|
| -bool GetProtocAbsolutePath(string* path) {
|
| -#ifdef _WIN32
|
| - char buffer[MAX_PATH];
|
| - int len = GetModuleFileNameA(NULL, buffer, MAX_PATH);
|
| -#elif __APPLE__
|
| - char buffer[PATH_MAX];
|
| - int len = 0;
|
| -
|
| - char dirtybuffer[PATH_MAX];
|
| - uint32_t size = sizeof(dirtybuffer);
|
| - if (_NSGetExecutablePath(dirtybuffer, &size) == 0) {
|
| - realpath(dirtybuffer, buffer);
|
| - len = strlen(buffer);
|
| - }
|
| -#else
|
| - char buffer[PATH_MAX];
|
| - int len = readlink("/proc/self/exe", buffer, PATH_MAX);
|
| -#endif
|
| - if (len > 0) {
|
| - path->assign(buffer, len);
|
| - return true;
|
| - } else {
|
| - return false;
|
| - }
|
| -}
|
| -
|
| -// Whether a path is where google/protobuf/descriptor.proto and other well-known
|
| -// type protos are installed.
|
| -bool IsInstalledProtoPath(const string& path) {
|
| - // Checking the descriptor.proto file should be good enough.
|
| - string file_path = path + "/google/protobuf/descriptor.proto";
|
| - return access(file_path.c_str(), F_OK) != -1;
|
| -}
|
| -
|
| -// Add the paths where google/protobuf/descritor.proto and other well-known
|
| -// type protos are installed.
|
| -void AddDefaultProtoPaths(vector<pair<string, string> >* paths) {
|
| - // TODO(xiaofeng): The code currently only checks relative paths of where
|
| - // the protoc binary is installed. We probably should make it handle more
|
| - // cases than that.
|
| - string path;
|
| - if (!GetProtocAbsolutePath(&path)) {
|
| - return;
|
| - }
|
| - // Strip the binary name.
|
| - size_t pos = path.find_last_of("/\\");
|
| - if (pos == string::npos || pos == 0) {
|
| - return;
|
| - }
|
| - path = path.substr(0, pos);
|
| - // Check the binary's directory.
|
| - if (IsInstalledProtoPath(path)) {
|
| - paths->push_back(pair<string, string>("", path));
|
| - return;
|
| - }
|
| - // Check if there is an include subdirectory.
|
| - if (IsInstalledProtoPath(path + "/include")) {
|
| - paths->push_back(pair<string, string>("", path + "/include"));
|
| - return;
|
| - }
|
| - // Check if the upper level directory has an "include" subdirectory.
|
| - pos = path.find_last_of("/\\");
|
| - if (pos == string::npos || pos == 0) {
|
| - return;
|
| - }
|
| - path = path.substr(0, pos);
|
| - if (IsInstalledProtoPath(path + "/include")) {
|
| - paths->push_back(pair<string, string>("", path + "/include"));
|
| - return;
|
| - }
|
| -}
|
| } // namespace
|
|
|
| // A MultiFileErrorCollector that prints errors to stderr.
|
| @@ -276,9 +197,9 @@ class CommandLineInterface::ErrorPrinter : public MultiFileErrorCollector,
|
| if (format_ == CommandLineInterface::ERROR_FORMAT_MSVS &&
|
| tree_ != NULL &&
|
| tree_->VirtualFileToDiskFile(filename, &dfile)) {
|
| - std::cerr << dfile;
|
| + cerr << dfile;
|
| } else {
|
| - std::cerr << filename;
|
| + cerr << filename;
|
| }
|
|
|
| // Users typically expect 1-based line/column numbers, so we add 1
|
| @@ -287,16 +208,15 @@ class CommandLineInterface::ErrorPrinter : public MultiFileErrorCollector,
|
| // Allow for both GCC- and Visual-Studio-compatible output.
|
| switch (format_) {
|
| case CommandLineInterface::ERROR_FORMAT_GCC:
|
| - std::cerr << ":" << (line + 1) << ":" << (column + 1);
|
| + cerr << ":" << (line + 1) << ":" << (column + 1);
|
| break;
|
| case CommandLineInterface::ERROR_FORMAT_MSVS:
|
| - std::cerr << "(" << (line + 1)
|
| - << ") : error in column=" << (column + 1);
|
| + cerr << "(" << (line + 1) << ") : error in column=" << (column + 1);
|
| break;
|
| }
|
| }
|
|
|
| - std::cerr << ": " << message << std::endl;
|
| + cerr << ": " << message << endl;
|
| }
|
|
|
| // implements io::ErrorCollector -----------------------------------
|
| @@ -330,12 +250,8 @@ class CommandLineInterface::GeneratorContextImpl : public GeneratorContext {
|
| // format, unless one has already been written.
|
| void AddJarManifest();
|
|
|
| - // Get name of all output files.
|
| - void GetOutputFilenames(vector<string>* output_filenames);
|
| -
|
| // implements GeneratorContext --------------------------------------
|
| io::ZeroCopyOutputStream* Open(const string& filename);
|
| - io::ZeroCopyOutputStream* OpenForAppend(const string& filename);
|
| io::ZeroCopyOutputStream* OpenForInsert(
|
| const string& filename, const string& insertion_point);
|
| void ListParsedFiles(vector<const FileDescriptor*>* output) {
|
| @@ -355,8 +271,7 @@ class CommandLineInterface::GeneratorContextImpl : public GeneratorContext {
|
| class CommandLineInterface::MemoryOutputStream
|
| : public io::ZeroCopyOutputStream {
|
| public:
|
| - MemoryOutputStream(GeneratorContextImpl* directory, const string& filename,
|
| - bool append_mode);
|
| + MemoryOutputStream(GeneratorContextImpl* directory, const string& filename);
|
| MemoryOutputStream(GeneratorContextImpl* directory, const string& filename,
|
| const string& insertion_point);
|
| virtual ~MemoryOutputStream();
|
| @@ -375,11 +290,8 @@ class CommandLineInterface::MemoryOutputStream
|
| // The string we're building.
|
| string data_;
|
|
|
| - // Whether we should append the output stream to the existing file.
|
| - bool append_mode_;
|
| -
|
| // StringOutputStream writing to data_.
|
| - google::protobuf::scoped_ptr<io::StringOutputStream> inner_;
|
| + scoped_ptr<io::StringOutputStream> inner_;
|
| };
|
|
|
| // -------------------------------------------------------------------
|
| @@ -424,7 +336,7 @@ bool CommandLineInterface::GeneratorContextImpl::WriteAllToDisk(
|
|
|
| if (file_descriptor < 0) {
|
| int error = errno;
|
| - std::cerr << filename << ": " << strerror(error);
|
| + cerr << filename << ": " << strerror(error);
|
| return false;
|
| }
|
|
|
| @@ -448,9 +360,9 @@ bool CommandLineInterface::GeneratorContextImpl::WriteAllToDisk(
|
|
|
| if (write_result < 0) {
|
| int error = errno;
|
| - std::cerr << filename << ": write: " << strerror(error);
|
| + cerr << filename << ": write: " << strerror(error);
|
| } else {
|
| - std::cerr << filename << ": write() returned zero?" << std::endl;
|
| + cerr << filename << ": write() returned zero?" << endl;
|
| }
|
| return false;
|
| }
|
| @@ -461,7 +373,7 @@ bool CommandLineInterface::GeneratorContextImpl::WriteAllToDisk(
|
|
|
| if (close(file_descriptor) != 0) {
|
| int error = errno;
|
| - std::cerr << filename << ": close: " << strerror(error);
|
| + cerr << filename << ": close: " << strerror(error);
|
| return false;
|
| }
|
| }
|
| @@ -484,7 +396,7 @@ bool CommandLineInterface::GeneratorContextImpl::WriteAllToZip(
|
|
|
| if (file_descriptor < 0) {
|
| int error = errno;
|
| - std::cerr << filename << ": " << strerror(error);
|
| + cerr << filename << ": " << strerror(error);
|
| return false;
|
| }
|
|
|
| @@ -500,11 +412,11 @@ bool CommandLineInterface::GeneratorContextImpl::WriteAllToZip(
|
| zip_writer.WriteDirectory();
|
|
|
| if (stream.GetErrno() != 0) {
|
| - std::cerr << filename << ": " << strerror(stream.GetErrno()) << std::endl;
|
| + cerr << filename << ": " << strerror(stream.GetErrno()) << endl;
|
| }
|
|
|
| if (!stream.Close()) {
|
| - std::cerr << filename << ": " << strerror(stream.GetErrno()) << std::endl;
|
| + cerr << filename << ": " << strerror(stream.GetErrno()) << endl;
|
| }
|
|
|
| return true;
|
| @@ -520,23 +432,9 @@ void CommandLineInterface::GeneratorContextImpl::AddJarManifest() {
|
| }
|
| }
|
|
|
| -void CommandLineInterface::GeneratorContextImpl::GetOutputFilenames(
|
| - vector<string>* output_filenames) {
|
| - for (map<string, string*>::iterator iter = files_.begin();
|
| - iter != files_.end(); ++iter) {
|
| - output_filenames->push_back(iter->first);
|
| - }
|
| -}
|
| -
|
| io::ZeroCopyOutputStream* CommandLineInterface::GeneratorContextImpl::Open(
|
| const string& filename) {
|
| - return new MemoryOutputStream(this, filename, false);
|
| -}
|
| -
|
| -io::ZeroCopyOutputStream*
|
| -CommandLineInterface::GeneratorContextImpl::OpenForAppend(
|
| - const string& filename) {
|
| - return new MemoryOutputStream(this, filename, true);
|
| + return new MemoryOutputStream(this, filename);
|
| }
|
|
|
| io::ZeroCopyOutputStream*
|
| @@ -548,10 +446,9 @@ CommandLineInterface::GeneratorContextImpl::OpenForInsert(
|
| // -------------------------------------------------------------------
|
|
|
| CommandLineInterface::MemoryOutputStream::MemoryOutputStream(
|
| - GeneratorContextImpl* directory, const string& filename, bool append_mode)
|
| + GeneratorContextImpl* directory, const string& filename)
|
| : directory_(directory),
|
| filename_(filename),
|
| - append_mode_(append_mode),
|
| inner_(new io::StringOutputStream(&data_)) {
|
| }
|
|
|
| @@ -574,13 +471,8 @@ CommandLineInterface::MemoryOutputStream::~MemoryOutputStream() {
|
| if (insertion_point_.empty()) {
|
| // This was just a regular Open().
|
| if (*map_slot != NULL) {
|
| - if (append_mode_) {
|
| - (*map_slot)->append(data_);
|
| - } else {
|
| - std::cerr << filename_ << ": Tried to write the same file twice."
|
| - << std::endl;
|
| - directory_->had_error_ = true;
|
| - }
|
| + cerr << filename_ << ": Tried to write the same file twice." << endl;
|
| + directory_->had_error_ = true;
|
| return;
|
| }
|
|
|
| @@ -596,9 +488,8 @@ CommandLineInterface::MemoryOutputStream::~MemoryOutputStream() {
|
|
|
| // Find the file we are going to insert into.
|
| if (*map_slot == NULL) {
|
| - std::cerr << filename_
|
| - << ": Tried to insert into file that doesn't exist."
|
| - << std::endl;
|
| + cerr << filename_ << ": Tried to insert into file that doesn't exist."
|
| + << endl;
|
| directory_->had_error_ = true;
|
| return;
|
| }
|
| @@ -610,8 +501,8 @@ CommandLineInterface::MemoryOutputStream::~MemoryOutputStream() {
|
| string::size_type pos = target->find(magic_string);
|
|
|
| if (pos == string::npos) {
|
| - std::cerr << filename_ << ": insertion point \"" << insertion_point_
|
| - << "\" not found." << std::endl;
|
| + cerr << filename_ << ": insertion point \"" << insertion_point_
|
| + << "\" not found." << endl;
|
| directory_->had_error_ = true;
|
| return;
|
| }
|
| @@ -674,7 +565,6 @@ CommandLineInterface::MemoryOutputStream::~MemoryOutputStream() {
|
|
|
| CommandLineInterface::CommandLineInterface()
|
| : mode_(MODE_COMPILE),
|
| - print_mode_(PRINT_NONE),
|
| error_format_(ERROR_FORMAT_GCC),
|
| imports_in_descriptor_set_(false),
|
| source_info_in_descriptor_set_(false),
|
| @@ -720,8 +610,6 @@ int CommandLineInterface::Run(int argc, const char* const argv[]) {
|
| break;
|
| }
|
|
|
| - AddDefaultProtoPaths(&proto_path_);
|
| -
|
| // Set up the source tree.
|
| DiskSourceTree source_tree;
|
| for (int i = 0; i < proto_path_.size(); i++) {
|
| @@ -744,9 +632,7 @@ int CommandLineInterface::Run(int argc, const char* const argv[]) {
|
| // Parse each file.
|
| for (int i = 0; i < input_files_.size(); i++) {
|
| // Import the file.
|
| - importer.AddUnusedImportTrackFile(input_files_[i]);
|
| const FileDescriptor* parsed_file = importer.Import(input_files_[i]);
|
| - importer.ClearUnusedImportTrackFiles();
|
| if (parsed_file == NULL) return 1;
|
| parsed_files.push_back(parsed_file);
|
|
|
| @@ -761,6 +647,7 @@ int CommandLineInterface::Run(int argc, const char* const argv[]) {
|
| // We construct a separate GeneratorContext for each output location. Note
|
| // that two code generators may output to the same location, in which case
|
| // they should share a single GeneratorContext so that OpenForInsert() works.
|
| + typedef hash_map<string, GeneratorContextImpl*> GeneratorContextMap;
|
| GeneratorContextMap output_directories;
|
|
|
| // Generate output.
|
| @@ -807,13 +694,6 @@ int CommandLineInterface::Run(int argc, const char* const argv[]) {
|
| }
|
| }
|
|
|
| - if (!dependency_out_name_.empty()) {
|
| - if (!GenerateDependencyManifestFile(parsed_files, output_directories,
|
| - &source_tree)) {
|
| - return 1;
|
| - }
|
| - }
|
| -
|
| STLDeleteValues(&output_directories);
|
|
|
| if (!descriptor_set_name_.empty()) {
|
| @@ -841,25 +721,6 @@ int CommandLineInterface::Run(int argc, const char* const argv[]) {
|
| }
|
| }
|
|
|
| - if (mode_ == MODE_PRINT) {
|
| - switch (print_mode_) {
|
| - case PRINT_FREE_FIELDS:
|
| - for (int i = 0; i < parsed_files.size(); ++i) {
|
| - const FileDescriptor* fd = parsed_files[i];
|
| - for (int j = 0; j < fd->message_type_count(); ++j) {
|
| - PrintFreeFieldNumbers(fd->message_type(j));
|
| - }
|
| - }
|
| - break;
|
| - case PRINT_NONE:
|
| - GOOGLE_LOG(ERROR) << "If the code reaches here, it usually means a bug of "
|
| - "flag parsing in the CommonadLineInterface.";
|
| - return 1;
|
| -
|
| - // Do not add a default case.
|
| - }
|
| - }
|
| -
|
| return 0;
|
| }
|
|
|
| @@ -872,10 +733,8 @@ void CommandLineInterface::Clear() {
|
| output_directives_.clear();
|
| codec_type_.clear();
|
| descriptor_set_name_.clear();
|
| - dependency_out_name_.clear();
|
|
|
| mode_ = MODE_COMPILE;
|
| - print_mode_ = PRINT_NONE;
|
| imports_in_descriptor_set_ = false;
|
| source_info_in_descriptor_set_ = false;
|
| disallow_services_ = false;
|
| @@ -891,31 +750,27 @@ bool CommandLineInterface::MakeInputsBeProtoPathRelative(
|
| input_files_[i] = virtual_file;
|
| break;
|
| case DiskSourceTree::SHADOWED:
|
| - std::cerr << input_files_[i]
|
| - << ": Input is shadowed in the --proto_path by \""
|
| - << shadowing_disk_file
|
| - << "\". Either use the latter file as your input or reorder "
|
| - "the --proto_path so that the former file's location "
|
| - "comes first." << std::endl;
|
| + cerr << input_files_[i] << ": Input is shadowed in the --proto_path "
|
| + "by \"" << shadowing_disk_file << "\". Either use the latter "
|
| + "file as your input or reorder the --proto_path so that the "
|
| + "former file's location comes first." << endl;
|
| return false;
|
| case DiskSourceTree::CANNOT_OPEN:
|
| - std::cerr << input_files_[i] << ": " << strerror(errno) << std::endl;
|
| + cerr << input_files_[i] << ": " << strerror(errno) << endl;
|
| return false;
|
| case DiskSourceTree::NO_MAPPING:
|
| // First check if the file exists at all.
|
| if (access(input_files_[i].c_str(), F_OK) < 0) {
|
| // File does not even exist.
|
| - std::cerr << input_files_[i] << ": " << strerror(ENOENT) << std::endl;
|
| + cerr << input_files_[i] << ": " << strerror(ENOENT) << endl;
|
| } else {
|
| - std::cerr
|
| - << input_files_[i]
|
| - << ": File does not reside within any path "
|
| - "specified using --proto_path (or -I). You must specify a "
|
| - "--proto_path which encompasses this file. Note that the "
|
| - "proto_path must be an exact prefix of the .proto file "
|
| - "names -- protoc is too dumb to figure out when two paths "
|
| - "(e.g. absolute and relative) are equivalent (it's harder "
|
| - "than you think)." << std::endl;
|
| + cerr << input_files_[i] << ": File does not reside within any path "
|
| + "specified using --proto_path (or -I). You must specify a "
|
| + "--proto_path which encompasses this file. Note that the "
|
| + "proto_path must be an exact prefix of the .proto file "
|
| + "names -- protoc is too dumb to figure out when two paths "
|
| + "(e.g. absolute and relative) are equivalent (it's harder "
|
| + "than you think)." << endl;
|
| }
|
| return false;
|
| }
|
| @@ -935,10 +790,9 @@ CommandLineInterface::ParseArguments(int argc, const char* const argv[]) {
|
| if (ParseArgument(argv[i], &name, &value)) {
|
| // Returned true => Use the next argument as the flag value.
|
| if (i + 1 == argc || argv[i+1][0] == '-') {
|
| - std::cerr << "Missing value for flag: " << name << std::endl;
|
| + cerr << "Missing value for flag: " << name << endl;
|
| if (name == "--decode") {
|
| - std::cerr << "To decode an unknown message, use --decode_raw."
|
| - << std::endl;
|
| + cerr << "To decode an unknown message, use --decode_raw." << endl;
|
| }
|
| return PARSE_ARGUMENT_FAIL;
|
| } else {
|
| @@ -963,36 +817,24 @@ CommandLineInterface::ParseArguments(int argc, const char* const argv[]) {
|
| // Check some errror cases.
|
| bool decoding_raw = (mode_ == MODE_DECODE) && codec_type_.empty();
|
| if (decoding_raw && !input_files_.empty()) {
|
| - std::cerr << "When using --decode_raw, no input files should be given."
|
| - << std::endl;
|
| + cerr << "When using --decode_raw, no input files should be given." << endl;
|
| return PARSE_ARGUMENT_FAIL;
|
| } else if (!decoding_raw && input_files_.empty()) {
|
| - std::cerr << "Missing input file." << std::endl;
|
| + cerr << "Missing input file." << endl;
|
| return PARSE_ARGUMENT_FAIL;
|
| }
|
| if (mode_ == MODE_COMPILE && output_directives_.empty() &&
|
| descriptor_set_name_.empty()) {
|
| - std::cerr << "Missing output directives." << std::endl;
|
| - return PARSE_ARGUMENT_FAIL;
|
| - }
|
| - if (mode_ != MODE_COMPILE && !dependency_out_name_.empty()) {
|
| - std::cerr << "Can only use --dependency_out=FILE when generating code."
|
| - << std::endl;
|
| - return PARSE_ARGUMENT_FAIL;
|
| - }
|
| - if (!dependency_out_name_.empty() && input_files_.size() > 1) {
|
| - std::cerr
|
| - << "Can only process one input file when using --dependency_out=FILE."
|
| - << std::endl;
|
| + cerr << "Missing output directives." << endl;
|
| return PARSE_ARGUMENT_FAIL;
|
| }
|
| if (imports_in_descriptor_set_ && descriptor_set_name_.empty()) {
|
| - std::cerr << "--include_imports only makes sense when combined with "
|
| - "--descriptor_set_out." << std::endl;
|
| + cerr << "--include_imports only makes sense when combined with "
|
| + "--descriptor_set_out." << endl;
|
| }
|
| if (source_info_in_descriptor_set_ && descriptor_set_name_.empty()) {
|
| - std::cerr << "--include_source_info only makes sense when combined with "
|
| - "--descriptor_set_out." << std::endl;
|
| + cerr << "--include_source_info only makes sense when combined with "
|
| + "--descriptor_set_out." << endl;
|
| }
|
|
|
| return PARSE_ARGUMENT_DONE_AND_CONTINUE;
|
| @@ -1047,8 +889,7 @@ bool CommandLineInterface::ParseArgument(const char* arg,
|
| *name == "--include_imports" ||
|
| *name == "--include_source_info" ||
|
| *name == "--version" ||
|
| - *name == "--decode_raw" ||
|
| - *name == "--print_free_field_numbers") {
|
| + *name == "--decode_raw") {
|
| // HACK: These are the only flags that don't take a value.
|
| // They probably should not be hard-coded like this but for now it's
|
| // not worth doing better.
|
| @@ -1065,12 +906,10 @@ CommandLineInterface::InterpretArgument(const string& name,
|
| if (name.empty()) {
|
| // Not a flag. Just a filename.
|
| if (value.empty()) {
|
| - std::cerr
|
| - << "You seem to have passed an empty string as one of the "
|
| - "arguments to " << executable_name_
|
| - << ". This is actually "
|
| - "sort of hard to do. Congrats. Unfortunately it is not valid "
|
| - "input so the program is going to die now." << std::endl;
|
| + cerr << "You seem to have passed an empty string as one of the "
|
| + "arguments to " << executable_name_ << ". This is actually "
|
| + "sort of hard to do. Congrats. Unfortunately it is not valid "
|
| + "input so the program is going to die now." << endl;
|
| return PARSE_ARGUMENT_FAIL;
|
| }
|
|
|
| @@ -1080,8 +919,8 @@ CommandLineInterface::InterpretArgument(const string& name,
|
| // Java's -classpath (and some other languages) delimits path components
|
| // with colons. Let's accept that syntax too just to make things more
|
| // intuitive.
|
| - vector<string> parts = Split(
|
| - value, kPathSeparator, true);
|
| + vector<string> parts;
|
| + SplitStringUsing(value, kPathSeparator, &parts);
|
|
|
| for (int i = 0; i < parts.size(); i++) {
|
| string virtual_path;
|
| @@ -1097,16 +936,14 @@ CommandLineInterface::InterpretArgument(const string& name,
|
| }
|
|
|
| if (disk_path.empty()) {
|
| - std::cerr
|
| - << "--proto_path passed empty directory name. (Use \".\" for "
|
| - "current directory.)" << std::endl;
|
| + cerr << "--proto_path passed empty directory name. (Use \".\" for "
|
| + "current directory.)" << endl;
|
| return PARSE_ARGUMENT_FAIL;
|
| }
|
|
|
| // Make sure disk path exists, warn otherwise.
|
| if (access(disk_path.c_str(), F_OK) < 0) {
|
| - std::cerr << disk_path << ": warning: directory does not exist."
|
| - << std::endl;
|
| + cerr << disk_path << ": warning: directory does not exist." << endl;
|
| }
|
|
|
| // Don't use make_pair as the old/default standard library on Solaris
|
| @@ -1117,42 +954,30 @@ CommandLineInterface::InterpretArgument(const string& name,
|
|
|
| } else if (name == "-o" || name == "--descriptor_set_out") {
|
| if (!descriptor_set_name_.empty()) {
|
| - std::cerr << name << " may only be passed once." << std::endl;
|
| + cerr << name << " may only be passed once." << endl;
|
| return PARSE_ARGUMENT_FAIL;
|
| }
|
| if (value.empty()) {
|
| - std::cerr << name << " requires a non-empty value." << std::endl;
|
| + cerr << name << " requires a non-empty value." << endl;
|
| return PARSE_ARGUMENT_FAIL;
|
| }
|
| if (mode_ != MODE_COMPILE) {
|
| - std::cerr
|
| - << "Cannot use --encode or --decode and generate descriptors at the "
|
| - "same time." << std::endl;
|
| + cerr << "Cannot use --encode or --decode and generate descriptors at the "
|
| + "same time." << endl;
|
| return PARSE_ARGUMENT_FAIL;
|
| }
|
| descriptor_set_name_ = value;
|
|
|
| - } else if (name == "--dependency_out") {
|
| - if (!dependency_out_name_.empty()) {
|
| - std::cerr << name << " may only be passed once." << std::endl;
|
| - return PARSE_ARGUMENT_FAIL;
|
| - }
|
| - if (value.empty()) {
|
| - std::cerr << name << " requires a non-empty value." << std::endl;
|
| - return PARSE_ARGUMENT_FAIL;
|
| - }
|
| - dependency_out_name_ = value;
|
| -
|
| } else if (name == "--include_imports") {
|
| if (imports_in_descriptor_set_) {
|
| - std::cerr << name << " may only be passed once." << std::endl;
|
| + cerr << name << " may only be passed once." << endl;
|
| return PARSE_ARGUMENT_FAIL;
|
| }
|
| imports_in_descriptor_set_ = true;
|
|
|
| } else if (name == "--include_source_info") {
|
| if (source_info_in_descriptor_set_) {
|
| - std::cerr << name << " may only be passed once." << std::endl;
|
| + cerr << name << " may only be passed once." << endl;
|
| return PARSE_ARGUMENT_FAIL;
|
| }
|
| source_info_in_descriptor_set_ = true;
|
| @@ -1163,7 +988,7 @@ CommandLineInterface::InterpretArgument(const string& name,
|
|
|
| } else if (name == "--version") {
|
| if (!version_info_.empty()) {
|
| - std::cout << version_info_ << std::endl;
|
| + cout << version_info_ << endl;
|
| }
|
| cout << "libprotoc "
|
| << protobuf::internal::VersionString(GOOGLE_PROTOBUF_VERSION)
|
| @@ -1176,28 +1001,25 @@ CommandLineInterface::InterpretArgument(const string& name,
|
| } else if (name == "--encode" || name == "--decode" ||
|
| name == "--decode_raw") {
|
| if (mode_ != MODE_COMPILE) {
|
| - std::cerr << "Only one of --encode and --decode can be specified."
|
| - << std::endl;
|
| + cerr << "Only one of --encode and --decode can be specified." << endl;
|
| return PARSE_ARGUMENT_FAIL;
|
| }
|
| if (!output_directives_.empty() || !descriptor_set_name_.empty()) {
|
| - std::cerr << "Cannot use " << name
|
| - << " and generate code or descriptors at the same time."
|
| - << std::endl;
|
| + cerr << "Cannot use " << name
|
| + << " and generate code or descriptors at the same time." << endl;
|
| return PARSE_ARGUMENT_FAIL;
|
| }
|
|
|
| mode_ = (name == "--encode") ? MODE_ENCODE : MODE_DECODE;
|
|
|
| if (value.empty() && name != "--decode_raw") {
|
| - std::cerr << "Type name for " << name << " cannot be blank." << std::endl;
|
| + cerr << "Type name for " << name << " cannot be blank." << endl;
|
| if (name == "--decode") {
|
| - std::cerr << "To decode an unknown message, use --decode_raw."
|
| - << std::endl;
|
| + cerr << "To decode an unknown message, use --decode_raw." << endl;
|
| }
|
| return PARSE_ARGUMENT_FAIL;
|
| } else if (!value.empty() && name == "--decode_raw") {
|
| - std::cerr << "--decode_raw does not take a parameter." << std::endl;
|
| + cerr << "--decode_raw does not take a parameter." << endl;
|
| return PARSE_ARGUMENT_FAIL;
|
| }
|
|
|
| @@ -1209,13 +1031,13 @@ CommandLineInterface::InterpretArgument(const string& name,
|
| } else if (value == "msvs") {
|
| error_format_ = ERROR_FORMAT_MSVS;
|
| } else {
|
| - std::cerr << "Unknown error format: " << value << std::endl;
|
| + cerr << "Unknown error format: " << value << endl;
|
| return PARSE_ARGUMENT_FAIL;
|
| }
|
|
|
| } else if (name == "--plugin") {
|
| if (plugin_prefix_.empty()) {
|
| - std::cerr << "This compiler does not support plugins." << std::endl;
|
| + cerr << "This compiler does not support plugins." << endl;
|
| return PARSE_ARGUMENT_FAIL;
|
| }
|
|
|
| @@ -1239,21 +1061,6 @@ CommandLineInterface::InterpretArgument(const string& name,
|
|
|
| plugins_[plugin_name] = path;
|
|
|
| - } else if (name == "--print_free_field_numbers") {
|
| - if (mode_ != MODE_COMPILE) {
|
| - std::cerr << "Cannot use " << name
|
| - << " and use --encode, --decode or print "
|
| - << "other info at the same time." << std::endl;
|
| - return PARSE_ARGUMENT_FAIL;
|
| - }
|
| - if (!output_directives_.empty() || !descriptor_set_name_.empty()) {
|
| - std::cerr << "Cannot use " << name
|
| - << " and generate code or descriptors at the same time."
|
| - << std::endl;
|
| - return PARSE_ARGUMENT_FAIL;
|
| - }
|
| - mode_ = MODE_PRINT;
|
| - print_mode_ = PRINT_FREE_FIELDS;
|
| } else {
|
| // Some other flag. Look it up in the generators list.
|
| const GeneratorInfo* generator_info =
|
| @@ -1263,7 +1070,7 @@ CommandLineInterface::InterpretArgument(const string& name,
|
| // Check if it's a generator option flag.
|
| generator_info = FindOrNull(generators_by_option_name_, name);
|
| if (generator_info == NULL) {
|
| - std::cerr << "Unknown flag: " << name << std::endl;
|
| + cerr << "Unknown flag: " << name << endl;
|
| return PARSE_ARGUMENT_FAIL;
|
| } else {
|
| string* parameters = &generator_parameters_[generator_info->flag_name];
|
| @@ -1275,8 +1082,8 @@ CommandLineInterface::InterpretArgument(const string& name,
|
| } else {
|
| // It's an output flag. Add it to the output directives.
|
| if (mode_ != MODE_COMPILE) {
|
| - std::cerr << "Cannot use --encode, --decode or print .proto info and "
|
| - "generate code at the same time." << std::endl;
|
| + cerr << "Cannot use --encode or --decode and generate code at the "
|
| + "same time." << endl;
|
| return PARSE_ARGUMENT_FAIL;
|
| }
|
|
|
| @@ -1308,7 +1115,7 @@ CommandLineInterface::InterpretArgument(const string& name,
|
|
|
| void CommandLineInterface::PrintHelpText() {
|
| // Sorry for indentation here; line wrapping would be uglier.
|
| - std::cerr <<
|
| + cerr <<
|
| "Usage: " << executable_name_ << " [OPTION] PROTO_FILES\n"
|
| "Parse PROTO_FILES and generate output based on the options given:\n"
|
| " -IPATH, --proto_path=PATH Specify the directory in which to search for\n"
|
| @@ -1342,20 +1149,11 @@ void CommandLineInterface::PrintHelpText() {
|
| " include information about the original\n"
|
| " location of each decl in the source file as\n"
|
| " well as surrounding comments.\n"
|
| -" --dependency_out=FILE Write a dependency output file in the format\n"
|
| -" expected by make. This writes the transitive\n"
|
| -" set of input file paths to FILE\n"
|
| " --error_format=FORMAT Set the format in which to print errors.\n"
|
| " FORMAT may be 'gcc' (the default) or 'msvs'\n"
|
| -" (Microsoft Visual Studio format).\n"
|
| -" --print_free_field_numbers Print the free field numbers of the messages\n"
|
| -" defined in the given proto files. Groups share\n"
|
| -" the same field number space with the parent \n"
|
| -" message. Extension ranges are counted as \n"
|
| -" occupied fields numbers."
|
| - << std::endl;
|
| +" (Microsoft Visual Studio format)." << endl;
|
| if (!plugin_prefix_.empty()) {
|
| - std::cerr <<
|
| + cerr <<
|
| " --plugin=EXECUTABLE Specifies a plugin executable to use.\n"
|
| " Normally, protoc searches the PATH for\n"
|
| " plugins, but you may specify additional\n"
|
| @@ -1363,7 +1161,7 @@ void CommandLineInterface::PrintHelpText() {
|
| " Additionally, EXECUTABLE may be of the form\n"
|
| " NAME=PATH, in which case the given plugin name\n"
|
| " is mapped to the given executable even if\n"
|
| -" the executable's own name differs." << std::endl;
|
| +" the executable's own name differs." << endl;
|
| }
|
|
|
| for (GeneratorMap::iterator iter = generators_by_flag_name_.begin();
|
| @@ -1371,9 +1169,9 @@ void CommandLineInterface::PrintHelpText() {
|
| // FIXME(kenton): If the text is long enough it will wrap, which is ugly,
|
| // but fixing this nicely (e.g. splitting on spaces) is probably more
|
| // trouble than it's worth.
|
| - std::cerr << " " << iter->first << "=OUT_DIR "
|
| - << string(19 - iter->first.size(), ' ') // Spaces for alignment.
|
| - << iter->second.help_text << std::endl;
|
| + cerr << " " << iter->first << "=OUT_DIR "
|
| + << string(19 - iter->first.size(), ' ') // Spaces for alignment.
|
| + << iter->second.help_text << endl;
|
| }
|
| }
|
|
|
| @@ -1396,7 +1194,7 @@ bool CommandLineInterface::GenerateOutput(
|
| if (!GeneratePluginOutput(parsed_files, plugin_name,
|
| output_directive.parameter,
|
| generator_context, &error)) {
|
| - std::cerr << output_directive.name << ": " << error << std::endl;
|
| + cerr << output_directive.name << ": " << error << endl;
|
| return false;
|
| }
|
| } else {
|
| @@ -1408,95 +1206,14 @@ bool CommandLineInterface::GenerateOutput(
|
| }
|
| parameters.append(generator_parameters_[output_directive.name]);
|
| }
|
| - if (output_directive.generator->HasGenerateAll()) {
|
| - if (!output_directive.generator->GenerateAll(
|
| - parsed_files, parameters, generator_context, &error)) {
|
| - // Generator returned an error.
|
| - std::cerr << output_directive.name << ": "
|
| - << ": " << error << std::endl;
|
| - return false;
|
| - }
|
| - } else {
|
| - for (int i = 0; i < parsed_files.size(); i++) {
|
| - if (!output_directive.generator->Generate(parsed_files[i], parameters,
|
| - generator_context, &error)) {
|
| - // Generator returned an error.
|
| - std::cerr << output_directive.name << ": " << parsed_files[i]->name()
|
| - << ": " << error << std::endl;
|
| - return false;
|
| - }
|
| - }
|
| - }
|
| - }
|
| -
|
| - return true;
|
| -}
|
| -
|
| -bool CommandLineInterface::GenerateDependencyManifestFile(
|
| - const vector<const FileDescriptor*>& parsed_files,
|
| - const GeneratorContextMap& output_directories,
|
| - DiskSourceTree* source_tree) {
|
| - FileDescriptorSet file_set;
|
| -
|
| - set<const FileDescriptor*> already_seen;
|
| - for (int i = 0; i < parsed_files.size(); i++) {
|
| - GetTransitiveDependencies(parsed_files[i],
|
| - false,
|
| - &already_seen,
|
| - file_set.mutable_file());
|
| - }
|
| -
|
| - vector<string> output_filenames;
|
| - for (GeneratorContextMap::const_iterator iter = output_directories.begin();
|
| - iter != output_directories.end(); ++iter) {
|
| - const string& location = iter->first;
|
| - GeneratorContextImpl* directory = iter->second;
|
| - vector<string> relative_output_filenames;
|
| - directory->GetOutputFilenames(&relative_output_filenames);
|
| - for (int i = 0; i < relative_output_filenames.size(); i++) {
|
| - string output_filename = location + relative_output_filenames[i];
|
| - if (output_filename.compare(0, 2, "./") == 0) {
|
| - output_filename = output_filename.substr(2);
|
| + for (int i = 0; i < parsed_files.size(); i++) {
|
| + if (!output_directive.generator->Generate(parsed_files[i], parameters,
|
| + generator_context, &error)) {
|
| + // Generator returned an error.
|
| + cerr << output_directive.name << ": " << parsed_files[i]->name() << ": "
|
| + << error << endl;
|
| + return false;
|
| }
|
| - output_filenames.push_back(output_filename);
|
| - }
|
| - }
|
| -
|
| - int fd;
|
| - do {
|
| - fd = open(dependency_out_name_.c_str(),
|
| - O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666);
|
| - } while (fd < 0 && errno == EINTR);
|
| -
|
| - if (fd < 0) {
|
| - perror(dependency_out_name_.c_str());
|
| - return false;
|
| - }
|
| -
|
| - io::FileOutputStream out(fd);
|
| - io::Printer printer(&out, '$');
|
| -
|
| - for (int i = 0; i < output_filenames.size(); i++) {
|
| - printer.Print(output_filenames[i].c_str());
|
| - if (i == output_filenames.size() - 1) {
|
| - printer.Print(":");
|
| - } else {
|
| - printer.Print(" \\\n");
|
| - }
|
| - }
|
| -
|
| - for (int i = 0; i < file_set.file_size(); i++) {
|
| - const FileDescriptorProto& file = file_set.file(i);
|
| - const string& virtual_file = file.name();
|
| - string disk_file;
|
| - if (source_tree &&
|
| - source_tree->VirtualFileToDiskFile(virtual_file, &disk_file)) {
|
| - printer.Print(" $disk_file$", "disk_file", disk_file);
|
| - if (i < file_set.file_size() - 1) printer.Print("\\\n");
|
| - } else {
|
| - std::cerr << "Unable to identify path for file " << virtual_file
|
| - << std::endl;
|
| - return false;
|
| }
|
| }
|
|
|
| @@ -1542,7 +1259,7 @@ bool CommandLineInterface::GeneratePluginOutput(
|
|
|
| // Write the files. We do this even if there was a generator error in order
|
| // to match the behavior of a compiled-in generator.
|
| - google::protobuf::scoped_ptr<io::ZeroCopyOutputStream> current_output;
|
| + scoped_ptr<io::ZeroCopyOutputStream> current_output;
|
| for (int i = 0; i < response.file_size(); i++) {
|
| const CodeGeneratorResponse::File& output_file = response.file(i);
|
|
|
| @@ -1586,12 +1303,12 @@ bool CommandLineInterface::EncodeOrDecode(const DescriptorPool* pool) {
|
| // Look up the type.
|
| const Descriptor* type = pool->FindMessageTypeByName(codec_type_);
|
| if (type == NULL) {
|
| - std::cerr << "Type not defined: " << codec_type_ << std::endl;
|
| + cerr << "Type not defined: " << codec_type_ << endl;
|
| return false;
|
| }
|
|
|
| DynamicMessageFactory dynamic_factory(pool);
|
| - google::protobuf::scoped_ptr<Message> message(dynamic_factory.GetPrototype(type)->New());
|
| + scoped_ptr<Message> message(dynamic_factory.GetPrototype(type)->New());
|
|
|
| if (mode_ == MODE_ENCODE) {
|
| SetFdToTextMode(STDIN_FILENO);
|
| @@ -1612,32 +1329,32 @@ bool CommandLineInterface::EncodeOrDecode(const DescriptorPool* pool) {
|
| parser.AllowPartialMessage(true);
|
|
|
| if (!parser.Parse(&in, message.get())) {
|
| - std::cerr << "Failed to parse input." << std::endl;
|
| + cerr << "Failed to parse input." << endl;
|
| return false;
|
| }
|
| } else {
|
| // Input is binary.
|
| if (!message->ParsePartialFromZeroCopyStream(&in)) {
|
| - std::cerr << "Failed to parse input." << std::endl;
|
| + cerr << "Failed to parse input." << endl;
|
| return false;
|
| }
|
| }
|
|
|
| if (!message->IsInitialized()) {
|
| - std::cerr << "warning: Input message is missing required fields: "
|
| - << message->InitializationErrorString() << std::endl;
|
| + cerr << "warning: Input message is missing required fields: "
|
| + << message->InitializationErrorString() << endl;
|
| }
|
|
|
| if (mode_ == MODE_ENCODE) {
|
| // Output is binary.
|
| if (!message->SerializePartialToZeroCopyStream(&out)) {
|
| - std::cerr << "output: I/O error." << std::endl;
|
| + cerr << "output: I/O error." << endl;
|
| return false;
|
| }
|
| } else {
|
| // Output is text.
|
| if (!TextFormat::Print(*message, &out)) {
|
| - std::cerr << "output: I/O error." << std::endl;
|
| + cerr << "output: I/O error." << endl;
|
| return false;
|
| }
|
| }
|
| @@ -1679,14 +1396,12 @@ bool CommandLineInterface::WriteDescriptorSet(
|
|
|
| io::FileOutputStream out(fd);
|
| if (!file_set.SerializeToZeroCopyStream(&out)) {
|
| - std::cerr << descriptor_set_name_ << ": " << strerror(out.GetErrno())
|
| - << std::endl;
|
| + cerr << descriptor_set_name_ << ": " << strerror(out.GetErrno()) << endl;
|
| out.Close();
|
| return false;
|
| }
|
| if (!out.Close()) {
|
| - std::cerr << descriptor_set_name_ << ": " << strerror(out.GetErrno())
|
| - << std::endl;
|
| + cerr << descriptor_set_name_ << ": " << strerror(out.GetErrno()) << endl;
|
| return false;
|
| }
|
|
|
| @@ -1716,117 +1431,6 @@ void CommandLineInterface::GetTransitiveDependencies(
|
| }
|
| }
|
|
|
| -namespace {
|
| -
|
| -// Utility function for PrintFreeFieldNumbers.
|
| -// Stores occupied ranges into the ranges parameter, and next level of sub
|
| -// message types into the nested_messages parameter. The FieldRange is left
|
| -// inclusive, right exclusive. i.e. [a, b).
|
| -//
|
| -// Nested Messages:
|
| -// Note that it only stores the nested message type, iff the nested type is
|
| -// either a direct child of the given descriptor, or the nested type is a
|
| -// decendent of the given descriptor and all the nodes between the
|
| -// nested type and the given descriptor are group types. e.g.
|
| -//
|
| -// message Foo {
|
| -// message Bar {
|
| -// message NestedBar {}
|
| -// }
|
| -// group Baz = 1 {
|
| -// group NestedBazGroup = 2 {
|
| -// message Quz {
|
| -// message NestedQuz {}
|
| -// }
|
| -// }
|
| -// message NestedBaz {}
|
| -// }
|
| -// }
|
| -//
|
| -// In this case, Bar, Quz and NestedBaz will be added into the nested types.
|
| -// Since free field numbers of group types will not be printed, this makes sure
|
| -// the nested message types in groups will not be dropped. The nested_messages
|
| -// parameter will contain the direct children (when groups are ignored in the
|
| -// tree) of the given descriptor for the caller to traverse. The declaration
|
| -// order of the nested messages is also preserved.
|
| -typedef pair<int, int> FieldRange;
|
| -void GatherOccupiedFieldRanges(const Descriptor* descriptor,
|
| - set<FieldRange>* ranges,
|
| - vector<const Descriptor*>* nested_messages) {
|
| - set<const Descriptor*> groups;
|
| - for (int i = 0; i < descriptor->field_count(); ++i) {
|
| - const FieldDescriptor* fd = descriptor->field(i);
|
| - ranges->insert(FieldRange(fd->number(), fd->number() + 1));
|
| - if (fd->type() == FieldDescriptor::TYPE_GROUP) {
|
| - groups.insert(fd->message_type());
|
| - }
|
| - }
|
| - for (int i = 0; i < descriptor->extension_range_count(); ++i) {
|
| - ranges->insert(FieldRange(descriptor->extension_range(i)->start,
|
| - descriptor->extension_range(i)->end));
|
| - }
|
| - for (int i = 0; i < descriptor->reserved_range_count(); ++i) {
|
| - ranges->insert(FieldRange(descriptor->reserved_range(i)->start,
|
| - descriptor->reserved_range(i)->end));
|
| - }
|
| - // Handle the nested messages/groups in declaration order to make it
|
| - // post-order strict.
|
| - for (int i = 0; i < descriptor->nested_type_count(); ++i) {
|
| - const Descriptor* nested_desc = descriptor->nested_type(i);
|
| - if (groups.find(nested_desc) != groups.end()) {
|
| - GatherOccupiedFieldRanges(nested_desc, ranges, nested_messages);
|
| - } else {
|
| - nested_messages->push_back(nested_desc);
|
| - }
|
| - }
|
| -}
|
| -
|
| -// Utility function for PrintFreeFieldNumbers.
|
| -// Actually prints the formatted free field numbers for given message name and
|
| -// occupied ranges.
|
| -void FormatFreeFieldNumbers(const string& name,
|
| - const set<FieldRange>& ranges) {
|
| - string output;
|
| - StringAppendF(&output, "%-35s free:", name.c_str());
|
| - int next_free_number = 1;
|
| - for (set<FieldRange>::const_iterator i = ranges.begin();
|
| - i != ranges.end(); ++i) {
|
| - // This happens when groups re-use parent field numbers, in which
|
| - // case we skip the FieldRange entirely.
|
| - if (next_free_number >= i->second) continue;
|
| -
|
| - if (next_free_number < i->first) {
|
| - if (next_free_number + 1 == i->first) {
|
| - // Singleton
|
| - StringAppendF(&output, " %d", next_free_number);
|
| - } else {
|
| - // Range
|
| - StringAppendF(&output, " %d-%d", next_free_number, i->first - 1);
|
| - }
|
| - }
|
| - next_free_number = i->second;
|
| - }
|
| - if (next_free_number <= FieldDescriptor::kMaxNumber) {
|
| - StringAppendF(&output, " %d-INF", next_free_number);
|
| - }
|
| - std::cout << output << std::endl;
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| -void CommandLineInterface::PrintFreeFieldNumbers(
|
| - const Descriptor* descriptor) {
|
| - set<FieldRange> ranges;
|
| - vector<const Descriptor*> nested_messages;
|
| - GatherOccupiedFieldRanges(descriptor, &ranges, &nested_messages);
|
| -
|
| - for (int i = 0; i < nested_messages.size(); ++i) {
|
| - PrintFreeFieldNumbers(nested_messages[i]);
|
| - }
|
| - FormatFreeFieldNumbers(descriptor->full_name(), ranges);
|
| -}
|
| -
|
| -
|
|
|
| } // namespace compiler
|
| } // namespace protobuf
|
|
|