22 #ifndef DCCLDYNAMICPROTOBUFMANAGER20110419H
23 #define DCCLDYNAMICPROTOBUFMANAGER20110419H
31 #include <google/protobuf/descriptor.h>
32 #include <google/protobuf/descriptor.pb.h>
33 #include <google/protobuf/dynamic_message.h>
34 #include <google/protobuf/descriptor_database.h>
35 #include <google/protobuf/compiler/importer.h>
37 #include <boost/shared_ptr.hpp>
38 #include <boost/version.hpp>
54 static const google::protobuf::Descriptor*
find_descriptor(
const std::string& protobuf_type_name)
57 const google::protobuf::Descriptor* desc = google::protobuf::DescriptorPool::generated_pool()->FindMessageTypeByName(protobuf_type_name);
61 desc = user_descriptor_pool().FindMessageTypeByName(protobuf_type_name);
75 template<
typename GoogleProtobufMessagePo
inter>
77 const std::string& protobuf_type_name)
79 const google::protobuf::Descriptor* desc =
find_descriptor(protobuf_type_name);
81 return new_protobuf_message<GoogleProtobufMessagePointer>(desc);
83 throw(std::runtime_error(
"Unknown type " + protobuf_type_name +
", be sure it is loaded at compile-time, via dlopen, or with a call to add_protobuf_file()"));
91 template<
typename GoogleProtobufMessagePo
inter>
93 const google::protobuf::Descriptor* desc)
94 {
return GoogleProtobufMessagePointer(msg_factory().GetPrototype(desc)->New()); }
101 const google::protobuf::Descriptor* desc)
102 {
return new_protobuf_message<boost::shared_ptr<google::protobuf::Message> >(desc); }
109 const std::string& protobuf_type_name)
110 {
return new_protobuf_message<boost::shared_ptr<google::protobuf::Message> >(protobuf_type_name); }
114 static void add_database(boost::shared_ptr<google::protobuf::DescriptorDatabase> database)
116 get_instance()->databases_.push_back(database);
117 get_instance()->update_databases();
123 get_instance()->enable_disk_source_database();
136 static const google::protobuf::FileDescriptor*
145 if(!get_instance()->disk_source_tree_)
146 throw(std::runtime_error(
"Must called enable_compilation() before loading proto files directly"));
148 get_instance()->disk_source_tree_->MapPath(
"", path);
156 void* handle = dlopen(shared_lib_path.c_str(), RTLD_LAZY);
158 get_instance()->dl_handles_.push_back(handle);
162 static void protobuf_shutdown()
164 get_instance()->shutdown();
170 const google::protobuf::FileDescriptorProto& proto);
172 static google::protobuf::DynamicMessageFactory& msg_factory()
173 {
return *get_instance()->msg_factory_; }
174 static google::protobuf::DescriptorPool& user_descriptor_pool()
175 {
return *get_instance()->user_descriptor_pool_; }
176 static google::protobuf::SimpleDescriptorDatabase& simple_database()
177 {
return *get_instance()->simple_database_; }
181 inst_.reset(
new DynamicProtobufManager);
188 #if BOOST_VERSION >= 107000
190 friend void boost::checked_delete(T*) BOOST_NOEXCEPT;
193 friend void boost::checked_delete(T*);
196 static boost::shared_ptr<DynamicProtobufManager> inst_;
198 static DynamicProtobufManager* get_instance()
201 inst_.reset(
new DynamicProtobufManager);
206 DynamicProtobufManager()
207 : generated_database_(new google::protobuf::DescriptorPoolDatabase(*google::protobuf::DescriptorPool::generated_pool())),
208 simple_database_(new google::protobuf::SimpleDescriptorDatabase),
209 msg_factory_(new google::protobuf::DynamicMessageFactory)
211 databases_.push_back(simple_database_);
212 databases_.push_back(generated_database_);
214 msg_factory_->SetDelegateToGeneratedFactory(
true);
219 ~DynamicProtobufManager()
226 for(std::vector<void *>::iterator it = dl_handles_.begin(),
227 n = dl_handles_.end(); it != n; ++it)
229 google::protobuf::ShutdownProtobufLibrary();
234 void update_databases()
236 std::vector<google::protobuf::DescriptorDatabase*> databases;
238 for(std::vector<boost::shared_ptr<google::protobuf::DescriptorDatabase> >::const_iterator it = databases_.begin(), end = databases_.end(); it != end; ++it)
239 databases.push_back(it->get());
241 merged_database_.reset(
new google::protobuf::MergedDescriptorDatabase(databases));
242 user_descriptor_pool_.reset(
new google::protobuf::DescriptorPool(merged_database_.get()));
245 void enable_disk_source_database();
247 DynamicProtobufManager(
const DynamicProtobufManager&);
248 DynamicProtobufManager& operator= (
const DynamicProtobufManager&);
251 std::vector<boost::shared_ptr<google::protobuf::DescriptorDatabase> > databases_;
254 boost::shared_ptr<google::protobuf::DescriptorPoolDatabase> generated_database_;
255 boost::shared_ptr<google::protobuf::SimpleDescriptorDatabase> simple_database_;
256 boost::shared_ptr<google::protobuf::MergedDescriptorDatabase> merged_database_;
257 boost::shared_ptr<google::protobuf::DescriptorPool> user_descriptor_pool_;
258 boost::shared_ptr<google::protobuf::DynamicMessageFactory> msg_factory_;
261 boost::shared_ptr<google::protobuf::compiler::DiskSourceTree> disk_source_tree_;
262 boost::shared_ptr<google::protobuf::compiler::SourceTreeDescriptorDatabase> source_database_;
264 class DLogMultiFileErrorCollector
267 void AddError(
const std::string & filename,
int line,
int column,
268 const std::string & message);
271 boost::shared_ptr<DLogMultiFileErrorCollector> error_collector_;
273 std::vector<void *> dl_handles_;