#ifndef _GPD_XS_DESCRIPTORLOADER_INCLUDED
#define _GPD_XS_DESCRIPTORLOADER_INCLUDED
#include "sourcetree.h"
#include <google/protobuf/compiler/importer.h>
namespace gpd {
// alternative SourceTreeDescriptorDatabase for protobuf 3.6 or older
class SourceTreeDescriptorDatabaseWithFallback : public google::protobuf::DescriptorDatabase {
public:
SourceTreeDescriptorDatabaseWithFallback(google::protobuf::compiler::SourceTree *source_tree,
google::protobuf::DescriptorDatabase *fallback_database);
// forwarded SourceTreeDescriptorDatabase methods
void RecordErrorsTo(google::protobuf::compiler::MultiFileErrorCollector* error_collector) {
database.RecordErrorsTo(error_collector);
}
google::protobuf::DescriptorPool::ErrorCollector* GetValidationErrorCollector() {
return database.GetValidationErrorCollector();
}
// DescriptorDatabase implementation
bool FindFileByName(const std::string& filename,
google::protobuf::FileDescriptorProto* output);
bool FindFileContainingSymbol(const std::string& symbol_name,
google::protobuf::FileDescriptorProto* output) {
return false;
}
bool FindFileContainingExtension(const std::string& containing_type,
int field_number,
google::protobuf::FileDescriptorProto* output) {
return false;
}
private:
google::protobuf::compiler::SourceTree *source_tree;
google::protobuf::compiler::SourceTreeDescriptorDatabase database;
google::protobuf::DescriptorDatabase *fallback_database;
};
// a reimplementation of Importer, with a different DescriptorPool
class DescriptorLoader {
class CollectMultiFileErrors : public google::protobuf::compiler::MultiFileErrorCollector {
public:
virtual void AddError(const std::string &filename, int line, int column, const std::string &message);
virtual void AddWarning(const std::string &filename, int line, int column, const std::string &message);
void maybe_croak();
private:
std::string errors;
};
public:
DescriptorLoader();
~DescriptorLoader();
const google::protobuf::FileDescriptor *load_proto(const std::string &filename);
const std::vector<const google::protobuf::FileDescriptor *> load_serialized(const char *buffer, size_t length);
inline const google::protobuf::DescriptorPool *pool() const {
return &merged_pool;
}
void map_disk_path(const std::string &virtual_path, const std::string &disk_path) {
disk_source_tree.MapPath(virtual_path, disk_path);
}
void add_memory_file(const std::string &file_name, const char *data, size_t length) {
memory_source_tree.AddFile(file_name, data, length);
}
void maybe_croak() {
multifile_error_collector.maybe_croak();
}
private:
CollectMultiFileErrors multifile_error_collector;
OverlaySourceTree overlay_source_tree;
MemorySourceTree memory_source_tree;
google::protobuf::DescriptorPoolDatabase generated_database;
google::protobuf::compiler::DiskSourceTree disk_source_tree;
#if GOOGLE_PROTOBUF_VERSION >= 3007000
google::protobuf::compiler::SourceTreeDescriptorDatabase source_database;
#else
SourceTreeDescriptorDatabaseWithFallback source_database;
#endif
google::protobuf::SimpleDescriptorDatabase binary_database;
google::protobuf::MergedDescriptorDatabase merged_source_binary_database;
google::protobuf::DescriptorPool merged_pool;
};
}
#endif