24 #include "field_codec_message_stack.h"
25 #include "../field_codec.h"
30 void dccl::internal::MessageStack::push(
const google::protobuf::Descriptor* desc)
33 data_.desc.push_back(desc);
34 ++descriptors_pushed_;
37 void dccl::internal::MessageStack::push(
const google::protobuf::FieldDescriptor* field)
39 data_.field.push_back(field);
43 void dccl::internal::MessageStack::push(MessagePart part)
45 data_.parts.push_back(part);
49 void dccl::internal::MessageStack::__pop_desc()
51 if (!data_.desc.empty())
52 data_.desc.pop_back();
53 --descriptors_pushed_;
56 void dccl::internal::MessageStack::__pop_field()
58 if (!data_.field.empty())
59 data_.field.pop_back();
63 void dccl::internal::MessageStack::__pop_parts()
65 if (!data_.parts.empty())
66 data_.parts.pop_back();
70 void dccl::internal::MessageStack::__pop_messages()
72 if (!data_.messages.empty())
73 data_.messages.pop_back();
78 MessageStackData& data,
79 const google::protobuf::FieldDescriptor* field)
80 : data_(data), descriptors_pushed_(0), fields_pushed_(0), parts_pushed_(0), messages_pushed_(0)
84 if (field->cpp_type() == google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE)
86 MessagePart
part = UNKNOWN;
87 if (field->options().GetExtension(dccl::field).has_in_head())
90 part = field->options().GetExtension(dccl::field).in_head() ? HEAD : BODY;
95 part = current_part();
98 push(field->message_type());
100 push_message(root_message, field);
106 const google::protobuf::FieldDescriptor* field,
109 push_message(root_message, field, index);
113 const google::protobuf::FieldDescriptor* field,
116 if (data_.messages.empty() && root_message)
118 data_.messages.push_back({root_message,
nullptr});
122 if (field->cpp_type() == google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE)
125 if (!data_.messages.empty() && field == data_.messages.back().field &&
126 !data_.messages.empty())
128 data_.messages.pop_back();
133 if (data_.messages.size() &&
134 data_.messages.back().msg->GetDescriptor() == field->containing_type())
136 const auto* refl = data_.messages.back().msg->GetReflection();
137 if (field->is_repeated())
139 if (index >= 0 && index < refl->FieldSize(*data_.messages.back().msg, field))
141 data_.messages.push_back(
142 {&refl->GetRepeatedMessage(*data_.messages.back().msg, field, index),
149 data_.messages.push_back(
150 {&refl->GetMessage(*data_.messages.back().msg, field), field});
157 dccl::internal::MessageStack::~MessageStack()
159 while (fields_pushed_ > 0) __pop_field();
160 while (descriptors_pushed_ > 0) __pop_desc();
161 while (parts_pushed_ > 0) __pop_parts();
162 while (messages_pushed_ > 0) __pop_messages();