25 #include "field_codec_message_stack.h"
26 #include "../field_codec.h"
31 void dccl::internal::MessageStack::push(
const google::protobuf::Descriptor* desc)
34 data_.desc.push_back(desc);
35 ++descriptors_pushed_;
38 void dccl::internal::MessageStack::push(
const google::protobuf::FieldDescriptor* field)
40 data_.field.push_back(field);
44 void dccl::internal::MessageStack::push(MessagePart part)
46 data_.parts.push_back(part);
50 void dccl::internal::MessageStack::__pop_desc()
52 if (!data_.desc.empty())
53 data_.desc.pop_back();
54 --descriptors_pushed_;
57 void dccl::internal::MessageStack::__pop_field()
59 if (!data_.field.empty())
60 data_.field.pop_back();
64 void dccl::internal::MessageStack::__pop_parts()
66 if (!data_.parts.empty())
67 data_.parts.pop_back();
71 void dccl::internal::MessageStack::__pop_messages()
73 if (!data_.messages.empty())
74 data_.messages.pop_back();
79 MessageStackData& data,
80 const google::protobuf::FieldDescriptor* field)
81 : data_(data), descriptors_pushed_(0), fields_pushed_(0), parts_pushed_(0), messages_pushed_(0)
85 if (field->cpp_type() == google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE)
87 MessagePart
part = UNKNOWN;
88 if (field->options().GetExtension(dccl::field).has_in_head())
91 part = field->options().GetExtension(dccl::field).in_head() ? HEAD : BODY;
96 part = current_part();
99 push(field->message_type());
101 push_message(root_message, field);
107 const google::protobuf::FieldDescriptor* field,
110 push_message(root_message, field, index);
114 const google::protobuf::FieldDescriptor* field,
117 if (data_.messages.empty() && root_message)
119 data_.messages.push_back({root_message,
nullptr});
123 if (field->cpp_type() == google::protobuf::FieldDescriptor::CPPTYPE_MESSAGE)
126 if (!data_.messages.empty() && field == data_.messages.back().field &&
127 !data_.messages.empty())
129 data_.messages.pop_back();
134 if (data_.messages.size() &&
135 data_.messages.back().msg->GetDescriptor() == field->containing_type())
137 const auto* refl = data_.messages.back().msg->GetReflection();
138 if (field->is_repeated())
140 if (index >= 0 && index < refl->FieldSize(*data_.messages.back().msg, field))
142 data_.messages.push_back(
143 {&refl->GetRepeatedMessage(*data_.messages.back().msg, field, index),
150 data_.messages.push_back(
151 {&refl->GetMessage(*data_.messages.back().msg, field), field});
158 dccl::internal::MessageStack::~MessageStack()
160 while (fields_pushed_ > 0) __pop_field();
161 while (descriptors_pushed_ > 0) __pop_desc();
162 while (parts_pushed_ > 0) __pop_parts();
163 while (messages_pushed_ > 0) __pop_messages();