#include "dynamicproto.h" #include #include #include #include #include using namespace google::protobuf::compiler; using namespace google::protobuf; namespace { class ErrorCollector : public MultiFileErrorCollector { public: void AddError(const std::string& file_name, int line, int column, const std::string& message) override { std::cerr << "Error in: " << file_name << " line: " << line << " column: " << column << " message: " << message << std::endl; } }; DiskSourceTree source_tree; ErrorCollector error_collector; std::unique_ptr importer; DynamicMessageFactory factory; // This needs to be kept around } // namespace namespace dynamicproto { void warnNotInitialized() { std::cerr << "Warning: dynamicproto has not been initalized" << std::endl; } void init(const std::vector& include_paths) { for (auto& path: include_paths) { source_tree.MapPath("", path); } importer = std::unique_ptr(new Importer(&source_tree, &error_collector)); } void fileDescriptorDependencies(const FileDescriptor* fdesc, std::vector& result) { if(fdesc) { size_t n = fdesc->dependency_count(); for (size_t i=0; idependency(i), result); } result.push_back(fdesc); } } // Get a FileDescriptor for the file and all its dependencies, // the latter of which appear at the beginning of the vector. std::vector fileDescriptors(const std::string& file_name) { std::vector result; if(importer) { const FileDescriptor* fdesc = importer->Import(file_name); fileDescriptorDependencies(fdesc, result); } else { warnNotInitialized(); } return result; } // Find extensions of full_name in desc and add them to result. void extensionsOf(const FileDescriptor* desc, const std::string& full_name, std::vector& result) { // TODO: look in all messages that may contain inner extensions if(desc) { int n = desc->extension_count(); for (int i=0;iextension(i); if(e->containing_type()->full_name()==full_name) result.push_back(e); } n = desc->dependency_count(); for (int i=0;idependency(i), full_name, result); } } } std::vector enums(const FileDescriptor* extDesc) { std::vector result; if(extDesc) { int n = extDesc->enum_type_count(); for (int i=0;ienum_type(i); result.push_back(e); } } return result; } void print(const EnumDescriptor* e, std::ostream& o) { o << "enum " << e->name() << " { "; int n = e->value_count(); bool first = true; for (int i=0; ivalue(i)->name() << "=" << (i+1); } o << "}"; } Message* newMessage(const FileDescriptor* fdesc, const std::string& name) { auto desc = fdesc->FindMessageTypeByName(name); if(desc) { auto p = factory.GetPrototype(desc); if(p) return p->New(); } size_t n = fdesc->dependency_count(); for (size_t i=0; idependency(i), name); if(m) return m; } return nullptr; } } // namespace dynamicproto