23#include "dynamic_conditions.h"
27#include "thirdparty/sol/sol.hpp"
29LUALIB_API
int luaopen_pb(lua_State* L);
30#define SOL_ALL_SAFETIES_ON 1
31#define SOL_PRINT_ERRORS 1
34void 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);
44dccl::DynamicConditions::DynamicConditions() =
default;
46dccl::DynamicConditions::~DynamicConditions()
52 lua_->script(
"pb.clear()");
58void dccl::DynamicConditions::regenerate(
const google::protobuf::Message* this_msg,
59 const google::protobuf::Message* root_msg,
int index)
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 auto [desc_load_success, desc_load_value] =
85 std::tuple<bool, int>(desc_load(file_desc_set.SerializeAsString()));
86 assert(desc_load_success);
87 const auto& decode_script = R
"(
88 local this_encoded_msg, this_type, root_encoded_msg, root_type, cpp_index = ...;
89 pb.option('use_default_metatable');
90 root = pb.decode(root_type, root_encoded_msg);
91 this = pb.decode(this_type, this_encoded_msg); this_index = cpp_index+1;
95 sol::load_result decode_message = lua_->load(decode_script);
96 if (!decode_message.valid())
98 sol::error err = decode_message;
99 throw(Exception(std::string(
"Failed to load condition script into the Lua program: ") +
101 this_msg_->GetDescriptor()));
107 this_msg_->SerializePartialAsString(), this_msg_->GetDescriptor()->full_name(),
108 root_msg_->SerializePartialAsString(), root_msg_->GetDescriptor()->full_name(), index);
116 return field_desc_->options().GetExtension(dccl::field).dynamic_conditions();
118 throw(Exception(
"Null field_desc"));
121bool dccl::DynamicConditions::has_max_bytes()
124 msg_desc_->options().GetExtension(dccl::msg).has_dynamic_conditions() &&
125 msg_desc_->options().GetExtension(dccl::msg).dynamic_conditions().has_max_bytes();
128bool dccl::DynamicConditions::required()
131 if (is_initialized())
133 if (conditions().has_required_if())
135 auto condition_script = return_prefix(conditions().required_if());
136 bool required = lua_->script(condition_script);
139 else if (conditions().has_only_if())
141 auto condition_script = return_prefix(conditions().only_if());
142 bool only = lua_->script(condition_script);
156 throw(Exception(
"DCCL built without Lua support: cannot use dynamic_conditions"));
160bool dccl::DynamicConditions::omit()
163 if (is_initialized())
165 if (conditions().has_omit_if())
167 auto condition_script = return_prefix(conditions().omit_if());
168 bool omit = lua_->script(condition_script);
171 else if (conditions().has_only_if())
173 auto condition_script = return_prefix(conditions().only_if());
174 bool only = lua_->script(condition_script);
187 throw(Exception(
"DCCL built without Lua support: cannot use dynamic_conditions"));
191double dccl::DynamicConditions::min()
194 if (is_initialized())
196 auto condition_script = return_prefix(conditions().min());
197 double v = lua_->script(condition_script);
202 return -std::numeric_limits<double>::infinity();
205 throw(Exception(
"DCCL built without Lua support: cannot use dynamic_conditions"));
209double dccl::DynamicConditions::max()
212 if (is_initialized())
214 auto condition_script = return_prefix(conditions().max());
215 double v = lua_->script(condition_script);
220 return std::numeric_limits<double>::infinity();
223 throw(Exception(
"DCCL built without Lua support: cannot use dynamic_conditions"));
227uint32_t dccl::DynamicConditions::max_bytes()
230 if (is_message_initialized())
232 auto condition_script = return_prefix(
233 msg_desc_->options().GetExtension(dccl::msg).dynamic_conditions().max_bytes());
234 double v = lua_->script(condition_script);
235 return static_cast<uint32_t
>(v);
239 return std::numeric_limits<uint32_t>::max();
242 throw(Exception(
"DCCL built without Lua support: cannot use dynamic_conditions"));