#pragma once #include <library/cpp/unified_agent_client/f_maybe.h> #include <util/generic/deque.h> #include <util/generic/string.h> namespace NUnifiedAgent::NPW { class TLengthDelimited; class TFieldLink { public: TFieldLink(TLengthDelimited* container, bool repeated = false, size_t keySize = 1); void SetValueSize(bool empty, size_t size); private: TLengthDelimited* Container; int OuterSize; bool Repeated; size_t KeySize; }; class TLengthDelimited { public: explicit TLengthDelimited(const TFMaybe<TFieldLink>& link = Nothing()); void IncSize(int sizeDelta); size_t ByteSizeLong() const { return static_cast<size_t>(ByteSize); } private: TFMaybe<TFieldLink> Link; int ByteSize; }; using TMessage = TLengthDelimited; template <typename T> class TRepeatedField: public TLengthDelimited { public: static_assert(std::is_same_v<T, ui32> || std::is_same_v<T, ui64> || std::is_same_v<T, i64>, "type is not supported"); using TLengthDelimited::TLengthDelimited; void Add(T value); }; template <typename T> class TRepeatedPtrField { public: explicit TRepeatedPtrField(TMessage* message, size_t keySize = 1) : Message(message) , Children() , KeySize(keySize) { } size_t GetSize() const { return Children.size(); } T& Get(size_t index) { return Children[index]; } T& Add() { if constexpr (std::is_constructible<T, TFieldLink>::value) { Children.emplace_back(TFieldLink(Message, true, KeySize)); } else { Children.emplace_back(Message); } return Children.back(); } private: TMessage* Message; TDeque<T> Children; size_t KeySize; }; template <typename T> class TNumberField { public: static_assert(std::is_same_v<T, ui32> || std::is_same_v<T, ui64> || std::is_same_v<T, i64>, "type is not supported"); explicit TNumberField(const TFieldLink& link); void SetValue(T value); private: TFieldLink Link; }; template <typename T> class TFixedNumberField { public: static_assert(std::is_same_v<T, ui32> || std::is_same_v<T, ui64> || std::is_same_v<T, i64>, "type is not supported"); explicit TFixedNumberField(const TFieldLink& link); void SetValue(); private: TFieldLink Link; }; class TStringField { public: explicit TStringField(const TFieldLink& link); void SetValue(const TString& value); private: TFieldLink Link; }; extern template class TNumberField<ui64>; extern template class TNumberField<ui32>; extern template class TNumberField<i64>; extern template class TFixedNumberField<ui64>; extern template class TFixedNumberField<ui32>; extern template class TFixedNumberField<i64>; extern template class TRepeatedField<ui64>; extern template class TRepeatedField<ui32>; extern template class TRepeatedField<i64>; }