6#include <userver/compiler/impl/constexpr.hpp> 
    7#include <userver/logging/log_extra.hpp> 
    8#include <userver/logging/log_helper.hpp> 
    9#include <userver/utils/encoding/tskv.hpp> 
   11USERVER_NAMESPACE_BEGIN
 
   15[[noreturn]] 
void ThrowInvalidEscapedTagKey(std::string_view key);
 
   19  template <
typename StringType, 
typename Enabled = std::enable_if_t<
 
   20                                     !std::is_same_v<StringType, TagKey>>>
 
   23  std::string_view GetEscapedKey() 
const noexcept;
 
   26  std::string_view escaped_key_;
 
   29class RuntimeTagKey 
final {
 
   31  explicit RuntimeTagKey(std::string_view unescaped_key);
 
   33  std::string_view GetUnescapedKey() 
const noexcept;
 
   36  std::string_view unescaped_key_;
 
   43  void PutTag(TagKey key, 
const T& value);
 
   46  void PutTag(RuntimeTagKey key, 
const T& value);
 
   49  void PutLogExtra(
const LogExtra& extra);
 
   53  void ExtendLogExtra(
const LogExtra& extra);
 
   56  friend class logging::LogHelper;
 
   58  explicit TagWriter(LogHelper& lh) 
noexcept;
 
   60  void PutKey(TagKey key);
 
   61  void PutKey(RuntimeTagKey key);
 
   63  void MarkValueEnd() 
noexcept;
 
   68constexpr bool DoesTagNeedEscaping(std::string_view key) 
noexcept {
 
   69  for (
const char c : key) {
 
   70    const bool needs_no_escaping_in_all_formats =
 
   71        (c >= 
'a' && c <= 
'z') || (c >= 
'A' && c <= 
'Z') ||
 
   72        (c >= 
'0' && c <= 
'9') || c == 
'_' || c == 
'-' || c == 
'/';
 
   73    if (!needs_no_escaping_in_all_formats) {
 
   80template <
typename StringType, 
typename Enabled>
 
   82    : escaped_key_(escaped_key) {
 
   83  if (DoesTagNeedEscaping(escaped_key_)) {
 
   84    ThrowInvalidEscapedTagKey(escaped_key_);
 
   89void TagWriter::PutTag(TagKey key, 
const T& value) {
 
   96void TagWriter::PutTag(RuntimeTagKey key, 
const T& value) {