8 namespace gp = google::protobuf;
12 const gp::FileDescriptorSet &descriptor_set,
15 , _proto_pool(&_proto_database)
18 gp::FileDescriptorProto unused;
20 for (
int i = 0; i < descriptor_set.file_size(); ++i)
22 const auto&
file = descriptor_set.file(i);
23 if (!_proto_database.FindFileByName(
file.name(), &unused))
25 if (!_proto_database.Add(file))
27 throw std::runtime_error(
28 fmt::format(
"failed to add definition {} to protoDB",
34 _msg_descriptor = _proto_pool.FindMessageTypeByName(type_name);
36 if (_msg_descriptor ==
nullptr)
38 throw std::runtime_error(
"Cannot get message descriptor");
45 const google::protobuf::Message* prototype_msg =
46 _msg_factory.GetPrototype(_msg_descriptor);
48 google::protobuf::Message* mutable_msg = prototype_msg->New();
49 if (!mutable_msg->ParseFromArray(serialized_msg.
data(),
50 serialized_msg.
size()))
55 std::function<void(const google::protobuf::Message&, const std::string&, const bool)> ParseImpl;
57 ParseImpl = [&](
const google::protobuf::Message&
msg,
const std::string& prefix,
const bool is_map)
59 const gp::Reflection* reflection = msg.GetReflection();
60 const gp::Descriptor* descriptor = msg.GetDescriptor();
68 std::string key = prefix.empty() ?
75 if (
field->name() ==
"key") {
90 bool repeated =
false;
91 if (
field->is_repeated())
93 count = reflection->FieldSize(msg,
field);
97 if( repeated && count > maxArraySize() )
101 count = std::max(count, maxArraySize());
115 bool is_double =
true;
117 switch(
field->cpp_type())
119 case gp::FieldDescriptor::CPPTYPE_DOUBLE:{
120 value = !repeated ? reflection->GetDouble(msg,
field) :
121 reflection->GetRepeatedDouble(msg,
field,
index);
123 case gp::FieldDescriptor::CPPTYPE_FLOAT:{
124 auto tmp = !repeated ? reflection->GetFloat(msg,
field) :
125 reflection->GetRepeatedFloat(msg,
field,
index);
126 value =
static_cast<double>(tmp);
128 case gp::FieldDescriptor::CPPTYPE_UINT32:{
129 auto tmp = !repeated ? reflection->GetUInt32(msg,
field) :
130 reflection->GetRepeatedUInt32(msg,
field,
index);
131 value =
static_cast<double>(tmp);
133 case gp::FieldDescriptor::CPPTYPE_UINT64:{
134 auto tmp = !repeated ? reflection->GetUInt64(msg,
field) :
135 reflection->GetRepeatedUInt64(msg,
field,
index);
136 value =
static_cast<double>(tmp);
138 case gp::FieldDescriptor::CPPTYPE_BOOL:{
139 auto tmp = !repeated ? reflection->GetBool(msg,
field) :
140 reflection->GetRepeatedBool(msg,
field,
index);
141 value =
static_cast<double>(tmp);
143 case gp::FieldDescriptor::CPPTYPE_INT32:{
144 auto tmp = !repeated ? reflection->GetInt32(msg,
field) :
145 reflection->GetRepeatedInt32(msg,
field,
index);
146 value =
static_cast<double>(tmp);
148 case gp::FieldDescriptor::CPPTYPE_INT64:{
149 auto tmp = !repeated ? reflection->GetInt64(msg,
field) :
150 reflection->GetRepeatedInt64(msg,
field,
index);
151 value =
static_cast<double>(tmp);
153 case gp::FieldDescriptor::CPPTYPE_ENUM:{
154 auto tmp = !repeated ? reflection->GetEnum(msg,
field) :
155 reflection->GetRepeatedEnum(msg,
field,
index);
157 auto& series = this->getStringSeries(key + suffix);
158 series.pushBack({timestamp, tmp->name()});
161 case gp::FieldDescriptor::CPPTYPE_STRING:{
162 auto tmp = !repeated ? reflection->GetString(msg,
field) :
163 reflection->GetRepeatedString(msg,
field,
index);
165 if( tmp.size() > 100 )
170 auto& series = this->getStringSeries(key + suffix);
171 series.pushBack({timestamp, tmp});
174 case gp::FieldDescriptor::CPPTYPE_MESSAGE:
177 #pragma push_macro("GetMessage") 179 const auto& new_msg = repeated ?
180 reflection->GetRepeatedMessage(msg,
field,
index) :
181 reflection->GetMessage(msg,
field);
182 #pragma pop_macro("GetMessage") 183 if (
field->is_map()) {
186 const auto* map_descriptor = new_msg.GetDescriptor();
187 const auto* map_reflection = new_msg.GetReflection();
188 const auto* key_field = map_descriptor->FindFieldByName(
"key");
189 switch(key_field->cpp_type())
192 case gp::FieldDescriptor::CPPTYPE_STRING:{
194 "/{}", map_reflection->GetString(new_msg, key_field));
196 case gp::FieldDescriptor::CPPTYPE_INT32:{
198 "/{}", map_reflection->GetInt32(new_msg, key_field));
200 case gp::FieldDescriptor::CPPTYPE_INT64:{
202 "/{}", map_reflection->GetInt64(new_msg, key_field));
204 case gp::FieldDescriptor::CPPTYPE_UINT32:{
206 "/{}", map_reflection->GetUInt32(new_msg, key_field));
208 case gp::FieldDescriptor::CPPTYPE_UINT64:{
210 "/{}", map_reflection->GetUInt64(new_msg, key_field));
214 ParseImpl(new_msg, key + suffix,
field->is_map());
222 auto& series = this->getSeries(key + suffix);
223 series.pushBack({timestamp, value});
230 ParseImpl(*mutable_msg, _topic_name,
false);
ProtobufParser(const std::string &topic_name, const google::protobuf::Descriptor *descriptor, PlotDataMapRef &data)
constexpr auto count() -> size_t
std::string type_name(lua_State *L, type t)
static void field(LexState *ls, ConsControl *cc)
bool parseMessage(const MessageRef serialized_msg, double ×tamp) override
const uint8_t * data() const
The MessageParser is the base class used to parse a message with a specific encoding+schema.
std::basic_string< Char > format(const text_style &ts, const S &format_str, const Args &... args)