#pragma once #include #include #include #include #include #include #include namespace NYql { class TVisitorTransformerBase: public TSyncTransformerBase { public: using THandler = std::function; TVisitorTransformerBase(bool failOnUnknown) : FailOnUnknown(failOnUnknown) { } TStatus DoTransform(TExprNode::TPtr input, TExprNode::TPtr& output, TExprContext& ctx) final; void Rewind() final { } bool CanParse(const TExprNode& node) const { return Handlers.contains(node.Content()); } protected: void AddHandler(std::initializer_list names, THandler handler); template THandler Hndl(TStatus(TDerived::* handler)(const TExprNode::TPtr&, TExprNode::TPtr&, TExprContext&)) { return [this, handler] (TExprNode::TPtr input, TExprNode::TPtr& output, TExprContext& ctx) { return (static_cast(this)->*handler)(input, output, ctx); }; } template THandler Hndl(TStatus(TDerived::* handler)(const TExprNode::TPtr&, TExprContext&)) { return [this, handler] (TExprNode::TPtr input, TExprNode::TPtr& /*output*/, TExprContext& ctx) { return (static_cast(this)->*handler)(input, ctx); }; } template THandler Hndl(TStatus(TDerived::* handler)(NNodes::TExprBase, TExprContext&)) { return [this, handler] (TExprNode::TPtr input, TExprNode::TPtr& /*output*/, TExprContext& ctx) { return (static_cast(this)->*handler)(NNodes::TExprBase(input), ctx); }; } THandler Hndl(TStatus(*handler)(const TExprNode::TPtr&, TExprContext&)) { return [handler] (TExprNode::TPtr input, TExprNode::TPtr& /*output*/, TExprContext& ctx) { return handler(input, ctx); }; } THandler Hndl(TStatus(*handler)(NNodes::TExprBase, TExprContext&)) { return [handler] (TExprNode::TPtr input, TExprNode::TPtr& /*output*/, TExprContext& ctx) { return handler(NNodes::TExprBase(input), ctx); }; } protected: const bool FailOnUnknown; THashMap Handlers; }; } // NYql