24 #ifndef DCCLDYNAMICPROTOBUFMANAGER20110419H
25 #define DCCLDYNAMICPROTOBUFMANAGER20110419H
33 #include <google/protobuf/compiler/importer.h>
34 #include <google/protobuf/descriptor.h>
35 #include <google/protobuf/descriptor.pb.h>
36 #include <google/protobuf/descriptor_database.h>
37 #include <google/protobuf/dynamic_message.h>
41 #include "thread_safety.h"
62 static const google::protobuf::Descriptor*
63 find_descriptor(
const std::string& protobuf_type_name,
bool user_pool_first =
false);
75 template <
typename GoogleProtobufMessagePo
inter>
77 bool user_pool_first =
false)
79 DCCL_LOCK_DYNAMIC_PROTOBUF_MANAGER_MUTEX
81 const google::protobuf::Descriptor* desc =
84 return new_protobuf_message<GoogleProtobufMessagePointer>(desc);
86 throw(std::runtime_error(
"Unknown type " + protobuf_type_name +
87 ", be sure it is loaded at compile-time, via dlopen, or with "
88 "a call to add_protobuf_file()"));
96 template <
typename GoogleProtobufMessagePo
inter>
97 static GoogleProtobufMessagePointer
100 DCCL_LOCK_DYNAMIC_PROTOBUF_MANAGER_MUTEX
101 return GoogleProtobufMessagePointer(
102 get_instance()->msg_factory_->GetPrototype(desc)->New());
109 static std::shared_ptr<google::protobuf::Message>
116 static std::shared_ptr<google::protobuf::Message>
120 static void add_database(std::shared_ptr<google::protobuf::DescriptorDatabase> database);
125 DCCL_LOCK_DYNAMIC_PROTOBUF_MANAGER_MUTEX
126 get_instance()->enable_disk_source_database();
139 static const google::protobuf::FileDescriptor*
152 static void protobuf_shutdown()
154 DCCL_LOCK_DYNAMIC_PROTOBUF_MANAGER_MUTEX
155 get_instance()->shutdown();
159 static const google::protobuf::FileDescriptor*
164 DCCL_LOCK_DYNAMIC_PROTOBUF_MANAGER_MUTEX
165 inst_.reset(
new DynamicProtobufManager, DynamicProtobufManager::custom_deleter);
168 static void custom_deleter(DynamicProtobufManager* obj) {
delete obj; }
170 #if !(DCCL_THREAD_SUPPORT)
173 static google::protobuf::DynamicMessageFactory& msg_factory()
175 return *get_instance()->msg_factory_;
177 static google::protobuf::DescriptorPool& user_descriptor_pool()
179 return *get_instance()->user_descriptor_pool_;
181 static google::protobuf::SimpleDescriptorDatabase& simple_database()
183 return *get_instance()->simple_database_;
186 template <
typename T =
void>
static google::protobuf::DynamicMessageFactory& msg_factory()
188 static_assert(!std::is_same<T, T>::value,
189 "msg_factory() has been removed for thread-safety "
190 "reasons, use msg_factory_call(...) instead.");
192 return *get_instance()->msg_factory_;
194 template <
typename T =
void>
static google::protobuf::DescriptorPool& user_descriptor_pool()
196 static_assert(!std::is_same<T, T>::value,
197 "user_descriptor_pool() has been removed for thread-safety reasons, use "
198 "user_descriptor_pool_call(...) instead.");
200 return *get_instance()->user_descriptor_pool_;
202 template <
typename T =
void>
203 static google::protobuf::SimpleDescriptorDatabase& simple_database()
205 static_assert(!std::is_same<T, T>::value,
206 "simple_database() has been removed for thread-safety reasons, use "
207 "simple_database_call(...) instead.");
209 return *get_instance()->simple_database_;
213 template <
typename ReturnType,
typename... Args1,
typename... Args2>
215 msg_factory_call(ReturnType (google::protobuf::DynamicMessageFactory::*func)(Args1...)
const,
218 DCCL_LOCK_DYNAMIC_PROTOBUF_MANAGER_MUTEX
219 return ((*get_instance()->msg_factory_).*func)(args...);
222 template <
typename ReturnType,
typename... Args1,
typename... Args2>
224 user_descriptor_pool_call(ReturnType (google::protobuf::DescriptorPool::*func)(Args1...)
const,
227 DCCL_LOCK_DYNAMIC_PROTOBUF_MANAGER_MUTEX
228 return ((*get_instance()->user_descriptor_pool_).*func)(args...);
231 template <
typename ReturnType,
typename... Args1,
typename... Args2>
233 simple_database_call(ReturnType (google::protobuf::SimpleDescriptorDatabase::*func)(Args1...)
237 DCCL_LOCK_DYNAMIC_PROTOBUF_MANAGER_MUTEX
238 return ((*get_instance()->simple_database_).*func)(args...);
242 static std::shared_ptr<DynamicProtobufManager> inst_;
243 static DynamicProtobufManager* get_instance()
245 DCCL_LOCK_DYNAMIC_PROTOBUF_MANAGER_MUTEX
248 inst_.reset(
new DynamicProtobufManager, DynamicProtobufManager::custom_deleter);
252 DynamicProtobufManager()
253 : generated_database_(new google::protobuf::DescriptorPoolDatabase(
254 *google::protobuf::DescriptorPool::generated_pool())),
255 simple_database_(new google::protobuf::SimpleDescriptorDatabase),
256 msg_factory_(new google::protobuf::DynamicMessageFactory)
258 databases_.push_back(simple_database_);
259 databases_.push_back(generated_database_);
261 msg_factory_->SetDelegateToGeneratedFactory(
true);
266 ~DynamicProtobufManager() =
default;
270 for (
auto& dl_handle : dl_handles_) dlclose(dl_handle);
271 google::protobuf::ShutdownProtobufLibrary();
275 void update_databases()
277 std::vector<google::protobuf::DescriptorDatabase*> databases;
279 for (
const auto& database : databases_) databases.push_back(database.get());
281 merged_database_.reset(
new google::protobuf::MergedDescriptorDatabase(databases));
282 user_descriptor_pool_.reset(
new google::protobuf::DescriptorPool(merged_database_.get()));
285 void enable_disk_source_database();
288 std::vector<std::shared_ptr<google::protobuf::DescriptorDatabase>> databases_;
291 std::shared_ptr<google::protobuf::DescriptorPoolDatabase> generated_database_;
292 std::shared_ptr<google::protobuf::SimpleDescriptorDatabase> simple_database_;
293 std::shared_ptr<google::protobuf::MergedDescriptorDatabase> merged_database_;
294 std::shared_ptr<google::protobuf::DescriptorPool> user_descriptor_pool_;
295 std::shared_ptr<google::protobuf::DynamicMessageFactory> msg_factory_;
298 std::shared_ptr<google::protobuf::compiler::DiskSourceTree> disk_source_tree_;
299 std::shared_ptr<google::protobuf::compiler::SourceTreeDescriptorDatabase> source_database_;
303 void AddError(
const std::string& filename,
int line,
int column,
304 const std::string& message)
override;
307 std::shared_ptr<DLogMultiFileErrorCollector> error_collector_;
309 std::vector<void*> dl_handles_;