From 4529cb782d6962d3a1e38d761cfa24a3c1bac8dd Mon Sep 17 00:00:00 2001
From: galtsev <galtsev@yandex-team.com>
Date: Wed, 19 Apr 2023 23:02:45 +0300
Subject: YT-18920: Parse unknown enum values

---
 library/cpp/yt/string/enum-inl.h | 26 +++++++++++++++++++++++++-
 1 file changed, 25 insertions(+), 1 deletion(-)

(limited to 'library/cpp/yt/string/enum-inl.h')

diff --git a/library/cpp/yt/string/enum-inl.h b/library/cpp/yt/string/enum-inl.h
index 7e6785efb4..2fa138f52f 100644
--- a/library/cpp/yt/string/enum-inl.h
+++ b/library/cpp/yt/string/enum-inl.h
@@ -4,6 +4,8 @@
 #include "enum.h"
 #endif
 
+#include <library/cpp/yt/exception/exception.h>
+
 #include <util/string/printf.h>
 
 namespace NYT {
@@ -28,7 +30,29 @@ template <class T>
 std::optional<T> TryParseEnum(TStringBuf value)
 {
     auto tryFromString = [] (TStringBuf value) -> std::optional<T> {
-        return TEnumTraits<T>::FindValueByLiteral(DecodeEnumValue(value));
+        try {
+            return TEnumTraits<T>::FindValueByLiteral(DecodeEnumValue(value));
+        } catch (const TSimpleException&) {
+            TStringBuf typeName;
+            auto isTypeNameCorrect = value.NextTok('(', typeName) && typeName == TEnumTraits<T>::GetTypeName();
+            if (!isTypeNameCorrect) {
+                throw;
+            }
+
+            TStringBuf enumValue;
+            std::underlying_type_t<T> underlyingValue;
+            auto isEnumValueCorrect = value.NextTok(')', enumValue) && TryFromString(enumValue, underlyingValue);
+            if (!isEnumValueCorrect) {
+                throw;
+            }
+
+            auto isParsingComplete = value.empty();
+            if (!isParsingComplete) {
+                throw;
+            }
+
+            return static_cast<T>(underlyingValue);
+        }
     };
 
     if constexpr (TEnumTraits<T>::IsBitEnum) {
-- 
cgit v1.2.3