mkql_node_serialization.cpp 78 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217
  1. #include "mkql_node_serialization.h"
  2. #include "mkql_node.h"
  3. #include "mkql_node_visitor.h"
  4. #include "mkql_type_ops.h"
  5. #include <yql/essentials/minikql/pack_num.h>
  6. #include <library/cpp/containers/stack_vector/stack_vec.h>
  7. #include <library/cpp/packedtypes/zigzag.h>
  8. #include <util/generic/algorithm.h>
  9. #include <util/system/unaligned_mem.h>
  10. namespace NKikimr {
  11. namespace NMiniKQL {
  12. using namespace NDetail;
  13. namespace {
  14. static const char KindMask = 0x0f;
  15. static const char TypeMask = 0x7f;
  16. static_assert(KindMask == char(TType::EKind::ReservedKind), "Kind should be encoded in 4 bit");
  17. static const char UserMarker1 = 0x10;
  18. static const char UserMarker2 = 0x20;
  19. static const char UserMarker3 = 0x40;
  20. static const char TypeMarker = '\x80';
  21. static const char SystemMask = KindMask;
  22. static const char CommandMask = '\xf0';
  23. static const ui32 NameRefMark = 0x01;
  24. static const ui32 RequiresNextPass = 0x80000000u;
  25. static const ui32 AllPassesDone = 0xFFFFFFFFu;
  26. enum class ESystemCommand {
  27. Begin = 0x10,
  28. End = 0x20,
  29. Ref = 0x30,
  30. BeginNotImmediate = 0x40,
  31. LastCommand = 0xf0
  32. };
  33. inline ui32 GetBitmapBytes(ui32 count) {
  34. return (count + 7) / 8;
  35. }
  36. inline void SetBitmapBit(char* bitmap, ui32 index) {
  37. bitmap[index / 8] |= (1 << (index & 7));
  38. }
  39. inline bool GetBitmapBit(const char* bitmap, ui32 index) {
  40. return (bitmap[index / 8] & (1 << (index & 7))) != 0;
  41. }
  42. class TPrepareWriteNodeVisitor : public TEmptyNodeVisitor {
  43. public:
  44. using TEmptyNodeVisitor::Visit;
  45. void Visit(TStructType& node) override {
  46. for (ui32 i = 0, e = node.GetMembersCount(); i < e; ++i) {
  47. auto memberName = node.GetMemberNameStr(i);
  48. AddName(memberName);
  49. }
  50. }
  51. void Visit(TCallableType& node) override {
  52. auto name = node.GetNameStr();
  53. AddName(name);
  54. }
  55. void Visit(TResourceType& node) override {
  56. auto name = node.GetTagStr();
  57. AddName(name);
  58. }
  59. THashMap<TInternName, ui32>& GetNames() {
  60. return Names;
  61. }
  62. TVector<TInternName>& GetNameOrder() {
  63. return NameOrder;
  64. }
  65. private:
  66. void AddName(const TInternName& name) {
  67. auto iter = Names.emplace(name, 0);
  68. if (iter.second) {
  69. NameOrder.emplace_back(name);
  70. }
  71. ++iter.first->second;
  72. }
  73. private:
  74. THashMap<TInternName, ui32> Names;
  75. TVector<TInternName> NameOrder;
  76. };
  77. class TWriter {
  78. public:
  79. friend class TPreVisitor;
  80. friend class TPostVisitor;
  81. class TPreVisitor : public INodeVisitor {
  82. public:
  83. TPreVisitor(TWriter& owner)
  84. : Owner(owner)
  85. , IsProcessed0(false)
  86. {
  87. }
  88. void Visit(TTypeType& node) override {
  89. Y_UNUSED(node);
  90. Owner.Write(TypeMarker | (char)TType::EKind::Type);
  91. IsProcessed0 = true;
  92. }
  93. void Visit(TVoidType& node) override {
  94. Y_UNUSED(node);
  95. Owner.Write(TypeMarker | (char)TType::EKind::Void);
  96. IsProcessed0 = true;
  97. }
  98. void Visit(TNullType& node) override {
  99. Y_UNUSED(node);
  100. Owner.Write(TypeMarker | (char)TType::EKind::Null);
  101. IsProcessed0 = true;
  102. }
  103. void Visit(TEmptyListType& node) override {
  104. Y_UNUSED(node);
  105. Owner.Write(TypeMarker | (char)TType::EKind::EmptyList);
  106. IsProcessed0 = true;
  107. }
  108. void Visit(TEmptyDictType& node) override {
  109. Y_UNUSED(node);
  110. Owner.Write(TypeMarker | (char)TType::EKind::EmptyDict);
  111. IsProcessed0 = true;
  112. }
  113. void Visit(TDataType& node) override {
  114. if (node.GetCookie() != 0) {
  115. Owner.WriteReference(node);
  116. IsProcessed0 = true;
  117. return;
  118. }
  119. Owner.Write(TypeMarker | (char)TType::EKind::Data);
  120. Owner.WriteVar32(node.GetSchemeType());
  121. if (NUdf::TDataType<NUdf::TDecimal>::Id == node.GetSchemeType()) {
  122. const auto& params = static_cast<TDataDecimalType&>(node).GetParams();
  123. Owner.Write(params.first);
  124. Owner.Write(params.second);
  125. }
  126. IsProcessed0 = false;
  127. }
  128. void Visit(TPgType& node) override {
  129. if (node.GetCookie() != 0) {
  130. Owner.WriteReference(node);
  131. IsProcessed0 = true;
  132. return;
  133. }
  134. Owner.Write(TypeMarker | (char)TType::EKind::Pg);
  135. Owner.WriteVar32(node.GetTypeId());
  136. IsProcessed0 = false;
  137. }
  138. void Visit(TStructType& node) override {
  139. if (node.GetCookie() != 0) {
  140. Owner.WriteReference(node);
  141. IsProcessed0 = true;
  142. return;
  143. }
  144. Owner.Write(TypeMarker | (char)TType::EKind::Struct);
  145. Owner.WriteVar32(node.GetMembersCount());
  146. for (ui32 i = node.GetMembersCount(); i-- > 0;) {
  147. auto memberType = node.GetMemberType(i);
  148. Owner.AddChildNode(*memberType);
  149. }
  150. IsProcessed0 = false;
  151. }
  152. void Visit(TListType& node) override {
  153. if (node.GetCookie() != 0) {
  154. Owner.WriteReference(node);
  155. IsProcessed0 = true;
  156. return;
  157. }
  158. Owner.Write(TypeMarker | (char)TType::EKind::List);
  159. auto itemType = node.GetItemType();
  160. Owner.AddChildNode(*itemType);
  161. IsProcessed0 = false;
  162. }
  163. void Visit(TStreamType& node) override {
  164. if (node.GetCookie() != 0) {
  165. Owner.WriteReference(node);
  166. IsProcessed0 = true;
  167. return;
  168. }
  169. Owner.Write(TypeMarker | (char)TType::EKind::Stream);
  170. auto itemType = node.GetItemType();
  171. Owner.AddChildNode(*itemType);
  172. IsProcessed0 = false;
  173. }
  174. void Visit(TFlowType& node) override {
  175. if (node.GetCookie() != 0) {
  176. Owner.WriteReference(node);
  177. IsProcessed0 = true;
  178. return;
  179. }
  180. Owner.Write(TypeMarker | (char)TType::EKind::Flow);
  181. auto itemType = node.GetItemType();
  182. Owner.AddChildNode(*itemType);
  183. IsProcessed0 = false;
  184. }
  185. void Visit(TBlockType& node) override {
  186. if (node.GetCookie() != 0) {
  187. Owner.WriteReference(node);
  188. IsProcessed0 = true;
  189. return;
  190. }
  191. Owner.Write(TypeMarker | (char)TType::EKind::Block);
  192. auto itemType = node.GetItemType();
  193. Owner.AddChildNode(*itemType);
  194. IsProcessed0 = false;
  195. }
  196. void Visit(TMultiType& node) override {
  197. if (node.GetCookie() != 0) {
  198. Owner.WriteReference(node);
  199. IsProcessed0 = true;
  200. return;
  201. }
  202. Owner.Write(TypeMarker | (char)TType::EKind::Multi);
  203. Owner.WriteVar32(node.GetElementsCount());
  204. for (ui32 i = node.GetElementsCount(); i-- > 0;) {
  205. auto elementType = node.GetElementType(i);
  206. Owner.AddChildNode(*elementType);
  207. }
  208. IsProcessed0 = false;
  209. }
  210. void Visit(TTaggedType& node) override {
  211. if (node.GetCookie() != 0) {
  212. Owner.WriteReference(node);
  213. IsProcessed0 = true;
  214. return;
  215. }
  216. Owner.Write(TypeMarker | (char)TType::EKind::Tagged);
  217. auto baseType = node.GetBaseType();
  218. Owner.AddChildNode(*baseType);
  219. IsProcessed0 = false;
  220. }
  221. void Visit(TOptionalType& node) override {
  222. if (node.GetCookie() != 0) {
  223. Owner.WriteReference(node);
  224. IsProcessed0 = true;
  225. return;
  226. }
  227. Owner.Write(TypeMarker | (char)TType::EKind::Optional);
  228. auto itemType = node.GetItemType();
  229. Owner.AddChildNode(*itemType);
  230. IsProcessed0 = false;
  231. }
  232. void Visit(TDictType& node) override {
  233. if (node.GetCookie() != 0) {
  234. Owner.WriteReference(node);
  235. IsProcessed0 = true;
  236. return;
  237. }
  238. Owner.Write(TypeMarker | (char)TType::EKind::Dict);
  239. auto keyType = node.GetKeyType();
  240. auto payloadType = node.GetPayloadType();
  241. Owner.AddChildNode(*payloadType);
  242. Owner.AddChildNode(*keyType);
  243. IsProcessed0 = false;
  244. }
  245. void Visit(TCallableType& node) override {
  246. if (node.GetCookie() != 0) {
  247. Owner.WriteReference(node);
  248. IsProcessed0 = true;
  249. return;
  250. }
  251. Owner.Write(TypeMarker | (char)TType::EKind::Callable
  252. | (node.IsMergeDisabled() ? UserMarker2 : 0) | (node.GetPayload() ? UserMarker3 : 0));
  253. Owner.WriteVar32(node.GetArgumentsCount());
  254. auto returnType = node.GetReturnType();
  255. if (node.GetPayload()) {
  256. Owner.AddChildNode(*node.GetPayload());
  257. }
  258. for (ui32 i = node.GetArgumentsCount(); i-- > 0;) {
  259. auto argumentType = node.GetArgumentType(i);
  260. Owner.AddChildNode(*argumentType);
  261. }
  262. Owner.AddChildNode(*returnType);
  263. IsProcessed0 = false;
  264. }
  265. void Visit(TAnyType& node) override {
  266. Y_UNUSED(node);
  267. Owner.Write(TypeMarker | (char)TType::EKind::Any);
  268. IsProcessed0 = true;
  269. }
  270. void Visit(TTupleType& node) override {
  271. if (node.GetCookie() != 0) {
  272. Owner.WriteReference(node);
  273. IsProcessed0 = true;
  274. return;
  275. }
  276. Owner.Write(TypeMarker | (char)TType::EKind::Tuple);
  277. Owner.WriteVar32(node.GetElementsCount());
  278. for (ui32 i = node.GetElementsCount(); i-- > 0;) {
  279. auto elementType = node.GetElementType(i);
  280. Owner.AddChildNode(*elementType);
  281. }
  282. IsProcessed0 = false;
  283. }
  284. void Visit(TResourceType& node) override {
  285. if (node.GetCookie() != 0) {
  286. Owner.WriteReference(node);
  287. IsProcessed0 = true;
  288. return;
  289. }
  290. Owner.Write(TypeMarker | (char)TType::EKind::Resource);
  291. auto tag = node.GetTagStr();
  292. Owner.WriteName(tag);
  293. IsProcessed0 = false;
  294. }
  295. void Visit(TVariantType& node) override {
  296. if (node.GetCookie() != 0) {
  297. Owner.WriteReference(node);
  298. IsProcessed0 = true;
  299. return;
  300. }
  301. Owner.Write(TypeMarker | (char)TType::EKind::Variant);
  302. auto underlyingType = node.GetUnderlyingType();
  303. Owner.AddChildNode(*underlyingType);
  304. IsProcessed0 = false;
  305. }
  306. void Visit(TVoid& node) override {
  307. Y_UNUSED(node);
  308. Owner.Write((char)TType::EKind::Void);
  309. IsProcessed0 = true;
  310. }
  311. void Visit(TNull& node) override {
  312. Y_UNUSED(node);
  313. Owner.Write((char)TType::EKind::Null);
  314. IsProcessed0 = true;
  315. }
  316. void Visit(TEmptyList& node) override {
  317. Y_UNUSED(node);
  318. Owner.Write((char)TType::EKind::EmptyList);
  319. IsProcessed0 = true;
  320. }
  321. void Visit(TEmptyDict& node) override {
  322. Y_UNUSED(node);
  323. Owner.Write((char)TType::EKind::EmptyDict);
  324. IsProcessed0 = true;
  325. }
  326. void Visit(TDataLiteral& node) override {
  327. if (node.GetCookie() != 0) {
  328. Owner.WriteReference(node);
  329. IsProcessed0 = true;
  330. return;
  331. }
  332. Owner.Write((char)TType::EKind::Data);
  333. auto type = node.GetType();
  334. Owner.AddChildNode(*type);
  335. IsProcessed0 = false;
  336. }
  337. void Visit(TStructLiteral& node) override {
  338. if (node.GetCookie() != 0) {
  339. Owner.WriteReference(node);
  340. IsProcessed0 = true;
  341. return;
  342. }
  343. Owner.Write((char)TType::EKind::Struct);
  344. auto type = node.GetType();
  345. Y_DEBUG_ABORT_UNLESS(node.GetValuesCount() == type->GetMembersCount());
  346. for (ui32 i = node.GetValuesCount(); i-- > 0; ) {
  347. auto value = node.GetValue(i);
  348. Owner.AddChildNode(*value.GetNode());
  349. }
  350. Owner.AddChildNode(*type);
  351. IsProcessed0 = false;
  352. }
  353. void Visit(TListLiteral& node) override {
  354. if (node.GetCookie() != 0) {
  355. Owner.WriteReference(node);
  356. IsProcessed0 = true;
  357. return;
  358. }
  359. Owner.Write((char)TType::EKind::List);
  360. auto type = node.GetType();
  361. Owner.WriteVar32(node.GetItemsCount());
  362. for (ui32 i = node.GetItemsCount(); i > 0; --i) {
  363. auto item = node.GetItems()[i - 1];
  364. Owner.AddChildNode(*item.GetNode());
  365. }
  366. Owner.AddChildNode(*type);
  367. IsProcessed0 = false;
  368. }
  369. void Visit(TOptionalLiteral& node) override {
  370. if (node.GetCookie() != 0) {
  371. Owner.WriteReference(node);
  372. IsProcessed0 = true;
  373. return;
  374. }
  375. TRuntimeNode item;
  376. if (node.HasItem())
  377. item = node.GetItem();
  378. Owner.Write((char)TType::EKind::Optional | (item.GetNode() ? UserMarker1 : 0) | (item.IsImmediate() ? UserMarker2 : 0));
  379. auto type = node.GetType();
  380. if (item.GetNode()) {
  381. Owner.AddChildNode(*item.GetNode());
  382. }
  383. Owner.AddChildNode(*type);
  384. IsProcessed0 = false;
  385. }
  386. void Visit(TDictLiteral& node) override {
  387. if (node.GetCookie() != 0) {
  388. Owner.WriteReference(node);
  389. IsProcessed0 = true;
  390. return;
  391. }
  392. Owner.Write((char)TType::EKind::Dict);
  393. auto type = node.GetType();
  394. Owner.WriteVar32(node.GetItemsCount());
  395. for (ui32 i = node.GetItemsCount(); i-- > 0;) {
  396. auto item = node.GetItem(i);
  397. Owner.AddChildNode(*item.second.GetNode());
  398. Owner.AddChildNode(*item.first.GetNode());
  399. }
  400. Owner.AddChildNode(*type);
  401. IsProcessed0 = false;
  402. }
  403. void Visit(TCallable& node) override {
  404. if (node.GetCookie() != 0) {
  405. Owner.WriteReference(node);
  406. IsProcessed0 = true;
  407. return;
  408. }
  409. Owner.Write((char)TType::EKind::Callable | (node.HasResult() ? UserMarker1 : 0) |
  410. ((node.GetUniqueId() != 0) ? UserMarker2 : 0));
  411. auto type = node.GetType();
  412. if (node.HasResult()) {
  413. auto result = node.GetResult();
  414. Owner.AddChildNode(*result.GetNode());
  415. } else {
  416. Y_DEBUG_ABORT_UNLESS(node.GetInputsCount() == type->GetArgumentsCount());
  417. for (ui32 i = node.GetInputsCount(); i-- > 0;) {
  418. auto input = node.GetInput(i);
  419. Owner.AddChildNode(*input.GetNode());
  420. }
  421. }
  422. Owner.AddChildNode(*type);
  423. IsProcessed0 = false;
  424. }
  425. void Visit(TAny& node) override {
  426. if (node.GetCookie() != 0) {
  427. Owner.WriteReference(node);
  428. IsProcessed0 = true;
  429. return;
  430. }
  431. TRuntimeNode item;
  432. if (node.HasItem())
  433. item = node.GetItem();
  434. Owner.Write((char)TType::EKind::Any | (item.GetNode() ? UserMarker1 : 0) | (item.IsImmediate() ? UserMarker2 : 0));
  435. if (item.GetNode()) {
  436. Owner.AddChildNode(*item.GetNode());
  437. }
  438. IsProcessed0 = false;
  439. }
  440. void Visit(TTupleLiteral& node) override {
  441. if (node.GetCookie() != 0) {
  442. Owner.WriteReference(node);
  443. IsProcessed0 = true;
  444. return;
  445. }
  446. Owner.Write((char)TType::EKind::Tuple);
  447. auto type = node.GetType();
  448. Y_DEBUG_ABORT_UNLESS(node.GetValuesCount() == type->GetElementsCount());
  449. for (ui32 i = node.GetValuesCount(); i-- > 0;) {
  450. auto value = node.GetValue(i);
  451. Owner.AddChildNode(*value.GetNode());
  452. }
  453. Owner.AddChildNode(*type);
  454. IsProcessed0 = false;
  455. }
  456. void Visit(TVariantLiteral& node) override {
  457. if (node.GetCookie() != 0) {
  458. Owner.WriteReference(node);
  459. IsProcessed0 = true;
  460. return;
  461. }
  462. TRuntimeNode item = node.GetItem();
  463. Owner.Write((char)TType::EKind::Variant | (item.IsImmediate() ? UserMarker1 : 0));
  464. auto type = node.GetType();
  465. Owner.AddChildNode(*item.GetNode());
  466. Owner.AddChildNode(*type);
  467. IsProcessed0 = false;
  468. }
  469. bool IsProcessed() const {
  470. return IsProcessed0;
  471. }
  472. private:
  473. TWriter& Owner;
  474. bool IsProcessed0;
  475. };
  476. class TPostVisitor : public INodeVisitor {
  477. public:
  478. TPostVisitor(TWriter& owner)
  479. : Owner(owner)
  480. {
  481. }
  482. void Visit(TTypeType& node) override {
  483. Y_UNUSED(node);
  484. }
  485. void Visit(TVoidType& node) override {
  486. Y_UNUSED(node);
  487. }
  488. void Visit(TNullType& node) override {
  489. Y_UNUSED(node);
  490. }
  491. void Visit(TEmptyListType& node) override {
  492. Y_UNUSED(node);
  493. }
  494. void Visit(TEmptyDictType& node) override {
  495. Y_UNUSED(node);
  496. }
  497. void Visit(TDataType& node) override {
  498. Owner.RegisterReference(node);
  499. }
  500. void Visit(TPgType& node) override {
  501. Owner.RegisterReference(node);
  502. }
  503. void Visit(TStructType& node) override {
  504. for (ui32 i = 0, e = node.GetMembersCount(); i < e; ++i) {
  505. auto memberName = node.GetMemberNameStr(i);
  506. Owner.WriteName(memberName);
  507. }
  508. Owner.RegisterReference(node);
  509. }
  510. void Visit(TListType& node) override {
  511. Owner.RegisterReference(node);
  512. }
  513. void Visit(TStreamType& node) override {
  514. Owner.RegisterReference(node);
  515. }
  516. void Visit(TFlowType& node) override {
  517. Owner.RegisterReference(node);
  518. }
  519. void Visit(TBlockType& node) override {
  520. Owner.Write(static_cast<ui8>(node.GetShape()));
  521. Owner.RegisterReference(node);
  522. }
  523. void Visit(TMultiType& node) override {
  524. Owner.RegisterReference(node);
  525. }
  526. void Visit(TTaggedType& node) override {
  527. auto tag = node.GetTagStr();
  528. Owner.WriteName(tag);
  529. Owner.RegisterReference(node);
  530. }
  531. void Visit(TOptionalType& node) override {
  532. Owner.RegisterReference(node);
  533. }
  534. void Visit(TDictType& node) override {
  535. Owner.RegisterReference(node);
  536. }
  537. void Visit(TCallableType& node) override {
  538. auto name = node.GetNameStr();
  539. Owner.WriteName(name);
  540. Owner.WriteVar32(node.GetOptionalArgumentsCount());
  541. Owner.RegisterReference(node);
  542. }
  543. void Visit(TAnyType& node) override {
  544. Y_UNUSED(node);
  545. }
  546. void Visit(TTupleType& node) override {
  547. Owner.RegisterReference(node);
  548. }
  549. void Visit(TResourceType& node) override {
  550. Owner.RegisterReference(node);
  551. }
  552. void Visit(TVariantType& node) override {
  553. Owner.RegisterReference(node);
  554. }
  555. void Visit(TVoid& node) override {
  556. Y_UNUSED(node);
  557. }
  558. void Visit(TNull& node) override {
  559. Y_UNUSED(node);
  560. }
  561. void Visit(TEmptyList& node) override {
  562. Y_UNUSED(node);
  563. }
  564. void Visit(TEmptyDict& node) override {
  565. Y_UNUSED(node);
  566. }
  567. void Visit(TDataLiteral& node) override {
  568. const auto type = node.GetType();
  569. if (type->GetSchemeType() != 0) {
  570. const auto& value = node.AsValue();
  571. switch (type->GetSchemeType()) {
  572. case NUdf::TDataType<bool>::Id:
  573. Owner.Write(value.Get<bool>());
  574. break;
  575. case NUdf::TDataType<ui8>::Id:
  576. Owner.Write(value.Get<ui8>());
  577. break;
  578. case NUdf::TDataType<i8>::Id:
  579. Owner.Write((ui8)value.Get<i8>());
  580. break;
  581. case NUdf::TDataType<i16>::Id:
  582. Owner.WriteVar32(ZigZagEncode(value.Get<i16>()));
  583. break;
  584. case NUdf::TDataType<ui16>::Id:
  585. Owner.WriteVar32(value.Get<ui16>());
  586. break;
  587. case NUdf::TDataType<i32>::Id:
  588. Owner.WriteVar32(ZigZagEncode(value.Get<i32>()));
  589. break;
  590. case NUdf::TDataType<ui32>::Id:
  591. Owner.WriteVar32(value.Get<ui32>());
  592. break;
  593. case NUdf::TDataType<float>::Id: {
  594. const auto v = value.Get<float>();
  595. Owner.WriteMany(&v, sizeof(v));
  596. break;
  597. }
  598. case NUdf::TDataType<i64>::Id:
  599. Owner.WriteVar64(ZigZagEncode(value.Get<i64>()));
  600. break;
  601. case NUdf::TDataType<ui64>::Id:
  602. Owner.WriteVar64(value.Get<ui64>());
  603. break;
  604. case NUdf::TDataType<double>::Id: {
  605. const auto v = value.Get<double>();
  606. Owner.WriteMany(&v, sizeof(v));
  607. break;
  608. }
  609. case NUdf::TDataType<NUdf::TDate>::Id:
  610. Owner.WriteVar32(value.Get<NUdf::TDataType<NUdf::TDate>::TLayout>());
  611. break;
  612. case NUdf::TDataType<NUdf::TDatetime>::Id:
  613. Owner.WriteVar32(value.Get<NUdf::TDataType<NUdf::TDatetime>::TLayout>());
  614. break;
  615. case NUdf::TDataType<NUdf::TTimestamp>::Id:
  616. Owner.WriteVar64(value.Get<NUdf::TDataType<NUdf::TTimestamp>::TLayout>());
  617. break;
  618. case NUdf::TDataType<NUdf::TTzDate>::Id: {
  619. Owner.WriteVar32(value.Get<NUdf::TDataType<NUdf::TTzDate>::TLayout>());
  620. Owner.WriteVar32(value.GetTimezoneId());
  621. break;
  622. }
  623. case NUdf::TDataType<NUdf::TTzDatetime>::Id: {
  624. Owner.WriteVar32(value.Get<NUdf::TDataType<NUdf::TTzDatetime>::TLayout>());
  625. Owner.WriteVar32(value.GetTimezoneId());
  626. break;
  627. }
  628. case NUdf::TDataType<NUdf::TTzTimestamp>::Id: {
  629. Owner.WriteVar64(value.Get<NUdf::TDataType<NUdf::TTzTimestamp>::TLayout>());
  630. Owner.WriteVar32(value.GetTimezoneId());
  631. break;
  632. }
  633. case NUdf::TDataType<NUdf::TInterval>::Id:
  634. Owner.WriteVar64(ZigZagEncode(value.Get<NUdf::TDataType<NUdf::TInterval>::TLayout>()));
  635. break;
  636. case NUdf::TDataType<NUdf::TDate32>::Id:
  637. Owner.WriteVar32(ZigZagEncode(value.Get<NUdf::TDataType<NUdf::TDate32>::TLayout>()));
  638. break;
  639. case NUdf::TDataType<NUdf::TDatetime64>::Id:
  640. Owner.WriteVar64(ZigZagEncode(value.Get<NUdf::TDataType<NUdf::TDatetime64>::TLayout>()));
  641. break;
  642. case NUdf::TDataType<NUdf::TTimestamp64>::Id:
  643. Owner.WriteVar64(ZigZagEncode(value.Get<NUdf::TDataType<NUdf::TTimestamp64>::TLayout>()));
  644. break;
  645. case NUdf::TDataType<NUdf::TInterval64>::Id:
  646. Owner.WriteVar64(ZigZagEncode(value.Get<NUdf::TDataType<NUdf::TInterval64>::TLayout>()));
  647. break;
  648. case NUdf::TDataType<NUdf::TTzDate32>::Id: {
  649. Owner.WriteVar32(ZigZagEncode(value.Get<NUdf::TDataType<NUdf::TTzDate32>::TLayout>()));
  650. Owner.WriteVar32(value.GetTimezoneId());
  651. break;
  652. }
  653. case NUdf::TDataType<NUdf::TTzDatetime64>::Id: {
  654. Owner.WriteVar64(ZigZagEncode(value.Get<NUdf::TDataType<NUdf::TTzDatetime64>::TLayout>()));
  655. Owner.WriteVar32(value.GetTimezoneId());
  656. break;
  657. }
  658. case NUdf::TDataType<NUdf::TTzTimestamp64>::Id: {
  659. Owner.WriteVar64(ZigZagEncode(value.Get<NUdf::TDataType<NUdf::TTzTimestamp64>::TLayout>()));
  660. Owner.WriteVar32(value.GetTimezoneId());
  661. break;
  662. }
  663. case NUdf::TDataType<NUdf::TUuid>::Id: {
  664. const auto v = value.AsStringRef();
  665. Owner.WriteMany(v.Data(), v.Size());
  666. break;
  667. }
  668. case NUdf::TDataType<NUdf::TDecimal>::Id:
  669. Owner.WriteMany(static_cast<const char*>(value.GetRawPtr()), sizeof(NYql::NDecimal::TInt128) - 1U);
  670. break;
  671. default: {
  672. const auto& buffer = value.AsStringRef();
  673. Owner.WriteVar32(buffer.Size());
  674. Owner.WriteMany(buffer.Data(), buffer.Size());
  675. }
  676. }
  677. }
  678. Owner.RegisterReference(node);
  679. }
  680. void Visit(TStructLiteral& node) override {
  681. auto type = node.GetType();
  682. Y_DEBUG_ABORT_UNLESS(node.GetValuesCount() == type->GetMembersCount());
  683. TStackVec<char> immediateFlags(GetBitmapBytes(node.GetValuesCount()));
  684. for (ui32 i = 0, e = node.GetValuesCount(); i < e; ++i) {
  685. auto value = node.GetValue(i);
  686. if (value.IsImmediate()) {
  687. SetBitmapBit(immediateFlags.data(), i);
  688. }
  689. }
  690. Owner.WriteMany(immediateFlags.data(), immediateFlags.size());
  691. Owner.RegisterReference(node);
  692. }
  693. void Visit(TListLiteral& node) override {
  694. TStackVec<char> immediateFlags(GetBitmapBytes(node.GetItemsCount()));
  695. for (ui32 i = 0; i < node.GetItemsCount(); ++i) {
  696. auto item = node.GetItems()[i];
  697. if (item.IsImmediate()) {
  698. SetBitmapBit(immediateFlags.data(), i);
  699. }
  700. }
  701. Owner.WriteMany(immediateFlags.data(), immediateFlags.size());
  702. Owner.RegisterReference(node);
  703. }
  704. void Visit(TOptionalLiteral& node) override {
  705. Owner.RegisterReference(node);
  706. }
  707. void Visit(TDictLiteral& node) override {
  708. TStackVec<char> immediateFlags(GetBitmapBytes(node.GetItemsCount() * 2));
  709. for (ui32 i = 0, e = node.GetItemsCount(); i < e; ++i) {
  710. auto item = node.GetItem(i);
  711. if (item.first.IsImmediate()) {
  712. SetBitmapBit(immediateFlags.data(), 2 * i);
  713. }
  714. if (item.second.IsImmediate()) {
  715. SetBitmapBit(immediateFlags.data(), 2 * i + 1);
  716. }
  717. }
  718. Owner.WriteMany(immediateFlags.data(), immediateFlags.size());
  719. Owner.RegisterReference(node);
  720. }
  721. void Visit(TCallable& node) override {
  722. if (node.HasResult()) {
  723. Owner.Write(node.GetResult().IsImmediate() ? 1 : 0);
  724. } else {
  725. auto type = node.GetType();
  726. Y_DEBUG_ABORT_UNLESS(node.GetInputsCount() == type->GetArgumentsCount());
  727. TStackVec<char> immediateFlags(GetBitmapBytes(node.GetInputsCount()));
  728. for (ui32 i = 0, e = node.GetInputsCount(); i < e; ++i) {
  729. auto input = node.GetInput(i);
  730. if (input.IsImmediate()) {
  731. SetBitmapBit(immediateFlags.data(), i);
  732. }
  733. }
  734. Owner.WriteMany(immediateFlags.data(), immediateFlags.size());
  735. }
  736. if (node.GetUniqueId() != 0)
  737. Owner.WriteVar32(node.GetUniqueId());
  738. Owner.RegisterReference(node);
  739. }
  740. void Visit(TAny& node) override {
  741. Owner.RegisterReference(node);
  742. }
  743. void Visit(TTupleLiteral& node) override {
  744. auto type = node.GetType();
  745. Y_DEBUG_ABORT_UNLESS(node.GetValuesCount() == type->GetElementsCount());
  746. TStackVec<char> immediateFlags(GetBitmapBytes(node.GetValuesCount()));
  747. for (ui32 i = 0, e = node.GetValuesCount(); i < e; ++i) {
  748. auto value = node.GetValue(i);
  749. if (value.IsImmediate()) {
  750. SetBitmapBit(immediateFlags.data(), i);
  751. }
  752. }
  753. Owner.WriteMany(immediateFlags.data(), immediateFlags.size());
  754. Owner.RegisterReference(node);
  755. }
  756. void Visit(TVariantLiteral& node) override {
  757. Owner.WriteVar32(node.GetIndex());
  758. Owner.RegisterReference(node);
  759. }
  760. private:
  761. TWriter& Owner;
  762. };
  763. TWriter(THashMap<TInternName, ui32>& names, TVector<TInternName>& nameOrder)
  764. {
  765. Names.swap(names);
  766. NameOrder.swap(nameOrder);
  767. }
  768. void Write(TRuntimeNode node) {
  769. Begin(node.IsImmediate());
  770. TPreVisitor preVisitor(*this);
  771. TPostVisitor postVisitor(*this);
  772. Stack.push_back(std::make_pair(node.GetNode(), false));
  773. while (!Stack.empty()) {
  774. auto& nodeAndFlag = Stack.back();
  775. if (!nodeAndFlag.second) {
  776. nodeAndFlag.second = true;
  777. auto prevSize = Stack.size();
  778. nodeAndFlag.first->Accept(preVisitor);
  779. if (preVisitor.IsProcessed()) { // ref or small node, some nodes have been added
  780. Y_DEBUG_ABORT_UNLESS(prevSize == Stack.size());
  781. Stack.pop_back();
  782. continue;
  783. }
  784. Y_DEBUG_ABORT_UNLESS(prevSize <= Stack.size());
  785. } else {
  786. auto prevSize = Stack.size();
  787. nodeAndFlag.first->Accept(postVisitor);
  788. Y_DEBUG_ABORT_UNLESS(prevSize == Stack.size());
  789. Stack.pop_back();
  790. }
  791. }
  792. End();
  793. }
  794. TString GetOutput() const {
  795. return Out;
  796. }
  797. private:
  798. void Begin(bool isImmediate) {
  799. Write(SystemMask | (isImmediate ? (char)ESystemCommand::Begin : (char)ESystemCommand::BeginNotImmediate));
  800. for (auto it = Names.begin(); it != Names.end();) {
  801. if (it->second <= 1) {
  802. Names.erase(it++);
  803. } else {
  804. ++it;
  805. }
  806. }
  807. WriteVar32(Names.size());
  808. ui32 nameIndex = 0;
  809. for (const auto& orderedName: NameOrder) {
  810. auto it = Names.find(orderedName);
  811. if (it == Names.end()) {
  812. continue;
  813. }
  814. const auto& name = it->first;
  815. WriteVar32(name.Str().size());
  816. WriteMany(name.Str().data(), name.Str().size());
  817. it->second = nameIndex++;
  818. }
  819. Y_DEBUG_ABORT_UNLESS(nameIndex == Names.size());
  820. }
  821. void End() {
  822. Write(SystemMask | (char)ESystemCommand::End);
  823. }
  824. void AddChildNode(TNode& node) {
  825. Stack.push_back(std::make_pair(&node, false));
  826. }
  827. void RegisterReference(TNode& node) {
  828. Y_DEBUG_ABORT_UNLESS(node.GetCookie() == 0);
  829. node.SetCookie(++ReferenceCount);
  830. }
  831. void WriteReference(TNode& node) {
  832. Write(SystemMask | (char)ESystemCommand::Ref);
  833. Y_DEBUG_ABORT_UNLESS(node.GetCookie() != 0);
  834. Y_DEBUG_ABORT_UNLESS(node.GetCookie() <= ReferenceCount);
  835. WriteVar32(node.GetCookie() - 1);
  836. }
  837. void WriteName(TInternName name) {
  838. auto it = Names.find(name);
  839. if (it == Names.end()) {
  840. WriteVar32(name.Str().size() << 1);
  841. WriteMany(name.Str().data(), name.Str().size());
  842. } else {
  843. WriteVar32((it->second << 1) | NameRefMark);
  844. }
  845. }
  846. Y_FORCE_INLINE void Write(char c) {
  847. Out.append(c);
  848. }
  849. Y_FORCE_INLINE void WriteMany(const void* buf, size_t len) {
  850. Out.AppendNoAlias((const char*)buf, len);
  851. }
  852. Y_FORCE_INLINE void WriteVar32(ui32 value) {
  853. char buf[MAX_PACKED32_SIZE];
  854. Out.AppendNoAlias(buf, Pack32(value, buf));
  855. }
  856. Y_FORCE_INLINE void WriteVar64(ui64 value) {
  857. char buf[MAX_PACKED64_SIZE];
  858. Out.AppendNoAlias(buf, Pack64(value, buf));
  859. }
  860. private:
  861. TString Out;
  862. ui32 ReferenceCount = 0;
  863. THashMap<TInternName, ui32> Names;
  864. TVector<TInternName> NameOrder;
  865. TVector<std::pair<TNode*, bool>> Stack;
  866. };
  867. class TReader {
  868. public:
  869. TReader(const TStringBuf& buffer, const TTypeEnvironment& env)
  870. : Current(buffer.data())
  871. , End(buffer.data() + buffer.size())
  872. , Env(env)
  873. {
  874. }
  875. TRuntimeNode Deserialize() {
  876. char header = Read();
  877. if ((header & SystemMask) != SystemMask)
  878. ThrowCorrupted();
  879. if ((header & CommandMask) != (char)ESystemCommand::Begin
  880. && (header & CommandMask) != (char)ESystemCommand::BeginNotImmediate)
  881. ThrowCorrupted();
  882. const bool notImmediate = ((header & CommandMask) == (char)ESystemCommand::BeginNotImmediate);
  883. const ui32 namesCount = ReadVar32();
  884. for (ui32 i = 0; i < namesCount; ++i) {
  885. LoadName();
  886. }
  887. const char* lastPos = Current;
  888. CtxStack.push_back(TNodeContext());
  889. while (!CtxStack.empty()) {
  890. auto& last = CtxStack.back();
  891. if (!last.Start) {
  892. last.Start = Current;
  893. } else {
  894. Current = last.Start;
  895. }
  896. if (last.NextPass == AllPassesDone) {
  897. Y_DEBUG_ABORT_UNLESS(last.ChildCount <= NodeStack.size());
  898. Reverse(NodeStack.end() - last.ChildCount, NodeStack.end());
  899. auto newNode = ReadNode();
  900. if (Current > lastPos) {
  901. lastPos = Current;
  902. }
  903. NodeStack.push_back(std::make_pair(newNode, Current));
  904. CtxStack.pop_back();
  905. continue;
  906. }
  907. const ui32 res = TryReadNode(last.NextPass);
  908. if (res & RequiresNextPass) {
  909. ++last.NextPass;
  910. } else {
  911. last.NextPass = AllPassesDone;
  912. }
  913. const ui32 childCount = res & ~RequiresNextPass;
  914. last.ChildCount += childCount;
  915. if (childCount != 0) {
  916. CtxStack.insert(CtxStack.end(), childCount, TNodeContext());
  917. } else {
  918. Y_DEBUG_ABORT_UNLESS(res == 0);
  919. }
  920. }
  921. Current = lastPos;
  922. if (NodeStack.size() != 1)
  923. ThrowCorrupted();
  924. TNode* node = PopNode();
  925. char footer = Read();
  926. if (footer != (SystemMask | (char)ESystemCommand::End))
  927. ThrowCorrupted();
  928. if (Current != End)
  929. ThrowCorrupted();
  930. return TRuntimeNode(node, !notImmediate);
  931. }
  932. private:
  933. [[noreturn]] static void ThrowNoData() {
  934. THROW yexception() << "No more data in buffer";
  935. }
  936. [[noreturn]] static void ThrowCorrupted() {
  937. THROW yexception() << "Serialized data is corrupted";
  938. }
  939. Y_FORCE_INLINE char Read() {
  940. if (Current == End)
  941. ThrowNoData();
  942. return *Current++;
  943. }
  944. Y_FORCE_INLINE const char* ReadMany(ui32 count) {
  945. if (Current + count > End)
  946. ThrowNoData();
  947. const char* result = Current;
  948. Current += count;
  949. return result;
  950. }
  951. Y_FORCE_INLINE ui32 ReadVar32() {
  952. ui32 result = 0;
  953. size_t count = Unpack32(Current, End - Current, result);
  954. if (!count) {
  955. ThrowCorrupted();
  956. }
  957. Current += count;
  958. return result;
  959. }
  960. Y_FORCE_INLINE ui64 ReadVar64() {
  961. ui64 result = 0;
  962. size_t count = Unpack64(Current, End - Current, result);
  963. if (!count) {
  964. ThrowCorrupted();
  965. }
  966. Current += count;
  967. return result;
  968. }
  969. // eats header and returns count of child nodes
  970. ui32 TryReadNode(ui32 pass) {
  971. char code = Read();
  972. if ((code & KindMask) == SystemMask) {
  973. return TryReadSystemObject(code);
  974. } else if (code & TypeMarker) {
  975. return TryReadType(code);
  976. } else {
  977. return TryReadLiteral(code, pass);
  978. }
  979. }
  980. TNode* PopNode() {
  981. if (NodeStack.empty())
  982. ThrowCorrupted();
  983. auto nodeAndFinish = NodeStack.back();
  984. NodeStack.pop_back();
  985. Current = nodeAndFinish.second;
  986. return nodeAndFinish.first;
  987. }
  988. TNode* PeekNode(ui32 index) {
  989. if (index >= NodeStack.size())
  990. ThrowCorrupted();
  991. auto nodeAndFinish = NodeStack[NodeStack.size() - 1 - index];
  992. Current = nodeAndFinish.second;
  993. return nodeAndFinish.first;
  994. }
  995. TNode* ReadNode() {
  996. char code = Read();
  997. if ((code & KindMask) == SystemMask) {
  998. return ReadSystemObject(code);
  999. } else if (code & TypeMarker) {
  1000. return ReadType(code);
  1001. } else {
  1002. return ReadLiteral(code);
  1003. }
  1004. }
  1005. ui32 TryReadType(char code) {
  1006. switch ((TType::EKind)(code & KindMask)) {
  1007. case TType::EKind::Type:
  1008. return 0;
  1009. case TType::EKind::Void: // and EmptyList, EmptyDict
  1010. return 0;
  1011. case TType::EKind::Data:
  1012. return 0;
  1013. case TType::EKind::Struct:
  1014. return TryReadStructType();
  1015. case TType::EKind::List:
  1016. return 1;
  1017. case TType::EKind::Stream:
  1018. return 1;
  1019. case TType::EKind::Optional: // and Tagged
  1020. return 1;
  1021. case TType::EKind::Dict:
  1022. return 2;
  1023. case TType::EKind::Callable:
  1024. return TryReadCallableType(code);
  1025. case TType::EKind::Any:
  1026. return 0;
  1027. case TType::EKind::Tuple: // and Multi
  1028. return TryReadTupleOrMultiType();
  1029. case TType::EKind::Resource:
  1030. return 0;
  1031. case TType::EKind::Variant:
  1032. return 1;
  1033. case TType::EKind::Flow:
  1034. return 1;
  1035. case TType::EKind::Null:
  1036. return 0;
  1037. default:
  1038. ThrowCorrupted();
  1039. }
  1040. }
  1041. TNode* ReadType(char code) {
  1042. switch ((TType::EKind)(code & KindMask)) {
  1043. case TType::EKind::Type:
  1044. return ReadTypeType();
  1045. case TType::EKind::Void:
  1046. return ReadVoidOrEmptyListOrEmptyDictType(code);
  1047. case TType::EKind::Data:
  1048. return ReadDataOrPgType(code);
  1049. case TType::EKind::Struct:
  1050. return ReadStructType();
  1051. case TType::EKind::List:
  1052. return ReadListType();
  1053. case TType::EKind::Stream:
  1054. return ReadStreamType();
  1055. case TType::EKind::Optional:
  1056. return ReadOptionalOrTaggedType(code);
  1057. case TType::EKind::Dict:
  1058. return ReadDictType();
  1059. case TType::EKind::Callable:
  1060. return ReadCallableType(code);
  1061. case TType::EKind::Any:
  1062. return ReadAnyType();
  1063. case TType::EKind::Tuple:
  1064. return ReadTupleOrMultiType(code);
  1065. case TType::EKind::Resource:
  1066. return ReadResourceType();
  1067. case TType::EKind::Variant:
  1068. return ReadVariantType();
  1069. case TType::EKind::Flow:
  1070. return ReadFlowOrBlockType(code);
  1071. case TType::EKind::Null:
  1072. return ReadNullType();
  1073. default:
  1074. ThrowCorrupted();
  1075. }
  1076. }
  1077. TNode* ReadTypeType() {
  1078. auto node = Env.GetTypeOfTypeLazy();
  1079. return node;
  1080. }
  1081. TNode* ReadVoidOrEmptyListOrEmptyDictType(char code) {
  1082. switch ((TType::EKind)(code & TypeMask)) {
  1083. case TType::EKind::Void: return Env.GetTypeOfVoidLazy();
  1084. case TType::EKind::EmptyList: return Env.GetTypeOfEmptyListLazy();
  1085. case TType::EKind::EmptyDict: return Env.GetTypeOfEmptyDictLazy();
  1086. default:
  1087. ThrowCorrupted();
  1088. }
  1089. }
  1090. TNode* ReadNullType() {
  1091. auto node = Env.GetTypeOfNullLazy();
  1092. return node;
  1093. }
  1094. TNode* ReadDataType() {
  1095. const auto schemeType = ReadVar32();
  1096. if (NUdf::TDataType<NUdf::TDecimal>::Id == schemeType) {
  1097. const ui8 precision = Read();
  1098. const ui8 scale = Read();
  1099. Nodes.emplace_back(TDataDecimalType::Create(precision, scale, Env));
  1100. } else {
  1101. Nodes.emplace_back(TDataType::Create(static_cast<NUdf::TDataTypeId>(schemeType), Env));
  1102. }
  1103. return Nodes.back();
  1104. }
  1105. TNode* ReadPgType() {
  1106. const auto typeId = ReadVar32();
  1107. Nodes.emplace_back(TPgType::Create(typeId, Env));
  1108. return Nodes.back();
  1109. }
  1110. ui32 TryReadKeyType(char code) {
  1111. const bool isRoot = (code & UserMarker1) != 0;
  1112. const bool hasStaticValue = (code & UserMarker2) != 0;
  1113. if (isRoot) {
  1114. return 0;
  1115. } else {
  1116. return hasStaticValue ? 2 : 1;
  1117. }
  1118. }
  1119. ui32 TryReadStructType() {
  1120. const ui32 membersCount = ReadVar32();
  1121. return membersCount;
  1122. }
  1123. ui32 TryReadTupleOrMultiType() {
  1124. const ui32 elementsCount = ReadVar32();
  1125. return elementsCount;
  1126. }
  1127. TNode* ReadStructType() {
  1128. const ui32 membersCount = ReadVar32();
  1129. TStackVec<TStructMember> members(membersCount);
  1130. for (ui32 i = 0; i < membersCount; ++i) {
  1131. auto memberTypeNode = PopNode();
  1132. if (memberTypeNode->GetType()->GetKind() != TType::EKind::Type)
  1133. ThrowCorrupted();
  1134. members[i].Type = static_cast<TType*>(memberTypeNode);
  1135. }
  1136. for (ui32 i = 0; i < membersCount; ++i) {
  1137. members[i].Name = ReadName();
  1138. }
  1139. auto node = TStructType::Create(membersCount, members.data(), Env);
  1140. Nodes.push_back(node);
  1141. return node;
  1142. }
  1143. TNode* ReadTupleOrMultiType(char code) {
  1144. const ui32 elementsCount = ReadVar32();
  1145. TStackVec<TType*> elements(elementsCount);
  1146. for (ui32 i = 0; i < elementsCount; ++i) {
  1147. auto elementTypeNode = PopNode();
  1148. if (elementTypeNode->GetType()->GetKind() != TType::EKind::Type)
  1149. ThrowCorrupted();
  1150. auto elementType = static_cast<TType*>(elementTypeNode);
  1151. elements[i] = elementType;
  1152. }
  1153. TNode* node = nullptr;
  1154. switch ((TType::EKind)(code & TypeMask)) {
  1155. case TType::EKind::Tuple:
  1156. node = TTupleType::Create(elementsCount, elements.data(), Env);
  1157. break;
  1158. case TType::EKind::Multi:
  1159. node = TMultiType::Create(elementsCount, elements.data(), Env);
  1160. break;
  1161. default:
  1162. ThrowCorrupted();
  1163. }
  1164. Nodes.push_back(node);
  1165. return node;
  1166. }
  1167. TNode* ReadListType() {
  1168. auto itemTypeNode = PopNode();
  1169. if (itemTypeNode->GetType()->GetKind() != TType::EKind::Type)
  1170. ThrowCorrupted();
  1171. auto itemType = static_cast<TType*>(itemTypeNode);
  1172. auto node = TListType::Create(itemType, Env);
  1173. Nodes.push_back(node);
  1174. return node;
  1175. }
  1176. TNode* ReadStreamType() {
  1177. auto itemTypeNode = PopNode();
  1178. if (itemTypeNode->GetType()->GetKind() != TType::EKind::Type)
  1179. ThrowCorrupted();
  1180. auto itemType = static_cast<TType*>(itemTypeNode);
  1181. auto node = TStreamType::Create(itemType, Env);
  1182. Nodes.push_back(node);
  1183. return node;
  1184. }
  1185. TNode* ReadFlowOrBlockType(char code) {
  1186. switch ((TType::EKind)(code & TypeMask)) {
  1187. case TType::EKind::Flow: return ReadFlowType();
  1188. case TType::EKind::Block: return ReadBlockType();
  1189. default:
  1190. ThrowCorrupted();
  1191. }
  1192. }
  1193. TNode* ReadFlowType() {
  1194. auto itemTypeNode = PopNode();
  1195. if (itemTypeNode->GetType()->GetKind() != TType::EKind::Type)
  1196. ThrowCorrupted();
  1197. auto itemType = static_cast<TType*>(itemTypeNode);
  1198. auto node = TFlowType::Create(itemType, Env);
  1199. Nodes.push_back(node);
  1200. return node;
  1201. }
  1202. TNode* ReadBlockType() {
  1203. auto itemTypeNode = PopNode();
  1204. if (itemTypeNode->GetType()->GetKind() != TType::EKind::Type) {
  1205. ThrowCorrupted();
  1206. }
  1207. const auto shapeChar = Read();
  1208. if (shapeChar != static_cast<char>(TBlockType::EShape::Scalar) &&
  1209. shapeChar != static_cast<char>(TBlockType::EShape::Many))
  1210. {
  1211. ThrowCorrupted();
  1212. }
  1213. const auto shape = static_cast<TBlockType::EShape>(shapeChar);
  1214. auto itemType = static_cast<TType*>(itemTypeNode);
  1215. auto node = TBlockType::Create(itemType, shape, Env);
  1216. Nodes.push_back(node);
  1217. return node;
  1218. }
  1219. TNode* ReadTaggedType() {
  1220. auto baseTypeNode = PopNode();
  1221. if (baseTypeNode->GetType()->GetKind() != TType::EKind::Type)
  1222. ThrowCorrupted();
  1223. auto tag = ReadName();
  1224. auto baseType = static_cast<TType*>(baseTypeNode);
  1225. auto node = TTaggedType::Create(baseType, tag, Env);
  1226. Nodes.push_back(node);
  1227. return node;
  1228. }
  1229. TNode* ReadOptionalType() {
  1230. auto itemTypeNode = PopNode();
  1231. if (itemTypeNode->GetType()->GetKind() != TType::EKind::Type)
  1232. ThrowCorrupted();
  1233. auto itemType = static_cast<TType*>(itemTypeNode);
  1234. auto node = TOptionalType::Create(itemType, Env);
  1235. Nodes.push_back(node);
  1236. return node;
  1237. }
  1238. TNode* ReadOptionalOrTaggedType(char code) {
  1239. switch ((TType::EKind)(code & TypeMask)) {
  1240. case TType::EKind::Optional: return ReadOptionalType();
  1241. case TType::EKind::Tagged: return ReadTaggedType();
  1242. default:
  1243. ThrowCorrupted();
  1244. }
  1245. }
  1246. TNode* ReadDataOrPgType(char code) {
  1247. switch ((TType::EKind)(code & TypeMask)) {
  1248. case TType::EKind::Data: return ReadDataType();
  1249. case TType::EKind::Pg: return ReadPgType();
  1250. default:
  1251. ThrowCorrupted();
  1252. }
  1253. }
  1254. TNode* ReadDictType() {
  1255. auto keyTypeNode = PopNode();
  1256. if (keyTypeNode->GetType()->GetKind() != TType::EKind::Type)
  1257. ThrowCorrupted();
  1258. auto keyType = static_cast<TType*>(keyTypeNode);
  1259. auto payloadTypeNode = PopNode();
  1260. if (payloadTypeNode->GetType()->GetKind() != TType::EKind::Type)
  1261. ThrowCorrupted();
  1262. auto payloadType = static_cast<TType*>(payloadTypeNode);
  1263. auto node = TDictType::Create(keyType, payloadType, Env);
  1264. Nodes.push_back(node);
  1265. return node;
  1266. }
  1267. ui32 TryReadCallableType(char code) {
  1268. const bool hasPayload = (code & UserMarker3) != 0;
  1269. const ui32 argumentsCount = ReadVar32();
  1270. return 1 + argumentsCount + (hasPayload ? 1 : 0);
  1271. }
  1272. TNode* ReadCallableType(char code) {
  1273. const bool isMergeDisabled = (code & UserMarker2) != 0;
  1274. const bool hasPayload = (code & UserMarker3) != 0;
  1275. const ui32 argumentsCount = ReadVar32();
  1276. auto returnTypeNode = PopNode();
  1277. if (returnTypeNode->GetType()->GetKind() != TType::EKind::Type)
  1278. ThrowCorrupted();
  1279. auto returnType = static_cast<TType*>(returnTypeNode);
  1280. TStackVec<TType*> arguments(argumentsCount);
  1281. for (ui32 i = 0; i < argumentsCount; ++i) {
  1282. auto argumentTypeNode = PopNode();
  1283. if (argumentTypeNode->GetType()->GetKind() != TType::EKind::Type)
  1284. ThrowCorrupted();
  1285. auto argumentType = static_cast<TType*>(argumentTypeNode);
  1286. arguments[i] = argumentType;
  1287. }
  1288. TNode* payload = nullptr;
  1289. if (hasPayload) {
  1290. payload = PopNode();
  1291. }
  1292. auto name = ReadName();
  1293. const ui32 optArgsCount = ReadVar32();
  1294. auto node = TCallableType::Create(returnType, name, argumentsCount, arguments.data(), payload, Env);
  1295. if (isMergeDisabled)
  1296. node->DisableMerge();
  1297. node->SetOptionalArgumentsCount(optArgsCount);
  1298. Nodes.push_back(node);
  1299. return node;
  1300. }
  1301. TNode* ReadAnyType() {
  1302. auto node = Env.GetAnyTypeLazy();
  1303. return node;
  1304. }
  1305. TNode* ReadResourceType() {
  1306. auto tag = ReadName();
  1307. auto node = TResourceType::Create(tag, Env);
  1308. Nodes.push_back(node);
  1309. return node;
  1310. }
  1311. TNode* ReadVariantType() {
  1312. auto underlyingTypeNode = PopNode();
  1313. if (underlyingTypeNode->GetType()->GetKind() != TType::EKind::Type)
  1314. ThrowCorrupted();
  1315. auto underlyingType = static_cast<TType*>(underlyingTypeNode);
  1316. auto node = TVariantType::Create(underlyingType, Env);
  1317. Nodes.push_back(node);
  1318. return node;
  1319. }
  1320. ui32 TryReadLiteral(char code, ui32 pass) {
  1321. switch ((TType::EKind)(code & KindMask)) {
  1322. case TType::EKind::Type:
  1323. ThrowCorrupted();
  1324. break;
  1325. case TType::EKind::Void:
  1326. return 0;
  1327. case TType::EKind::Data:
  1328. return 1;
  1329. case TType::EKind::Struct:
  1330. return TryReadStructLiteral(pass);
  1331. case TType::EKind::List:
  1332. return TryReadListLiteral();
  1333. case TType::EKind::Optional:
  1334. return TryReadOptionalLiteral(code);
  1335. case TType::EKind::Dict:
  1336. return TryReadDictLiteral();
  1337. case TType::EKind::Callable:
  1338. return TryReadCallable(code, pass);
  1339. case TType::EKind::Any:
  1340. return TryReadAny(code);
  1341. case TType::EKind::Tuple:
  1342. return TryReadTupleLiteral(pass);
  1343. case TType::EKind::Variant:
  1344. return 2;
  1345. case TType::EKind::Null:
  1346. return 0;
  1347. default:
  1348. ThrowCorrupted();
  1349. }
  1350. }
  1351. TNode* ReadLiteral(char code) {
  1352. switch ((TType::EKind)(code & KindMask)) {
  1353. case TType::EKind::Type:
  1354. ThrowCorrupted();
  1355. break;
  1356. case TType::EKind::Void:
  1357. return ReadVoid(code);
  1358. case TType::EKind::Data:
  1359. return ReadDataLiteral();
  1360. case TType::EKind::Struct:
  1361. return ReadStructLiteral();
  1362. case TType::EKind::List:
  1363. return ReadListLiteral();
  1364. case TType::EKind::Optional:
  1365. return ReadOptionalLiteral(code);
  1366. case TType::EKind::Dict:
  1367. return ReadDictLiteral();
  1368. case TType::EKind::Callable:
  1369. return ReadCallable(code);
  1370. case TType::EKind::Any:
  1371. return ReadAny(code);
  1372. case TType::EKind::Tuple:
  1373. return ReadTupleLiteral();
  1374. case TType::EKind::Variant:
  1375. return ReadVariantLiteral(code);
  1376. case TType::EKind::Null:
  1377. return ReadNull();
  1378. default:
  1379. ThrowCorrupted();
  1380. }
  1381. }
  1382. TNode* ReadVoid(char code) {
  1383. switch ((TType::EKind)(code & TypeMask)) {
  1384. case TType::EKind::Void: return Env.GetVoidLazy();
  1385. case TType::EKind::EmptyList: return Env.GetEmptyListLazy();
  1386. case TType::EKind::EmptyDict: return Env.GetEmptyDictLazy();
  1387. default:
  1388. ThrowCorrupted();
  1389. }
  1390. }
  1391. TNode* ReadNull() {
  1392. auto node = Env.GetNullLazy();
  1393. return node;
  1394. }
  1395. TNode* ReadDataLiteral() {
  1396. auto type = PopNode();
  1397. if (type->GetType()->GetKind() != TType::EKind::Type)
  1398. ThrowCorrupted();
  1399. if (static_cast<const TType&>(*type).GetKind() != TType::EKind::Data)
  1400. ThrowCorrupted();
  1401. auto dataType = static_cast<TDataType*>(type);
  1402. NUdf::TUnboxedValuePod value;
  1403. switch (dataType->GetSchemeType()) {
  1404. case 0:
  1405. break;
  1406. case NUdf::TDataType<bool>::Id:
  1407. value = NUdf::TUnboxedValuePod((bool)Read());
  1408. break;
  1409. case NUdf::TDataType<i8>::Id:
  1410. {
  1411. value = NUdf::TUnboxedValuePod((i8)Read());
  1412. break;
  1413. }
  1414. case NUdf::TDataType<ui8>::Id:
  1415. {
  1416. value = NUdf::TUnboxedValuePod((ui8)Read());
  1417. break;
  1418. }
  1419. case NUdf::TDataType<i16>::Id:
  1420. {
  1421. value = NUdf::TUnboxedValuePod((i16)ZigZagDecode((ui16)ReadVar32()));
  1422. break;
  1423. }
  1424. case NUdf::TDataType<ui16>::Id:
  1425. {
  1426. value = NUdf::TUnboxedValuePod((ui16)ReadVar32());
  1427. break;
  1428. }
  1429. case NUdf::TDataType<i32>::Id:
  1430. {
  1431. value = NUdf::TUnboxedValuePod((i32)ZigZagDecode(ReadVar32()));
  1432. break;
  1433. }
  1434. case NUdf::TDataType<ui32>::Id:
  1435. {
  1436. value = NUdf::TUnboxedValuePod((ui32)ReadVar32());
  1437. break;
  1438. }
  1439. case NUdf::TDataType<float>::Id:
  1440. {
  1441. value = NUdf::TUnboxedValuePod(ReadUnaligned<float>(reinterpret_cast<const float*>(ReadMany(sizeof(float)))));
  1442. break;
  1443. }
  1444. case NUdf::TDataType<i64>::Id:
  1445. {
  1446. value = NUdf::TUnboxedValuePod((i64)ZigZagDecode(ReadVar64()));
  1447. break;
  1448. }
  1449. case NUdf::TDataType<ui64>::Id:
  1450. {
  1451. value = NUdf::TUnboxedValuePod((ui64)ReadVar64());
  1452. break;
  1453. }
  1454. case NUdf::TDataType<double>::Id:
  1455. {
  1456. value = NUdf::TUnboxedValuePod(ReadUnaligned<double>(reinterpret_cast<const double*>(ReadMany(sizeof(double)))));
  1457. break;
  1458. }
  1459. case NUdf::TDataType<NUdf::TDate>::Id:
  1460. {
  1461. value = NUdf::TUnboxedValuePod(static_cast<NUdf::TDataType<NUdf::TDate>::TLayout>(ReadVar32()));
  1462. break;
  1463. }
  1464. case NUdf::TDataType<NUdf::TDatetime>::Id:
  1465. {
  1466. value = NUdf::TUnboxedValuePod(static_cast<NUdf::TDataType<NUdf::TDatetime>::TLayout>(ReadVar32()));
  1467. break;
  1468. }
  1469. case NUdf::TDataType<NUdf::TTimestamp>::Id:
  1470. {
  1471. value = NUdf::TUnboxedValuePod(static_cast<NUdf::TDataType<NUdf::TTimestamp>::TLayout>(ReadVar64()));
  1472. break;
  1473. }
  1474. case NUdf::TDataType<NUdf::TInterval>::Id:
  1475. {
  1476. value = NUdf::TUnboxedValuePod(static_cast<NUdf::TDataType<NUdf::TInterval>::TLayout>(ZigZagDecode(ReadVar64())));
  1477. break;
  1478. }
  1479. case NUdf::TDataType<NUdf::TTzDate>::Id:
  1480. {
  1481. value = NUdf::TUnboxedValuePod(static_cast<NUdf::TDataType<NUdf::TTzDate>::TLayout>(ReadVar32()));
  1482. const ui32 tzId = ReadVar32();
  1483. MKQL_ENSURE(tzId <= Max<ui16>() && IsValidTimezoneId((ui16)tzId), "Unknown timezone: " << tzId);
  1484. value.SetTimezoneId((ui16)tzId);
  1485. break;
  1486. }
  1487. case NUdf::TDataType<NUdf::TTzDatetime>::Id:
  1488. {
  1489. value = NUdf::TUnboxedValuePod(static_cast<NUdf::TDataType<NUdf::TTzDatetime>::TLayout>(ReadVar32()));
  1490. const ui32 tzId = ReadVar32();
  1491. MKQL_ENSURE(tzId <= Max<ui16>() && IsValidTimezoneId((ui16)tzId), "Unknown timezone: " << tzId);
  1492. value.SetTimezoneId((ui16)tzId);
  1493. break;
  1494. }
  1495. case NUdf::TDataType<NUdf::TTzTimestamp>::Id:
  1496. {
  1497. value = NUdf::TUnboxedValuePod(static_cast<NUdf::TDataType<NUdf::TTzTimestamp>::TLayout>(ReadVar64()));
  1498. const ui32 tzId = ReadVar32();
  1499. MKQL_ENSURE(tzId <= Max<ui16>() && IsValidTimezoneId((ui16)tzId), "Unknown timezone: " << tzId);
  1500. value.SetTimezoneId((ui16)tzId);
  1501. break;
  1502. }
  1503. case NUdf::TDataType<NUdf::TDate32>::Id:
  1504. {
  1505. value = NUdf::TUnboxedValuePod(static_cast<NUdf::TDataType<NUdf::TDate32>::TLayout>(ZigZagDecode(ReadVar32())));
  1506. break;
  1507. }
  1508. case NUdf::TDataType<NUdf::TDatetime64>::Id:
  1509. {
  1510. value = NUdf::TUnboxedValuePod(static_cast<NUdf::TDataType<NUdf::TDatetime64>::TLayout>(ZigZagDecode(ReadVar64())));
  1511. break;
  1512. }
  1513. case NUdf::TDataType<NUdf::TTimestamp64>::Id:
  1514. {
  1515. value = NUdf::TUnboxedValuePod(static_cast<NUdf::TDataType<NUdf::TTimestamp64>::TLayout>(ZigZagDecode(ReadVar64())));
  1516. break;
  1517. }
  1518. case NUdf::TDataType<NUdf::TInterval64>::Id:
  1519. {
  1520. value = NUdf::TUnboxedValuePod(static_cast<NUdf::TDataType<NUdf::TInterval64>::TLayout>(ZigZagDecode(ReadVar64())));
  1521. break;
  1522. }
  1523. case NUdf::TDataType<NUdf::TTzDate32>::Id:
  1524. {
  1525. value = NUdf::TUnboxedValuePod(static_cast<NUdf::TDataType<NUdf::TTzDate32>::TLayout>(ZigZagDecode(ReadVar32())));
  1526. const ui32 tzId = ReadVar32();
  1527. MKQL_ENSURE(tzId <= Max<ui16>() && IsValidTimezoneId((ui16)tzId), "Unknown timezone: " << tzId);
  1528. value.SetTimezoneId((ui16)tzId);
  1529. break;
  1530. }
  1531. case NUdf::TDataType<NUdf::TTzDatetime64>::Id:
  1532. {
  1533. value = NUdf::TUnboxedValuePod(static_cast<NUdf::TDataType<NUdf::TTzDatetime64>::TLayout>(ZigZagDecode(ReadVar64())));
  1534. const ui32 tzId = ReadVar32();
  1535. MKQL_ENSURE(tzId <= Max<ui16>() && IsValidTimezoneId((ui16)tzId), "Unknown timezone: " << tzId);
  1536. value.SetTimezoneId((ui16)tzId);
  1537. break;
  1538. }
  1539. case NUdf::TDataType<NUdf::TTzTimestamp64>::Id:
  1540. {
  1541. value = NUdf::TUnboxedValuePod(static_cast<NUdf::TDataType<NUdf::TTzTimestamp64>::TLayout>(ZigZagDecode(ReadVar64())));
  1542. const ui32 tzId = ReadVar32();
  1543. MKQL_ENSURE(tzId <= Max<ui16>() && IsValidTimezoneId((ui16)tzId), "Unknown timezone: " << tzId);
  1544. value.SetTimezoneId((ui16)tzId);
  1545. break;
  1546. }
  1547. case NUdf::TDataType<NUdf::TUuid>::Id:
  1548. {
  1549. const char* buffer = ReadMany(16);
  1550. value = Env.NewStringValue(NUdf::TStringRef(buffer, 16));
  1551. break;
  1552. }
  1553. case NUdf::TDataType<NUdf::TDecimal>::Id:
  1554. {
  1555. value = NUdf::TUnboxedValuePod::Zero();
  1556. const char* buffer = ReadMany(sizeof(NYql::NDecimal::TInt128) - 1U);
  1557. std::memcpy(static_cast<char*>(value.GetRawPtr()), buffer, sizeof(NYql::NDecimal::TInt128) - 1U);
  1558. break;
  1559. }
  1560. default:
  1561. const ui32 size = ReadVar32();
  1562. const char* buffer = ReadMany(size);
  1563. value = Env.NewStringValue(NUdf::TStringRef(buffer, size));
  1564. break;
  1565. }
  1566. const auto node = TDataLiteral::Create(value, dataType, Env);
  1567. Nodes.emplace_back(node);
  1568. return node;
  1569. }
  1570. ui32 TryReadKeyLiteral(char code) {
  1571. const bool isRoot = (code & UserMarker1) != 0;
  1572. const bool hasValue = (code & UserMarker2) != 0;
  1573. if (isRoot) {
  1574. return 1;
  1575. } else {
  1576. return hasValue ? 3 : 2;
  1577. }
  1578. }
  1579. ui32 TryReadStructLiteral(ui32 pass) {
  1580. if (pass == 0) {
  1581. return 1 + RequiresNextPass;
  1582. }
  1583. auto type = PeekNode(0);
  1584. if (type->GetType()->GetKind() != TType::EKind::Type)
  1585. ThrowCorrupted();
  1586. if (static_cast<const TType&>(*type).GetKind() != TType::EKind::Struct)
  1587. ThrowCorrupted();
  1588. auto structType = static_cast<TStructType*>(type);
  1589. const ui32 valuesCount = structType->GetMembersCount();
  1590. return valuesCount;
  1591. }
  1592. TNode* ReadStructLiteral() {
  1593. auto type = PopNode();
  1594. if (type->GetType()->GetKind() != TType::EKind::Type)
  1595. ThrowCorrupted();
  1596. if (static_cast<const TType&>(*type).GetKind() != TType::EKind::Struct)
  1597. ThrowCorrupted();
  1598. auto structType = static_cast<TStructType*>(type);
  1599. const ui32 valuesCount = structType->GetMembersCount();
  1600. TStackVec<TRuntimeNode> values(valuesCount);
  1601. for (ui32 i = 0; i < valuesCount; ++i) {
  1602. auto item = PopNode();
  1603. values[i] = TRuntimeNode(item, false);
  1604. }
  1605. const char* immediateFlags = ReadMany(GetBitmapBytes(valuesCount));
  1606. for (ui32 i = 0; i < valuesCount; ++i) {
  1607. values[i] = TRuntimeNode(values[i].GetNode(), GetBitmapBit(immediateFlags, i));
  1608. }
  1609. auto node = TStructLiteral::Create(valuesCount, values.data(), structType, Env);
  1610. Nodes.push_back(node);
  1611. return node;
  1612. }
  1613. ui32 TryReadTupleLiteral(ui32 pass) {
  1614. if (pass == 0) {
  1615. return 1 + RequiresNextPass;
  1616. }
  1617. auto type = PeekNode(0);
  1618. if (type->GetType()->GetKind() != TType::EKind::Type)
  1619. ThrowCorrupted();
  1620. if (static_cast<const TType&>(*type).GetKind() != TType::EKind::Tuple)
  1621. ThrowCorrupted();
  1622. auto tupleType = static_cast<TTupleType*>(type);
  1623. const ui32 valuesCount = tupleType->GetElementsCount();
  1624. return valuesCount;
  1625. }
  1626. TNode* ReadTupleLiteral() {
  1627. auto type = PopNode();
  1628. if (!type->GetType()->IsType())
  1629. ThrowCorrupted();
  1630. if (!static_cast<const TType&>(*type).IsTuple())
  1631. ThrowCorrupted();
  1632. auto tupleType = static_cast<TTupleType*>(type);
  1633. const ui32 valuesCount = tupleType->GetElementsCount();
  1634. TStackVec<TRuntimeNode> values(valuesCount);
  1635. for (ui32 i = 0; i < valuesCount; ++i) {
  1636. auto item = PopNode();
  1637. values[i] = TRuntimeNode(item, false);
  1638. }
  1639. const char* immediateFlags = ReadMany(GetBitmapBytes(valuesCount));
  1640. for (ui32 i = 0; i < valuesCount; ++i) {
  1641. values[i] = TRuntimeNode(values[i].GetNode(), GetBitmapBit(immediateFlags, i));
  1642. }
  1643. auto node = TTupleLiteral::Create(valuesCount, values.data(), tupleType, Env);
  1644. Nodes.push_back(node);
  1645. return node;
  1646. }
  1647. ui32 TryReadListLiteral() {
  1648. const ui32 itemsCount = ReadVar32();
  1649. return 1 + itemsCount;
  1650. }
  1651. TNode* ReadListLiteral() {
  1652. const ui32 itemsCount = ReadVar32();
  1653. auto type = PopNode();
  1654. if (type->GetType()->GetKind() != TType::EKind::Type)
  1655. ThrowCorrupted();
  1656. if (static_cast<const TType&>(*type).GetKind() != TType::EKind::List)
  1657. ThrowCorrupted();
  1658. auto listType = static_cast<TListType*>(type);
  1659. TVector<TRuntimeNode> items;
  1660. items.reserve(itemsCount);
  1661. for (ui32 i = 0; i < itemsCount; ++i) {
  1662. auto item = PopNode();
  1663. items.push_back(TRuntimeNode(item, false));
  1664. }
  1665. const char* immediateFlags = ReadMany(GetBitmapBytes(itemsCount));
  1666. for (ui32 i = 0; i < itemsCount; ++i) {
  1667. auto& x = items[i];
  1668. x = TRuntimeNode(x.GetNode(), GetBitmapBit(immediateFlags, i));
  1669. }
  1670. auto node = TListLiteral::Create(items.data(), items.size(), listType, Env);
  1671. Nodes.push_back(node);
  1672. return node;
  1673. }
  1674. ui32 TryReadOptionalLiteral(char code) {
  1675. const bool hasItem = (code & UserMarker1) != 0;
  1676. return hasItem ? 2 : 1;
  1677. }
  1678. TNode* ReadOptionalLiteral(char code) {
  1679. const bool hasItem = (code & UserMarker1) != 0;
  1680. const bool isItemImmediate = (code & UserMarker2) != 0;
  1681. auto type = PopNode();
  1682. if (type->GetType()->GetKind() != TType::EKind::Type)
  1683. ThrowCorrupted();
  1684. if (static_cast<const TType&>(*type).GetKind() != TType::EKind::Optional)
  1685. ThrowCorrupted();
  1686. auto optionalType = static_cast<TOptionalType*>(type);
  1687. TNode* node;
  1688. if (hasItem) {
  1689. auto item = PopNode();
  1690. node = TOptionalLiteral::Create(TRuntimeNode(item, isItemImmediate), optionalType, Env);
  1691. } else {
  1692. node = TOptionalLiteral::Create(optionalType, Env);
  1693. }
  1694. Nodes.push_back(node);
  1695. return node;
  1696. }
  1697. ui32 TryReadDictLiteral() {
  1698. const ui32 itemsCount = ReadVar32();
  1699. return 1 + 2 * itemsCount;
  1700. }
  1701. TNode* ReadDictLiteral() {
  1702. const ui32 itemsCount = ReadVar32();
  1703. auto type = PopNode();
  1704. if (type->GetType()->GetKind() != TType::EKind::Type)
  1705. ThrowCorrupted();
  1706. if (static_cast<const TType&>(*type).GetKind() != TType::EKind::Dict)
  1707. ThrowCorrupted();
  1708. auto dictType = static_cast<TDictType*>(type);
  1709. TStackVec<std::pair<TRuntimeNode, TRuntimeNode>> items(itemsCount);
  1710. for (ui32 i = 0; i < itemsCount; ++i) {
  1711. auto key = PopNode();
  1712. auto payload = PopNode();
  1713. items[i].first = TRuntimeNode(key, false);
  1714. items[i].second = TRuntimeNode(payload, false);
  1715. }
  1716. const char* immediateFlags = ReadMany(GetBitmapBytes(itemsCount * 2));
  1717. for (ui32 i = 0; i < itemsCount; ++i) {
  1718. items[i].first = TRuntimeNode(items[i].first.GetNode(), GetBitmapBit(immediateFlags, 2 * i));
  1719. items[i].second = TRuntimeNode(items[i].second.GetNode(), GetBitmapBit(immediateFlags, 2 * i + 1));
  1720. }
  1721. auto node = TDictLiteral::Create(itemsCount, items.data(), dictType, Env);
  1722. Nodes.push_back(node);
  1723. return node;
  1724. }
  1725. ui32 TryReadCallable(char code, ui32 pass) {
  1726. const bool hasResult = (code & UserMarker1) != 0;
  1727. if (hasResult) {
  1728. return 2;
  1729. }
  1730. if (pass == 0) {
  1731. return 1 | RequiresNextPass;
  1732. }
  1733. auto type = PeekNode(0);
  1734. if (type->GetType()->GetKind() != TType::EKind::Type)
  1735. ThrowCorrupted();
  1736. if (static_cast<const TType&>(*type).GetKind() != TType::EKind::Callable)
  1737. ThrowCorrupted();
  1738. auto callableType = static_cast<TCallableType*>(type);
  1739. const ui32 inputsCount = callableType->GetArgumentsCount();
  1740. return inputsCount;
  1741. }
  1742. TNode* ReadCallable(char code) {
  1743. const bool hasResult = (code & UserMarker1) != 0;
  1744. const bool hasUniqueId = (code & UserMarker2) != 0;
  1745. auto type = PopNode();
  1746. if (type->GetType()->GetKind() != TType::EKind::Type)
  1747. ThrowCorrupted();
  1748. if (static_cast<const TType&>(*type).GetKind() != TType::EKind::Callable)
  1749. ThrowCorrupted();
  1750. auto callableType = static_cast<TCallableType*>(type);
  1751. TCallable* node;
  1752. if (hasResult) {
  1753. auto resultNode = PopNode();
  1754. const bool isResultImmediate = (Read() != 0);
  1755. node = TCallable::Create(TRuntimeNode(resultNode, isResultImmediate), callableType, Env);
  1756. } else {
  1757. const ui32 inputsCount = callableType->GetArgumentsCount();
  1758. TStackVec<TRuntimeNode> inputs(inputsCount);
  1759. for (ui32 i = 0; i < inputsCount; ++i) {
  1760. auto input = PopNode();
  1761. inputs[i] = TRuntimeNode(input, false);
  1762. }
  1763. const char* immediateFlags = ReadMany(GetBitmapBytes(inputsCount));
  1764. for (ui32 i = 0; i < inputsCount; ++i) {
  1765. inputs[i] = TRuntimeNode(inputs[i].GetNode(), GetBitmapBit(immediateFlags, i));
  1766. }
  1767. node = TCallable::Create(inputsCount, inputs.data(), callableType, Env);
  1768. }
  1769. if (hasUniqueId) {
  1770. node->SetUniqueId(ReadVar32());
  1771. }
  1772. Nodes.push_back(node);
  1773. return node;
  1774. }
  1775. ui32 TryReadAny(char code) {
  1776. const bool hasItem = (code & UserMarker1) != 0;
  1777. return hasItem ? 1 : 0;
  1778. }
  1779. TNode* ReadAny(char code) {
  1780. const bool hasItem = (code & UserMarker1) != 0;
  1781. const bool isItemImmediate = (code & UserMarker2) != 0;
  1782. TAny* node = TAny::Create(Env);
  1783. if (hasItem) {
  1784. auto item = PopNode();
  1785. node->SetItem(TRuntimeNode(item, isItemImmediate));
  1786. }
  1787. Nodes.push_back(node);
  1788. return node;
  1789. }
  1790. TNode* ReadVariantLiteral(char code) {
  1791. const bool isItemImmediate = (code & UserMarker1) != 0;
  1792. auto type = PopNode();
  1793. if (type->GetType()->GetKind() != TType::EKind::Type)
  1794. ThrowCorrupted();
  1795. if (static_cast<const TType&>(*type).GetKind() != TType::EKind::Variant)
  1796. ThrowCorrupted();
  1797. auto variantType = static_cast<TVariantType*>(type);
  1798. auto item = PopNode();
  1799. ui32 index = ReadVar32();
  1800. TNode* node = TVariantLiteral::Create(TRuntimeNode(item, isItemImmediate), index, variantType, Env);
  1801. Nodes.push_back(node);
  1802. return node;
  1803. }
  1804. ui32 TryReadSystemObject(char code) {
  1805. switch (code & CommandMask) {
  1806. case (ui32)ESystemCommand::Ref:
  1807. return 0;
  1808. default:
  1809. ThrowCorrupted();
  1810. }
  1811. }
  1812. TNode* ReadSystemObject(char code) {
  1813. switch (code & CommandMask) {
  1814. case (ui32)ESystemCommand::Ref:
  1815. return ReadReference();
  1816. default:
  1817. ThrowCorrupted();
  1818. }
  1819. }
  1820. TNode* ReadReference() {
  1821. const ui32 index = ReadVar32();
  1822. if (index >= Nodes.size())
  1823. ThrowCorrupted();
  1824. return Nodes[index];
  1825. }
  1826. void LoadName() {
  1827. const ui32 length = ReadVar32();
  1828. const char* buffer = ReadMany(length);
  1829. TStringBuf name(buffer, buffer + length);
  1830. Names.push_back(name);
  1831. }
  1832. TStringBuf ReadName() {
  1833. const ui32 nameDescriptor = ReadVar32();
  1834. if (nameDescriptor & NameRefMark) {
  1835. const ui32 nameIndex = nameDescriptor >> 1;
  1836. if (nameIndex >= Names.size())
  1837. ThrowCorrupted();
  1838. return Names[nameIndex];
  1839. } else {
  1840. const ui32 length = nameDescriptor >> 1;
  1841. const char* buffer = ReadMany(length);
  1842. return TStringBuf(buffer, buffer + length);
  1843. }
  1844. }
  1845. private:
  1846. struct TNodeContext {
  1847. const char* Start;
  1848. ui32 NextPass;
  1849. ui32 ChildCount;
  1850. TNodeContext()
  1851. : Start(nullptr)
  1852. , NextPass(0)
  1853. , ChildCount(0)
  1854. {
  1855. }
  1856. };
  1857. const char* Current;
  1858. const char* const End;
  1859. const TTypeEnvironment& Env;
  1860. TVector<TNode*> Nodes;
  1861. TVector<TStringBuf> Names;
  1862. TVector<TNodeContext> CtxStack;
  1863. TVector<std::pair<TNode*, const char*>> NodeStack;
  1864. };
  1865. }
  1866. TString SerializeNode(TNode* node, const TTypeEnvironment& env) noexcept{
  1867. return SerializeRuntimeNode(TRuntimeNode(node, true), env);
  1868. }
  1869. TString SerializeRuntimeNode(TExploringNodeVisitor& explorer, TRuntimeNode node, const TTypeEnvironment& env) noexcept{
  1870. Y_UNUSED(env);
  1871. TPrepareWriteNodeVisitor preparer;
  1872. for (auto node : explorer.GetNodes()) {
  1873. node->Accept(preparer);
  1874. }
  1875. auto& names = preparer.GetNames();
  1876. auto& nameOrder = preparer.GetNameOrder();
  1877. TWriter writer(names, nameOrder);
  1878. writer.Write(node);
  1879. for (auto node : explorer.GetNodes()) {
  1880. node->SetCookie(0);
  1881. }
  1882. return writer.GetOutput();
  1883. }
  1884. TString SerializeRuntimeNode(TRuntimeNode node, const TTypeEnvironment& env) noexcept{
  1885. TExploringNodeVisitor explorer;
  1886. explorer.Walk(node.GetNode(), env);
  1887. return SerializeRuntimeNode(explorer, node, env);
  1888. }
  1889. TNode* DeserializeNode(const TStringBuf& buffer, const TTypeEnvironment& env) {
  1890. return DeserializeRuntimeNode(buffer, env).GetNode();
  1891. }
  1892. TRuntimeNode DeserializeRuntimeNode(const TStringBuf& buffer, const TTypeEnvironment& env) {
  1893. TReader reader(buffer, env);
  1894. return reader.Deserialize();
  1895. }
  1896. }
  1897. }