23 #include "dynamic_conditions.h"
24 #include "exception.h"
27 #include "thirdparty/sol/sol.hpp"
29 LUALIB_API
int luaopen_pb(lua_State* L);
30 #define SOL_ALL_SAFETIES_ON 1
31 #define SOL_PRINT_ERRORS 1
34 void build_file_desc_set(
const google::protobuf::FileDescriptor* file_desc,
35 google::protobuf::FileDescriptorSet& file_desc_set)
37 for (
int i = 0, n = file_desc->dependency_count(); i < n; ++i)
38 build_file_desc_set(file_desc->dependency(i), file_desc_set);
40 google::protobuf::FileDescriptorProto* file_desc_proto = file_desc_set.add_file();
41 file_desc->CopyTo(file_desc_proto);
44 dccl::DynamicConditions::DynamicConditions() =
default;
46 dccl::DynamicConditions::~DynamicConditions()
52 lua_->script(
"pb.clear()");
62 set_repeated_index(index);
67 this_msg_ = root_msg_;
70 if (this_msg_ && root_msg_)
74 lua_ =
new sol::state;
75 lua_->open_libraries();
76 lua_->require(
"pb", luaopen_pb);
79 sol::load_result desc_load = lua_->load(R
"(local desc = ...; return pb.load(desc) )");
81 google::protobuf::FileDescriptorSet file_desc_set;
82 build_file_desc_set(root_msg_->GetDescriptor()->file(), file_desc_set);
84 std::tuple<bool, int> desc_load_result = desc_load(file_desc_set.SerializeAsString());
85 assert(std::get<0>(desc_load_result));
86 const auto& decode_script = R
"(
87 local this_encoded_msg, this_type, root_encoded_msg, root_type, cpp_index = ...;
88 pb.option('use_default_metatable');
89 root = pb.decode(root_type, root_encoded_msg);
90 this = pb.decode(this_type, this_encoded_msg); this_index = cpp_index+1;
94 sol::load_result decode_message = lua_->load(decode_script);
95 if (!decode_message.valid())
97 sol::error err = decode_message;
98 throw(Exception(std::string(
"Failed to load condition script into the Lua program: ") +
100 this_msg_->GetDescriptor()));
106 this_msg_->SerializePartialAsString(), this_msg_->GetDescriptor()->full_name(),
107 root_msg_->SerializePartialAsString(), root_msg_->GetDescriptor()->full_name(), index);
115 return field_desc_->options().GetExtension(dccl::field).dynamic_conditions();
117 throw(Exception(
"Null field_desc"));
120 bool dccl::DynamicConditions::required()
123 if (is_initialized())
125 if (conditions().has_required_if())
127 auto condition_script = return_prefix(conditions().required_if());
128 bool required = lua_->script(condition_script);
131 else if (conditions().has_only_if())
133 auto condition_script = return_prefix(conditions().only_if());
134 bool only = lua_->script(condition_script);
148 throw(Exception(
"DCCL built without Lua support: cannot use dynamic_conditions"));
152 bool dccl::DynamicConditions::omit()
155 if (is_initialized())
157 if (conditions().has_omit_if())
159 auto condition_script = return_prefix(conditions().omit_if());
160 bool omit = lua_->script(condition_script);
163 else if (conditions().has_only_if())
165 auto condition_script = return_prefix(conditions().only_if());
166 bool only = lua_->script(condition_script);
179 throw(Exception(
"DCCL built without Lua support: cannot use dynamic_conditions"));
183 double dccl::DynamicConditions::min()
186 if (is_initialized())
188 auto condition_script = return_prefix(conditions().min());
189 double v = lua_->script(condition_script);
194 return -std::numeric_limits<double>::infinity();
197 throw(Exception(
"DCCL built without Lua support: cannot use dynamic_conditions"));
201 double dccl::DynamicConditions::max()
204 if (is_initialized())
206 auto condition_script = return_prefix(conditions().max());
207 double v = lua_->script(condition_script);
212 return std::numeric_limits<double>::infinity();
215 throw(Exception(
"DCCL built without Lua support: cannot use dynamic_conditions"));