aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorarkady-e1ppa <arkady-e1ppa@yandex-team.com>2024-12-02 20:05:42 +0300
committerarkady-e1ppa <arkady-e1ppa@yandex-team.com>2024-12-02 20:37:33 +0300
commitc6bd6398f1bec61405c83f91872481e3b5e33510 (patch)
treefafdbaeec8430e4bcfb8d53dd273e1254001a610
parente4293e758af131e7ef7ca74bfa1ef6f9b74b58cb (diff)
downloadydb-c6bd6398f1bec61405c83f91872481e3b5e33510.tar.gz
YT-23686: Better support of UnrecognizedStrategy and DefaultUnrecognizedStrategy options
commit_hash:17934f79fcde35cab012586ea54a37681007fb70
-rw-r--r--yt/yt/core/ytree/unittests/yson_struct_ut.cpp70
-rw-r--r--yt/yt/core/ytree/yson_struct-inl.h5
-rw-r--r--yt/yt/core/ytree/yson_struct.h2
-rw-r--r--yt/yt/core/ytree/yson_struct_detail-inl.h71
-rw-r--r--yt/yt/core/ytree/yson_struct_detail.h8
5 files changed, 134 insertions, 22 deletions
diff --git a/yt/yt/core/ytree/unittests/yson_struct_ut.cpp b/yt/yt/core/ytree/unittests/yson_struct_ut.cpp
index 615fef5a32..614810de56 100644
--- a/yt/yt/core/ytree/unittests/yson_struct_ut.cpp
+++ b/yt/yt/core/ytree/unittests/yson_struct_ut.cpp
@@ -3645,5 +3645,75 @@ TEST(TYsonStructTest, OverrideWithComparisonFromTemplatedFunction)
////////////////////////////////////////////////////////////////////////////////
+struct THasFieldWithDefaultedStrategy
+ : public TYsonStructLite
+{
+ TIntrusivePtr<TConfigWithOneLevelNesting> Field;
+
+ REGISTER_YSON_STRUCT_LITE(THasFieldWithDefaultedStrategy);
+
+ static void Register(TRegistrar registrar)
+ {
+ registrar.Parameter("field", &TThis::Field)
+ .Default()
+ .DefaultUnrecognizedStrategy(EUnrecognizedStrategy::Throw);
+ }
+};
+
+struct THasFieldWithDefaultedStrategyAndOwnRecursiveStrategy
+ : public TYsonStructLite
+{
+ TIntrusivePtr<TConfigWithOneLevelNesting> Field;
+
+ REGISTER_YSON_STRUCT_LITE(THasFieldWithDefaultedStrategyAndOwnRecursiveStrategy);
+
+ static void Register(TRegistrar registrar)
+ {
+ registrar.UnrecognizedStrategy(EUnrecognizedStrategy::KeepRecursive);
+
+ registrar.Parameter("field", &TThis::Field)
+ .Default()
+ .DefaultUnrecognizedStrategy(EUnrecognizedStrategy::Throw)
+ .EnforceDefaultUnrecognizedStrategy();
+ }
+};
+
+TEST(TYsonStructTest, DefaultUnrecognizedStrategy1)
+{
+ auto source = BuildYsonNodeFluently().BeginMap()
+ .Item("field").BeginMap()
+ .Item("unrecognized").Value(42)
+ .EndMap()
+ .EndMap();
+
+ THasFieldWithDefaultedStrategy yson = {};
+ EXPECT_ANY_THROW(Deserialize(yson, source->AsMap()));
+}
+
+TEST(TYsonStructTest, DefaultUnrecognizedStrategy2)
+{
+ auto source = BuildYsonNodeFluently().BeginMap()
+ .Item("field").BeginMap()
+ .Item("sub").BeginMap()
+ .EndMap()
+ .EndMap()
+ .EndMap();
+
+ THasFieldWithDefaultedStrategy yson = {};
+ Deserialize(yson, source->AsMap());
+}
+
+TEST(TYsonStructTest, DefaultUnrecognizedStrategy3)
+{
+ auto source = BuildYsonNodeFluently().BeginMap()
+ .Item("field").BeginMap()
+ .Item("unrecognized").Value(42)
+ .EndMap()
+ .EndMap();
+
+ THasFieldWithDefaultedStrategyAndOwnRecursiveStrategy yson = {};
+ EXPECT_ANY_THROW(Deserialize(yson, source->AsMap()));
+}
+
} // namespace
} // namespace NYT::NYTree
diff --git a/yt/yt/core/ytree/yson_struct-inl.h b/yt/yt/core/ytree/yson_struct-inl.h
index 6e9bdb2d96..34103976da 100644
--- a/yt/yt/core/ytree/yson_struct-inl.h
+++ b/yt/yt/core/ytree/yson_struct-inl.h
@@ -288,11 +288,14 @@ void Serialize(const T& value, NYson::IYsonConsumer* consumer)
}
template <CExternallySerializable T, CYsonStructSource TSource>
-void Deserialize(T& value, TSource source, bool postprocess, bool setDefaults)
+void Deserialize(T& value, TSource source, bool postprocess, bool setDefaults, std::optional<EUnrecognizedStrategy> strategy)
{
using TTraits = TGetExternalizedYsonStructTraits<T>;
using TSerializer = typename TTraits::TExternalSerializer;
auto serializer = TSerializer::template CreateWritable<T, TSerializer>(value, setDefaults);
+ if (strategy) {
+ serializer.SetUnrecognizedStrategy(*strategy);
+ }
serializer.Load(std::move(source), postprocess, setDefaults);
}
diff --git a/yt/yt/core/ytree/yson_struct.h b/yt/yt/core/ytree/yson_struct.h
index 4fd373e49c..24eb811a88 100644
--- a/yt/yt/core/ytree/yson_struct.h
+++ b/yt/yt/core/ytree/yson_struct.h
@@ -393,7 +393,7 @@ void Deserialize(TYsonStructBase& value, NYson::TYsonPullParserCursor* cursor);
template <CExternallySerializable T>
void Serialize(const T& value, NYson::IYsonConsumer* consumer);
template <CExternallySerializable T, CYsonStructSource TSource>
-void Deserialize(T& value, TSource source, bool postprocess = true, bool setDefaults = true);
+void Deserialize(T& value, TSource source, bool postprocess = true, bool setDefaults = true, std::optional<EUnrecognizedStrategy> strategy = {});
template <class T>
TIntrusivePtr<T> UpdateYsonStruct(
diff --git a/yt/yt/core/ytree/yson_struct_detail-inl.h b/yt/yt/core/ytree/yson_struct_detail-inl.h
index bc7dbdb130..3a4cdea34f 100644
--- a/yt/yt/core/ytree/yson_struct_detail-inl.h
+++ b/yt/yt/core/ytree/yson_struct_detail-inl.h
@@ -189,7 +189,7 @@ void LoadFromSource(
std::optional<T>& parameter,
TSource source,
const NYPath::TYPath& path,
- std::optional<EUnrecognizedStrategy> recursiveUnrecognizedStrategy);
+ std::optional<EUnrecognizedStrategy> unrecognizedStrategy);
// std::vector
template <CYsonStructSource TSource, CStdVector TVector>
@@ -197,7 +197,7 @@ void LoadFromSource(
TVector& parameter,
TSource source,
const NYPath::TYPath& path,
- std::optional<EUnrecognizedStrategy> recursiveUnrecognizedStrategy);
+ std::optional<EUnrecognizedStrategy> unrecognizedStrategy);
// any map.
template <CYsonStructSource TSource, CAnyMap TMap>
@@ -205,7 +205,7 @@ void LoadFromSource(
TMap& parameter,
TSource source,
const NYPath::TYPath& path,
- std::optional<EUnrecognizedStrategy> recursiveUnrecognizedStrategy);
+ std::optional<EUnrecognizedStrategy> unrecognizedStrategy);
////////////////////////////////////////////////////////////////////////////////
@@ -274,14 +274,14 @@ void LoadFromSource(
TIntrusivePtr<T>& parameter,
TSource source,
const NYPath::TYPath& path,
- std::optional<EUnrecognizedStrategy> recursiveUnrecognizedStrategy)
+ std::optional<EUnrecognizedStrategy> unrecognizedStrategy)
{
if (!parameter) {
parameter = New<T>();
}
- if (recursiveUnrecognizedStrategy) {
- parameter->SetUnrecognizedStrategy(*recursiveUnrecognizedStrategy);
+ if (unrecognizedStrategy) {
+ parameter->SetUnrecognizedStrategy(*unrecognizedStrategy);
}
parameter->Load(std::move(source), /*postprocess*/ false, /*setDefaults*/ false, path);
@@ -293,9 +293,12 @@ void LoadFromSource(
T& parameter,
TSource source,
const NYPath::TYPath& path,
- std::optional<EUnrecognizedStrategy> /*ignored*/)
+ std::optional<EUnrecognizedStrategy> unrecognizedStrategy)
{
try {
+ if (unrecognizedStrategy) {
+ parameter.SetUnrecognizedStrategy(*unrecognizedStrategy);
+ }
parameter.Load(std::move(source), /*postprocess*/ false, /*setDefaults*/ false, path);
} catch (const std::exception& ex) {
THROW_ERROR_EXCEPTION("Error reading parameter %v", path)
@@ -309,10 +312,10 @@ void LoadFromSource(
T& parameter,
TSource source,
const NYPath::TYPath& path,
- std::optional<EUnrecognizedStrategy> /*ignored*/)
+ std::optional<EUnrecognizedStrategy> unrecognizedStrategy)
{
try {
- Deserialize(parameter, std::move(source), /*postprocess*/ false, /*setDefaults*/ false);
+ Deserialize(parameter, std::move(source), /*postprocess*/ false, /*setDefaults*/ false, unrecognizedStrategy);
} catch (const std::exception& ex) {
THROW_ERROR_EXCEPTION("Error reading parameter %v", path)
<< ex;
@@ -328,7 +331,7 @@ void LoadFromSource(
TExtension& parameter,
TSource source,
const NYPath::TYPath& path,
- std::optional<EUnrecognizedStrategy> recursiveUnrecognizedStrategy)
+ std::optional<EUnrecognizedStrategy> unrecognizedStrategy)
{
static_assert(CYsonStructFieldFor<TExtension, TSource>, "You must add alias TImplementsYsonStructField");
@@ -338,7 +341,7 @@ void LoadFromSource(
/*postprocess*/ false,
/*setDefaults*/ false,
path,
- recursiveUnrecognizedStrategy);
+ unrecognizedStrategy);
} catch (const std::exception& ex) {
THROW_ERROR_EXCEPTION("Error loading parameter %v", path)
<< ex;
@@ -351,7 +354,7 @@ void LoadFromSource(
std::optional<T>& parameter,
TSource source,
const NYPath::TYPath& path,
- std::optional<EUnrecognizedStrategy> recursiveUnrecognizedStrategy)
+ std::optional<EUnrecognizedStrategy> unrecognizedStrategy)
{
using TTraits = TYsonSourceTraits<TSource>;
@@ -363,12 +366,12 @@ void LoadFromSource(
}
if (parameter.has_value()) {
- LoadFromSource(*parameter, std::move(source), path, recursiveUnrecognizedStrategy);
+ LoadFromSource(*parameter, std::move(source), path, unrecognizedStrategy);
return;
}
T value;
- LoadFromSource(value, std::move(source), path, recursiveUnrecognizedStrategy);
+ LoadFromSource(value, std::move(source), path, unrecognizedStrategy);
parameter = std::move(value);
} catch (const std::exception& ex) {
@@ -383,7 +386,7 @@ void LoadFromSource(
TVector& parameter,
TSource source,
const NYPath::TYPath& path,
- std::optional<EUnrecognizedStrategy> recursiveUnrecognizedStrategy)
+ std::optional<EUnrecognizedStrategy> unrecognizedStrategy)
{
using TTraits = TYsonSourceTraits<TSource>;
@@ -396,7 +399,7 @@ void LoadFromSource(
vector.emplace_back(),
elementSource,
path + "/" + NYPath::ToYPathLiteral(index),
- recursiveUnrecognizedStrategy);
+ unrecognizedStrategy);
++index;
});
} catch (const std::exception& ex) {
@@ -411,7 +414,7 @@ void LoadFromSource(
TMap& parameter,
TSource source,
const NYPath::TYPath& path,
- std::optional<EUnrecognizedStrategy> recursiveUnrecognizedStrategy)
+ std::optional<EUnrecognizedStrategy> unrecognizedStrategy)
{
using TTraits = TYsonSourceTraits<TSource>;
// TODO(arkady-e1ppa): Remove "typename" when clang-14 is abolished.
@@ -425,7 +428,7 @@ void LoadFromSource(
value,
childSource,
path + "/" + NYPath::ToYPathLiteral(key),
- recursiveUnrecognizedStrategy);
+ unrecognizedStrategy);
map[DeserializeMapKey<TKey>(key)] = std::move(value);
});
} catch (const std::exception& ex) {
@@ -751,6 +754,13 @@ void TYsonStructParameter<TValue>::Load(
const TLoadParameterOptions& options)
{
if (node) {
+ auto unrecognizedStrategy = options.RecursiveUnrecognizedRecursively;
+ if (EnforceDefaultUnrecognizedStrategy_) {
+ unrecognizedStrategy.reset();
+ }
+ if (!unrecognizedStrategy) {
+ unrecognizedStrategy = DefaultUnrecognizedStrategy_;
+ }
if (ResetOnLoad_) {
NPrivate::ResetOnLoad(FieldAccessor_->GetValue(self));
}
@@ -758,7 +768,7 @@ void TYsonStructParameter<TValue>::Load(
FieldAccessor_->GetValue(self),
std::move(node),
options.Path,
- options.RecursiveUnrecognizedRecursively);
+ unrecognizedStrategy);
if (auto* bitmap = self->GetSetFieldsBitmap()) {
bitmap->Set(FieldIndex_);
@@ -776,6 +786,13 @@ void TYsonStructParameter<TValue>::Load(
const TLoadParameterOptions& options)
{
if (cursor) {
+ auto unrecognizedStrategy = options.RecursiveUnrecognizedRecursively;
+ if (EnforceDefaultUnrecognizedStrategy_) {
+ unrecognizedStrategy.reset();
+ }
+ if (!unrecognizedStrategy) {
+ unrecognizedStrategy = DefaultUnrecognizedStrategy_;
+ }
if (ResetOnLoad_) {
NPrivate::ResetOnLoad(FieldAccessor_->GetValue(self));
}
@@ -783,7 +800,7 @@ void TYsonStructParameter<TValue>::Load(
FieldAccessor_->GetValue(self),
cursor,
options.Path,
- options.RecursiveUnrecognizedRecursively);
+ unrecognizedStrategy);
if (auto* bitmap = self->GetSetFieldsBitmap()) {
bitmap->Set(FieldIndex_);
@@ -893,6 +910,20 @@ TYsonStructParameter<TValue>& TYsonStructParameter<TValue>::ResetOnLoad()
}
template <class TValue>
+TYsonStructParameter<TValue>& TYsonStructParameter<TValue>::DefaultUnrecognizedStrategy(EUnrecognizedStrategy strategy)
+{
+ DefaultUnrecognizedStrategy_.emplace(strategy);
+ return *this;
+}
+
+template <class TValue>
+TYsonStructParameter<TValue>& TYsonStructParameter<TValue>::EnforceDefaultUnrecognizedStrategy()
+{
+ EnforceDefaultUnrecognizedStrategy_ = true;
+ return *this;
+}
+
+template <class TValue>
const std::vector<TString>& TYsonStructParameter<TValue>::GetAliases() const
{
return Aliases_;
diff --git a/yt/yt/core/ytree/yson_struct_detail.h b/yt/yt/core/ytree/yson_struct_detail.h
index bd9f3b1917..3ed99df7ec 100644
--- a/yt/yt/core/ytree/yson_struct_detail.h
+++ b/yt/yt/core/ytree/yson_struct_detail.h
@@ -317,6 +317,12 @@ public:
TYsonStructParameter& Alias(const TString& name);
// Set field to T() (or suitable analogue) before deserializations.
TYsonStructParameter& ResetOnLoad();
+ // Uses given unrecognized strategy in |Load| if there was no strategy supplied.
+ TYsonStructParameter& DefaultUnrecognizedStrategy(EUnrecognizedStrategy strategy);
+ // Forces given parameter to ignore unrecognized strategy even if it set to
+ // some recursive version. Combination with |DefaultUnrecognizedStrategy| enables
+ // behavior which ensures selected default strategy for all fields below.
+ TYsonStructParameter& EnforceDefaultUnrecognizedStrategy();
// Register constructor with parameters as initializer of default value for ref-counted class.
template <class... TArgs>
@@ -333,6 +339,8 @@ private:
bool TriviallyInitializedIntrusivePtr_ = false;
bool Optional_ = false;
bool ResetOnLoad_ = false;
+ std::optional<EUnrecognizedStrategy> DefaultUnrecognizedStrategy_;
+ bool EnforceDefaultUnrecognizedStrategy_ = false;
const int FieldIndex_ = -1;
};