#else
#include <unistd.h>
#endif
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
#include <errno.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
#include <algorithm>
#include <memory>
#include <google/protobuf/compiler/importer.h>
#include <google/protobuf/compiler/parser.h>
+#include <google/protobuf/io/io_win32.h>
#include <google/protobuf/io/tokenizer.h>
#include <google/protobuf/io/zero_copy_stream_impl.h>
#include <google/protobuf/stubs/strutil.h>
-#include <google/protobuf/stubs/io_win32.h>
#ifdef _WIN32
#include <ctype.h>
#ifdef _WIN32
// DO NOT include <io.h>, instead create functions in io_win32.{h,cc} and import
// them like we do below.
-using google::protobuf::internal::win32::access;
-using google::protobuf::internal::win32::open;
+using google::protobuf::io::win32::access;
+using google::protobuf::io::win32::open;
#endif
// Returns true if the text looks like a Windows-style absolute path, starting
// with a drive letter. Example: "C:\foo". TODO(kenton): Share this with
// copy in command_line_interface.cc?
-static bool IsWindowsAbsolutePath(const string& text) {
+static bool IsWindowsAbsolutePath(const std::string& text) {
#if defined(_WIN32) || defined(__CYGWIN__)
- return text.size() >= 3 && text[1] == ':' &&
- isalpha(text[0]) &&
- (text[2] == '/' || text[2] == '\\') &&
- text.find_last_of(':') == 1;
+ return text.size() >= 3 && text[1] == ':' && isalpha(text[0]) &&
+ (text[2] == '/' || text[2] == '\\') && text.find_last_of(':') == 1;
#else
return false;
#endif
class SourceTreeDescriptorDatabase::SingleFileErrorCollector
: public io::ErrorCollector {
public:
- SingleFileErrorCollector(const string& filename,
+ SingleFileErrorCollector(const std::string& filename,
MultiFileErrorCollector* multi_file_error_collector)
- : filename_(filename),
- multi_file_error_collector_(multi_file_error_collector),
- had_errors_(false) {}
+ : filename_(filename),
+ multi_file_error_collector_(multi_file_error_collector),
+ had_errors_(false) {}
~SingleFileErrorCollector() {}
bool had_errors() { return had_errors_; }
// implements ErrorCollector ---------------------------------------
- void AddError(int line, int column, const string& message) {
+ void AddError(int line, int column, const std::string& message) override {
if (multi_file_error_collector_ != NULL) {
multi_file_error_collector_->AddError(filename_, line, column, message);
}
}
private:
- string filename_;
+ std::string filename_;
MultiFileErrorCollector* multi_file_error_collector_;
bool had_errors_;
};
SourceTreeDescriptorDatabase::SourceTreeDescriptorDatabase(
SourceTree* source_tree)
- : source_tree_(source_tree),
- error_collector_(NULL),
- using_validation_error_collector_(false),
- validation_error_collector_(this) {}
+ : source_tree_(source_tree),
+ fallback_database_(nullptr),
+ error_collector_(nullptr),
+ using_validation_error_collector_(false),
+ validation_error_collector_(this) {}
+
+SourceTreeDescriptorDatabase::SourceTreeDescriptorDatabase(
+ SourceTree* source_tree, DescriptorDatabase* fallback_database)
+ : source_tree_(source_tree),
+ fallback_database_(fallback_database),
+ error_collector_(nullptr),
+ using_validation_error_collector_(false),
+ validation_error_collector_(this) {}
SourceTreeDescriptorDatabase::~SourceTreeDescriptorDatabase() {}
-bool SourceTreeDescriptorDatabase::FindFileByName(
- const string& filename, FileDescriptorProto* output) {
+bool SourceTreeDescriptorDatabase::FindFileByName(const std::string& filename,
+ FileDescriptorProto* output) {
std::unique_ptr<io::ZeroCopyInputStream> input(source_tree_->Open(filename));
if (input == NULL) {
+ if (fallback_database_ != nullptr &&
+ fallback_database_->FindFileByName(filename, output)) {
+ return true;
+ }
if (error_collector_ != NULL) {
error_collector_->AddError(filename, -1, 0,
source_tree_->GetLastErrorMessage());
// Parse it.
output->set_name(filename);
- return parser.Parse(&tokenizer, output) &&
- !file_error_collector.had_errors();
+ return parser.Parse(&tokenizer, output) && !file_error_collector.had_errors();
}
bool SourceTreeDescriptorDatabase::FindFileContainingSymbol(
- const string& symbol_name, FileDescriptorProto* output) {
+ const std::string& symbol_name, FileDescriptorProto* output) {
return false;
}
bool SourceTreeDescriptorDatabase::FindFileContainingExtension(
- const string& containing_type, int field_number,
+ const std::string& containing_type, int field_number,
FileDescriptorProto* output) {
return false;
}
// -------------------------------------------------------------------
SourceTreeDescriptorDatabase::ValidationErrorCollector::
-ValidationErrorCollector(SourceTreeDescriptorDatabase* owner)
- : owner_(owner) {}
+ ValidationErrorCollector(SourceTreeDescriptorDatabase* owner)
+ : owner_(owner) {}
SourceTreeDescriptorDatabase::ValidationErrorCollector::
-~ValidationErrorCollector() {}
+ ~ValidationErrorCollector() {}
void SourceTreeDescriptorDatabase::ValidationErrorCollector::AddError(
- const string& filename,
- const string& element_name,
- const Message* descriptor,
- ErrorLocation location,
- const string& message) {
+ const std::string& filename, const std::string& element_name,
+ const Message* descriptor, ErrorLocation location,
+ const std::string& message) {
if (owner_->error_collector_ == NULL) return;
int line, column;
- owner_->source_locations_.Find(descriptor, location, &line, &column);
+ if (location == DescriptorPool::ErrorCollector::IMPORT) {
+ owner_->source_locations_.FindImport(descriptor, element_name, &line,
+ &column);
+ } else {
+ owner_->source_locations_.Find(descriptor, location, &line, &column);
+ }
owner_->error_collector_->AddError(filename, line, column, message);
}
void SourceTreeDescriptorDatabase::ValidationErrorCollector::AddWarning(
- const string& filename,
- const string& element_name,
- const Message* descriptor,
- ErrorLocation location,
- const string& message) {
+ const std::string& filename, const std::string& element_name,
+ const Message* descriptor, ErrorLocation location,
+ const std::string& message) {
if (owner_->error_collector_ == NULL) return;
int line, column;
- owner_->source_locations_.Find(descriptor, location, &line, &column);
+ if (location == DescriptorPool::ErrorCollector::IMPORT) {
+ owner_->source_locations_.FindImport(descriptor, element_name, &line,
+ &column);
+ } else {
+ owner_->source_locations_.Find(descriptor, location, &line, &column);
+ }
owner_->error_collector_->AddWarning(filename, line, column, message);
}
Importer::Importer(SourceTree* source_tree,
MultiFileErrorCollector* error_collector)
- : database_(source_tree),
- pool_(&database_, database_.GetValidationErrorCollector()) {
+ : database_(source_tree),
+ pool_(&database_, database_.GetValidationErrorCollector()) {
pool_.EnforceWeakDependencies(true);
database_.RecordErrorsTo(error_collector);
}
Importer::~Importer() {}
-const FileDescriptor* Importer::Import(const string& filename) {
+const FileDescriptor* Importer::Import(const std::string& filename) {
return pool_.FindFileByName(filename);
}
-void Importer::AddUnusedImportTrackFile(const string& file_name) {
+void Importer::AddUnusedImportTrackFile(const std::string& file_name) {
pool_.AddUnusedImportTrackFile(file_name);
}
SourceTree::~SourceTree() {}
-string SourceTree::GetLastErrorMessage() {
- return "File not found.";
-}
+std::string SourceTree::GetLastErrorMessage() { return "File not found."; }
DiskSourceTree::DiskSourceTree() {}
DiskSourceTree::~DiskSourceTree() {}
-static inline char LastChar(const string& str) {
+static inline char LastChar(const std::string& str) {
return str[str.size() - 1];
}
// then if foo/bar is a symbolic link, foo/bar/baz.proto will canonicalize
// to a path which does not appear to be under foo, and thus the compiler
// will complain that baz.proto is not inside the --proto_path.
-static string CanonicalizePath(string path) {
+static std::string CanonicalizePath(std::string path) {
#ifdef _WIN32
// The Win32 API accepts forward slashes as a path delimiter even though
// backslashes are standard. Let's avoid confusion and use only forward
}
#endif
- std::vector<string> canonical_parts;
- std::vector<string> parts = Split(
+ std::vector<std::string> canonical_parts;
+ std::vector<std::string> parts = Split(
path, "/", true); // Note: Removes empty parts.
for (int i = 0; i < parts.size(); i++) {
if (parts[i] == ".") {
canonical_parts.push_back(parts[i]);
}
}
- string result = Join(canonical_parts, "/");
+ std::string result = Join(canonical_parts, "/");
if (!path.empty() && path[0] == '/') {
// Restore leading slash.
result = '/' + result;
}
- if (!path.empty() && LastChar(path) == '/' &&
- !result.empty() && LastChar(result) != '/') {
+ if (!path.empty() && LastChar(path) == '/' && !result.empty() &&
+ LastChar(result) != '/') {
// Restore trailing slash.
result += '/';
}
return result;
}
-static inline bool ContainsParentReference(const string& path) {
+static inline bool ContainsParentReference(const std::string& path) {
return path == ".." || HasPrefixString(path, "../") ||
HasSuffixString(path, "/..") || path.find("/../") != string::npos;
}
// assert(!ApplyMapping("foo/bar", "baz", "qux", &result));
// assert(!ApplyMapping("foo/bar", "baz", "qux", &result));
// assert(!ApplyMapping("foobar", "foo", "baz", &result));
-static bool ApplyMapping(const string& filename,
- const string& old_prefix,
- const string& new_prefix,
- string* result) {
+static bool ApplyMapping(const std::string& filename,
+ const std::string& old_prefix,
+ const std::string& new_prefix, std::string* result) {
if (old_prefix.empty()) {
// old_prefix matches any relative path.
if (ContainsParentReference(filename)) {
if (after_prefix_start != -1) {
// Yep. So the prefixes are directories and the filename is a file
// inside them.
- string after_prefix = filename.substr(after_prefix_start);
+ std::string after_prefix = filename.substr(after_prefix_start);
if (ContainsParentReference(after_prefix)) {
// We do not allow the file name to use "..".
return false;
return false;
}
-void DiskSourceTree::MapPath(const string& virtual_path,
- const string& disk_path) {
+void DiskSourceTree::MapPath(const std::string& virtual_path,
+ const std::string& disk_path) {
mappings_.push_back(Mapping(virtual_path, CanonicalizePath(disk_path)));
}
DiskSourceTree::DiskFileToVirtualFileResult
-DiskSourceTree::DiskFileToVirtualFile(
- const string& disk_file,
- string* virtual_file,
- string* shadowing_disk_file) {
+DiskSourceTree::DiskFileToVirtualFile(const std::string& disk_file,
+ std::string* virtual_file,
+ std::string* shadowing_disk_file) {
int mapping_index = -1;
- string canonical_disk_file = CanonicalizePath(disk_file);
+ std::string canonical_disk_file = CanonicalizePath(disk_file);
for (int i = 0; i < mappings_.size(); i++) {
// Apply the mapping in reverse.
return SUCCESS;
}
-bool DiskSourceTree::VirtualFileToDiskFile(const string& virtual_file,
- string* disk_file) {
+bool DiskSourceTree::VirtualFileToDiskFile(const std::string& virtual_file,
+ std::string* disk_file) {
std::unique_ptr<io::ZeroCopyInputStream> stream(
OpenVirtualFile(virtual_file, disk_file));
return stream != NULL;
}
-io::ZeroCopyInputStream* DiskSourceTree::Open(const string& filename) {
+io::ZeroCopyInputStream* DiskSourceTree::Open(const std::string& filename) {
return OpenVirtualFile(filename, NULL);
}
-string DiskSourceTree::GetLastErrorMessage() {
+std::string DiskSourceTree::GetLastErrorMessage() {
return last_error_message_;
}
io::ZeroCopyInputStream* DiskSourceTree::OpenVirtualFile(
- const string& virtual_file,
- string* disk_file) {
+ const std::string& virtual_file, std::string* disk_file) {
if (virtual_file != CanonicalizePath(virtual_file) ||
ContainsParentReference(virtual_file)) {
// We do not allow importing of paths containing things like ".." or
// consecutive slashes since the compiler expects files to be uniquely
// identified by file name.
- last_error_message_ = "Backslashes, consecutive slashes, \".\", or \"..\" "
- "are not allowed in the virtual path";
+ last_error_message_ =
+ "Backslashes, consecutive slashes, \".\", or \"..\" "
+ "are not allowed in the virtual path";
return NULL;
}
for (int i = 0; i < mappings_.size(); i++) {
- string temp_disk_file;
+ std::string temp_disk_file;
if (ApplyMapping(virtual_file, mappings_[i].virtual_path,
mappings_[i].disk_path, &temp_disk_file)) {
io::ZeroCopyInputStream* stream = OpenDiskFile(temp_disk_file);
if (errno == EACCES) {
// The file exists but is not readable.
- last_error_message_ = "Read access is denied for file: " +
- temp_disk_file;
+ last_error_message_ =
+ "Read access is denied for file: " + temp_disk_file;
return NULL;
}
}
}
io::ZeroCopyInputStream* DiskSourceTree::OpenDiskFile(
- const string& filename) {
+ const std::string& filename) {
int file_descriptor;
do {
file_descriptor = open(filename.c_str(), O_RDONLY);