aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbabenko <babenko@yandex-team.com>2024-08-22 15:35:59 +0300
committerbabenko <babenko@yandex-team.com>2024-08-22 15:46:30 +0300
commitf9fbb65f64b68c5de5cf257c04e06ac6aeaeb1e8 (patch)
treea4dab5ac21a6f2f190889537b9693c226a0eec8f
parent1475372a2d8a1ace4610a95415eb1cfe97fc26d1 (diff)
downloadydb-f9fbb65f64b68c5de5cf257c04e06ac6aeaeb1e8.tar.gz
YT-21993: Fix duplicate type tag on derive from template
7ec29a7b370f343f910075ff9fd87ea9469d2aa0
-rw-r--r--yt/yt/core/phoenix/descriptors.cpp16
-rw-r--r--yt/yt/core/phoenix/descriptors.h2
-rw-r--r--yt/yt/core/phoenix/type_decl-inl.h6
-rw-r--r--yt/yt/core/phoenix/type_def-inl.h49
-rw-r--r--yt/yt/core/phoenix/type_registry.cpp17
-rw-r--r--yt/yt/core/phoenix/unittests/phoenix_ut.cpp33
6 files changed, 102 insertions, 21 deletions
diff --git a/yt/yt/core/phoenix/descriptors.cpp b/yt/yt/core/phoenix/descriptors.cpp
index 90ee72f7fc..eb1f22a472 100644
--- a/yt/yt/core/phoenix/descriptors.cpp
+++ b/yt/yt/core/phoenix/descriptors.cpp
@@ -136,15 +136,29 @@ const TTypeDescriptor& TUniverseDescriptor::GetTypeDescriptorByTagOrThrow(TTypeT
return *descriptor;
}
+const TTypeDescriptor& TUniverseDescriptor::GetTypeDescriptorByTag(TTypeTag tag) const
+{
+ const auto* descriptor = FindTypeDescriptorByTag(tag);
+ YT_VERIFY(descriptor);
+ return *descriptor;
+}
+
const TTypeDescriptor* TUniverseDescriptor::FindTypeDescriptorByTypeIndex(std::type_index typeIndex) const
{
auto it = TypeIndexToDescriptor_.find(typeIndex);
return it == TypeIndexToDescriptor_.end() ? nullptr : it->second;
}
+const TTypeDescriptor& TUniverseDescriptor::GetTypeDescriptorByTypeIndex(std::type_index typeIndex) const
+{
+ const auto* descriptor = FindTypeDescriptorByTypeIndex(typeIndex);
+ YT_VERIFY(descriptor);
+ return *descriptor;
+}
+
const TTypeDescriptor& TUniverseDescriptor::GetTypeDescriptorByTypeIndexOrThrow(std::type_index typeIndex) const
{
- const auto& descriptor = FindTypeDescriptorByTypeIndex(typeIndex);
+ const auto* descriptor = FindTypeDescriptorByTypeIndex(typeIndex);
if (!descriptor) {
THROW_ERROR_EXCEPTION("Type %v is not registered",
CppDemangle(typeIndex.name()));
diff --git a/yt/yt/core/phoenix/descriptors.h b/yt/yt/core/phoenix/descriptors.h
index 1ec630a75d..854ae0caf1 100644
--- a/yt/yt/core/phoenix/descriptors.h
+++ b/yt/yt/core/phoenix/descriptors.h
@@ -91,9 +91,11 @@ public:
const NYson::TYsonString& GetSchemaYson() const;
const TTypeDescriptor* FindTypeDescriptorByTag(TTypeTag tag) const ;
+ const TTypeDescriptor& GetTypeDescriptorByTag(TTypeTag tag) const;
const TTypeDescriptor& GetTypeDescriptorByTagOrThrow(TTypeTag tag) const;
const TTypeDescriptor* FindTypeDescriptorByTypeIndex(std::type_index typeIndex) const ;
+ const TTypeDescriptor& GetTypeDescriptorByTypeIndex(std::type_index typeIndex) const;
const TTypeDescriptor& GetTypeDescriptorByTypeIndexOrThrow(std::type_index typeIndex) const;
private:
diff --git a/yt/yt/core/phoenix/type_decl-inl.h b/yt/yt/core/phoenix/type_decl-inl.h
index fb6c2f5c19..2e5d62fd3c 100644
--- a/yt/yt/core/phoenix/type_decl-inl.h
+++ b/yt/yt/core/phoenix/type_decl-inl.h
@@ -83,7 +83,7 @@ private: \
public: \
static const ::NYT::NPhoenix2::TTypeDescriptor& GetTypeDescriptor() \
{ \
- static const auto& descriptor = ::NYT::NPhoenix2::NDetail::RegisterTypeDescriptorImpl<type, /*Template*/ true>(); \
+ static const auto& descriptor = ::NYT::NPhoenix2::NDetail::GetTypeDescriptorByTagUnchecked(TypeTag); \
return descriptor; \
} \
\
@@ -136,4 +136,8 @@ public: \
////////////////////////////////////////////////////////////////////////////////
+const TTypeDescriptor& GetTypeDescriptorByTagUnchecked(TTypeTag tag);
+
+////////////////////////////////////////////////////////////////////////////////
+
} // namespace NYT::NPhoenix2::NDetail
diff --git a/yt/yt/core/phoenix/type_def-inl.h b/yt/yt/core/phoenix/type_def-inl.h
index 9b40b0f703..166909e178 100644
--- a/yt/yt/core/phoenix/type_def-inl.h
+++ b/yt/yt/core/phoenix/type_def-inl.h
@@ -18,6 +18,8 @@
#include <concepts>
+namespace NYT::NPhoenix2::NDetail {
+
////////////////////////////////////////////////////////////////////////////////
#undef PHOENIX_DEFINE_TYPE
@@ -26,22 +28,10 @@
////////////////////////////////////////////////////////////////////////////////
-#define PHOENIX_DEFINE_TYPE__STATIC_INIT(type, parenthesizedTypeArgs) \
- template <class T> \
- struct TPhoenixTypeInitializer__; \
- \
- template <> \
- struct TPhoenixTypeInitializer__<type PP_DEPAREN(parenthesizedTypeArgs)> \
- { \
- [[maybe_unused]] static inline const void* Dummy = &type PP_DEPAREN(parenthesizedTypeArgs)::GetTypeDescriptor(); \
- }
-
#define PHOENIX_DEFINE_TYPE(type) \
- PHOENIX_DEFINE_TYPE__STATIC_INIT(type, ()); \
- \
const ::NYT::NPhoenix2::TTypeDescriptor& type::GetTypeDescriptor() \
{ \
- static const auto& descriptor = ::NYT::NPhoenix2::NDetail::RegisterTypeDescriptorImpl<type, /*Template*/ false>(); \
+ static const auto& descriptor = ::NYT::NPhoenix2::NDetail::GetTypeDescriptorByTagUnchecked(TypeTag); \
return descriptor; \
} \
\
@@ -79,23 +69,46 @@
YT_VERIFY(context.IsLoad()); \
type::LoadImpl(context.LoadContext()); \
} \
+ } \
+ \
+ template <class T> \
+ struct TPhoenixTypeInitializer__; \
+ \
+ template <> \
+ struct TPhoenixTypeInitializer__<type> \
+ { \
+ [[maybe_unused]] static inline const void* Dummy = &::NYT::NPhoenix2::NDetail::RegisterTypeDescriptorImpl<type, false>(); \
}
#define PHOENIX_DEFINE_TEMPLATE_TYPE(type, parenthesizedTypeArgs) \
- PHOENIX_DEFINE_TYPE__STATIC_INIT(type, parenthesizedTypeArgs)
+ template <class T> \
+ struct TPhoenixTypeInitializer__; \
+ \
+ template <> \
+ struct TPhoenixTypeInitializer__<type PP_DEPAREN(parenthesizedTypeArgs)> \
+ { \
+ [[maybe_unused]] static inline const void* Dummy = &::NYT::NPhoenix2::NDetail::RegisterTypeDescriptorImpl<type PP_DEPAREN(parenthesizedTypeArgs), true>(); \
+ }
#define PHOENIX_DEFINE_OPAQUE_TYPE(type) \
- PHOENIX_DEFINE_TYPE__STATIC_INIT(type, ()); \
- \
const ::NYT::NPhoenix2::TTypeDescriptor& type::GetTypeDescriptor() \
{ \
- static const auto& descriptor = ::NYT::NPhoenix2::NDetail::RegisterOpaqueTypeDescriptorImpl<type>(); \
+ static const auto& descriptor = ::NYT::NPhoenix2::NDetail::GetTypeDescriptorByTagUnchecked(TypeTag); \
return descriptor; \
+ } \
+ \
+ template <class T> \
+ struct TPhoenixTypeInitializer__; \
+ \
+ template <> \
+ struct TPhoenixTypeInitializer__<type> \
+ { \
+ [[maybe_unused]] static inline const void* Dummy = &::NYT::NPhoenix2::NDetail::RegisterOpaqueTypeDescriptorImpl<type>(); \
}
////////////////////////////////////////////////////////////////////////////////
-namespace NYT::NPhoenix2::NDetail {
+const TTypeDescriptor& GetTypeDescriptorByTagUnchecked(TTypeTag tag);
////////////////////////////////////////////////////////////////////////////////
diff --git a/yt/yt/core/phoenix/type_registry.cpp b/yt/yt/core/phoenix/type_registry.cpp
index 11c1ca2f26..e4a9d46780 100644
--- a/yt/yt/core/phoenix/type_registry.cpp
+++ b/yt/yt/core/phoenix/type_registry.cpp
@@ -80,6 +80,11 @@ public:
if (!Sealed_.exchange(true)) {
YT_LOG_INFO("Type registry is sealed");
}
+ return GetUniverseDescriptorUnchecked();
+ }
+
+ const TUniverseDescriptor& GetUniverseDescriptorUnchecked()
+ {
return UniverseDescriptor_;
}
@@ -88,13 +93,23 @@ private:
std::atomic<bool> Sealed_;
};
+TTypeRegistry* GetTypeRegistry()
+{
+ return LeakySingleton<NDetail::TTypeRegistry>();
+}
+
+const TTypeDescriptor& GetTypeDescriptorByTagUnchecked(TTypeTag tag)
+{
+ return GetTypeRegistry()->GetUniverseDescriptorUnchecked().GetTypeDescriptorByTag(tag);
+}
+
} // namespace NDetail
////////////////////////////////////////////////////////////////////////////////
ITypeRegistry* ITypeRegistry::Get()
{
- return LeakySingleton<NDetail::TTypeRegistry>();
+ return NDetail::GetTypeRegistry();
}
////////////////////////////////////////////////////////////////////////////////
diff --git a/yt/yt/core/phoenix/unittests/phoenix_ut.cpp b/yt/yt/core/phoenix/unittests/phoenix_ut.cpp
index b93bf8868b..e55261ba18 100644
--- a/yt/yt/core/phoenix/unittests/phoenix_ut.cpp
+++ b/yt/yt/core/phoenix/unittests/phoenix_ut.cpp
@@ -1578,5 +1578,38 @@ TEST(TPhoenixTest, PrivateInner)
////////////////////////////////////////////////////////////////////////////////
+namespace NSeveralSpecializationsOfOneTemplate {
+
+struct TDerivedFromTemplate
+ : public TPair<double, double>
+{
+ bool operator==(const TDerivedFromTemplate&) const = default;
+
+ PHOENIX_DECLARE_TYPE(TDerivedFromTemplate, 0xf09c298f);
+};
+
+void TDerivedFromTemplate::RegisterMetadata(auto&& registrar)
+{
+ registrar.template BaseType<TPair<double, double>>();
+}
+
+PHOENIX_DEFINE_TYPE(TDerivedFromTemplate);
+
+} // namespace NSeveralSpecializationsOfOneTemplate
+
+TEST(TPhoenixTest, SeveralSpecializationsOfOneTemplate)
+{
+ using namespace NSeveralSpecializationsOfOneTemplate;
+
+ TDerivedFromTemplate tp1;
+ tp1.First = 1.1;
+ tp1.Second = 2.2;
+
+ auto tp2 = Deserialize<TDerivedFromTemplate>(Serialize(tp1));
+ EXPECT_EQ(tp1, tp2);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
} // namespace
} // namespace NYT::NPhoenix2