25 #include "field_codec_default_message.h"
32 void dccl::v2::DefaultMessageCodec::any_encode(Bitset* bits,
const dccl::any& wire_value)
34 if (is_empty(wire_value))
35 *bits = Bitset(min_size());
37 *bits = traverse_const_message<Encoder, Bitset>(wire_value);
40 unsigned dccl::v2::DefaultMessageCodec::any_size(
const dccl::any& wire_value)
42 if (is_empty(wire_value))
45 return traverse_const_message<Size, unsigned>(wire_value);
48 void dccl::v2::DefaultMessageCodec::any_decode(Bitset* bits, dccl::any* wire_value)
52 auto* msg = dccl::any_cast<google::protobuf::Message*>(*wire_value);
54 const google::protobuf::Descriptor* desc = msg->GetDescriptor();
55 const google::protobuf::Reflection* refl = msg->GetReflection();
57 for (
int i = 0, n = desc->field_count(); i < n; ++i)
59 const google::protobuf::FieldDescriptor* field_desc = desc->field(i);
61 if (!check_field(field_desc))
64 std::shared_ptr<FieldCodecBase> codec = find(field_desc);
65 std::shared_ptr<internal::FromProtoCppTypeBase> helper =
66 manager().type_helper().find(field_desc);
68 if (field_desc->is_repeated())
70 std::vector<dccl::any> wire_values;
71 if (field_desc->cpp_type() == google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE)
74 m = field_desc->options().GetExtension(dccl::field).max_repeat();
76 wire_values.emplace_back(refl->AddMessage(msg, field_desc));
78 codec->field_decode_repeated(bits, &wire_values, field_desc);
80 for (
auto& wire_value : wire_values)
82 if (is_empty(wire_value))
83 refl->RemoveLast(msg, field_desc);
89 codec->field_decode_repeated(bits, &wire_values, field_desc);
90 for (
auto& wire_value : wire_values)
91 helper->add_value(field_desc, msg, wire_value);
97 if (field_desc->cpp_type() == google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE)
100 wire_value = refl->MutableMessage(msg, field_desc);
101 codec->field_decode(bits, &wire_value, field_desc);
102 if (is_empty(wire_value))
103 refl->ClearField(msg, field_desc);
108 codec->field_decode(bits, &wire_value, field_desc);
109 helper->set_value(field_desc, msg, wire_value);
114 std::vector<const google::protobuf::FieldDescriptor*> set_fields;
115 refl->ListFields(*msg, &set_fields);
116 if (set_fields.empty() && this_field())
117 *wire_value = dccl::any();
121 catch (dccl::bad_any_cast& e)
124 "Bad type given to traverse mutable, expecting google::protobuf::Message*, got " +
125 std::string(wire_value->type().name())));
129 unsigned dccl::v2::DefaultMessageCodec::max_size()
132 traverse_descriptor<MaxSize>(&u);
136 unsigned dccl::v2::DefaultMessageCodec::min_size()
139 traverse_descriptor<MinSize>(&u);
143 void dccl::v2::DefaultMessageCodec::validate()
149 if (desc->oneof_decl_count() != 0)
150 throw(Exception(
"DCCL Codec Version 2 does not support 'oneof' declarations"), desc);
152 traverse_descriptor<Validate>(&b);
155 std::string dccl::v2::DefaultMessageCodec::info()
157 std::stringstream ss;
158 traverse_descriptor<Info>(&ss);
162 std::size_t dccl::v2::DefaultMessageCodec::hash()
164 std::size_t hash = 0;
165 traverse_descriptor<Hash>(&hash);
169 bool dccl::v2::DefaultMessageCodec::check_field(
const google::protobuf::FieldDescriptor* field)
178 if (dccl_field_options.omit())
182 else if (message_data().current_part() == UNKNOWN)
184 if (field->cpp_type() == google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE &&
185 find(field)->name() ==
186 Codec::default_codec_name())
188 else if ((part() == HEAD && !dccl_field_options.in_head()) ||
189 (part() == BODY && dccl_field_options.in_head()))
194 else if (message_data().current_part() != part())