21
21
#ifdef THRIFT_SCHEMA_AVAILABLE
22
22
23
23
#include < unordered_set>
24
+ #include < folly/SharedMutex.h>
24
25
#include < folly/synchronization/RelaxedAtomic.h>
25
26
#include < thrift/lib/cpp/util/EnumUtils.h>
27
+ #include < thrift/lib/cpp2/dynamic/TypeSystem.h>
26
28
#include < thrift/lib/cpp2/runtime/BaseSchemaRegistry.h>
27
29
#include < thrift/lib/cpp2/schema/SyntaxGraph.h>
28
30
#include < thrift/lib/cpp2/schema/detail/SchemaBackedResolver.h>
31
33
namespace apache ::thrift {
32
34
namespace detail {
33
35
template <typename T>
34
- struct SyntaxGraphNodeTag {
36
+ struct NodeTag {
35
37
using type = T;
36
38
};
37
39
38
40
template <typename T>
39
41
constexpr auto getSyntaxGraphNodeTypeFor () {
40
42
if constexpr (is_thrift_service_tag_v<T>) {
41
- return SyntaxGraphNodeTag <syntax_graph::ServiceNode>{};
43
+ return NodeTag <syntax_graph::ServiceNode>{};
42
44
} else if constexpr (is_thrift_struct_v<T>) {
43
- return SyntaxGraphNodeTag <syntax_graph::StructNode>{};
45
+ return NodeTag <syntax_graph::StructNode>{};
44
46
} else if constexpr (is_thrift_union_v<T>) {
45
- return SyntaxGraphNodeTag <syntax_graph::UnionNode>{};
47
+ return NodeTag <syntax_graph::UnionNode>{};
46
48
} else if constexpr (is_thrift_exception_v<T>) {
47
- return SyntaxGraphNodeTag <syntax_graph::ExceptionNode>{};
49
+ return NodeTag <syntax_graph::ExceptionNode>{};
48
50
} else if constexpr (util::is_thrift_enum_v<T>) {
49
- return SyntaxGraphNodeTag <syntax_graph::EnumNode>{};
51
+ return NodeTag <syntax_graph::EnumNode>{};
50
52
} else {
51
53
static_assert (folly::always_false<T>, " Unsupported Thrift type" );
52
54
}
53
55
// It's unclear how to include typedefs and constants here.
54
56
// TODO: interactions
55
57
}
56
58
59
+ template <typename T>
60
+ constexpr auto getTypeSystemNodeTypeFor () {
61
+ if constexpr (is_thrift_struct_v<T>) {
62
+ return NodeTag<type_system::StructNode>{};
63
+ } else if constexpr (is_thrift_union_v<T>) {
64
+ return NodeTag<type_system::UnionNode>{};
65
+ } else if constexpr (util::is_thrift_enum_v<T>) {
66
+ return NodeTag<type_system::EnumNode>{};
67
+ } else {
68
+ static_assert (folly::always_false<T>, " Unsupported Thrift type" );
69
+ }
70
+ }
71
+
57
72
template <typename T>
58
73
using SyntaxGraphNodeTypeFor =
59
74
typename decltype (getSyntaxGraphNodeTypeFor<T>())::type;
75
+
76
+ template <typename T>
77
+ using TypeSystemNodeTypeFor =
78
+ typename decltype (getTypeSystemNodeTypeFor<T>())::type;
60
79
} // namespace detail
61
80
namespace test {
62
81
struct SchemaTest ;
@@ -88,6 +107,36 @@ class SchemaRegistry {
88
107
.template as <detail::SyntaxGraphNodeTypeFor<T>>();
89
108
}
90
109
110
+ /* *
111
+ * Gets TypeSystem node for given URI, or nullopt if not found.
112
+ * Only types defined in a file with the `any` cpp2 compiler option enabled
113
+ * can be found using this method.
114
+ */
115
+ std::optional<type_system::DefinitionRef> getTypeSystemDefinitionRefByUri (
116
+ const std::string_view uri) const ;
117
+
118
+ /* *
119
+ * Gets TypeSystem node for given definition, or throws `std::out_of_range` if
120
+ * not present in schema.
121
+ */
122
+ template <typename T>
123
+ type_system::DefinitionRef getTypeSystemDefinitionRef () const {
124
+ const syntax_graph::DefinitionNode& sgNode = getDefinitionNode<T>();
125
+ std::lock_guard<folly::SharedMutex> wlock (typeSystemMutex_);
126
+ return syntaxGraph_->asTypeSystemDefinitionRef (sgNode);
127
+ }
128
+
129
+ /* *
130
+ * Gets TypeSystem node for given definition, or throws `std::out_of_range` if
131
+ * not present in schema. Returns most-derived type (e.g. StructNode) that
132
+ * matches the template parameter.
133
+ */
134
+ template <typename T>
135
+ const detail::TypeSystemNodeTypeFor<T>& getTypeSystemNode () const {
136
+ return getTypeSystemDefinitionRef<T>()
137
+ .template asType <detail::TypeSystemNodeTypeFor<T>>();
138
+ }
139
+
91
140
explicit SchemaRegistry (BaseSchemaRegistry& base);
92
141
~SchemaRegistry ();
93
142
@@ -111,6 +160,9 @@ class SchemaRegistry {
111
160
112
161
std::unique_ptr<syntax_graph::SyntaxGraph> syntaxGraph_;
113
162
syntax_graph::detail::IncrementalResolver* resolver_;
163
+ // Synchronizes access to syntaxGraph_->asTypeSystem* methods, which are not
164
+ // thread-safe.
165
+ mutable folly::SharedMutex typeSystemMutex_;
114
166
115
167
friend struct test ::SchemaTest;
116
168
};
0 commit comments