yql_ast.h 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  1. #pragma once
  2. #include "yql_errors.h"
  3. #include <library/cpp/deprecated/enum_codegen/enum_codegen.h>
  4. #include <util/generic/ptr.h>
  5. #include <util/generic/strbuf.h>
  6. #include <util/generic/string.h>
  7. #include <util/generic/vector.h>
  8. #include <util/stream/output.h>
  9. #include <util/stream/str.h>
  10. #include <util/memory/pool.h>
  11. #include <util/generic/array_ref.h>
  12. namespace NYql {
  13. struct TNodeFlags {
  14. enum : ui16 {
  15. Default = 0,
  16. ArbitraryContent = 0x01,
  17. BinaryContent = 0x02,
  18. MultilineContent = 0x04,
  19. };
  20. static constexpr ui32 FlagsMask = 0x07; // all flags should fit here
  21. };
  22. struct TAstNode {
  23. #define YQL_AST_NODE_TYPE_MAP(xx) \
  24. xx(List, 0) \
  25. xx(Atom, 1) \
  26. enum EType : ui32 {
  27. YQL_AST_NODE_TYPE_MAP(ENUM_VALUE_GEN)
  28. };
  29. static const ui32 SmallListCount = 2;
  30. void PrintTo(IOutputStream& out) const;
  31. void PrettyPrintTo(IOutputStream& out, ui32 prettyFlags) const;
  32. inline TString ToString() const {
  33. TStringStream str;
  34. PrintTo(str);
  35. return str.Str();
  36. }
  37. inline TString ToString(ui32 prettyFlags) const {
  38. TStringStream str;
  39. PrettyPrintTo(str, prettyFlags);
  40. return str.Str();
  41. }
  42. inline EType GetType() const {
  43. return Type;
  44. }
  45. inline bool IsAtom() const {
  46. return Type == Atom;
  47. }
  48. inline bool IsList() const {
  49. return Type == List;
  50. }
  51. inline bool IsListOfSize(ui32 len) const {
  52. return Type == List && ListCount == len;
  53. }
  54. inline TPosition GetPosition() const {
  55. return Position;
  56. }
  57. inline void SetPosition(TPosition position) {
  58. Position = position;
  59. }
  60. inline TStringBuf GetContent() const {
  61. Y_ABORT_UNLESS(IsAtom());
  62. return TStringBuf(Data.A.Content, Data.A.Size);
  63. }
  64. inline void SetContent(TStringBuf newContent, TMemoryPool& pool) {
  65. Y_ABORT_UNLESS(IsAtom());
  66. auto poolContent = pool.AppendString(newContent);
  67. Data.A.Content = poolContent.data();
  68. Data.A.Size = poolContent.size();
  69. }
  70. inline void SetLiteralContent(TStringBuf newContent) {
  71. Y_ABORT_UNLESS(IsAtom());
  72. Data.A.Content = newContent.data();
  73. Data.A.Size = newContent.size();
  74. }
  75. inline ui32 GetFlags() const {
  76. Y_ABORT_UNLESS(IsAtom());
  77. return Data.A.Flags;
  78. }
  79. inline void SetFlags(ui32 flags) {
  80. Y_ABORT_UNLESS(IsAtom());
  81. Data.A.Flags = flags;
  82. }
  83. inline ui32 GetChildrenCount() const {
  84. Y_ABORT_UNLESS(IsList());
  85. return ListCount;
  86. }
  87. inline const TAstNode* GetChild(ui32 index) const {
  88. Y_ABORT_UNLESS(IsList());
  89. Y_ABORT_UNLESS(index < ListCount);
  90. if (ListCount <= SmallListCount) {
  91. return Data.S.Children[index];
  92. } else {
  93. return Data.L.Children[index];
  94. }
  95. }
  96. inline TAstNode* GetChild(ui32 index) {
  97. Y_ABORT_UNLESS(IsList());
  98. Y_ABORT_UNLESS(index < ListCount);
  99. if (ListCount <= SmallListCount) {
  100. return Data.S.Children[index];
  101. } else {
  102. return Data.L.Children[index];
  103. }
  104. }
  105. inline TArrayRef<TAstNode* const> GetChildren() const {
  106. Y_ABORT_UNLESS(IsList());
  107. return {ListCount <= SmallListCount ? Data.S.Children : Data.L.Children, ListCount};
  108. }
  109. static inline TAstNode* NewAtom(TPosition position, TStringBuf content, TMemoryPool& pool, ui32 flags = TNodeFlags::Default) {
  110. auto poolContent = pool.AppendString(content);
  111. auto ret = pool.Allocate<TAstNode>();
  112. ::new(ret) TAstNode(position, poolContent, flags);
  113. return ret;
  114. }
  115. // atom with non-owning content, useful for literal strings
  116. static inline TAstNode* NewLiteralAtom(TPosition position, TStringBuf content, TMemoryPool& pool, ui32 flags = TNodeFlags::Default) {
  117. auto ret = pool.Allocate<TAstNode>();
  118. ::new(ret) TAstNode(position, content, flags);
  119. return ret;
  120. }
  121. static inline TAstNode* NewList(TPosition position, TAstNode** children, ui32 childrenCount, TMemoryPool& pool) {
  122. TAstNode** poolChildren = nullptr;
  123. if (childrenCount) {
  124. if (childrenCount > SmallListCount) {
  125. poolChildren = pool.AllocateArray<TAstNode*>(childrenCount);
  126. memcpy(poolChildren, children, sizeof(void*) * childrenCount);
  127. } else {
  128. poolChildren = children;
  129. }
  130. for (ui32 index = 0; index < childrenCount; ++index) {
  131. Y_ABORT_UNLESS(poolChildren[index]);
  132. }
  133. }
  134. auto ret = pool.Allocate<TAstNode>();
  135. ::new(ret) TAstNode(position, poolChildren, childrenCount);
  136. return ret;
  137. }
  138. template <typename... TNodes>
  139. static inline TAstNode* NewList(TPosition position, TMemoryPool& pool, TNodes... nodes) {
  140. TAstNode* children[] = { nodes... };
  141. return NewList(position, children, sizeof...(nodes), pool);
  142. }
  143. static inline TAstNode* NewList(TPosition position, TMemoryPool& pool) {
  144. return NewList(position, nullptr, 0, pool);
  145. }
  146. static TAstNode QuoteAtom;
  147. static inline TAstNode* Quote(TPosition position, TMemoryPool& pool, TAstNode* node) {
  148. return NewList(position, pool, &QuoteAtom, node);
  149. }
  150. inline ~TAstNode() {}
  151. void Destroy() {
  152. TString().swap(Position.File);
  153. }
  154. private:
  155. inline TAstNode(TPosition position, TStringBuf content, ui32 flags)
  156. : Position(position)
  157. , Type(Atom)
  158. , ListCount(0)
  159. {
  160. Data.A.Content = content.data();
  161. Data.A.Size = content.size();
  162. Data.A.Flags = flags;
  163. }
  164. inline TAstNode(TPosition position, TAstNode** children, ui32 childrenCount)
  165. : Position(position)
  166. , Type(List)
  167. , ListCount(childrenCount)
  168. {
  169. if (childrenCount <= SmallListCount) {
  170. for (ui32 index = 0; index < childrenCount; ++index) {
  171. Data.S.Children[index] = children[index];
  172. }
  173. } else {
  174. Data.L.Children = children;
  175. }
  176. }
  177. TPosition Position;
  178. const EType Type;
  179. const ui32 ListCount;
  180. struct TAtom {
  181. const char* Content;
  182. ui32 Size;
  183. ui32 Flags;
  184. };
  185. struct TListType {
  186. TAstNode** Children;
  187. };
  188. struct TSmallList {
  189. TAstNode* Children[SmallListCount];
  190. };
  191. union {
  192. TAtom A;
  193. TListType L;
  194. TSmallList S;
  195. } Data;
  196. };
  197. enum class ESyntaxType {
  198. YQLv0,
  199. YQLv1,
  200. Pg,
  201. };
  202. class IAutoParamBuilder;
  203. class IAutoParamDataBuilder;
  204. class IAutoParamTypeBuilder {
  205. public:
  206. virtual ~IAutoParamTypeBuilder() = default;
  207. virtual void Pg(const TString& name) = 0;
  208. virtual void BeginList() = 0;
  209. virtual void EndList() = 0;
  210. virtual void BeginTuple() = 0;
  211. virtual void EndTuple() = 0;
  212. virtual void BeforeItem() = 0;
  213. virtual void AfterItem() = 0;
  214. virtual IAutoParamDataBuilder& FinishType() = 0;
  215. };
  216. class IAutoParamDataBuilder {
  217. public:
  218. virtual ~IAutoParamDataBuilder() = default;
  219. virtual void Pg(const TMaybe<TString>& value) = 0;
  220. virtual void BeginList() = 0;
  221. virtual void EndList() = 0;
  222. virtual void BeginTuple() = 0;
  223. virtual void EndTuple() = 0;
  224. virtual void BeforeItem() = 0;
  225. virtual void AfterItem() = 0;
  226. virtual IAutoParamBuilder& FinishData() = 0;
  227. };
  228. class IAutoParamBuilder : public TThrRefBase {
  229. public:
  230. virtual ~IAutoParamBuilder() = default;
  231. virtual ui32 Size() const = 0;
  232. virtual bool Contains(const TString& name) const = 0;
  233. virtual IAutoParamTypeBuilder& Add(const TString& name) = 0;
  234. };
  235. using IAutoParamBuilderPtr = TIntrusivePtr<IAutoParamBuilder>;
  236. class IAutoParamBuilderFactory {
  237. public:
  238. virtual ~IAutoParamBuilderFactory() = default;
  239. virtual IAutoParamBuilderPtr MakeBuilder() = 0;
  240. };
  241. struct TAstParseResult {
  242. std::unique_ptr<TMemoryPool> Pool;
  243. TAstNode* Root = nullptr;
  244. TIssues Issues;
  245. IAutoParamBuilderPtr PgAutoParamValues;
  246. ESyntaxType ActualSyntaxType = ESyntaxType::YQLv1;
  247. inline bool IsOk() const {
  248. return !!Root;
  249. }
  250. TAstParseResult() = default;
  251. ~TAstParseResult();
  252. TAstParseResult(const TAstParseResult&) = delete;
  253. TAstParseResult& operator=(const TAstParseResult&) = delete;
  254. TAstParseResult(TAstParseResult&&);
  255. TAstParseResult& operator=(TAstParseResult&&);
  256. void Destroy();
  257. };
  258. struct TStmtParseInfo {
  259. bool KeepInCache = true;
  260. TMaybe<TString> CommandTagName = {};
  261. };
  262. struct TAstPrintFlags {
  263. enum {
  264. Default = 0,
  265. PerLine = 0x01,
  266. ShortQuote = 0x02,
  267. AdaptArbitraryContent = 0x04,
  268. };
  269. };
  270. TAstParseResult ParseAst(const TStringBuf& str, TMemoryPool* externalPool = nullptr, const TString& file = {});
  271. } // namespace NYql
  272. template<>
  273. void Out<NYql::TAstNode::EType>(class IOutputStream &o, NYql::TAstNode::EType x);