25 #ifdef MESSAGE_SUPPORT 36 namespace p = google::protobuf;
40 void MessageParser::consumeFieldMessage(p::Message* message,
const p::Reflection* reflection,
const p::FieldDescriptor* field,
bool expand_oneof,
41 bool skip_inactive_oneof, std::list<std::string>* nested_names)
43 FieldInformation
info;
44 getFieldInformation(message, field, info, nested_names,
true);
46 if (field->is_repeated())
48 for (
int i = 0; i < reflection->FieldSize(*message, field); ++i)
50 p::Message* new_message = reflection->MutableRepeatedMessage(message, field, i);
52 if (_fun_msg_event) _fun_msg_event(MessageEvent::MessageStart, info);
54 parse(new_message, expand_oneof, skip_inactive_oneof, nested_names);
56 if (_fun_msg_event) _fun_msg_event(MessageEvent::MessageEnd, info);
61 p::Message* new_message = reflection->MutableMessage(message, field);
63 if (_fun_msg_event) _fun_msg_event(MessageEvent::MessageStart, info);
65 parse(new_message, expand_oneof, skip_inactive_oneof, nested_names);
67 if (_fun_msg_event) _fun_msg_event(MessageEvent::MessageEnd, info);
71 void MessageParser::consumeFieldValue(p::Message* message,
const p::Reflection* reflection,
const p::FieldDescriptor* field,
72 std::list<std::string>* nested_names)
74 switch (field->cpp_type())
76 case p::FieldDescriptor::CPPTYPE_INT32:
78 if (field->is_repeated())
80 std::vector<std::int32_t> values;
81 for (
int i = 0; i < reflection->FieldSize(*message, field); ++i) values.push_back(reflection->GetRepeatedInt32(*message, field, i));
83 if (_fun_value_int32_array)
85 FieldInformation
info;
86 getFieldInformation(message, field, info, nested_names,
false);
87 _fun_value_int32_array(values, info);
90 PRINT_WARNING_COND(_verbose,
"MessageParser: found value '" << field->name() <<
"' [int32 array] but no callback is registered.");
94 std::int32_t value = reflection->GetInt32(*message, field);
97 FieldInformation
info;
98 getFieldInformation(message, field, info, nested_names,
false);
99 _fun_value_int32(value, info);
102 PRINT_WARNING_COND(_verbose,
"MessageParser: found value '" << field->name() <<
"' [int32] but no callback is registered.");
106 case p::FieldDescriptor::CPPTYPE_UINT32:
108 if (field->is_repeated())
110 std::vector<std::uint32_t> values;
111 for (
int i = 0; i < reflection->FieldSize(*message, field); ++i) values.push_back(reflection->GetRepeatedUInt32(*message, field, i));
113 if (_fun_value_uint32_array)
115 FieldInformation
info;
116 getFieldInformation(message, field, info, nested_names,
false);
117 _fun_value_uint32_array(values, info);
121 "MessageParser: found value '" << field->name() <<
"' [uint32 array] but no callback is registered.");
125 std::uint32_t value = reflection->GetUInt32(*message, field);
126 if (_fun_value_uint32)
128 FieldInformation
info;
129 getFieldInformation(message, field, info, nested_names,
false);
130 _fun_value_uint32(value, info);
133 PRINT_WARNING_COND(_verbose,
"MessageParser: found value '" << field->name() <<
"' [uint32] but no callback is registered.");
137 case p::FieldDescriptor::CPPTYPE_INT64:
139 if (field->is_repeated())
141 std::vector<std::int64_t> values;
142 for (
int i = 0; i < reflection->FieldSize(*message, field); ++i) values.push_back(reflection->GetRepeatedInt64(*message, field, i));
144 if (_fun_value_int64_array)
146 FieldInformation
info;
147 getFieldInformation(message, field, info, nested_names,
false);
148 _fun_value_int64_array(values, info);
151 PRINT_WARNING_COND(_verbose,
"MessageParser: found value '" << field->name() <<
"' [int64 array] but no callback is registered.");
155 std::int64_t value = reflection->GetInt64(*message, field);
156 if (_fun_value_int64)
158 FieldInformation
info;
159 getFieldInformation(message, field, info, nested_names,
false);
160 _fun_value_int64(value, info);
163 PRINT_WARNING_COND(_verbose,
"MessageParser: found value '" << field->name() <<
"' [int64] but no callback is registered.");
167 case p::FieldDescriptor::CPPTYPE_UINT64:
169 if (field->is_repeated())
171 std::vector<std::uint64_t> values;
172 for (
int i = 0; i < reflection->FieldSize(*message, field); ++i) values.push_back(reflection->GetRepeatedUInt64(*message, field, i));
174 if (_fun_value_uint64_array)
176 FieldInformation
info;
177 getFieldInformation(message, field, info, nested_names,
false);
178 _fun_value_uint64_array(values, info);
182 "MessageParser: found value '" << field->name() <<
"' [uint64 array] but no callback is registered.");
186 std::uint64_t value = reflection->GetUInt64(*message, field);
187 if (_fun_value_uint64)
189 FieldInformation
info;
190 getFieldInformation(message, field, info, nested_names,
false);
191 _fun_value_uint64(value, info);
194 PRINT_WARNING_COND(_verbose,
"MessageParser: found value '" << field->name() <<
"' [uint64] but no callback is registered.");
198 case p::FieldDescriptor::CPPTYPE_FLOAT:
200 if (field->is_repeated())
202 std::vector<float> values;
203 for (
int i = 0; i < reflection->FieldSize(*message, field); ++i) values.push_back(reflection->GetRepeatedFloat(*message, field, i));
205 if (_fun_value_float_array)
207 FieldInformation
info;
208 getFieldInformation(message, field, info, nested_names,
false);
209 _fun_value_float_array(values, info);
212 PRINT_WARNING_COND(_verbose,
"MessageParser: found value '" << field->name() <<
"' [float array] but no callback is registered.");
216 float value = reflection->GetFloat(*message, field);
217 if (_fun_value_float)
219 FieldInformation
info;
220 getFieldInformation(message, field, info, nested_names,
false);
221 _fun_value_float(value, info);
224 PRINT_WARNING_COND(_verbose,
"MessageParser: found value '" << field->name() <<
"' [float] but no callback is registered.");
228 case p::FieldDescriptor::CPPTYPE_DOUBLE:
230 if (field->is_repeated())
232 std::vector<double> values;
233 for (
int i = 0; i < reflection->FieldSize(*message, field); ++i) values.push_back(reflection->GetRepeatedDouble(*message, field, i));
235 if (_fun_value_double_array)
237 FieldInformation
info;
238 getFieldInformation(message, field, info, nested_names,
false);
239 _fun_value_double_array(values, info);
243 "MessageParser: found value '" << field->name() <<
"' [double array] but no callback is registered.");
247 double value = reflection->GetDouble(*message, field);
248 if (_fun_value_double)
250 FieldInformation
info;
251 getFieldInformation(message, field, info, nested_names,
false);
252 _fun_value_double(value, info);
255 PRINT_WARNING_COND(_verbose,
"MessageParser: found value '" << field->name() <<
"' [double] but no callback is registered.");
259 case p::FieldDescriptor::CPPTYPE_STRING:
261 if (field->is_repeated())
263 std::vector<std::string> values;
264 for (
int i = 0; i < reflection->FieldSize(*message, field); ++i) values.push_back(reflection->GetRepeatedString(*message, field, i));
266 if (_fun_value_string_array)
268 FieldInformation
info;
269 getFieldInformation(message, field, info, nested_names,
false);
270 _fun_value_string_array(values, info);
274 "MessageParser: found value '" << field->name() <<
"' [string array] but no callback is registered.");
278 std::string
text = reflection->GetString(*message, field);
279 FieldInformation
info;
280 getFieldInformation(message, field, info, nested_names,
false);
282 if (info.info_text.first && info.info_text.second)
284 if (_fun_value_string_info)
285 _fun_value_string_info(text, info);
288 "MessageParser: found value '" << field->name() <<
"' [string info] but no callback is registered.");
292 if (_fun_value_string)
293 _fun_value_string(text, info);
295 PRINT_WARNING_COND(_verbose,
"MessageParser: found value '" << field->name() <<
"' [string] but no callback is registered.");
300 case p::FieldDescriptor::CPPTYPE_BOOL:
302 if (field->is_repeated())
304 std::vector<bool> values;
305 for (
int i = 0; i < reflection->FieldSize(*message, field); ++i) values.push_back(reflection->GetRepeatedBool(*message, field, i));
307 if (_fun_value_bool_array)
309 FieldInformation
info;
310 getFieldInformation(message, field, info, nested_names,
false);
311 _fun_value_bool_array(values, info);
314 PRINT_WARNING_COND(_verbose,
"MessageParser: found value '" << field->name() <<
"' [bool array] but no callback is registered.");
318 bool flag = reflection->GetBool(*message, field);
321 FieldInformation
info;
322 getFieldInformation(message, field, info, nested_names,
false);
323 _fun_value_bool(flag, info);
326 PRINT_WARNING_COND(_verbose,
"MessageParser: found value '" << field->name() <<
"' [bool] but no callback is registered.");
330 case p::FieldDescriptor::CPPTYPE_ENUM:
332 if (field->is_repeated())
334 std::vector<std::string> values;
335 for (
int i = 0; i < reflection->FieldSize(*message, field); ++i)
337 const p::EnumValueDescriptor* enum_desc = reflection->GetRepeatedEnum(*message, field, i);
338 values.push_back(enum_desc->name());
341 if (_fun_value_enum_array)
343 FieldInformation
info;
344 getFieldInformation(message, field, info, nested_names,
false);
345 _fun_value_enum_array(values, info);
348 PRINT_WARNING_COND(_verbose,
"MessageParser: found value '" << field->name() <<
"' [enum array] but no callback is registered.");
352 const p::EnumValueDescriptor* enum_desc = reflection->GetEnum(*message, field);
354 std::string name = enum_desc->name();
357 FieldInformation
info;
358 getFieldInformation(message, field, info, nested_names,
false);
359 _fun_value_enum(name, info);
362 PRINT_WARNING_COND(_verbose,
"MessageParser: found value '" << field->name() <<
"' [enum] but no callback is registered.");
366 case p::FieldDescriptor::CPPTYPE_MESSAGE:
369 "MessageParser: CPPTYPE_MESSAGE '" << field->name() <<
"' should be handeld in a different parser method...");
374 PRINT_WARNING_COND(_verbose,
"MessageParser: Field '" << field->name() <<
"' unknown / not implemented.");
380 void MessageParser::parseField(p::Message* message,
const p::FieldDescriptor* field,
bool expand_oneof,
bool expand_first_oneof,
381 bool skip_inactive_oneof, std::list<std::string>* nested_names)
383 if (nested_names) nested_names->push_back(field->name());
385 bool expand_field =
true;
388 const p::OneofDescriptor* oneof = field->containing_oneof();
394 FieldInformation
info;
395 getFieldInformation(message, field, info, nested_names);
396 _fun_msg_event(MessageEvent::OneOf, info);
398 if (expand_oneof || expand_first_oneof)
400 if (message->GetReflection()->HasOneof(*message, oneof))
402 const p::FieldDescriptor* oneof_field = message->GetReflection()->GetOneofFieldDescriptor(*message, oneof);
404 if (skip_inactive_oneof && field != oneof_field) expand_field =
false;
408 if (skip_inactive_oneof) expand_field =
false;
412 expand_field =
false;
418 if (field->cpp_type() == p::FieldDescriptor::CPPTYPE_MESSAGE)
420 consumeFieldMessage(message, message->GetReflection(), field, expand_oneof, skip_inactive_oneof, nested_names);
424 consumeFieldValue(message, message->GetReflection(), field, nested_names);
428 if (nested_names) nested_names->pop_back();
431 void MessageParser::parse(p::Message* message,
bool expand_oneof,
bool skip_inactive_oneof, std::list<std::string>* nested_names)
434 const p::Descriptor* desc = message->GetDescriptor();
437 int num_fields = desc->field_count();
438 for (
int i = 0; i < num_fields; ++i)
440 const p::FieldDescriptor* field = desc->field(i);
441 parseField(message, field, expand_oneof, expand_oneof, skip_inactive_oneof, nested_names);
445 void MessageParser::getFieldInformation(p::Message* message,
const p::FieldDescriptor* field, FieldInformation& info,
446 std::list<std::string>* nested_names,
bool is_message)
449 info.field_name = field->name();
450 info.msg_type = message->GetTypeName();
455 if (field->is_repeated())
457 info.new_message = message->GetReflection()->FieldSize(*message, field) == 0;
461 info.new_message = !message->GetReflection()->HasField(*message, field);
465 info.new_message =
false;
468 if (nested_names) info.nested_names = *nested_names;
471 info.oneof_descriptor = field->containing_oneof();
472 if (info.oneof_descriptor)
473 info.oneof_selected_field = message->GetReflection()->GetOneofFieldDescriptor(*message, info.oneof_descriptor);
476 const p::EnumDescriptor* enum_desc = field->enum_type();
479 for (
int i = 0; i < enum_desc->value_count(); ++i)
481 info.enum_list.push_back(enum_desc->value(i)->name());
486 info.field_raw = field;
487 info.message_raw = message;
490 const p::FieldOptions& options = field->options();
493 if (options.HasExtension(messages::default_value))
494 info.default_value = std::make_pair(
true, options.GetExtension(messages::default_value));
496 info.default_value = std::make_pair(
false, 0.0);
499 if (options.HasExtension(messages::min_value))
500 info.min_value = std::make_pair(
true, options.GetExtension(messages::min_value));
502 info.min_value = std::make_pair(
false, 0.0);
505 if (options.HasExtension(messages::max_value))
506 info.max_value = std::make_pair(
true, options.GetExtension(messages::max_value));
508 info.max_value = std::make_pair(
false, 0.0);
511 if (options.HasExtension(messages::dynamic_size))
512 info.dynamic_size = options.GetExtension(messages::dynamic_size);
514 info.dynamic_size =
false;
517 if (options.HasExtension(messages::min_size))
518 info.min_size = std::make_pair(
true, options.GetExtension(messages::min_size));
520 info.min_size = std::make_pair(
false, 0);
523 if (options.HasExtension(messages::max_size))
524 info.max_size = std::make_pair(
true, options.GetExtension(messages::max_size));
530 info.info_text = std::make_pair(
true, options.GetExtension(
messages::info));
532 info.info_text = std::make_pair(
false,
false);
535 if (options.HasExtension(messages::description))
536 info.description = std::make_pair(
true, options.GetExtension(messages::description));
538 info.description = std::make_pair(
false,
"");
541 if (options.HasExtension(messages::label))
542 info.label = std::make_pair(
true, options.GetExtension(messages::label));
544 info.label = std::make_pair(
false,
"");
547 if (options.HasExtension(messages::gui_type))
548 info.gui_type = std::make_pair(
true, options.GetExtension(messages::gui_type));
550 info.gui_type = std::make_pair(
false, (messages::GuiType)0);
553 if (options.HasExtension(messages::collapsed)) info.collapsed = options.GetExtension(messages::collapsed);
556 if (options.HasExtension(messages::update_signals)) info.update_signals = options.GetExtension(messages::update_signals);
559 if (options.HasExtension(messages::print_description)) info.print_description = options.GetExtension(messages::print_description);
562 if (info.new_message)
564 const p::MessageOptions& msg_options = message->GetDescriptor()->options();
567 if (msg_options.HasExtension(messages::msg_description))
568 info.msg_description = std::make_pair(
true, msg_options.GetExtension(messages::msg_description));
570 info.msg_description = std::make_pair(
false,
"");
574 std::string MessageParser::nestedNamesToString(
const std::list<std::string>& namespaces)
577 if (namespaces.empty())
return text;
578 auto it = namespaces.begin();
580 for (it = std::next(it); it != namespaces.end(); ++it) text +=
"." + *it;
#define PRINT_WARNING_COND(cond, msg)
Print msg-stream only if cond == true.