1#include <userver/proto-structs/io/context.hpp>
4#include <google/protobuf/descriptor.h>
6#include <userver/utils/impl/internal_tag.hpp>
10namespace proto_structs::io {
12std::string Context::GetCurrentPath(
int current_field_number)
const {
13 const ::google::protobuf::Descriptor* last_message_desc =
nullptr;
14 auto result = GetCurrentPathImpl(last_message_desc);
16 if (last_message_desc) {
17 auto field_desc = last_message_desc->FindFieldByNumber(current_field_number);
20 result.append(fmt::format(
".{}", field_desc->name()));
22 result.append(fmt::format(
".<unknown_{}>", current_field_number));
29std::string Context::GetCurrentPath(
const ::google::protobuf::FieldDescriptor& current_field_desc)
const {
30 const ::google::protobuf::Descriptor* last_message_desc =
nullptr;
31 auto result = GetCurrentPathImpl(last_message_desc);
33 if (last_message_desc) {
34 if (current_field_desc.containing_type() == last_message_desc) {
35 result.append(fmt::format(
".{}", current_field_desc.name()));
37 result.append(fmt::format(
".<unknown_{}>", current_field_desc.number()));
44std::string Context::GetCurrentPath()
const {
45 const ::google::protobuf::Descriptor* last_message_desc =
nullptr;
46 return GetCurrentPathImpl(last_message_desc);
49std::string Context::GetCurrentPathImpl(
const ::google::protobuf::Descriptor*& last_message_desc)
const {
50 auto current_ptr = &top_message_desc_;
54 result = current_ptr->full_name();
56 for (
const auto& field_number : path_) {
57 auto field_desc = current_ptr->FindFieldByNumber(field_number);
59 if (field_desc && field_desc->type() == ::google::protobuf::FieldDescriptor::TYPE_MESSAGE) {
60 result.append(fmt::format(
".{}", field_desc->name()));
61 current_ptr = field_desc->message_type();
63 result.append(fmt::format(
".<unknown_{}>", field_number));
64 current_ptr =
nullptr;
69 last_message_desc = current_ptr;
73template <
typename TError>
74const std::vector<TError>& ContextWithErrors<TError>::GetErrors(utils::impl::InternalTag)
const&
noexcept {
78template <
typename TError>
79std::vector<TError>&& ContextWithErrors<TError>::GetErrors(utils::impl::InternalTag) &&
noexcept {
80 return std::move(errors_);
83template <
typename TError>
84void ContextWithErrors<TError>::AddError(
int field_number, std::string_view reason) {
85 AddError(GetCurrentPath(field_number), reason);
88template <
typename TError>
89void ContextWithErrors<
90 TError>::AddError(
const ::google::protobuf::FieldDescriptor& field_desc, std::string_view reason) {
91 AddError(GetCurrentPath(field_desc), reason);
94template <
typename TError>
95void ContextWithErrors<TError>::AddError(std::string_view reason) {
96 AddError(GetCurrentPath(), reason);
99template <
typename TError>
100void ContextWithErrors<TError>::AddError(std::string_view path, std::string_view reason) {
101 errors_.emplace_back(path, reason);
102 throw Error{errors_.back()};
105template class ContextWithErrors<ReadError>;
106template class ContextWithErrors<WriteError>;