yql_expr.h 89 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922
  1. #pragma once
  2. #include "yql_ast.h"
  3. #include "yql_expr_types.h"
  4. #include "yql_type_string.h"
  5. #include "yql_expr_builder.h"
  6. #include "yql_gc_nodes.h"
  7. #include "yql_constraint.h"
  8. #include "yql_pos_handle.h"
  9. #include <yql/essentials/core/url_lister/interface/url_lister_manager.h>
  10. #include <yql/essentials/utils/yql_panic.h>
  11. #include <yql/essentials/public/issue/yql_issue_manager.h>
  12. #include <yql/essentials/public/udf/udf_data_type.h>
  13. #include <library/cpp/yson/node/node.h>
  14. #include <library/cpp/yson/writer.h>
  15. #include <library/cpp/string_utils/levenshtein_diff/levenshtein_diff.h>
  16. #include <library/cpp/enumbitset/enumbitset.h>
  17. #include <library/cpp/containers/stack_vector/stack_vec.h>
  18. #include <library/cpp/deprecated/enum_codegen/enum_codegen.h>
  19. #include <util/string/ascii.h>
  20. #include <util/string/builder.h>
  21. #include <util/generic/array_ref.h>
  22. #include <util/generic/deque.h>
  23. #include <util/generic/cast.h>
  24. #include <util/generic/hash.h>
  25. #include <util/generic/maybe.h>
  26. #include <util/generic/set.h>
  27. #include <util/generic/bt_exception.h>
  28. #include <util/generic/algorithm.h>
  29. #include <util/digest/murmur.h>
  30. #include <algorithm>
  31. #include <unordered_set>
  32. #include <unordered_map>
  33. #include <span>
  34. #include <stack>
  35. //#define YQL_CHECK_NODES_CONSISTENCY
  36. #ifdef YQL_CHECK_NODES_CONSISTENCY
  37. #define ENSURE_NOT_DELETED \
  38. YQL_ENSURE(!Dead(), "Access to dead node # " << UniqueId_ << ": " << Type_ << " '" << ContentUnchecked() << "'");
  39. #define ENSURE_NOT_FROZEN \
  40. YQL_ENSURE(!Frozen(), "Change in frozen node # " << UniqueId_ << ": " << Type_ << " '" << ContentUnchecked() << "'");
  41. #define ENSURE_NOT_FROZEN_CTX \
  42. YQL_ENSURE(!Frozen, "Change in frozen expr context.");
  43. #else
  44. #define ENSURE_NOT_DELETED Y_DEBUG_ABORT_UNLESS(!Dead(), "Access to dead node # %lu: %d '%s'", UniqueId_, (int)Type_, TString(ContentUnchecked()).data());
  45. #define ENSURE_NOT_FROZEN Y_DEBUG_ABORT_UNLESS(!Frozen());
  46. #define ENSURE_NOT_FROZEN_CTX Y_DEBUG_ABORT_UNLESS(!Frozen);
  47. #endif
  48. namespace NYql {
  49. using NUdf::EDataSlot;
  50. class TUnitExprType;
  51. class TMultiExprType;
  52. class TTupleExprType;
  53. class TStructExprType;
  54. class TItemExprType;
  55. class TListExprType;
  56. class TStreamExprType;
  57. class TDataExprType;
  58. class TPgExprType;
  59. class TWorldExprType;
  60. class TOptionalExprType;
  61. class TCallableExprType;
  62. class TResourceExprType;
  63. class TTypeExprType;
  64. class TDictExprType;
  65. class TVoidExprType;
  66. class TNullExprType;
  67. class TGenericExprType;
  68. class TTaggedExprType;
  69. class TErrorExprType;
  70. class TVariantExprType;
  71. class TStreamExprType;
  72. class TFlowExprType;
  73. class TEmptyListExprType;
  74. class TEmptyDictExprType;
  75. class TBlockExprType;
  76. class TScalarExprType;
  77. const size_t DefaultMistypeDistance = 3;
  78. const TString YqlVirtualPrefix = "_yql_virtual_";
  79. extern const TStringBuf ZeroString;
  80. struct TTypeAnnotationVisitor {
  81. virtual ~TTypeAnnotationVisitor() = default;
  82. virtual void Visit(const TUnitExprType& type) = 0;
  83. virtual void Visit(const TMultiExprType& type) = 0;
  84. virtual void Visit(const TTupleExprType& type) = 0;
  85. virtual void Visit(const TStructExprType& type) = 0;
  86. virtual void Visit(const TItemExprType& type) = 0;
  87. virtual void Visit(const TListExprType& type) = 0;
  88. virtual void Visit(const TStreamExprType& type) = 0;
  89. virtual void Visit(const TFlowExprType& type) = 0;
  90. virtual void Visit(const TDataExprType& type) = 0;
  91. virtual void Visit(const TPgExprType& type) = 0;
  92. virtual void Visit(const TWorldExprType& type) = 0;
  93. virtual void Visit(const TOptionalExprType& type) = 0;
  94. virtual void Visit(const TCallableExprType& type) = 0;
  95. virtual void Visit(const TResourceExprType& type) = 0;
  96. virtual void Visit(const TTypeExprType& type) = 0;
  97. virtual void Visit(const TDictExprType& type) = 0;
  98. virtual void Visit(const TVoidExprType& type) = 0;
  99. virtual void Visit(const TNullExprType& type) = 0;
  100. virtual void Visit(const TGenericExprType& type) = 0;
  101. virtual void Visit(const TTaggedExprType& type) = 0;
  102. virtual void Visit(const TErrorExprType& type) = 0;
  103. virtual void Visit(const TVariantExprType& type) = 0;
  104. virtual void Visit(const TEmptyListExprType& type) = 0;
  105. virtual void Visit(const TEmptyDictExprType& type) = 0;
  106. virtual void Visit(const TBlockExprType& type) = 0;
  107. virtual void Visit(const TScalarExprType& type) = 0;
  108. };
  109. struct TDefaultTypeAnnotationVisitor : public TTypeAnnotationVisitor {
  110. void Visit(const TUnitExprType& type) override;
  111. void Visit(const TMultiExprType& type) override;
  112. void Visit(const TTupleExprType& type) override;
  113. void Visit(const TStructExprType& type) override;
  114. void Visit(const TItemExprType& type) override;
  115. void Visit(const TListExprType& type) override;
  116. void Visit(const TStreamExprType& type) override;
  117. void Visit(const TFlowExprType& type) override;
  118. void Visit(const TDataExprType& type) override;
  119. void Visit(const TPgExprType& type) override;
  120. void Visit(const TWorldExprType& type) override;
  121. void Visit(const TOptionalExprType& type) override;
  122. void Visit(const TCallableExprType& type) override;
  123. void Visit(const TResourceExprType& type) override;
  124. void Visit(const TTypeExprType& type) override;
  125. void Visit(const TDictExprType& type) override;
  126. void Visit(const TVoidExprType& type) override;
  127. void Visit(const TNullExprType& type) override;
  128. void Visit(const TGenericExprType& type) override;
  129. void Visit(const TTaggedExprType& type) override;
  130. void Visit(const TErrorExprType& type) override;
  131. void Visit(const TVariantExprType& type) override;
  132. void Visit(const TEmptyListExprType& type) override;
  133. void Visit(const TEmptyDictExprType& type) override;
  134. void Visit(const TBlockExprType& type) override;
  135. void Visit(const TScalarExprType& type) override;
  136. };
  137. class TErrorTypeVisitor : public TDefaultTypeAnnotationVisitor
  138. {
  139. public:
  140. TErrorTypeVisitor(TExprContext& ctx);
  141. void Visit(const TErrorExprType& type) override;
  142. bool HasErrors() const;
  143. private:
  144. TExprContext& Ctx_;
  145. bool HasErrors_ = false;
  146. };
  147. enum ETypeAnnotationFlags : ui32 {
  148. TypeNonComposable = 0x01,
  149. TypeNonPersistable = 0x02,
  150. TypeNonComputable = 0x04,
  151. TypeNonInspectable = 0x08,
  152. TypeNonHashable = 0x10,
  153. TypeNonEquatable = 0x20,
  154. TypeNonComparable = 0x40,
  155. TypeHasNull = 0x80,
  156. TypeHasOptional = 0x100,
  157. TypeHasManyValues = 0x200,
  158. TypeHasBareYson = 0x400,
  159. TypeHasNestedOptional = 0x800,
  160. TypeNonPresortable = 0x1000,
  161. TypeHasDynamicSize = 0x2000,
  162. TypeNonComparableInternal = 0x4000,
  163. };
  164. const ui64 TypeHashMagic = 0x10000;
  165. inline ui64 StreamHash(const void* buffer, size_t size, ui64 seed) {
  166. return MurmurHash(buffer, size, seed);
  167. }
  168. inline ui64 StreamHash(ui64 value, ui64 seed) {
  169. return MurmurHash(&value, sizeof(value), seed);
  170. }
  171. void ReportError(TExprContext& ctx, const TIssue& issue);
  172. class TTypeAnnotationNode {
  173. protected:
  174. TTypeAnnotationNode(ETypeAnnotationKind kind, ui32 flags, ui64 hash, ui64 usedPgExtensions)
  175. : Kind(kind)
  176. , Flags(flags)
  177. , Hash(hash)
  178. , UsedPgExtensions(usedPgExtensions)
  179. {
  180. }
  181. public:
  182. virtual ~TTypeAnnotationNode() = default;
  183. template <typename T>
  184. const T* Cast() const {
  185. static_assert(std::is_base_of<TTypeAnnotationNode, T>::value,
  186. "Should be derived from TTypeAnnotationNode");
  187. const auto ret = dynamic_cast<const T*>(this);
  188. YQL_ENSURE(ret, "Cannot cast type " << *this << " to " << ETypeAnnotationKind(T::KindValue));
  189. return ret;
  190. }
  191. template <typename T>
  192. const T* UserCast(TPosition pos, TExprContext& ctx) const {
  193. static_assert(std::is_base_of<TTypeAnnotationNode, T>::value,
  194. "Should be derived from TTypeAnnotationNode");
  195. const auto ret = dynamic_cast<const T*>(this);
  196. if (!ret) {
  197. ReportError(ctx, TIssue(pos, TStringBuilder() << "Cannot cast type " << *this << " to " << ETypeAnnotationKind(T::KindValue)));
  198. }
  199. return ret;
  200. }
  201. ETypeAnnotationKind GetKind() const {
  202. return Kind;
  203. }
  204. bool IsComposable() const {
  205. return (GetFlags() & TypeNonComposable) == 0;
  206. }
  207. bool IsPersistable() const {
  208. return (GetFlags() & TypeNonPersistable) == 0;
  209. }
  210. bool IsComputable() const {
  211. return (GetFlags() & TypeNonComputable) == 0;
  212. }
  213. bool IsInspectable() const {
  214. return (GetFlags() & TypeNonInspectable) == 0;
  215. }
  216. bool IsHashable() const {
  217. return IsPersistable() && (GetFlags() & TypeNonHashable) == 0;
  218. }
  219. bool IsEquatable() const {
  220. return IsPersistable() && (GetFlags() & TypeNonEquatable) == 0;
  221. }
  222. bool IsComparable() const {
  223. return IsPersistable() && (GetFlags() & TypeNonComparable) == 0;
  224. }
  225. bool IsComparableInternal() const {
  226. return IsPersistable() && (GetFlags() & TypeNonComparableInternal) == 0;
  227. }
  228. bool HasNull() const {
  229. return (GetFlags() & TypeHasNull) != 0;
  230. }
  231. bool HasOptional() const {
  232. return (GetFlags() & TypeHasOptional) != 0;
  233. }
  234. bool HasNestedOptional() const {
  235. return (GetFlags() & TypeHasNestedOptional) != 0;
  236. }
  237. bool HasOptionalOrNull() const {
  238. return (GetFlags() & (TypeHasOptional | TypeHasNull)) != 0;
  239. }
  240. bool IsOptionalOrNull() const {
  241. auto kind = GetKind();
  242. return kind == ETypeAnnotationKind::Optional || kind == ETypeAnnotationKind::Null || kind == ETypeAnnotationKind::Pg;
  243. }
  244. bool IsBlockOrScalar() const {
  245. return IsBlock() || IsScalar();
  246. }
  247. bool IsBlock() const {
  248. return GetKind() == ETypeAnnotationKind::Block;
  249. }
  250. bool IsScalar() const {
  251. return GetKind() == ETypeAnnotationKind::Scalar;
  252. }
  253. bool HasFixedSizeRepr() const {
  254. return (GetFlags() & (TypeHasDynamicSize | TypeNonPersistable | TypeNonComputable)) == 0;
  255. }
  256. bool IsSingleton() const {
  257. return (GetFlags() & TypeHasManyValues) == 0;
  258. }
  259. bool HasBareYson() const {
  260. return (GetFlags() & TypeHasBareYson) != 0;
  261. }
  262. bool IsPresortSupported() const {
  263. return (GetFlags() & TypeNonPresortable) == 0;
  264. }
  265. ui32 GetFlags() const {
  266. return Flags;
  267. }
  268. ui64 GetHash() const {
  269. return Hash;
  270. }
  271. ui64 GetUsedPgExtensions() const {
  272. return UsedPgExtensions;
  273. }
  274. bool Equals(const TTypeAnnotationNode& node) const;
  275. void Accept(TTypeAnnotationVisitor& visitor) const;
  276. void Out(IOutputStream& out) const {
  277. out << FormatType(this);
  278. }
  279. struct THash {
  280. size_t operator()(const TTypeAnnotationNode* node) const {
  281. return node->GetHash();
  282. }
  283. };
  284. struct TEqual {
  285. bool operator()(const TTypeAnnotationNode* one, const TTypeAnnotationNode* two) const {
  286. return one->Equals(*two);
  287. }
  288. };
  289. typedef std::vector<const TTypeAnnotationNode*> TListType;
  290. typedef std::span<const TTypeAnnotationNode*> TSpanType;
  291. protected:
  292. template <typename T>
  293. static ui32 CombineFlags(const T& items) {
  294. ui32 flags = 0;
  295. for (auto& item : items) {
  296. flags |= item->GetFlags();
  297. }
  298. return flags;
  299. }
  300. template <typename T>
  301. static ui64 CombinePgExtensions(const T& items) {
  302. ui64 mask = 0;
  303. for (auto& item : items) {
  304. mask |= item->GetUsedPgExtensions();
  305. }
  306. return mask;
  307. }
  308. private:
  309. const ETypeAnnotationKind Kind;
  310. const ui32 Flags;
  311. const ui64 Hash;
  312. const ui64 UsedPgExtensions;
  313. };
  314. class TUnitExprType : public TTypeAnnotationNode {
  315. public:
  316. static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Unit;
  317. TUnitExprType(ui64 hash)
  318. : TTypeAnnotationNode(KindValue,
  319. TypeNonComputable | TypeNonPersistable, hash, 0)
  320. {
  321. }
  322. static ui64 MakeHash() {
  323. return TypeHashMagic | (ui64)ETypeAnnotationKind::Unit;
  324. }
  325. bool operator==(const TUnitExprType& other) const {
  326. Y_UNUSED(other);
  327. return true;
  328. }
  329. };
  330. class TTupleExprType : public TTypeAnnotationNode {
  331. public:
  332. static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Tuple;
  333. TTupleExprType(ui64 hash, const TTypeAnnotationNode::TListType& items)
  334. : TTypeAnnotationNode(KindValue, CombineFlags(items), hash, CombinePgExtensions(items))
  335. , Items(items)
  336. {
  337. }
  338. static ui64 MakeHash(const TTypeAnnotationNode::TListType& items) {
  339. ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Tuple;
  340. hash = StreamHash(items.size(), hash);
  341. for (const auto& item : items) {
  342. hash = StreamHash(item->GetHash(), hash);
  343. }
  344. return hash;
  345. }
  346. size_t GetSize() const {
  347. return Items.size();
  348. }
  349. const TTypeAnnotationNode::TListType& GetItems() const {
  350. return Items;
  351. }
  352. bool operator==(const TTupleExprType& other) const {
  353. if (GetSize() != other.GetSize()) {
  354. return false;
  355. }
  356. for (ui32 i = 0, e = GetSize(); i < e; ++i) {
  357. if (GetItems()[i] != other.GetItems()[i]) {
  358. return false;
  359. }
  360. }
  361. return true;
  362. }
  363. bool Validate(TPosition position, TExprContext& ctx) const;
  364. bool Validate(TPositionHandle position, TExprContext& ctx) const;
  365. private:
  366. TTypeAnnotationNode::TListType Items;
  367. };
  368. class TMultiExprType : public TTypeAnnotationNode {
  369. public:
  370. static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Multi;
  371. TMultiExprType(ui64 hash, const TTypeAnnotationNode::TListType& items)
  372. : TTypeAnnotationNode(KindValue, CombineFlags(items), hash, CombinePgExtensions(items))
  373. , Items(items)
  374. {
  375. }
  376. static ui64 MakeHash(const TTypeAnnotationNode::TListType& items) {
  377. ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Multi;
  378. hash = StreamHash(items.size(), hash);
  379. for (const auto& item : items) {
  380. hash = StreamHash(item->GetHash(), hash);
  381. }
  382. return hash;
  383. }
  384. size_t GetSize() const {
  385. return Items.size();
  386. }
  387. const TTypeAnnotationNode::TListType& GetItems() const {
  388. return Items;
  389. }
  390. bool operator==(const TMultiExprType& other) const {
  391. if (GetSize() != other.GetSize()) {
  392. return false;
  393. }
  394. for (ui32 i = 0, e = GetSize(); i < e; ++i) {
  395. if (GetItems()[i] != other.GetItems()[i]) {
  396. return false;
  397. }
  398. }
  399. return true;
  400. }
  401. bool Validate(TPosition position, TExprContext& ctx) const;
  402. bool Validate(TPositionHandle position, TExprContext& ctx) const;
  403. private:
  404. TTypeAnnotationNode::TListType Items;
  405. };
  406. struct TExprContext;
  407. bool ValidateName(TPosition position, TStringBuf name, TStringBuf descr, TExprContext& ctx);
  408. bool ValidateName(TPositionHandle position, TStringBuf name, TStringBuf descr, TExprContext& ctx);
  409. class TItemExprType : public TTypeAnnotationNode {
  410. public:
  411. static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Item;
  412. TItemExprType(ui64 hash, const TStringBuf& name, const TTypeAnnotationNode* itemType)
  413. : TTypeAnnotationNode(KindValue, itemType->GetFlags(), hash, itemType->GetUsedPgExtensions())
  414. , Name(name)
  415. , ItemType(itemType)
  416. {
  417. }
  418. static ui64 MakeHash(const TStringBuf& name, const TTypeAnnotationNode* itemType) {
  419. ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Item;
  420. hash = StreamHash(name.size(), hash);
  421. hash = StreamHash(name.data(), name.size(), hash);
  422. return StreamHash(itemType->GetHash(), hash);
  423. }
  424. bool Validate(TPosition position, TExprContext& ctx) const;
  425. bool Validate(TPositionHandle position, TExprContext& ctx) const;
  426. const TStringBuf& GetName() const {
  427. return Name;
  428. }
  429. TStringBuf GetCleanName(bool isVirtual) const;
  430. const TTypeAnnotationNode* GetItemType() const {
  431. return ItemType;
  432. }
  433. bool operator==(const TItemExprType& other) const {
  434. return GetName() == other.GetName() && GetItemType() == other.GetItemType();
  435. }
  436. const TItemExprType* GetCleanItem(bool isVirtual, TExprContext& ctx) const;
  437. private:
  438. const TStringBuf Name;
  439. const TTypeAnnotationNode* ItemType;
  440. };
  441. class TStructExprType : public TTypeAnnotationNode {
  442. public:
  443. static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Struct;
  444. struct TItemLess {
  445. bool operator()(const TItemExprType* x, const TItemExprType* y) const {
  446. return x->GetName() < y->GetName();
  447. };
  448. bool operator()(const TItemExprType* x, const TStringBuf& y) const {
  449. return x->GetName() < y;
  450. };
  451. bool operator()(const TStringBuf& x, const TItemExprType* y) const {
  452. return x < y->GetName();
  453. };
  454. };
  455. TStructExprType(ui64 hash, const TVector<const TItemExprType*>& items)
  456. : TTypeAnnotationNode(KindValue, TypeNonComparable | CombineFlags(items), hash, CombinePgExtensions(items))
  457. , Items(items)
  458. {
  459. }
  460. static ui64 MakeHash(const TVector<const TItemExprType*>& items) {
  461. Y_DEBUG_ABORT_UNLESS(IsSorted(items.begin(), items.end(), TItemLess()));
  462. ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Struct;
  463. hash = StreamHash(items.size(), hash);
  464. for (const auto& item : items) {
  465. hash = StreamHash(item->GetHash(), hash);
  466. }
  467. return hash;
  468. }
  469. bool Validate(TPosition position, TExprContext& ctx) const;
  470. bool Validate(TPositionHandle position, TExprContext& ctx) const;
  471. size_t GetSize() const {
  472. return Items.size();
  473. }
  474. const TVector<const TItemExprType*>& GetItems() const {
  475. return Items;
  476. }
  477. TMaybe<ui32> FindItem(const TStringBuf& name) const {
  478. auto it = LowerBound(Items.begin(), Items.end(), name, TItemLess());
  479. if (it == Items.end() || (*it)->GetName() != name) {
  480. return TMaybe<ui32>();
  481. }
  482. return it - Items.begin();
  483. }
  484. TMaybe<ui32> FindItemI(const TStringBuf& name, bool* isVirtual) const {
  485. for (ui32 v = 0; v < 2; ++v) {
  486. if (isVirtual) {
  487. *isVirtual = v > 0;
  488. }
  489. auto nameToSearch = (v ? YqlVirtualPrefix : "") + name;
  490. auto strict = FindItem(nameToSearch);
  491. if (strict) {
  492. return strict;
  493. }
  494. TMaybe<ui32> ret;
  495. for (ui32 i = 0; i < Items.size(); ++i) {
  496. if (AsciiEqualsIgnoreCase(nameToSearch, Items[i]->GetName())) {
  497. if (ret) {
  498. return Nothing();
  499. }
  500. ret = i;
  501. }
  502. }
  503. if (ret) {
  504. return ret;
  505. }
  506. }
  507. return Nothing();
  508. }
  509. const TTypeAnnotationNode* FindItemType(const TStringBuf& name) const {
  510. const auto it = LowerBound(Items.begin(), Items.end(), name, TItemLess());
  511. if (it == Items.end() || (*it)->GetName() != name) {
  512. return nullptr;
  513. }
  514. return (*it)->GetItemType();
  515. }
  516. TMaybe<TStringBuf> FindMistype(const TStringBuf& name) const {
  517. for (const auto& item: Items) {
  518. if (NLevenshtein::Distance(name, item->GetName()) < DefaultMistypeDistance) {
  519. return item->GetName();
  520. }
  521. }
  522. return TMaybe<TStringBuf>();
  523. }
  524. bool operator==(const TStructExprType& other) const {
  525. if (GetSize() != other.GetSize()) {
  526. return false;
  527. }
  528. for (ui32 i = 0, e = GetSize(); i < e; ++i) {
  529. if (GetItems()[i] != other.GetItems()[i]) {
  530. return false;
  531. }
  532. }
  533. return true;
  534. }
  535. TString ToString() const {
  536. TStringBuilder sb;
  537. for (std::size_t i = 0; i < Items.size(); i++) {
  538. sb << i << ": " << Items[i]->GetName() << "(" << FormatType(Items[i]->GetItemType()) << ")";
  539. if (i != Items.size() - 1) {
  540. sb << ", ";
  541. }
  542. }
  543. return sb;
  544. }
  545. private:
  546. TVector<const TItemExprType*> Items;
  547. };
  548. class TListExprType : public TTypeAnnotationNode {
  549. public:
  550. static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::List;
  551. TListExprType(ui64 hash, const TTypeAnnotationNode* itemType)
  552. : TTypeAnnotationNode(KindValue, itemType->GetFlags() | TypeHasDynamicSize, hash, itemType->GetUsedPgExtensions())
  553. , ItemType(itemType)
  554. {
  555. }
  556. static ui64 MakeHash(const TTypeAnnotationNode* itemType) {
  557. ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::List;
  558. return StreamHash(itemType->GetHash(), hash);
  559. }
  560. const TTypeAnnotationNode* GetItemType() const {
  561. return ItemType;
  562. }
  563. bool operator==(const TListExprType& other) const {
  564. return GetItemType() == other.GetItemType();
  565. }
  566. private:
  567. const TTypeAnnotationNode* ItemType;
  568. };
  569. class TStreamExprType : public TTypeAnnotationNode {
  570. public:
  571. static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Stream;
  572. TStreamExprType(ui64 hash, const TTypeAnnotationNode* itemType)
  573. : TTypeAnnotationNode(KindValue, itemType->GetFlags() | TypeNonPersistable, hash, itemType->GetUsedPgExtensions())
  574. , ItemType(itemType)
  575. {
  576. }
  577. static ui64 MakeHash(const TTypeAnnotationNode* itemType) {
  578. ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Stream;
  579. return StreamHash(itemType->GetHash(), hash);
  580. }
  581. const TTypeAnnotationNode* GetItemType() const {
  582. return ItemType;
  583. }
  584. bool operator==(const TStreamExprType& other) const {
  585. return GetItemType() == other.GetItemType();
  586. }
  587. private:
  588. const TTypeAnnotationNode* ItemType;
  589. };
  590. class TFlowExprType : public TTypeAnnotationNode {
  591. public:
  592. static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Flow;
  593. TFlowExprType(ui64 hash, const TTypeAnnotationNode* itemType)
  594. : TTypeAnnotationNode(KindValue, itemType->GetFlags() | TypeNonPersistable, hash, itemType->GetUsedPgExtensions())
  595. , ItemType(itemType)
  596. {
  597. }
  598. static ui64 MakeHash(const TTypeAnnotationNode* itemType) {
  599. ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Flow;
  600. return StreamHash(itemType->GetHash(), hash);
  601. }
  602. const TTypeAnnotationNode* GetItemType() const {
  603. return ItemType;
  604. }
  605. bool operator==(const TFlowExprType& other) const {
  606. return GetItemType() == other.GetItemType();
  607. }
  608. private:
  609. const TTypeAnnotationNode* ItemType;
  610. };
  611. class TBlockExprType : public TTypeAnnotationNode {
  612. public:
  613. static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Block;
  614. TBlockExprType(ui64 hash, const TTypeAnnotationNode* itemType)
  615. : TTypeAnnotationNode(KindValue, itemType->GetFlags() | TypeNonPersistable, hash, itemType->GetUsedPgExtensions())
  616. , ItemType(itemType)
  617. {
  618. }
  619. static ui64 MakeHash(const TTypeAnnotationNode* itemType) {
  620. ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Block;
  621. return StreamHash(itemType->GetHash(), hash);
  622. }
  623. const TTypeAnnotationNode* GetItemType() const {
  624. return ItemType;
  625. }
  626. bool operator==(const TBlockExprType& other) const {
  627. return GetItemType() == other.GetItemType();
  628. }
  629. private:
  630. const TTypeAnnotationNode* ItemType;
  631. };
  632. class TScalarExprType : public TTypeAnnotationNode {
  633. public:
  634. static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Scalar;
  635. TScalarExprType(ui64 hash, const TTypeAnnotationNode* itemType)
  636. : TTypeAnnotationNode(KindValue, itemType->GetFlags() | TypeNonPersistable, hash, itemType->GetUsedPgExtensions())
  637. , ItemType(itemType)
  638. {
  639. }
  640. static ui64 MakeHash(const TTypeAnnotationNode* itemType) {
  641. ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Scalar;
  642. return StreamHash(itemType->GetHash(), hash);
  643. }
  644. const TTypeAnnotationNode* GetItemType() const {
  645. return ItemType;
  646. }
  647. bool operator==(const TScalarExprType& other) const {
  648. return GetItemType() == other.GetItemType();
  649. }
  650. private:
  651. const TTypeAnnotationNode* ItemType;
  652. };
  653. class TDataExprType : public TTypeAnnotationNode {
  654. public:
  655. static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Data;
  656. TDataExprType(ui64 hash, EDataSlot slot)
  657. : TTypeAnnotationNode(KindValue, GetFlags(slot), hash, 0)
  658. , Slot(slot)
  659. {
  660. }
  661. static ui32 GetFlags(EDataSlot slot) {
  662. ui32 ret = TypeHasManyValues;
  663. auto props = NUdf::GetDataTypeInfo(slot).Features;
  664. if (!(props & NUdf::CanHash)) {
  665. ret |= TypeNonHashable;
  666. }
  667. if (!(props & NUdf::CanEquate)) {
  668. ret |= TypeNonEquatable;
  669. }
  670. if (!(props & NUdf::CanCompare)) {
  671. ret |= TypeNonComparable;
  672. ret |= TypeNonComparableInternal;
  673. }
  674. if (slot == NUdf::EDataSlot::Yson) {
  675. ret |= TypeHasBareYson;
  676. }
  677. if (props & NUdf::StringType) {
  678. ret |= TypeHasDynamicSize;
  679. }
  680. return ret;
  681. }
  682. static ui64 MakeHash(EDataSlot slot) {
  683. ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Data;
  684. auto dataType = NUdf::GetDataTypeInfo(slot).Name;
  685. hash = StreamHash(dataType.size(), hash);
  686. return StreamHash(dataType.data(), dataType.size(), hash);
  687. }
  688. EDataSlot GetSlot() const {
  689. return Slot;
  690. }
  691. TStringBuf GetName() const {
  692. return NUdf::GetDataTypeInfo(Slot).Name;
  693. }
  694. bool operator==(const TDataExprType& other) const {
  695. return Slot == other.Slot;
  696. }
  697. private:
  698. EDataSlot Slot;
  699. };
  700. class TDataExprParamsType : public TDataExprType {
  701. public:
  702. TDataExprParamsType(ui64 hash, EDataSlot slot, const TStringBuf& one, const TStringBuf& two)
  703. : TDataExprType(hash, slot), One(one), Two(two)
  704. {}
  705. static ui64 MakeHash(EDataSlot slot, const TStringBuf& one, const TStringBuf& two) {
  706. auto hash = TDataExprType::MakeHash(slot);
  707. hash = StreamHash(one.size(), hash);
  708. hash = StreamHash(one.data(), one.size(), hash);
  709. hash = StreamHash(two.size(), hash);
  710. hash = StreamHash(two.data(), two.size(), hash);
  711. return hash;
  712. }
  713. const TStringBuf& GetParamOne() const {
  714. return One;
  715. }
  716. const TStringBuf& GetParamTwo() const {
  717. return Two;
  718. }
  719. bool operator==(const TDataExprParamsType& other) const {
  720. return GetSlot() == other.GetSlot() && GetParamOne() == other.GetParamOne() && GetParamTwo() == other.GetParamTwo();
  721. }
  722. bool Validate(TPosition position, TExprContext& ctx) const;
  723. bool Validate(TPositionHandle position, TExprContext& ctx) const;
  724. private:
  725. const TStringBuf One, Two;
  726. };
  727. class TPgExprType : public TTypeAnnotationNode {
  728. public:
  729. static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Pg;
  730. // TODO: TypeHasDynamicSize for Pg types
  731. TPgExprType(ui64 hash, ui32 typeId)
  732. : TTypeAnnotationNode(KindValue, GetFlags(typeId), hash, GetPgExtensionsMask(typeId))
  733. , TypeId(typeId)
  734. {
  735. }
  736. static ui64 MakeHash(ui32 typeId) {
  737. ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Pg;
  738. return StreamHash(typeId, hash);
  739. }
  740. const TString& GetName() const;
  741. ui32 GetId() const {
  742. return TypeId;
  743. }
  744. bool operator==(const TPgExprType& other) const {
  745. return TypeId == other.TypeId;
  746. }
  747. private:
  748. ui32 GetFlags(ui32 typeId);
  749. ui64 GetPgExtensionsMask(ui32 typeId);
  750. private:
  751. ui32 TypeId;
  752. };
  753. ui64 MakePgExtensionMask(ui32 extensionIndex);
  754. class TWorldExprType : public TTypeAnnotationNode {
  755. public:
  756. static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::World;
  757. TWorldExprType(ui64 hash)
  758. : TTypeAnnotationNode(KindValue,
  759. TypeNonComposable | TypeNonComputable | TypeNonPersistable | TypeNonInspectable, hash, 0)
  760. {
  761. }
  762. static ui64 MakeHash() {
  763. return TypeHashMagic | (ui64)ETypeAnnotationKind::World;
  764. }
  765. bool operator==(const TWorldExprType& other) const {
  766. Y_UNUSED(other);
  767. return true;
  768. }
  769. };
  770. class TOptionalExprType : public TTypeAnnotationNode {
  771. public:
  772. static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Optional;
  773. TOptionalExprType(ui64 hash, const TTypeAnnotationNode* itemType)
  774. : TTypeAnnotationNode(KindValue, GetFlags(itemType), hash, itemType->GetUsedPgExtensions())
  775. , ItemType(itemType)
  776. {
  777. }
  778. static ui32 GetFlags(const TTypeAnnotationNode* itemType) {
  779. auto ret = TypeHasOptional | itemType->GetFlags();
  780. if (itemType->GetKind() == ETypeAnnotationKind::Data &&
  781. itemType->Cast<TDataExprType>()->GetSlot() == NUdf::EDataSlot::Yson) {
  782. ret = ret & ~TypeHasBareYson;
  783. }
  784. if (itemType->IsOptionalOrNull()) {
  785. ret |= TypeHasNestedOptional;
  786. }
  787. return ret;
  788. }
  789. static ui64 MakeHash(const TTypeAnnotationNode* itemType) {
  790. ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Optional;
  791. return StreamHash(itemType->GetHash(), hash);
  792. }
  793. const TTypeAnnotationNode* GetItemType() const {
  794. return ItemType;
  795. }
  796. bool operator==(const TOptionalExprType& other) const {
  797. return GetItemType() == other.GetItemType();
  798. }
  799. private:
  800. const TTypeAnnotationNode* ItemType;
  801. };
  802. class TVariantExprType : public TTypeAnnotationNode {
  803. public:
  804. static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Variant;
  805. TVariantExprType(ui64 hash, const TTypeAnnotationNode* underlyingType)
  806. : TTypeAnnotationNode(KindValue, MakeFlags(underlyingType), hash, underlyingType->GetUsedPgExtensions())
  807. , UnderlyingType(underlyingType)
  808. {
  809. }
  810. static ui64 MakeHash(const TTypeAnnotationNode* underlyingType) {
  811. ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Variant;
  812. return StreamHash(underlyingType->GetHash(), hash);
  813. }
  814. const TTypeAnnotationNode* GetUnderlyingType() const {
  815. return UnderlyingType;
  816. }
  817. bool operator==(const TVariantExprType& other) const {
  818. return GetUnderlyingType() == other.GetUnderlyingType();
  819. }
  820. bool Validate(TPosition position, TExprContext& ctx) const;
  821. bool Validate(TPositionHandle position, TExprContext& ctx) const;
  822. static ui32 MakeFlags(const TTypeAnnotationNode* underlyingType);
  823. private:
  824. const TTypeAnnotationNode* UnderlyingType;
  825. };
  826. class TTypeExprType : public TTypeAnnotationNode {
  827. public:
  828. static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Type;
  829. TTypeExprType(ui64 hash, const TTypeAnnotationNode* type)
  830. : TTypeAnnotationNode(KindValue, TypeNonPersistable | TypeNonComputable, hash, 0)
  831. , Type(type)
  832. {
  833. }
  834. static ui64 MakeHash(const TTypeAnnotationNode* type) {
  835. ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Type;
  836. return StreamHash(type->GetHash(), hash);
  837. }
  838. const TTypeAnnotationNode* GetType() const {
  839. return Type;
  840. }
  841. bool operator==(const TTypeExprType& other) const {
  842. return GetType() == other.GetType();
  843. }
  844. private:
  845. const TTypeAnnotationNode* Type;
  846. };
  847. class TDictExprType : public TTypeAnnotationNode {
  848. public:
  849. static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Dict;
  850. TDictExprType(ui64 hash, const TTypeAnnotationNode* keyType, const TTypeAnnotationNode* payloadType)
  851. : TTypeAnnotationNode(KindValue, TypeNonComparable | TypeHasDynamicSize |
  852. keyType->GetFlags() | payloadType->GetFlags(), hash,
  853. keyType->GetUsedPgExtensions() | payloadType->GetUsedPgExtensions())
  854. , KeyType(keyType)
  855. , PayloadType(payloadType)
  856. {
  857. }
  858. static ui64 MakeHash(const TTypeAnnotationNode* keyType, const TTypeAnnotationNode* payloadType) {
  859. ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Dict;
  860. return StreamHash(StreamHash(keyType->GetHash(), hash), payloadType->GetHash());
  861. }
  862. bool Validate(TPosition position, TExprContext& ctx) const;
  863. bool Validate(TPositionHandle position, TExprContext& ctx) const;
  864. const TTypeAnnotationNode* GetKeyType() const {
  865. return KeyType;
  866. }
  867. const TTypeAnnotationNode* GetPayloadType() const {
  868. return PayloadType;
  869. }
  870. bool operator==(const TDictExprType& other) const {
  871. return GetKeyType() == other.GetKeyType() &&
  872. GetPayloadType() == other.GetPayloadType();
  873. }
  874. private:
  875. const TTypeAnnotationNode* KeyType;
  876. const TTypeAnnotationNode* PayloadType;
  877. };
  878. class TVoidExprType : public TTypeAnnotationNode {
  879. public:
  880. static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Void;
  881. TVoidExprType(ui64 hash)
  882. : TTypeAnnotationNode(KindValue, 0, hash, 0)
  883. {
  884. }
  885. static ui64 MakeHash() {
  886. return TypeHashMagic | (ui64)ETypeAnnotationKind::Void;
  887. }
  888. bool operator==(const TVoidExprType& other) const {
  889. Y_UNUSED(other);
  890. return true;
  891. }
  892. };
  893. class TNullExprType : public TTypeAnnotationNode {
  894. public:
  895. static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Null;
  896. TNullExprType(ui64 hash)
  897. : TTypeAnnotationNode(KindValue, TypeHasNull, hash, 0)
  898. {
  899. }
  900. static ui64 MakeHash() {
  901. return TypeHashMagic | (ui64)ETypeAnnotationKind::Null;
  902. }
  903. bool operator==(const TNullExprType& other) const {
  904. Y_UNUSED(other);
  905. return true;
  906. }
  907. };
  908. class TCallableExprType : public TTypeAnnotationNode {
  909. public:
  910. static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Callable;
  911. struct TArgumentInfo {
  912. const TTypeAnnotationNode* Type = nullptr;
  913. TStringBuf Name;
  914. ui64 Flags = 0;
  915. bool operator==(const TArgumentInfo& other) const {
  916. return Type == other.Type && Name == other.Name && Flags == other.Flags;
  917. }
  918. bool operator!=(const TArgumentInfo& other) const {
  919. return !(*this == other);
  920. }
  921. };
  922. TCallableExprType(ui64 hash, const TTypeAnnotationNode* returnType, const TVector<TArgumentInfo>& arguments
  923. , size_t optionalArgumentsCount, const TStringBuf& payload)
  924. : TTypeAnnotationNode(KindValue, MakeFlags(returnType), hash, returnType->GetUsedPgExtensions())
  925. , ReturnType(returnType)
  926. , Arguments(arguments)
  927. , OptionalArgumentsCount(optionalArgumentsCount)
  928. , Payload(payload)
  929. {
  930. for (ui32 i = 0; i < Arguments.size(); ++i) {
  931. const auto& arg = Arguments[i];
  932. if (!arg.Name.empty()) {
  933. IndexByName.insert({ arg.Name, i });
  934. }
  935. }
  936. }
  937. static ui64 MakeHash(const TTypeAnnotationNode* returnType, const TVector<TArgumentInfo>& arguments
  938. , size_t optionalArgumentsCount, const TStringBuf& payload) {
  939. ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Callable;
  940. hash = StreamHash(returnType->GetHash(), hash);
  941. hash = StreamHash(arguments.size(), hash);
  942. for (const auto& arg : arguments) {
  943. hash = StreamHash(arg.Name.size(), hash);
  944. hash = StreamHash(arg.Name.data(), arg.Name.size(), hash);
  945. hash = StreamHash(arg.Flags, hash);
  946. hash = StreamHash(arg.Type->GetHash(), hash);
  947. }
  948. hash = StreamHash(optionalArgumentsCount, hash);
  949. hash = StreamHash(payload.size(), hash);
  950. hash = StreamHash(payload.data(), payload.size(), hash);
  951. return hash;
  952. }
  953. const TTypeAnnotationNode* GetReturnType() const {
  954. return ReturnType;
  955. }
  956. size_t GetOptionalArgumentsCount() const {
  957. return OptionalArgumentsCount;
  958. }
  959. const TStringBuf& GetPayload() const {
  960. return Payload;
  961. }
  962. size_t GetArgumentsSize() const {
  963. return Arguments.size();
  964. }
  965. const TVector<TArgumentInfo>& GetArguments() const {
  966. return Arguments;
  967. }
  968. bool operator==(const TCallableExprType& other) const {
  969. if (GetArgumentsSize() != other.GetArgumentsSize()) {
  970. return false;
  971. }
  972. if (GetOptionalArgumentsCount() != other.GetOptionalArgumentsCount()) {
  973. return false;
  974. }
  975. if (GetReturnType() != other.GetReturnType()) {
  976. return false;
  977. }
  978. for (ui32 i = 0, e = GetArgumentsSize(); i < e; ++i) {
  979. if (GetArguments()[i] != other.GetArguments()[i]) {
  980. return false;
  981. }
  982. }
  983. return true;
  984. }
  985. bool Validate(TPosition position, TExprContext& ctx) const;
  986. bool Validate(TPositionHandle position, TExprContext& ctx) const;
  987. TMaybe<ui32> ArgumentIndexByName(const TStringBuf& name) const {
  988. auto it = IndexByName.find(name);
  989. if (it == IndexByName.end()) {
  990. return {};
  991. }
  992. return it->second;
  993. }
  994. private:
  995. static ui32 MakeFlags(const TTypeAnnotationNode* returnType) {
  996. ui32 flags = TypeNonPersistable;
  997. flags |= returnType->GetFlags();
  998. return flags;
  999. }
  1000. private:
  1001. const TTypeAnnotationNode* ReturnType;
  1002. TVector<TArgumentInfo> Arguments;
  1003. const size_t OptionalArgumentsCount;
  1004. const TStringBuf Payload;
  1005. THashMap<TStringBuf, ui32> IndexByName;
  1006. };
  1007. class TGenericExprType : public TTypeAnnotationNode {
  1008. public:
  1009. static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Generic;
  1010. TGenericExprType(ui64 hash)
  1011. : TTypeAnnotationNode(KindValue, TypeNonComputable, hash, 0)
  1012. {
  1013. }
  1014. static ui64 MakeHash() {
  1015. return TypeHashMagic | (ui64)ETypeAnnotationKind::Generic;
  1016. }
  1017. bool operator==(const TGenericExprType& other) const {
  1018. Y_UNUSED(other);
  1019. return true;
  1020. }
  1021. };
  1022. class TResourceExprType : public TTypeAnnotationNode {
  1023. public:
  1024. static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Resource;
  1025. TResourceExprType(ui64 hash, const TStringBuf& tag)
  1026. : TTypeAnnotationNode(KindValue, TypeNonPersistable | TypeHasManyValues, hash, 0)
  1027. , Tag(tag)
  1028. {}
  1029. static ui64 MakeHash(const TStringBuf& tag) {
  1030. ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Resource;
  1031. hash = StreamHash(tag.size(), hash);
  1032. return StreamHash(tag.data(), tag.size(), hash);
  1033. }
  1034. const TStringBuf& GetTag() const {
  1035. return Tag;
  1036. }
  1037. bool operator==(const TResourceExprType& other) const {
  1038. return Tag == other.Tag;
  1039. }
  1040. private:
  1041. const TStringBuf Tag;
  1042. };
  1043. class TTaggedExprType : public TTypeAnnotationNode {
  1044. public:
  1045. static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Tagged;
  1046. TTaggedExprType(ui64 hash, const TTypeAnnotationNode* baseType, const TStringBuf& tag)
  1047. : TTypeAnnotationNode(KindValue, baseType->GetFlags(), hash, baseType->GetUsedPgExtensions())
  1048. , BaseType(baseType)
  1049. , Tag(tag)
  1050. {}
  1051. static ui64 MakeHash(const TTypeAnnotationNode* baseType, const TStringBuf& tag) {
  1052. ui64 hash = TypeHashMagic | (ui64)ETypeAnnotationKind::Tagged;
  1053. hash = StreamHash(baseType->GetHash(), hash);
  1054. hash = StreamHash(tag.size(), hash);
  1055. return StreamHash(tag.data(), tag.size(), hash);
  1056. }
  1057. const TStringBuf& GetTag() const {
  1058. return Tag;
  1059. }
  1060. const TTypeAnnotationNode* GetBaseType() const {
  1061. return BaseType;
  1062. }
  1063. bool operator==(const TTaggedExprType& other) const {
  1064. return Tag == other.Tag && GetBaseType() == other.GetBaseType();
  1065. }
  1066. bool Validate(TPosition position, TExprContext& ctx) const;
  1067. bool Validate(TPositionHandle position, TExprContext& ctx) const;
  1068. private:
  1069. const TTypeAnnotationNode* BaseType;
  1070. const TStringBuf Tag;
  1071. };
  1072. class TErrorExprType : public TTypeAnnotationNode {
  1073. public:
  1074. static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::Error;
  1075. TErrorExprType(ui64 hash, const TIssue& error)
  1076. : TTypeAnnotationNode(KindValue, 0, hash, 0)
  1077. , Error(error)
  1078. {}
  1079. static ui64 MakeHash(const TIssue& error) {
  1080. return error.Hash();
  1081. }
  1082. const TIssue& GetError() const {
  1083. return Error;
  1084. }
  1085. bool operator==(const TErrorExprType& other) const {
  1086. return Error == other.Error;
  1087. }
  1088. private:
  1089. const TIssue Error;
  1090. };
  1091. class TEmptyListExprType : public TTypeAnnotationNode {
  1092. public:
  1093. static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::EmptyList;
  1094. TEmptyListExprType(ui64 hash)
  1095. : TTypeAnnotationNode(KindValue, 0, hash, 0)
  1096. {
  1097. }
  1098. static ui64 MakeHash() {
  1099. return TypeHashMagic | (ui64)ETypeAnnotationKind::EmptyList;
  1100. }
  1101. bool operator==(const TEmptyListExprType& other) const {
  1102. Y_UNUSED(other);
  1103. return true;
  1104. }
  1105. };
  1106. class TEmptyDictExprType : public TTypeAnnotationNode {
  1107. public:
  1108. static constexpr ETypeAnnotationKind KindValue = ETypeAnnotationKind::EmptyDict;
  1109. TEmptyDictExprType(ui64 hash)
  1110. : TTypeAnnotationNode(KindValue, 0, hash, 0)
  1111. {
  1112. }
  1113. static ui64 MakeHash() {
  1114. return TypeHashMagic | (ui64)ETypeAnnotationKind::EmptyDict;
  1115. }
  1116. bool operator==(const TEmptyDictExprType& other) const {
  1117. Y_UNUSED(other);
  1118. return true;
  1119. }
  1120. };
  1121. inline bool TTypeAnnotationNode::Equals(const TTypeAnnotationNode& node) const {
  1122. if (this == &node) {
  1123. return true;
  1124. }
  1125. if (Hash != node.GetHash()) {
  1126. return false;
  1127. }
  1128. if (Kind != node.GetKind()) {
  1129. return false;
  1130. }
  1131. switch (Kind) {
  1132. case ETypeAnnotationKind::Unit:
  1133. return static_cast<const TUnitExprType&>(*this) == static_cast<const TUnitExprType&>(node);
  1134. case ETypeAnnotationKind::Tuple:
  1135. return static_cast<const TTupleExprType&>(*this) == static_cast<const TTupleExprType&>(node);
  1136. case ETypeAnnotationKind::Struct:
  1137. return static_cast<const TStructExprType&>(*this) == static_cast<const TStructExprType&>(node);
  1138. case ETypeAnnotationKind::Item:
  1139. return static_cast<const TItemExprType&>(*this) == static_cast<const TItemExprType&>(node);
  1140. case ETypeAnnotationKind::List:
  1141. return static_cast<const TListExprType&>(*this) == static_cast<const TListExprType&>(node);
  1142. case ETypeAnnotationKind::Data:
  1143. return static_cast<const TDataExprType&>(*this) == static_cast<const TDataExprType&>(node);
  1144. case ETypeAnnotationKind::Pg:
  1145. return static_cast<const TPgExprType&>(*this) == static_cast<const TPgExprType&>(node);
  1146. case ETypeAnnotationKind::World:
  1147. return static_cast<const TWorldExprType&>(*this) == static_cast<const TWorldExprType&>(node);
  1148. case ETypeAnnotationKind::Optional:
  1149. return static_cast<const TOptionalExprType&>(*this) == static_cast<const TOptionalExprType&>(node);
  1150. case ETypeAnnotationKind::Type:
  1151. return static_cast<const TTypeExprType&>(*this) == static_cast<const TTypeExprType&>(node);
  1152. case ETypeAnnotationKind::Dict:
  1153. return static_cast<const TDictExprType&>(*this) == static_cast<const TDictExprType&>(node);
  1154. case ETypeAnnotationKind::Void:
  1155. return static_cast<const TVoidExprType&>(*this) == static_cast<const TVoidExprType&>(node);
  1156. case ETypeAnnotationKind::Null:
  1157. return static_cast<const TNullExprType&>(*this) == static_cast<const TNullExprType&>(node);
  1158. case ETypeAnnotationKind::Callable:
  1159. return static_cast<const TCallableExprType&>(*this) == static_cast<const TCallableExprType&>(node);
  1160. case ETypeAnnotationKind::Generic:
  1161. return static_cast<const TGenericExprType&>(*this) == static_cast<const TGenericExprType&>(node);
  1162. case ETypeAnnotationKind::Resource:
  1163. return static_cast<const TResourceExprType&>(*this) == static_cast<const TResourceExprType&>(node);
  1164. case ETypeAnnotationKind::Tagged:
  1165. return static_cast<const TTaggedExprType&>(*this) == static_cast<const TTaggedExprType&>(node);
  1166. case ETypeAnnotationKind::Error:
  1167. return static_cast<const TErrorExprType&>(*this) == static_cast<const TErrorExprType&>(node);
  1168. case ETypeAnnotationKind::Variant:
  1169. return static_cast<const TVariantExprType&>(*this) == static_cast<const TVariantExprType&>(node);
  1170. case ETypeAnnotationKind::Stream:
  1171. return static_cast<const TStreamExprType&>(*this) == static_cast<const TStreamExprType&>(node);
  1172. case ETypeAnnotationKind::Flow:
  1173. return static_cast<const TFlowExprType&>(*this) == static_cast<const TFlowExprType&>(node);
  1174. case ETypeAnnotationKind::EmptyList:
  1175. return static_cast<const TEmptyListExprType&>(*this) == static_cast<const TEmptyListExprType&>(node);
  1176. case ETypeAnnotationKind::EmptyDict:
  1177. return static_cast<const TEmptyDictExprType&>(*this) == static_cast<const TEmptyDictExprType&>(node);
  1178. case ETypeAnnotationKind::Multi:
  1179. return static_cast<const TMultiExprType&>(*this) == static_cast<const TMultiExprType&>(node);
  1180. case ETypeAnnotationKind::Block:
  1181. return static_cast<const TBlockExprType&>(*this) == static_cast<const TBlockExprType&>(node);
  1182. case ETypeAnnotationKind::Scalar:
  1183. return static_cast<const TScalarExprType&>(*this) == static_cast<const TScalarExprType&>(node);
  1184. case ETypeAnnotationKind::LastType:
  1185. YQL_ENSURE(false, "Incorrect type");
  1186. }
  1187. return false;
  1188. }
  1189. inline void TTypeAnnotationNode::Accept(TTypeAnnotationVisitor& visitor) const {
  1190. switch (Kind) {
  1191. case ETypeAnnotationKind::Unit:
  1192. return visitor.Visit(static_cast<const TUnitExprType&>(*this));
  1193. case ETypeAnnotationKind::Tuple:
  1194. return visitor.Visit(static_cast<const TTupleExprType&>(*this));
  1195. case ETypeAnnotationKind::Struct:
  1196. return visitor.Visit(static_cast<const TStructExprType&>(*this));
  1197. case ETypeAnnotationKind::Item:
  1198. return visitor.Visit(static_cast<const TItemExprType&>(*this));
  1199. case ETypeAnnotationKind::List:
  1200. return visitor.Visit(static_cast<const TListExprType&>(*this));
  1201. case ETypeAnnotationKind::Data:
  1202. return visitor.Visit(static_cast<const TDataExprType&>(*this));
  1203. case ETypeAnnotationKind::Pg:
  1204. return visitor.Visit(static_cast<const TPgExprType&>(*this));
  1205. case ETypeAnnotationKind::World:
  1206. return visitor.Visit(static_cast<const TWorldExprType&>(*this));
  1207. case ETypeAnnotationKind::Optional:
  1208. return visitor.Visit(static_cast<const TOptionalExprType&>(*this));
  1209. case ETypeAnnotationKind::Type:
  1210. return visitor.Visit(static_cast<const TTypeExprType&>(*this));
  1211. case ETypeAnnotationKind::Dict:
  1212. return visitor.Visit(static_cast<const TDictExprType&>(*this));
  1213. case ETypeAnnotationKind::Void:
  1214. return visitor.Visit(static_cast<const TVoidExprType&>(*this));
  1215. case ETypeAnnotationKind::Null:
  1216. return visitor.Visit(static_cast<const TNullExprType&>(*this));
  1217. case ETypeAnnotationKind::Callable:
  1218. return visitor.Visit(static_cast<const TCallableExprType&>(*this));
  1219. case ETypeAnnotationKind::Generic:
  1220. return visitor.Visit(static_cast<const TGenericExprType&>(*this));
  1221. case ETypeAnnotationKind::Resource:
  1222. return visitor.Visit(static_cast<const TResourceExprType&>(*this));
  1223. case ETypeAnnotationKind::Tagged:
  1224. return visitor.Visit(static_cast<const TTaggedExprType&>(*this));
  1225. case ETypeAnnotationKind::Error:
  1226. return visitor.Visit(static_cast<const TErrorExprType&>(*this));
  1227. case ETypeAnnotationKind::Variant:
  1228. return visitor.Visit(static_cast<const TVariantExprType&>(*this));
  1229. case ETypeAnnotationKind::Stream:
  1230. return visitor.Visit(static_cast<const TStreamExprType&>(*this));
  1231. case ETypeAnnotationKind::Flow:
  1232. return visitor.Visit(static_cast<const TFlowExprType&>(*this));
  1233. case ETypeAnnotationKind::EmptyList:
  1234. return visitor.Visit(static_cast<const TEmptyListExprType&>(*this));
  1235. case ETypeAnnotationKind::EmptyDict:
  1236. return visitor.Visit(static_cast<const TEmptyDictExprType&>(*this));
  1237. case ETypeAnnotationKind::Multi:
  1238. return visitor.Visit(static_cast<const TMultiExprType&>(*this));
  1239. case ETypeAnnotationKind::Block:
  1240. return visitor.Visit(static_cast<const TBlockExprType&>(*this));
  1241. case ETypeAnnotationKind::Scalar:
  1242. return visitor.Visit(static_cast<const TScalarExprType&>(*this));
  1243. case ETypeAnnotationKind::LastType:
  1244. YQL_ENSURE(false, "Incorrect type");
  1245. }
  1246. }
  1247. class TExprNode {
  1248. friend class TExprNodeBuilder;
  1249. friend class TExprNodeReplaceBuilder;
  1250. friend struct TExprContext;
  1251. private:
  1252. struct TExprFlags {
  1253. enum : ui16 {
  1254. Default = 0,
  1255. Dead = 0x01,
  1256. Frozen = 0x02,
  1257. };
  1258. static constexpr ui32 FlagsMask = 0x03; // all flags should fit here
  1259. };
  1260. public:
  1261. typedef TIntrusivePtr<TExprNode> TPtr;
  1262. typedef std::vector<TPtr> TListType;
  1263. typedef TArrayRef<const TPtr> TChildrenType;
  1264. struct TPtrHash : private std::hash<const TExprNode*> {
  1265. size_t operator()(const TPtr& p) const {
  1266. return std::hash<const TExprNode*>::operator()(p.Get());
  1267. }
  1268. };
  1269. #define YQL_EXPR_NODE_TYPE_MAP(xx) \
  1270. xx(List, 0) \
  1271. xx(Atom, 1) \
  1272. xx(Callable, 2) \
  1273. xx(Lambda, 3) \
  1274. xx(Argument, 4) \
  1275. xx(Arguments, 5) \
  1276. xx(World, 7)
  1277. enum EType : ui8 {
  1278. YQL_EXPR_NODE_TYPE_MAP(ENUM_VALUE_GEN)
  1279. };
  1280. static constexpr ui32 TypeMask = 0x07; // all types should fit here
  1281. #define YQL_EXPR_NODE_STATE_MAP(xx) \
  1282. xx(Initial, 0) \
  1283. xx(TypeInProgress, 1) \
  1284. xx(TypePending, 2) \
  1285. xx(TypeComplete, 3) \
  1286. xx(ConstrInProgress, 4) \
  1287. xx(ConstrPending, 5) \
  1288. xx(ConstrComplete, 6) \
  1289. xx(ExecutionRequired, 7) \
  1290. xx(ExecutionInProgress, 8) \
  1291. xx(ExecutionPending, 9) \
  1292. xx(ExecutionComplete, 10) \
  1293. xx(Error, 11) \
  1294. xx(Last, 12)
  1295. enum class EState : ui8 {
  1296. YQL_EXPR_NODE_STATE_MAP(ENUM_VALUE_GEN)
  1297. };
  1298. static TPtr GetResult(const TPtr& node) {
  1299. return node->Type() == Callable ? node->Result : node;
  1300. }
  1301. const TExprNode& GetResult() const {
  1302. ENSURE_NOT_DELETED
  1303. if (Type() != Callable) {
  1304. return *this;
  1305. }
  1306. YQL_ENSURE(Result);
  1307. return *Result;
  1308. }
  1309. bool HasResult() const {
  1310. ENSURE_NOT_DELETED
  1311. return Type() != Callable || bool(Result);
  1312. }
  1313. void SetResult(TPtr&& result) {
  1314. ENSURE_NOT_DELETED
  1315. ENSURE_NOT_FROZEN
  1316. Result = std::move(result);
  1317. }
  1318. bool IsCallable(const std::string_view& name) const {
  1319. ENSURE_NOT_DELETED
  1320. return Type() == TExprNode::Callable && Content() == name;
  1321. }
  1322. bool IsCallable(const std::initializer_list<std::string_view>& names) const {
  1323. ENSURE_NOT_DELETED
  1324. return Type() == TExprNode::Callable && names.end() != std::find(names.begin(), names.end(), Content());
  1325. }
  1326. template <class TKey>
  1327. bool IsCallable(const THashSet<TKey>& names) const {
  1328. ENSURE_NOT_DELETED
  1329. return Type() == TExprNode::Callable && names.contains(Content());
  1330. }
  1331. bool IsCallable() const {
  1332. ENSURE_NOT_DELETED
  1333. return Type() == TExprNode::Callable;
  1334. }
  1335. bool IsAtom() const {
  1336. ENSURE_NOT_DELETED
  1337. return Type() == TExprNode::Atom;
  1338. }
  1339. bool IsWorld() const {
  1340. ENSURE_NOT_DELETED
  1341. return Type() == TExprNode::World;
  1342. }
  1343. bool IsAtom(const std::string_view& content) const {
  1344. ENSURE_NOT_DELETED
  1345. return Type() == TExprNode::Atom && Content() == content;
  1346. }
  1347. bool IsAtom(const std::initializer_list<std::string_view>& names) const {
  1348. ENSURE_NOT_DELETED
  1349. return Type() == TExprNode::Atom && names.end() != std::find(names.begin(), names.end(), Content());
  1350. }
  1351. bool IsList() const {
  1352. ENSURE_NOT_DELETED
  1353. return Type() == TExprNode::List;
  1354. }
  1355. bool IsLambda() const {
  1356. ENSURE_NOT_DELETED
  1357. return Type() == TExprNode::Lambda;
  1358. }
  1359. bool IsArgument() const {
  1360. ENSURE_NOT_DELETED
  1361. return Type() == TExprNode::Argument;
  1362. }
  1363. bool IsArguments() const {
  1364. ENSURE_NOT_DELETED
  1365. return Type() == TExprNode::Arguments;
  1366. }
  1367. bool IsComposable() const {
  1368. ENSURE_NOT_DELETED
  1369. return !IsLambda() && TypeAnnotation_->IsComposable();
  1370. }
  1371. bool IsPersistable() const {
  1372. ENSURE_NOT_DELETED
  1373. return !IsLambda() && TypeAnnotation_->IsPersistable();
  1374. }
  1375. bool IsComputable() const {
  1376. ENSURE_NOT_DELETED
  1377. return !IsLambda() && TypeAnnotation_->IsComputable();
  1378. }
  1379. bool IsInspectable() const {
  1380. ENSURE_NOT_DELETED
  1381. return !IsLambda() && TypeAnnotation_->IsInspectable();
  1382. }
  1383. bool ForDisclosing() const {
  1384. ENSURE_NOT_DELETED
  1385. return Type() == TExprNode::List && ShallBeDisclosed;
  1386. }
  1387. void SetDisclosing() {
  1388. ENSURE_NOT_DELETED
  1389. Y_ENSURE(Type() == TExprNode::List, "Must be list.");
  1390. ShallBeDisclosed = true;
  1391. }
  1392. ui32 GetFlagsToCompare() const {
  1393. ENSURE_NOT_DELETED
  1394. ui32 ret = Flags();
  1395. if ((ret & TNodeFlags::BinaryContent) == 0) {
  1396. ret |= TNodeFlags::ArbitraryContent | TNodeFlags::MultilineContent;
  1397. }
  1398. return ret;
  1399. }
  1400. TString Dump() const;
  1401. bool StartsExecution() const {
  1402. ENSURE_NOT_DELETED
  1403. return State == EState::ExecutionComplete
  1404. || State == EState::ExecutionInProgress
  1405. || State == EState::ExecutionRequired
  1406. || State == EState::ExecutionPending;
  1407. }
  1408. bool IsComplete() const {
  1409. YQL_ENSURE(HasLambdaScope);
  1410. return !OuterLambda;
  1411. }
  1412. bool IsLiteralList() const {
  1413. YQL_ENSURE(IsList());
  1414. return LiteralList;
  1415. }
  1416. void SetLiteralList(bool literal) {
  1417. YQL_ENSURE(IsList());
  1418. LiteralList = literal;
  1419. }
  1420. void Ref() {
  1421. ENSURE_NOT_DELETED
  1422. ENSURE_NOT_FROZEN
  1423. Y_ENSURE(RefCount_ < Max<ui32>());
  1424. ++RefCount_;
  1425. }
  1426. void UnRef() {
  1427. ENSURE_NOT_DELETED
  1428. ENSURE_NOT_FROZEN
  1429. if (!--RefCount_) {
  1430. Result.Reset();
  1431. Children_.clear();
  1432. Constraints_.Clear();
  1433. MarkDead();
  1434. }
  1435. }
  1436. ui32 UseCount() const { return RefCount_; }
  1437. bool Unique() const { return 1U == UseCount(); }
  1438. bool Dead() const {
  1439. return ExprFlags_ & TExprFlags::Dead;
  1440. }
  1441. TPositionHandle Pos() const {
  1442. ENSURE_NOT_DELETED
  1443. return Position_;
  1444. }
  1445. TPosition Pos(const TExprContext& ctx) const;
  1446. EType Type() const {
  1447. ENSURE_NOT_DELETED
  1448. return (EType)Type_;
  1449. }
  1450. TListType::size_type ChildrenSize() const {
  1451. ENSURE_NOT_DELETED
  1452. return Children_.size();
  1453. }
  1454. TExprNode* Child(ui32 index) const {
  1455. ENSURE_NOT_DELETED
  1456. Y_ENSURE(index < Children_.size(), "index out of range");
  1457. return Children_[index].Get();
  1458. }
  1459. TPtr ChildPtr(ui32 index) const {
  1460. ENSURE_NOT_DELETED
  1461. Y_ENSURE(index < Children_.size(), "index out of range");
  1462. return Children_[index];
  1463. }
  1464. TPtr& ChildRef(ui32 index) {
  1465. ENSURE_NOT_DELETED
  1466. ENSURE_NOT_FROZEN
  1467. Y_ENSURE(index < Children_.size(), "index out of range");
  1468. return Children_[index];
  1469. }
  1470. const TExprNode& Head() const {
  1471. ENSURE_NOT_DELETED
  1472. Y_ENSURE(!Children_.empty(), "no children");
  1473. return *Children_.front();
  1474. }
  1475. TExprNode& Head() {
  1476. ENSURE_NOT_DELETED
  1477. Y_ENSURE(!Children_.empty(), "no children");
  1478. return *Children_.front();
  1479. }
  1480. TPtr HeadPtr() const {
  1481. ENSURE_NOT_DELETED
  1482. Y_ENSURE(!Children_.empty(), "no children");
  1483. return Children_.front();
  1484. }
  1485. TPtr& HeadRef() {
  1486. ENSURE_NOT_DELETED
  1487. ENSURE_NOT_FROZEN
  1488. Y_ENSURE(!Children_.empty(), "no children");
  1489. return Children_.front();
  1490. }
  1491. const TExprNode& Tail() const {
  1492. ENSURE_NOT_DELETED
  1493. Y_ENSURE(!Children_.empty(), "no children");
  1494. return *Children_.back();
  1495. }
  1496. TExprNode& Tail() {
  1497. ENSURE_NOT_DELETED
  1498. Y_ENSURE(!Children_.empty(), "no children");
  1499. return *Children_.back();
  1500. }
  1501. TPtr TailPtr() const {
  1502. ENSURE_NOT_DELETED
  1503. Y_ENSURE(!Children_.empty(), "no children");
  1504. return Children_.back();
  1505. }
  1506. TPtr& TailRef() {
  1507. ENSURE_NOT_DELETED
  1508. ENSURE_NOT_FROZEN
  1509. Y_ENSURE(!Children_.empty(), "no children");
  1510. return Children_.back();
  1511. }
  1512. TChildrenType Children() const {
  1513. ENSURE_NOT_DELETED
  1514. return TChildrenType(Children_.data(), Children_.size());
  1515. }
  1516. TListType ChildrenList() const {
  1517. ENSURE_NOT_DELETED
  1518. return Children_;
  1519. }
  1520. void ChangeChildrenInplace(TListType&& newChildren) {
  1521. ENSURE_NOT_DELETED
  1522. Children_ = std::move(newChildren);
  1523. }
  1524. template<class F>
  1525. void ForEachChild(const F& visitor) const {
  1526. for (const auto& child : Children_)
  1527. visitor(*child);
  1528. }
  1529. TStringBuf Content() const {
  1530. ENSURE_NOT_DELETED
  1531. return ContentUnchecked();
  1532. }
  1533. ui32 Flags() const {
  1534. ENSURE_NOT_DELETED
  1535. return Flags_;
  1536. }
  1537. void NormalizeAtomFlags(const TExprNode& otherAtom) {
  1538. ENSURE_NOT_DELETED
  1539. ENSURE_NOT_FROZEN
  1540. Y_ENSURE(Type_ == Atom && otherAtom.Type_ == Atom, "Expected atoms");
  1541. Y_ENSURE((Flags_ & TNodeFlags::BinaryContent) ==
  1542. (otherAtom.Flags_ & TNodeFlags::BinaryContent), "Mismatch binary atom flags");
  1543. if (!(Flags_ & TNodeFlags::BinaryContent)) {
  1544. Flags_ = Min(Flags_, otherAtom.Flags_);
  1545. }
  1546. }
  1547. ui64 UniqueId() const {
  1548. ENSURE_NOT_DELETED
  1549. return UniqueId_;
  1550. }
  1551. const TConstraintNode* GetConstraint(TStringBuf name) const {
  1552. ENSURE_NOT_DELETED
  1553. Y_ENSURE(static_cast<EState>(State) >= EState::ConstrComplete);
  1554. return Constraints_.GetConstraint(name);
  1555. }
  1556. template <class TConstraintType>
  1557. const TConstraintType* GetConstraint() const {
  1558. ENSURE_NOT_DELETED
  1559. Y_ENSURE(static_cast<EState>(State) >= EState::ConstrComplete);
  1560. return Constraints_.GetConstraint<TConstraintType>();
  1561. }
  1562. const TConstraintNode::TListType& GetAllConstraints() const {
  1563. ENSURE_NOT_DELETED
  1564. Y_ENSURE(static_cast<EState>(State) >= EState::ConstrComplete);
  1565. return Constraints_.GetAllConstraints();
  1566. }
  1567. const TConstraintSet& GetConstraintSet() const {
  1568. ENSURE_NOT_DELETED
  1569. Y_ENSURE(static_cast<EState>(State) >= EState::ConstrComplete);
  1570. return Constraints_;
  1571. }
  1572. void AddConstraint(const TConstraintNode* node) {
  1573. ENSURE_NOT_DELETED
  1574. ENSURE_NOT_FROZEN
  1575. Y_ENSURE(static_cast<EState>(State) >= EState::TypeComplete);
  1576. Y_ENSURE(!StartsExecution());
  1577. Constraints_.AddConstraint(node);
  1578. State = EState::ConstrComplete;
  1579. }
  1580. void CopyConstraints(const TExprNode& node) {
  1581. ENSURE_NOT_DELETED
  1582. ENSURE_NOT_FROZEN
  1583. Y_ENSURE(static_cast<EState>(State) >= EState::TypeComplete);
  1584. Constraints_ = node.Constraints_;
  1585. State = EState::ConstrComplete;
  1586. }
  1587. void SetConstraints(const TConstraintSet& constraints) {
  1588. ENSURE_NOT_DELETED
  1589. ENSURE_NOT_FROZEN
  1590. Y_ENSURE(static_cast<EState>(State) >= EState::TypeComplete);
  1591. Constraints_ = constraints;
  1592. State = EState::ConstrComplete;
  1593. }
  1594. static TPtr NewAtom(ui64 uniqueId, TPositionHandle pos, const TStringBuf& content, ui32 flags) {
  1595. return Make(pos, Atom, {}, content, flags, uniqueId);
  1596. }
  1597. static TPtr NewArgument(ui64 uniqueId, TPositionHandle pos, const TStringBuf& name) {
  1598. return Make(pos, Argument, {}, name, 0, uniqueId);
  1599. }
  1600. static TPtr NewArguments(ui64 uniqueId, TPositionHandle pos, TListType&& argNodes) {
  1601. return Make(pos, Arguments, std::move(argNodes), ZeroString, 0, uniqueId);
  1602. }
  1603. static TPtr NewLambda(ui64 uniqueId, TPositionHandle pos, TListType&& lambda) {
  1604. return Make(pos, Lambda, std::move(lambda), ZeroString, 0, uniqueId);
  1605. }
  1606. static TPtr NewLambda(ui64 uniqueId, TPositionHandle pos, TPtr&& args, TListType&& body) {
  1607. TListType lambda(body.size() + 1U);
  1608. lambda.front() = std::move(args);
  1609. std::move(body.rbegin(), body.rend(), lambda.rbegin());
  1610. return NewLambda(uniqueId, pos, std::move(lambda));
  1611. }
  1612. static TPtr NewLambda(ui64 uniqueId, TPositionHandle pos, TPtr&& args, TPtr&& body) {
  1613. TListType children(body ? 2 : 1);
  1614. children.front() = std::move(args);
  1615. if (body) {
  1616. children.back() = std::move(body);
  1617. }
  1618. return NewLambda(uniqueId, pos, std::move(children));
  1619. }
  1620. static TPtr NewWorld(ui64 uniqueId, TPositionHandle pos) {
  1621. return Make(pos, World, {}, {}, 0, uniqueId);
  1622. }
  1623. static TPtr NewList(ui64 uniqueId, TPositionHandle pos, TListType&& children) {
  1624. return Make(pos, List, std::move(children), ZeroString, 0, uniqueId);
  1625. }
  1626. static TPtr NewCallable(ui64 uniqueId, TPositionHandle pos, const TStringBuf& name, TListType&& children) {
  1627. return Make(pos, Callable, std::move(children), name, 0, uniqueId);
  1628. }
  1629. TPtr Clone(ui64 newUniqueId) const {
  1630. ENSURE_NOT_DELETED
  1631. return Make(Position_, (EType)Type_, TListType(Children_), Content(), Flags_, newUniqueId);
  1632. }
  1633. TPtr CloneWithPosition(ui64 newUniqueId, TPositionHandle pos) const {
  1634. ENSURE_NOT_DELETED
  1635. return Make(pos, (EType)Type_, TListType(Children_), Content(), Flags_, newUniqueId);
  1636. }
  1637. static TPtr NewNode(TPositionHandle position, EType type, TListType&& children, const TStringBuf& content, ui32 flags, ui64 uniqueId) {
  1638. return Make(position, type, std::move(children), content, flags, uniqueId);
  1639. }
  1640. TPtr ChangeContent(ui64 newUniqueId, const TStringBuf& content) const {
  1641. ENSURE_NOT_DELETED
  1642. return Make(Position_, (EType)Type_, TListType(Children_), content, Flags_, newUniqueId);
  1643. }
  1644. TPtr ChangeChildren(ui64 newUniqueId, TListType&& children) const {
  1645. ENSURE_NOT_DELETED
  1646. return Make(Position_, (EType)Type_, std::move(children), Content(), Flags_, newUniqueId);
  1647. }
  1648. TPtr ChangeChild(ui64 newUniqueId, ui32 index, TPtr&& child) const {
  1649. ENSURE_NOT_DELETED
  1650. Y_ENSURE(index < Children_.size(), "index out of range");
  1651. TListType newChildren(Children_);
  1652. newChildren[index] = std::move(child);
  1653. return Make(Position_, (EType)Type_, std::move(newChildren), Content(), Flags_, newUniqueId);
  1654. }
  1655. void SetTypeAnn(const TTypeAnnotationNode* typeAnn) {
  1656. TypeAnnotation_ = typeAnn;
  1657. State = TypeAnnotation_ ? EState::TypeComplete : EState::Initial;
  1658. }
  1659. const TTypeAnnotationNode* GetTypeAnn() const {
  1660. return TypeAnnotation_;
  1661. }
  1662. EState GetState() const {
  1663. return State;
  1664. }
  1665. void SetState(EState state) {
  1666. State = state;
  1667. }
  1668. ui32 GetArgIndex() const {
  1669. YQL_ENSURE(Type() == EType::Argument);
  1670. return ArgIndex;
  1671. }
  1672. void SetArgIndex(ui32 argIndex) {
  1673. YQL_ENSURE(Type() == EType::Argument);
  1674. YQL_ENSURE(argIndex <= Max<ui16>());
  1675. ArgIndex = (ui16)argIndex;
  1676. }
  1677. ui64 GetHash() const {
  1678. Y_DEBUG_ABORT_UNLESS(HashAbove == HashBelow);
  1679. return HashAbove;
  1680. }
  1681. void SetHash(ui64 hash) {
  1682. HashAbove = HashBelow = hash;
  1683. }
  1684. ui64 GetHashAbove() const {
  1685. return HashAbove;
  1686. }
  1687. void SetHashAbove(ui64 hash) {
  1688. HashAbove = hash;
  1689. }
  1690. ui64 GetHashBelow() const {
  1691. return HashBelow;
  1692. }
  1693. void SetHashBelow(ui64 hash) {
  1694. HashBelow = hash;
  1695. }
  1696. ui64 GetBloom() const {
  1697. return Bloom;
  1698. }
  1699. void SetBloom(ui64 bloom) {
  1700. Bloom = bloom;
  1701. }
  1702. // return pair of outer and inner lambda.
  1703. std::optional<std::pair<const TExprNode*, const TExprNode*>> GetDependencyScope() const {
  1704. if (HasLambdaScope) {
  1705. return std::make_pair(OuterLambda, InnerLambda);
  1706. }
  1707. return std::nullopt;
  1708. }
  1709. void SetDependencyScope(const TExprNode* outerLambda, const TExprNode* innerLambda) {
  1710. Y_DEBUG_ABORT_UNLESS(outerLambda == innerLambda || outerLambda->GetLambdaLevel() < innerLambda->GetLambdaLevel(), "Wrong scope of closures.");
  1711. HasLambdaScope = 1;
  1712. OuterLambda = outerLambda;
  1713. InnerLambda = innerLambda;
  1714. }
  1715. ui16 GetLambdaLevel() const { return LambdaLevel; }
  1716. void SetLambdaLevel(ui16 lambdaLevel) { LambdaLevel = lambdaLevel; }
  1717. bool IsUsedInDependsOn() const {
  1718. YQL_ENSURE(Type() == EType::Argument);
  1719. return UsedInDependsOn;
  1720. }
  1721. void SetUsedInDependsOn() {
  1722. YQL_ENSURE(Type() == EType::Argument);
  1723. UsedInDependsOn = 1;
  1724. }
  1725. void SetUnorderedChildren() {
  1726. YQL_ENSURE(Type() == EType::List || Type() == EType::Callable);
  1727. UnordChildren = 1;
  1728. }
  1729. bool UnorderedChildren() const {
  1730. YQL_ENSURE(Type() == EType::List || Type() == EType::Callable);
  1731. return bool(UnordChildren);
  1732. }
  1733. ~TExprNode() {
  1734. Y_ABORT_UNLESS(Dead(), "Node (id: %lu, type: %s, content: '%s') not dead on destruction.",
  1735. UniqueId_, ToString(Type_).data(), TString(ContentUnchecked()).data());
  1736. Y_ABORT_UNLESS(!UseCount(), "Node (id: %lu, type: %s, content: '%s') has non-zero use count on destruction.",
  1737. UniqueId_, ToString(Type_).data(), TString(ContentUnchecked()).data());
  1738. }
  1739. private:
  1740. static TPtr Make(TPositionHandle position, EType type, TListType&& children, const TStringBuf& content, ui32 flags, ui64 uniqueId) {
  1741. Y_ENSURE(flags <= TNodeFlags::FlagsMask);
  1742. Y_ENSURE(children.size() <= Max<ui32>());
  1743. Y_ENSURE(content.size() <= Max<ui32>());
  1744. for (size_t i = 0; i < children.size(); ++i) {
  1745. Y_ENSURE(children[i], "Unable to create node " << content << ": " << i << "th child is null");
  1746. }
  1747. return TPtr(new TExprNode(position, type, std::move(children), content.data(), ui32(content.size()), flags, uniqueId));
  1748. }
  1749. TExprNode(TPositionHandle position, EType type, TListType&& children,
  1750. const char* content, ui32 contentSize, ui32 flags, ui64 uniqueId)
  1751. : Children_(std::move(children))
  1752. , Content_(content)
  1753. , UniqueId_(uniqueId)
  1754. , Position_(position)
  1755. , ContentSize(contentSize)
  1756. , Type_(type)
  1757. , Flags_(flags)
  1758. , ExprFlags_(TExprFlags::Default)
  1759. , State(EState::Initial)
  1760. , HasLambdaScope(0)
  1761. , UsedInDependsOn(0)
  1762. , UnordChildren(0)
  1763. , ShallBeDisclosed(0)
  1764. , LiteralList(0)
  1765. {}
  1766. TExprNode(const TExprNode&) = delete;
  1767. TExprNode(TExprNode&&) = delete;
  1768. TExprNode& operator=(const TExprNode&) = delete;
  1769. TExprNode& operator=(TExprNode&&) = delete;
  1770. bool Frozen() const {
  1771. return ExprFlags_ & TExprFlags::Frozen;
  1772. }
  1773. void MarkFrozen(bool frozen = true) {
  1774. if (frozen) {
  1775. ExprFlags_ |= TExprFlags::Frozen;
  1776. } else {
  1777. ExprFlags_ &= ~TExprFlags::Frozen;
  1778. }
  1779. }
  1780. void MarkDead() {
  1781. ExprFlags_ |= TExprFlags::Dead;
  1782. }
  1783. TStringBuf ContentUnchecked() const {
  1784. return TStringBuf(Content_, ContentSize);
  1785. }
  1786. TListType Children_;
  1787. TConstraintSet Constraints_;
  1788. const char* Content_ = nullptr;
  1789. const TExprNode* OuterLambda = nullptr;
  1790. const TExprNode* InnerLambda = nullptr;
  1791. TPtr Result;
  1792. ui64 HashAbove = 0ULL;
  1793. ui64 HashBelow = 0ULL;
  1794. ui64 Bloom = 0ULL;
  1795. const ui64 UniqueId_;
  1796. const TTypeAnnotationNode* TypeAnnotation_ = nullptr;
  1797. const TPositionHandle Position_;
  1798. ui32 RefCount_ = 0U;
  1799. const ui32 ContentSize;
  1800. ui16 ArgIndex = ui16(-1);
  1801. ui16 LambdaLevel = 0; // filled together with OuterLambda
  1802. ui16 IntermediateHashesCount = 0;
  1803. static_assert(TypeMask <= 7, "EType wont fit in 3 bits, increase Type_ bitfield size");
  1804. static_assert(TNodeFlags::FlagsMask <= 7, "TNodeFlags wont fit in 3 bits, increase Flags_ bitfield size");
  1805. static_assert(TExprFlags::FlagsMask <= 3, "TExprFlags wont fit in 2 bits, increase ExprFlags_ bitfield size");
  1806. static_assert(int(EState::Last) <= 16, "EState wont fit in 4 bits, increase State bitfield size");
  1807. struct {
  1808. ui8 Type_ : 3;
  1809. ui8 Flags_ : 3;
  1810. ui8 ExprFlags_ : 2;
  1811. EState State : 4;
  1812. ui8 HasLambdaScope : 1;
  1813. ui8 UsedInDependsOn : 1;
  1814. ui8 UnordChildren : 1;
  1815. ui8 ShallBeDisclosed: 1;
  1816. ui8 LiteralList : 1;
  1817. };
  1818. };
  1819. class TExportTable {
  1820. public:
  1821. using TSymbols = THashMap<TString, TExprNode::TPtr>;
  1822. TExportTable() = default;
  1823. TExportTable(TExprContext& ctx, TSymbols&& symbols)
  1824. : Symbols_(std::move(symbols))
  1825. , Ctx_(&ctx)
  1826. {}
  1827. const TSymbols& Symbols() const {
  1828. return Symbols_;
  1829. }
  1830. TSymbols& Symbols(TExprContext& ctx) {
  1831. if (Ctx_) {
  1832. YQL_ENSURE(Ctx_ == &ctx);
  1833. } else {
  1834. Ctx_ = &ctx;
  1835. }
  1836. return Symbols_;
  1837. }
  1838. TExprContext& ExprCtx() const {
  1839. YQL_ENSURE(Ctx_);
  1840. return *Ctx_;
  1841. }
  1842. private:
  1843. TSymbols Symbols_;
  1844. TExprContext* Ctx_ = nullptr;
  1845. };
  1846. using TModulesTable = THashMap<TString, TExportTable>;
  1847. class IModuleResolver {
  1848. public:
  1849. typedef std::shared_ptr<IModuleResolver> TPtr;
  1850. virtual bool AddFromFile(const std::string_view& file, TExprContext& ctx, ui16 syntaxVersion, ui32 packageVersion, TPosition pos = {}) = 0;
  1851. virtual bool AddFromUrl(const std::string_view& file, const std::string_view& url, const std::string_view& tokenName, TExprContext& ctx, ui16 syntaxVersion, ui32 packageVersion, TPosition pos = {}) = 0;
  1852. virtual bool AddFromMemory(const std::string_view& file, const TString& body, TExprContext& ctx, ui16 syntaxVersion, ui32 packageVersion, TPosition pos = {}) = 0;
  1853. virtual bool AddFromMemory(const std::string_view& file, const TString& body, TExprContext& ctx, ui16 syntaxVersion, ui32 packageVersion, TPosition pos, TString& moduleName, std::vector<TString>* exports = nullptr, std::vector<TString>* imports = nullptr) = 0;
  1854. virtual bool Link(TExprContext& ctx) = 0;
  1855. virtual void UpdateNextUniqueId(TExprContext& ctx) const = 0;
  1856. virtual ui64 GetNextUniqueId() const = 0;
  1857. virtual void RegisterPackage(const TString& package) = 0;
  1858. virtual bool SetPackageDefaultVersion(const TString& package, ui32 version) = 0;
  1859. virtual const TExportTable* GetModule(const TString& module) const = 0;
  1860. virtual void WriteStatistics(NYson::TYsonWriter& writer) = 0;
  1861. /*
  1862. Create new resolver which will use already collected modules in readonly manner.
  1863. Parent resolver should be alive while using child due to raw data sharing.
  1864. */
  1865. virtual IModuleResolver::TPtr CreateMutableChild() const = 0;
  1866. virtual void SetFileAliasPrefix(TString&& prefix) = 0;
  1867. virtual TString GetFileAliasPrefix() const = 0;
  1868. virtual ~IModuleResolver() = default;
  1869. };
  1870. struct TExprStep {
  1871. enum ELevel {
  1872. Params,
  1873. ExpandApplyForLambdas,
  1874. ValidateProviders,
  1875. Configure,
  1876. ExprEval,
  1877. DiscoveryIO,
  1878. Epochs,
  1879. Intents,
  1880. LoadTablesMetadata,
  1881. RewriteIO,
  1882. Recapture,
  1883. LastLevel
  1884. };
  1885. TExprStep()
  1886. {
  1887. }
  1888. void Done(ELevel level) {
  1889. Steps_.Set(level);
  1890. }
  1891. void Reset() {
  1892. Steps_.Reset();
  1893. }
  1894. TExprStep& Repeat(ELevel level) {
  1895. Steps_.Reset(level);
  1896. return *this;
  1897. }
  1898. bool IsDone(ELevel level) {
  1899. return Steps_.Test(level);
  1900. }
  1901. private:
  1902. TEnumBitSet<ELevel, Params, LastLevel> Steps_;
  1903. };
  1904. template <typename T>
  1905. struct TMakeTypeImpl;
  1906. template <class T>
  1907. using TNodeMap = std::unordered_map<const TExprNode*, T>;
  1908. using TNodeSet = std::unordered_set<const TExprNode*>;
  1909. using TNodeOnNodeOwnedMap = TNodeMap<TExprNode::TPtr>;
  1910. using TParentsMap = TNodeMap<TNodeSet>;
  1911. using TNodeMultiSet = std::unordered_multiset<const TExprNode*>;
  1912. using TParentsMultiMap = TNodeMap<TNodeMultiSet>;
  1913. template <>
  1914. struct TMakeTypeImpl<TVoidExprType> {
  1915. static const TVoidExprType* Make(TExprContext& ctx);
  1916. };
  1917. template <>
  1918. struct TMakeTypeImpl<TNullExprType> {
  1919. static const TNullExprType* Make(TExprContext& ctx);
  1920. };
  1921. template <>
  1922. struct TMakeTypeImpl<TEmptyListExprType> {
  1923. static const TEmptyListExprType* Make(TExprContext& ctx);
  1924. };
  1925. template <>
  1926. struct TMakeTypeImpl<TEmptyDictExprType> {
  1927. static const TEmptyDictExprType* Make(TExprContext& ctx);
  1928. };
  1929. template <>
  1930. struct TMakeTypeImpl<TUnitExprType> {
  1931. static const TUnitExprType* Make(TExprContext& ctx);
  1932. };
  1933. template <>
  1934. struct TMakeTypeImpl<TWorldExprType> {
  1935. static const TWorldExprType* Make(TExprContext& ctx);
  1936. };
  1937. template <>
  1938. struct TMakeTypeImpl<TGenericExprType> {
  1939. static const TGenericExprType* Make(TExprContext& ctx);
  1940. };
  1941. template <>
  1942. struct TMakeTypeImpl<TItemExprType> {
  1943. static const TItemExprType* Make(TExprContext& ctx, const TStringBuf& name, const TTypeAnnotationNode* itemType);
  1944. };
  1945. template <>
  1946. struct TMakeTypeImpl<TListExprType> {
  1947. static const TListExprType* Make(TExprContext& ctx, const TTypeAnnotationNode* itemType);
  1948. };
  1949. template <>
  1950. struct TMakeTypeImpl<TOptionalExprType> {
  1951. static const TOptionalExprType* Make(TExprContext& ctx, const TTypeAnnotationNode* itemType);
  1952. };
  1953. template <>
  1954. struct TMakeTypeImpl<TVariantExprType> {
  1955. static const TVariantExprType* Make(TExprContext& ctx, const TTypeAnnotationNode* underlyingType);
  1956. };
  1957. template <>
  1958. struct TMakeTypeImpl<TErrorExprType> {
  1959. static const TErrorExprType* Make(TExprContext& ctx, const TIssue& error);
  1960. };
  1961. template <>
  1962. struct TMakeTypeImpl<TDictExprType> {
  1963. static const TDictExprType* Make(TExprContext& ctx, const TTypeAnnotationNode* keyType,
  1964. const TTypeAnnotationNode* payloadType);
  1965. };
  1966. template <>
  1967. struct TMakeTypeImpl<TTypeExprType> {
  1968. static const TTypeExprType* Make(TExprContext& ctx, const TTypeAnnotationNode* baseType);
  1969. };
  1970. template <>
  1971. struct TMakeTypeImpl<TDataExprType> {
  1972. static const TDataExprType* Make(TExprContext& ctx, EDataSlot slot);
  1973. };
  1974. template <>
  1975. struct TMakeTypeImpl<TPgExprType> {
  1976. static const TPgExprType* Make(TExprContext& ctx, ui32 typeId);
  1977. };
  1978. template <>
  1979. struct TMakeTypeImpl<TDataExprParamsType> {
  1980. static const TDataExprParamsType* Make(TExprContext& ctx, EDataSlot slot, const TStringBuf& one, const TStringBuf& two);
  1981. };
  1982. template <>
  1983. struct TMakeTypeImpl<TCallableExprType> {
  1984. static const TCallableExprType* Make(
  1985. TExprContext& ctx, const TTypeAnnotationNode* returnType, const TVector<TCallableExprType::TArgumentInfo>& arguments,
  1986. size_t optionalArgumentsCount, const TStringBuf& payload);
  1987. };
  1988. template <>
  1989. struct TMakeTypeImpl<TResourceExprType> {
  1990. static const TResourceExprType* Make(TExprContext& ctx, const TStringBuf& tag);
  1991. };
  1992. template <>
  1993. struct TMakeTypeImpl<TTaggedExprType> {
  1994. static const TTaggedExprType* Make(TExprContext& ctx, const TTypeAnnotationNode* baseType, const TStringBuf& tag);
  1995. };
  1996. template <>
  1997. struct TMakeTypeImpl<TStructExprType> {
  1998. static const TStructExprType* Make(TExprContext& ctx, const TVector<const TItemExprType*>& items);
  1999. };
  2000. template <>
  2001. struct TMakeTypeImpl<TTupleExprType> {
  2002. static const TTupleExprType* Make(TExprContext& ctx, const TTypeAnnotationNode::TListType& items);
  2003. };
  2004. template <>
  2005. struct TMakeTypeImpl<TMultiExprType> {
  2006. static const TMultiExprType* Make(TExprContext& ctx, const TTypeAnnotationNode::TListType& items);
  2007. };
  2008. template <>
  2009. struct TMakeTypeImpl<TStreamExprType> {
  2010. static const TStreamExprType* Make(TExprContext& ctx, const TTypeAnnotationNode* itemType);
  2011. };
  2012. template <>
  2013. struct TMakeTypeImpl<TFlowExprType> {
  2014. static const TFlowExprType* Make(TExprContext& ctx, const TTypeAnnotationNode* itemType);
  2015. };
  2016. template <>
  2017. struct TMakeTypeImpl<TBlockExprType> {
  2018. static const TBlockExprType* Make(TExprContext& ctx, const TTypeAnnotationNode* itemType);
  2019. };
  2020. template <>
  2021. struct TMakeTypeImpl<TScalarExprType> {
  2022. static const TScalarExprType* Make(TExprContext& ctx, const TTypeAnnotationNode* itemType);
  2023. };
  2024. using TSingletonTypeCache = std::tuple<
  2025. const TVoidExprType*,
  2026. const TNullExprType*,
  2027. const TUnitExprType*,
  2028. const TEmptyListExprType*,
  2029. const TEmptyDictExprType*,
  2030. const TWorldExprType*,
  2031. const TGenericExprType*,
  2032. const TTupleExprType*,
  2033. const TStructExprType*,
  2034. const TMultiExprType*
  2035. >;
  2036. struct TExprContext : private TNonCopyable {
  2037. class TFreezeGuard {
  2038. public:
  2039. TFreezeGuard(const TFreezeGuard&) = delete;
  2040. TFreezeGuard& operator=(const TFreezeGuard&) = delete;
  2041. TFreezeGuard(TExprContext& ctx)
  2042. : Ctx(ctx)
  2043. {
  2044. Ctx.Freeze();
  2045. }
  2046. ~TFreezeGuard() {
  2047. Ctx.UnFreeze();
  2048. }
  2049. private:
  2050. TExprContext& Ctx;
  2051. };
  2052. TIssueManager IssueManager;
  2053. TNodeMap<TIssues> AssociativeIssues;
  2054. TMemoryPool StringPool;
  2055. std::unordered_set<std::string_view> Strings;
  2056. std::unordered_map<ui32, std::string_view> Indexes;
  2057. std::stack<std::unique_ptr<const TTypeAnnotationNode>> TypeNodes;
  2058. std::stack<std::unique_ptr<const TConstraintNode>> ConstraintNodes;
  2059. std::deque<std::unique_ptr<TExprNode>> ExprNodes;
  2060. TSingletonTypeCache SingletonTypeCache;
  2061. std::unordered_set<const TTypeAnnotationNode*, TTypeAnnotationNode::THash, TTypeAnnotationNode::TEqual> TypeSet;
  2062. std::unordered_set<const TConstraintNode*, TConstraintNode::THash, TConstraintNode::TEqual> ConstraintSet;
  2063. std::unordered_map<const TTypeAnnotationNode*, TExprNode::TPtr> TypeAsNodeCache;
  2064. std::unordered_set<TStringBuf, THash<TStringBuf>> DisabledConstraints;
  2065. ui64 NextUniqueId = 0;
  2066. ui64 NodeAllocationCounter = 0;
  2067. ui64 NodesAllocationLimit = 3000000;
  2068. ui64 StringsAllocationLimit = 100000000;
  2069. ui64 RepeatTransformLimit = 1000000;
  2070. ui64 RepeatTransformCounter = 0;
  2071. ui64 TypeAnnNodeRepeatLimit = 1000;
  2072. TGcNodeConfig GcConfig;
  2073. std::unordered_multimap<ui64, TExprNode*> UniqueNodes;
  2074. TExprStep Step;
  2075. bool Frozen;
  2076. explicit TExprContext(ui64 nextUniqueId = 0ULL);
  2077. ~TExprContext();
  2078. ui64 AllocateNextUniqueId() {
  2079. ENSURE_NOT_FROZEN_CTX
  2080. const auto ret = ++NextUniqueId;
  2081. return ret;
  2082. }
  2083. TStringBuf AppendString(const TStringBuf& buf) {
  2084. ENSURE_NOT_FROZEN_CTX
  2085. if (buf.size() == 0) {
  2086. return ZeroString;
  2087. }
  2088. auto it = Strings.find(buf);
  2089. if (it != Strings.end()) {
  2090. return *it;
  2091. }
  2092. auto newBuf = StringPool.AppendString(buf);
  2093. Strings.insert(it, newBuf);
  2094. return newBuf;
  2095. }
  2096. TPositionHandle AppendPosition(const TPosition& pos);
  2097. TPosition GetPosition(TPositionHandle handle) const;
  2098. TExprNodeBuilder Builder(TPositionHandle pos) {
  2099. return TExprNodeBuilder(pos, *this);
  2100. }
  2101. [[nodiscard]]
  2102. TExprNode::TPtr RenameNode(const TExprNode& node, const TStringBuf& name);
  2103. [[nodiscard]]
  2104. TExprNode::TPtr ShallowCopy(const TExprNode& node);
  2105. [[nodiscard]]
  2106. TExprNode::TPtr ShallowCopyWithPosition(const TExprNode& node, TPositionHandle pos);
  2107. [[nodiscard]]
  2108. TExprNode::TPtr ChangeChildren(const TExprNode& node, TExprNode::TListType&& children);
  2109. [[nodiscard]]
  2110. TExprNode::TPtr ChangeChild(const TExprNode& node, ui32 index, TExprNode::TPtr&& child);
  2111. [[nodiscard]]
  2112. TExprNode::TPtr ExactChangeChildren(const TExprNode& node, TExprNode::TListType&& children);
  2113. [[nodiscard]]
  2114. TExprNode::TPtr ExactShallowCopy(const TExprNode& node);
  2115. [[nodiscard]]
  2116. TExprNode::TPtr DeepCopyLambda(const TExprNode& node, TExprNode::TListType&& body);
  2117. [[nodiscard]]
  2118. TExprNode::TPtr DeepCopyLambda(const TExprNode& node, TExprNode::TPtr&& body = TExprNode::TPtr());
  2119. [[nodiscard]]
  2120. TExprNode::TPtr FuseLambdas(const TExprNode& outer, const TExprNode& inner);
  2121. using TCustomDeepCopier = std::function<bool(const TExprNode& node, TExprNode::TListType& newChildren)>;
  2122. [[nodiscard]]
  2123. TExprNode::TPtr DeepCopy(const TExprNode& node, TExprContext& nodeContext, TNodeOnNodeOwnedMap& deepClones,
  2124. bool internStrings, bool copyTypes, bool copyResult = false, TCustomDeepCopier customCopier = {});
  2125. [[nodiscard]]
  2126. TExprNode::TPtr SwapWithHead(const TExprNode& node);
  2127. TExprNode::TPtr ReplaceNode(TExprNode::TPtr&& start, const TExprNode& src, TExprNode::TPtr dst);
  2128. TExprNode::TPtr ReplaceNodes(TExprNode::TPtr&& start, const TNodeOnNodeOwnedMap& replaces);
  2129. template<bool KeepTypeAnns = false>
  2130. TExprNode::TListType ReplaceNodes(TExprNode::TListType&& start, const TNodeOnNodeOwnedMap& replaces);
  2131. TExprNode::TPtr NewAtom(TPositionHandle pos, const TStringBuf& content, ui32 flags = TNodeFlags::ArbitraryContent) {
  2132. ++NodeAllocationCounter;
  2133. const auto node = TExprNode::NewAtom(AllocateNextUniqueId(), pos, AppendString(content), flags);
  2134. ExprNodes.emplace_back(node.Get());
  2135. return node;
  2136. }
  2137. TExprNode::TPtr NewAtom(TPositionHandle pos, ui32 index) {
  2138. ++NodeAllocationCounter;
  2139. const auto node = TExprNode::NewAtom(AllocateNextUniqueId(), pos, GetIndexAsString(index), TNodeFlags::Default);
  2140. ExprNodes.emplace_back(node.Get());
  2141. return node;
  2142. }
  2143. TExprNode::TPtr NewArgument(TPositionHandle pos, const TStringBuf& name) {
  2144. ++NodeAllocationCounter;
  2145. const auto node = TExprNode::NewArgument(AllocateNextUniqueId(), pos, AppendString(name));
  2146. ExprNodes.emplace_back(node.Get());
  2147. return node;
  2148. }
  2149. TExprNode::TPtr NewArguments(TPositionHandle pos, TExprNode::TListType&& argNodes) {
  2150. ++NodeAllocationCounter;
  2151. const auto node = TExprNode::NewArguments(AllocateNextUniqueId(), pos, std::move(argNodes));
  2152. ExprNodes.emplace_back(node.Get());
  2153. return node;
  2154. }
  2155. TExprNode::TPtr NewLambda(TPositionHandle pos, TExprNode::TListType&& lambda) {
  2156. ++NodeAllocationCounter;
  2157. const auto node = TExprNode::NewLambda(AllocateNextUniqueId(), pos, std::move(lambda));
  2158. ExprNodes.emplace_back(node.Get());
  2159. return node;
  2160. }
  2161. TExprNode::TPtr NewLambda(TPositionHandle pos, TExprNode::TPtr&& args, TExprNode::TListType&& body) {
  2162. ++NodeAllocationCounter;
  2163. const auto node = TExprNode::NewLambda(AllocateNextUniqueId(), pos, std::move(args), std::move(body));
  2164. ExprNodes.emplace_back(node.Get());
  2165. return node;
  2166. }
  2167. TExprNode::TPtr NewLambda(TPositionHandle pos, TExprNode::TPtr&& args, TExprNode::TPtr&& body) {
  2168. ++NodeAllocationCounter;
  2169. const auto node = TExprNode::NewLambda(AllocateNextUniqueId(), pos, std::move(args), std::move(body));
  2170. ExprNodes.emplace_back(node.Get());
  2171. return node;
  2172. }
  2173. TExprNode::TPtr NewWorld(TPositionHandle pos) {
  2174. ++NodeAllocationCounter;
  2175. const auto node = TExprNode::NewWorld(AllocateNextUniqueId(), pos);
  2176. ExprNodes.emplace_back(node.Get());
  2177. return node;
  2178. }
  2179. TExprNode::TPtr NewList(TPositionHandle pos, TExprNode::TListType&& children) {
  2180. ++NodeAllocationCounter;
  2181. const auto node = TExprNode::NewList(AllocateNextUniqueId(), pos, std::move(children));
  2182. ExprNodes.emplace_back(node.Get());
  2183. return node;
  2184. }
  2185. TExprNode::TPtr NewCallable(TPositionHandle pos, const TStringBuf& name, TExprNode::TListType&& children) {
  2186. ++NodeAllocationCounter;
  2187. const auto node = TExprNode::NewCallable(AllocateNextUniqueId(), pos, AppendString(name), std::move(children));
  2188. ExprNodes.emplace_back(node.Get());
  2189. return node;
  2190. }
  2191. TExprNode::TPtr NewAtom(TPosition pos, const TStringBuf& content, ui32 flags = TNodeFlags::ArbitraryContent) {
  2192. return NewAtom(AppendPosition(pos), content, flags);
  2193. }
  2194. TExprNode::TPtr NewAtom(TPosition pos, ui32 index) {
  2195. return NewAtom(AppendPosition(pos), index);
  2196. }
  2197. TExprNode::TPtr NewArgument(TPosition pos, const TStringBuf& name) {
  2198. return NewArgument(AppendPosition(pos), name);
  2199. }
  2200. TExprNode::TPtr NewArguments(TPosition pos, TExprNode::TListType&& argNodes) {
  2201. return NewArguments(AppendPosition(pos), std::move(argNodes));
  2202. }
  2203. TExprNode::TPtr NewLambda(TPosition pos, TExprNode::TListType&& lambda) {
  2204. return NewLambda(AppendPosition(pos), std::move(lambda));
  2205. }
  2206. TExprNode::TPtr NewLambda(TPosition pos, TExprNode::TPtr&& args, TExprNode::TListType&& body) {
  2207. return NewLambda(AppendPosition(pos), std::move(args), std::move(body));
  2208. }
  2209. TExprNode::TPtr NewLambda(TPosition pos, TExprNode::TPtr&& args, TExprNode::TPtr&& body) {
  2210. return NewLambda(AppendPosition(pos), std::move(args), std::move(body));
  2211. }
  2212. TExprNode::TPtr NewWorld(TPosition pos) {
  2213. return NewWorld(AppendPosition(pos));
  2214. }
  2215. TExprNode::TPtr NewList(TPosition pos, TExprNode::TListType&& children) {
  2216. return NewList(AppendPosition(pos), std::move(children));
  2217. }
  2218. TExprNode::TPtr NewCallable(TPosition pos, const TStringBuf& name, TExprNode::TListType&& children) {
  2219. return NewCallable(AppendPosition(pos), name, std::move(children));
  2220. }
  2221. TExprNode::TPtr WrapByCallableIf(bool condition, const TStringBuf& callable, TExprNode::TPtr&& node);
  2222. template <typename T, typename... Args>
  2223. const T* MakeType(Args&&... args);
  2224. template <typename T, typename... Args>
  2225. const T* MakeConstraint(Args&&... args);
  2226. TConstraintSet MakeConstraintSet(const NYT::TNode& serializedConstraints);
  2227. void AddError(const TIssue& error) {
  2228. ENSURE_NOT_FROZEN_CTX
  2229. IssueManager.RaiseIssue(error);
  2230. }
  2231. bool AddWarning(const TIssue& warning) {
  2232. ENSURE_NOT_FROZEN_CTX
  2233. return IssueManager.RaiseWarning(warning);
  2234. }
  2235. void Freeze();
  2236. void UnFreeze();
  2237. void Reset();
  2238. template <class TConstraint>
  2239. bool IsConstraintEnabled() const {
  2240. return DisabledConstraints.find(TConstraint::Name()) == DisabledConstraints.end();
  2241. }
  2242. std::string_view GetIndexAsString(ui32 index);
  2243. private:
  2244. using TPositionHandleEqualPred = std::function<bool(TPositionHandle, TPositionHandle)>;
  2245. using TPositionHandleHasher = std::function<size_t(TPositionHandle)>;
  2246. bool IsEqual(TPositionHandle a, TPositionHandle b) const;
  2247. size_t GetHash(TPositionHandle p) const;
  2248. std::unordered_set<TPositionHandle, TPositionHandleHasher, TPositionHandleEqualPred> PositionSet;
  2249. std::deque<TPosition> Positions;
  2250. };
  2251. template <typename T, typename... Args>
  2252. inline const T* TExprContext::MakeConstraint(Args&&... args) {
  2253. ENSURE_NOT_FROZEN_CTX
  2254. if (!IsConstraintEnabled<T>()) {
  2255. return nullptr;
  2256. }
  2257. T sample(*this, std::forward<Args>(args)...);
  2258. const auto it = ConstraintSet.find(&sample);
  2259. if (ConstraintSet.cend() != it) {
  2260. return static_cast<const T*>(*it);
  2261. }
  2262. ConstraintNodes.emplace(new T(std::move(sample)));
  2263. const auto ins = ConstraintSet.emplace(ConstraintNodes.top().get());
  2264. return static_cast<const T*>(*ins.first);
  2265. }
  2266. #undef ENSURE_NOT_DELETED
  2267. #undef ENSURE_NOT_FROZEN
  2268. #undef ENSURE_NOT_FROZEN_CTX
  2269. inline bool IsSameAnnotation(const TTypeAnnotationNode& left, const TTypeAnnotationNode& right) {
  2270. return &left == &right;
  2271. }
  2272. template <typename T, typename... Args>
  2273. const T* TExprContext::MakeType(Args&&... args) {
  2274. return TMakeTypeImpl<T>::Make(*this, std::forward<Args>(args)...);
  2275. }
  2276. struct TExprAnnotationFlags {
  2277. enum {
  2278. None = 0x00,
  2279. Position = 0x01,
  2280. Types = 0x02
  2281. };
  2282. };
  2283. ///////////////////////////////////////////////////////////////////////////////
  2284. // TNodeException
  2285. ///////////////////////////////////////////////////////////////////////////////
  2286. class TNodeException: public yexception {
  2287. public:
  2288. TNodeException();
  2289. explicit TNodeException(const TExprNode& node);
  2290. explicit TNodeException(const TExprNode* node);
  2291. explicit TNodeException(const TPositionHandle& pos);
  2292. inline const TPositionHandle& Pos() const {
  2293. return Pos_;
  2294. }
  2295. private:
  2296. const TPositionHandle Pos_;
  2297. };
  2298. bool CompileExpr(TAstNode& astRoot, TExprNode::TPtr& exprRoot, TExprContext& ctx,
  2299. IModuleResolver* resolver, IUrlListerManager* urlListerManager,
  2300. bool hasAnnotations = false, ui32 typeAnnotationIndex = Max<ui32>(), ui16 syntaxVersion = 0);
  2301. bool CompileExpr(TAstNode& astRoot, TExprNode::TPtr& exprRoot, TExprContext& ctx,
  2302. IModuleResolver* resolver, IUrlListerManager* urlListerManager,
  2303. ui32 annotationFlags, ui16 syntaxVersion = 0);
  2304. struct TLibraryCohesion {
  2305. TExportTable Exports;
  2306. TNodeMap<std::pair<TString, TString>> Imports;
  2307. };
  2308. bool CompileExpr(TAstNode& astRoot, TLibraryCohesion& cohesion, TExprContext& ctx, ui16 syntaxVersion = 0);
  2309. const TTypeAnnotationNode* CompileTypeAnnotation(const TAstNode& node, TExprContext& ctx);
  2310. // validate consistency of arguments and lambdas
  2311. void CheckArguments(const TExprNode& root);
  2312. void CheckCounts(const TExprNode& root);
  2313. // Compare expression trees and return first diffrent nodes.
  2314. bool CompareExprTrees(const TExprNode*& one, const TExprNode*& two);
  2315. bool CompareExprTreeParts(const TExprNode& one, const TExprNode& two, const TNodeMap<ui32>& argsMap);
  2316. TString MakeCacheKey(const TExprNode& root);
  2317. void GatherParents(const TExprNode& node, TParentsMap& parentsMap);
  2318. struct TConvertToAstSettings {
  2319. ui32 AnnotationFlags = 0;
  2320. bool RefAtoms = false;
  2321. std::function<bool(const TExprNode&)> NoInlineFunc;
  2322. bool PrintArguments = false;
  2323. bool AllowFreeArgs = false;
  2324. bool NormalizeAtomFlags = false;
  2325. IAllocator* Allocator = TDefaultAllocator::Instance();
  2326. };
  2327. TAstParseResult ConvertToAst(const TExprNode& root, TExprContext& ctx, const TConvertToAstSettings& settings);
  2328. // refAtoms allows omit copying of atom bodies - they will be referenced from expr graph
  2329. TAstParseResult ConvertToAst(const TExprNode& root, TExprContext& ctx, ui32 annotationFlags, bool refAtoms);
  2330. TExprNode::TListType GetLambdaBody(const TExprNode& lambda);
  2331. TString SubstParameters(const TString& str, const TMaybe<NYT::TNode>& params, TSet<TString>* usedNames);
  2332. const TTypeAnnotationNode* GetSeqItemType(const TTypeAnnotationNode* seq);
  2333. const TTypeAnnotationNode& GetSeqItemType(const TTypeAnnotationNode& seq);
  2334. const TTypeAnnotationNode& RemoveOptionality(const TTypeAnnotationNode& type);
  2335. TMaybe<TIssue> NormalizeName(TPosition position, TString& name);
  2336. TString NormalizeName(const TStringBuf& name);
  2337. } // namespace NYql
  2338. template<>
  2339. inline void Out<NYql::TTypeAnnotationNode>(
  2340. IOutputStream &out, const NYql::TTypeAnnotationNode& type)
  2341. {
  2342. type.Out(out);
  2343. }
  2344. #include "yql_expr_builder.inl"