25 #ifndef DCCLDYNAMICPROTOBUFMANAGER20110419H
26 #define DCCLDYNAMICPROTOBUFMANAGER20110419H
34 #include <google/protobuf/compiler/importer.h>
35 #include <google/protobuf/descriptor.h>
36 #include <google/protobuf/descriptor.pb.h>
37 #include <google/protobuf/descriptor_database.h>
38 #include <google/protobuf/dynamic_message.h>
42 #include "thread_safety.h"
63 static const google::protobuf::Descriptor*
64 find_descriptor(
const std::string& protobuf_type_name,
bool user_pool_first =
false);
76 template <
typename GoogleProtobufMessagePo
inter>
78 bool user_pool_first =
false)
80 DCCL_LOCK_DYNAMIC_PROTOBUF_MANAGER_MUTEX
82 const google::protobuf::Descriptor* desc =
85 return new_protobuf_message<GoogleProtobufMessagePointer>(desc);
87 throw(std::runtime_error(
"Unknown type " + protobuf_type_name +
88 ", be sure it is loaded at compile-time, via dlopen, or with "
89 "a call to add_protobuf_file()"));
97 template <
typename GoogleProtobufMessagePo
inter>
98 static GoogleProtobufMessagePointer
101 DCCL_LOCK_DYNAMIC_PROTOBUF_MANAGER_MUTEX
102 return GoogleProtobufMessagePointer(
103 get_instance()->msg_factory_->GetPrototype(desc)->New());
110 static std::shared_ptr<google::protobuf::Message>
117 static std::shared_ptr<google::protobuf::Message>
121 static void add_database(std::shared_ptr<google::protobuf::DescriptorDatabase> database);
126 DCCL_LOCK_DYNAMIC_PROTOBUF_MANAGER_MUTEX
127 get_instance()->enable_disk_source_database();
140 static const google::protobuf::FileDescriptor*
153 static void protobuf_shutdown()
155 DCCL_LOCK_DYNAMIC_PROTOBUF_MANAGER_MUTEX
156 get_instance()->shutdown();
160 static const google::protobuf::FileDescriptor*
165 DCCL_LOCK_DYNAMIC_PROTOBUF_MANAGER_MUTEX
166 inst_.reset(
new DynamicProtobufManager, DynamicProtobufManager::custom_deleter);
169 static void custom_deleter(DynamicProtobufManager* obj) {
delete obj; }
171 #if !(DCCL_THREAD_SUPPORT)
174 static google::protobuf::DynamicMessageFactory& msg_factory()
176 return *get_instance()->msg_factory_;
178 static google::protobuf::DescriptorPool& user_descriptor_pool()
180 return *get_instance()->user_descriptor_pool_;
182 static google::protobuf::SimpleDescriptorDatabase& simple_database()
184 return *get_instance()->simple_database_;
187 template <
typename T =
void>
static google::protobuf::DynamicMessageFactory& msg_factory()
189 static_assert(!std::is_same<T, T>::value,
190 "msg_factory() has been removed for thread-safety "
191 "reasons, use msg_factory_call(...) instead.");
193 return *get_instance()->msg_factory_;
195 template <
typename T =
void>
static google::protobuf::DescriptorPool& user_descriptor_pool()
197 static_assert(!std::is_same<T, T>::value,
198 "user_descriptor_pool() has been removed for thread-safety reasons, use "
199 "user_descriptor_pool_call(...) instead.");
201 return *get_instance()->user_descriptor_pool_;
203 template <
typename T =
void>
204 static google::protobuf::SimpleDescriptorDatabase& simple_database()
206 static_assert(!std::is_same<T, T>::value,
207 "simple_database() has been removed for thread-safety reasons, use "
208 "simple_database_call(...) instead.");
210 return *get_instance()->simple_database_;
214 template <
typename ReturnType,
typename... Args1,
typename... Args2>
216 msg_factory_call(ReturnType (google::protobuf::DynamicMessageFactory::*func)(Args1...)
const,
219 DCCL_LOCK_DYNAMIC_PROTOBUF_MANAGER_MUTEX
220 return ((*get_instance()->msg_factory_).*func)(args...);
223 template <
typename ReturnType,
typename... Args1,
typename... Args2>
225 user_descriptor_pool_call(ReturnType (google::protobuf::DescriptorPool::*func)(Args1...)
const,
228 DCCL_LOCK_DYNAMIC_PROTOBUF_MANAGER_MUTEX
229 return ((*get_instance()->user_descriptor_pool_).*func)(args...);
232 template <
typename ReturnType,
typename... Args1,
typename... Args2>
234 simple_database_call(ReturnType (google::protobuf::SimpleDescriptorDatabase::*func)(Args1...)
238 DCCL_LOCK_DYNAMIC_PROTOBUF_MANAGER_MUTEX
239 return ((*get_instance()->simple_database_).*func)(args...);
243 static std::shared_ptr<DynamicProtobufManager> inst_;
244 static DynamicProtobufManager* get_instance()
246 DCCL_LOCK_DYNAMIC_PROTOBUF_MANAGER_MUTEX
249 inst_.reset(
new DynamicProtobufManager, DynamicProtobufManager::custom_deleter);
253 DynamicProtobufManager()
254 : generated_database_(new google::protobuf::DescriptorPoolDatabase(
255 *google::protobuf::DescriptorPool::generated_pool())),
256 simple_database_(new google::protobuf::SimpleDescriptorDatabase),
257 msg_factory_(new google::protobuf::DynamicMessageFactory)
259 databases_.push_back(simple_database_);
260 databases_.push_back(generated_database_);
262 msg_factory_->SetDelegateToGeneratedFactory(
true);
267 ~DynamicProtobufManager() =
default;
271 for (
auto& dl_handle : dl_handles_) dlclose(dl_handle);
272 google::protobuf::ShutdownProtobufLibrary();
276 void update_databases()
278 std::vector<google::protobuf::DescriptorDatabase*> databases;
280 for (
const auto& database : databases_) databases.push_back(database.get());
282 merged_database_.reset(
new google::protobuf::MergedDescriptorDatabase(databases));
283 user_descriptor_pool_.reset(
new google::protobuf::DescriptorPool(merged_database_.get()));
286 void enable_disk_source_database();
289 std::vector<std::shared_ptr<google::protobuf::DescriptorDatabase>> databases_;
292 std::shared_ptr<google::protobuf::DescriptorPoolDatabase> generated_database_;
293 std::shared_ptr<google::protobuf::SimpleDescriptorDatabase> simple_database_;
294 std::shared_ptr<google::protobuf::MergedDescriptorDatabase> merged_database_;
295 std::shared_ptr<google::protobuf::DescriptorPool> user_descriptor_pool_;
296 std::shared_ptr<google::protobuf::DynamicMessageFactory> msg_factory_;
299 std::shared_ptr<google::protobuf::compiler::DiskSourceTree> disk_source_tree_;
300 std::shared_ptr<google::protobuf::compiler::SourceTreeDescriptorDatabase> source_database_;
304 void AddError(
const std::string& filename,
int line,
int column,
305 const std::string& message)
override;
308 std::shared_ptr<DLogMultiFileErrorCollector> error_collector_;
310 std::vector<void*> dl_handles_;