25 #include "field_codec_default_message.h"
32 void dccl::v3::DefaultMessageCodec::any_encode(Bitset* bits,
const dccl::any& wire_value)
34 if (is_empty(wire_value))
36 *bits = Bitset(min_size());
40 *bits = traverse_const_message<Encoder, Bitset>(wire_value);
43 bits->push_front(
true);
47 unsigned dccl::v3::DefaultMessageCodec::any_size(
const dccl::any& wire_value)
49 if (is_empty(wire_value))
55 unsigned size = traverse_const_message<Size, unsigned>(wire_value);
58 const unsigned presence_bit = 1;
66 void dccl::v3::DefaultMessageCodec::any_decode(Bitset* bits, dccl::any* wire_value)
70 auto* msg = dccl::any_cast<google::protobuf::Message*>(*wire_value);
74 if (!bits->to_ulong())
76 *wire_value = dccl::any();
85 const google::protobuf::Descriptor* desc = msg->GetDescriptor();
86 const google::protobuf::Reflection* refl = msg->GetReflection();
88 for (
int i = 0, n = desc->field_count(); i < n; ++i)
90 const google::protobuf::FieldDescriptor* field_desc = desc->field(i);
92 if (!check_field(field_desc))
95 std::shared_ptr<FieldCodecBase> codec = find(field_desc);
96 std::shared_ptr<internal::FromProtoCppTypeBase> helper =
97 manager().type_helper().find(field_desc);
99 if (field_desc->is_repeated())
101 std::vector<dccl::any> field_values;
102 if (field_desc->cpp_type() == google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE)
104 unsigned max_repeat =
105 field_desc->options().GetExtension(dccl::field).max_repeat();
106 for (
unsigned j = 0, m = max_repeat; j < m; ++j)
107 field_values.emplace_back(refl->AddMessage(msg, field_desc));
109 codec->field_decode_repeated(bits, &field_values, field_desc);
112 for (
int j = field_values.size(), m = max_repeat; j < m; ++j)
114 refl->RemoveLast(msg, field_desc);
120 codec->field_decode_repeated(bits, &field_values, field_desc);
121 for (
auto& field_value : field_values)
122 helper->add_value(field_desc, msg, field_value);
128 DynamicConditions& dc = dynamic_conditions(field_desc);
129 if (dc.has_omit_if())
132 dc.regenerate(this_message(), root_message());
137 dccl::any field_value;
138 if (field_desc->cpp_type() == google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE)
141 field_value = refl->MutableMessage(msg, field_desc);
142 codec->field_decode(bits, &field_value, field_desc);
143 if (is_empty(field_value))
144 refl->ClearField(msg, field_desc);
149 codec->field_decode(bits, &field_value, field_desc);
150 helper->set_value(field_desc, msg, field_value);
155 std::vector<const google::protobuf::FieldDescriptor*> set_fields;
156 refl->ListFields(*msg, &set_fields);
159 catch (dccl::bad_any_cast& e)
162 "Bad type given to traverse mutable, expecting google::protobuf::Message*, got " +
163 std::string(wire_value->type().name())));
167 unsigned dccl::v3::DefaultMessageCodec::max_size()
170 traverse_descriptor<MaxSize>(&u);
174 const unsigned presence_bit = 1;
181 unsigned dccl::v3::DefaultMessageCodec::min_size()
185 const unsigned presence_bit = 1;
191 traverse_descriptor<MinSize>(&u);
196 void dccl::v3::DefaultMessageCodec::validate()
202 if (desc->oneof_decl_count() != 0)
203 throw(Exception(
"DCCL Codec Version 3 does not support 'oneof' declarations"), desc);
205 traverse_descriptor<Validate>(&b);
208 std::string dccl::v3::DefaultMessageCodec::info()
210 std::stringstream ss;
211 traverse_descriptor<Info>(&ss);
215 std::size_t dccl::v3::DefaultMessageCodec::hash()
217 std::size_t hash = 0;
218 traverse_descriptor<Hash>(&hash);
222 bool dccl::v3::DefaultMessageCodec::check_field(
const google::protobuf::FieldDescriptor* field)
231 if (dccl_field_options.omit())
235 else if (message_data().current_part() == UNKNOWN)
237 if ((part() == HEAD && !dccl_field_options.in_head()) ||
238 (part() == BODY && dccl_field_options.in_head()))
243 else if (message_data().current_part() != part())