signature.h 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772
  1. #pragma once
  2. #include "preprocessor.h"
  3. #include <library/cpp/lwtrace/protos/lwtrace.pb.h>
  4. #include <util/generic/cast.h>
  5. #include <util/generic/string.h>
  6. #include <util/generic/typetraits.h>
  7. #include <util/string/builder.h>
  8. #include <util/string/cast.h>
  9. #include <util/string/printf.h>
  10. #include <google/protobuf/descriptor.h>
  11. #include <google/protobuf/generated_enum_reflection.h>
  12. #include <library/cpp/lwtrace/protos/lwtrace.pb.h>
  13. #include <type_traits>
  14. namespace NLWTrace {
  15. // Class to hold parameter values parsed from trace query predicate operators
  16. template <class T>
  17. struct TParamConv {
  18. static T FromString(const TString& text) {
  19. return ::FromString<T>(text);
  20. }
  21. static TString ToString(const T& param) {
  22. return ::ToString(param);
  23. }
  24. };
  25. template <>
  26. struct TParamConv<TString const*> {
  27. static TString FromString(const TString& text) {
  28. return text;
  29. }
  30. static TString ToString(TString const* param) {
  31. return TString(*param);
  32. }
  33. };
  34. template <>
  35. struct TParamConv<ui8> {
  36. static ui8 FromString(const TString& text) {
  37. return (ui8)::FromString<ui16>(text);
  38. }
  39. static TString ToString(ui8 param) {
  40. return ::ToString((ui16)param);
  41. }
  42. };
  43. template <>
  44. struct TParamConv<i8> {
  45. static i8 FromString(const TString& text) {
  46. return (i8)::FromString<i16>(text);
  47. }
  48. static TString ToString(i8 param) {
  49. return ::ToString((i16)param);
  50. }
  51. };
  52. template <>
  53. struct TParamConv<double> {
  54. static double FromString(const TString& text) {
  55. return ::FromString<double>(text);
  56. }
  57. static TString ToString(double param) {
  58. return Sprintf("%.6lf", param);
  59. }
  60. };
  61. // Fake parameter type used as a placeholder for not used parameters (above the number of defined params for a specific probe)
  62. class TNil {
  63. };
  64. // Struct that holds and handles a value of parameter of any supported type.
  65. struct TParam {
  66. char Data[LWTRACE_MAX_PARAM_SIZE];
  67. template <class T>
  68. const T& Get() const {
  69. return *reinterpret_cast<const T*>(Data);
  70. }
  71. template <class T>
  72. T& Get() {
  73. return *reinterpret_cast<T*>(Data);
  74. }
  75. template <class T>
  76. void DefaultConstruct() {
  77. new (&Data) T();
  78. }
  79. template <class T>
  80. void CopyConstruct(const T& other) {
  81. new (&Data) T(other);
  82. }
  83. template <class T>
  84. void Destruct() {
  85. Get<T>().~T();
  86. }
  87. };
  88. template <>
  89. inline void TParam::DefaultConstruct<TNil>() {
  90. }
  91. template <>
  92. inline void TParam::CopyConstruct<TNil>(const TNil&) {
  93. }
  94. template <>
  95. inline void TParam::Destruct<TNil>() {
  96. }
  97. class TTypedParam {
  98. private:
  99. EParamTypePb Type;
  100. TParam Param; // Contains garbage if PT_UNKNOWN
  101. public:
  102. TTypedParam()
  103. : Type(PT_UNKNOWN)
  104. {
  105. }
  106. explicit TTypedParam(EParamTypePb type)
  107. : Type(type)
  108. {
  109. switch (Type) {
  110. #define FOREACH_PARAMTYPE_MACRO(n, t, v) \
  111. case PT_##v: \
  112. Param.DefaultConstruct<t>(); \
  113. return;
  114. FOREACH_PARAMTYPE(FOREACH_PARAMTYPE_MACRO)
  115. #undef FOREACH_PARAMTYPE_MACRO
  116. case PT_UNKNOWN:
  117. return;
  118. default:
  119. Y_ABORT("unknown param type");
  120. }
  121. }
  122. template <class T>
  123. explicit TTypedParam(const T& x, EParamTypePb type = PT_UNKNOWN)
  124. : Type(type)
  125. {
  126. Param.CopyConstruct<T>(x);
  127. }
  128. #define FOREACH_PARAMTYPE_MACRO(n, t, v) \
  129. explicit TTypedParam(const t& x) \
  130. : Type(PT_##v) { \
  131. Param.CopyConstruct<t>(x); \
  132. }
  133. FOREACH_PARAMTYPE(FOREACH_PARAMTYPE_MACRO)
  134. #undef FOREACH_PARAMTYPE_MACRO
  135. TTypedParam(const TTypedParam& o) {
  136. Assign(o);
  137. }
  138. TTypedParam& operator=(const TTypedParam& o) {
  139. Reset();
  140. Assign(o);
  141. return *this;
  142. }
  143. void Assign(const TTypedParam& o) {
  144. Type = o.Type;
  145. switch (Type) {
  146. #define FOREACH_PARAMTYPE_MACRO(n, t, v) \
  147. case PT_##v: \
  148. Param.CopyConstruct<t>(o.Param.Get<t>()); \
  149. return;
  150. FOREACH_PARAMTYPE(FOREACH_PARAMTYPE_MACRO)
  151. #undef FOREACH_PARAMTYPE_MACRO
  152. case PT_UNKNOWN:
  153. return;
  154. default:
  155. Y_ABORT("unknown param type");
  156. }
  157. }
  158. TTypedParam(TTypedParam&& o)
  159. : Type(o.Type)
  160. , Param(o.Param)
  161. {
  162. o.Type = PT_UNKNOWN; // To avoid Param destroy by source object dtor
  163. }
  164. TTypedParam(EParamTypePb type, const TParam& param)
  165. : Type(type)
  166. {
  167. Y_UNUSED(param); // for disabled lwtrace
  168. switch (Type) {
  169. #define FOREACH_PARAMTYPE_MACRO(n, t, v) \
  170. case PT_##v: \
  171. Param.CopyConstruct<t>(param.Get<t>()); \
  172. return;
  173. FOREACH_PARAMTYPE(FOREACH_PARAMTYPE_MACRO)
  174. #undef FOREACH_PARAMTYPE_MACRO
  175. case PT_UNKNOWN:
  176. return;
  177. default:
  178. Y_ABORT("unknown param type");
  179. }
  180. }
  181. ~TTypedParam() {
  182. Reset();
  183. }
  184. void Reset() {
  185. switch (Type) {
  186. #define FOREACH_PARAMTYPE_MACRO(n, t, v) \
  187. case PT_##v: \
  188. Param.Destruct<t>(); \
  189. return;
  190. FOREACH_PARAMTYPE(FOREACH_PARAMTYPE_MACRO)
  191. #undef FOREACH_PARAMTYPE_MACRO
  192. case PT_UNKNOWN:
  193. return;
  194. default:
  195. Y_ABORT("unknown param type");
  196. }
  197. Type = PT_UNKNOWN;
  198. }
  199. bool operator==(const TTypedParam& rhs) const {
  200. if (Y_LIKELY(Type == rhs.Type)) {
  201. switch (Type) {
  202. #define FOREACH_PARAMTYPE_MACRO(n, t, v) \
  203. case PT_##v: \
  204. return Param.Get<t>() == rhs.Param.Get<t>();
  205. FOREACH_PARAMTYPE(FOREACH_PARAMTYPE_MACRO)
  206. #undef FOREACH_PARAMTYPE_MACRO
  207. case PT_UNKNOWN:
  208. return false; // All unknowns are equal
  209. default:
  210. Y_ABORT("unknown param type");
  211. }
  212. } else {
  213. return false;
  214. }
  215. }
  216. bool operator!=(const TTypedParam& rhs) const {
  217. return !operator==(rhs);
  218. }
  219. bool operator<(const TTypedParam& rhs) const {
  220. if (Y_LIKELY(Type == rhs.Type)) {
  221. switch (Type) {
  222. #define FOREACH_PARAMTYPE_MACRO(n, t, v) \
  223. case PT_##v: \
  224. return Param.Get<t>() < rhs.Param.Get<t>();
  225. FOREACH_PARAMTYPE(FOREACH_PARAMTYPE_MACRO)
  226. #undef FOREACH_PARAMTYPE_MACRO
  227. case PT_UNKNOWN:
  228. return false; // All unknowns are equal
  229. default:
  230. Y_ABORT("unknown param type");
  231. }
  232. } else {
  233. return Type < rhs.Type;
  234. }
  235. }
  236. bool operator<=(const TTypedParam& rhs) const {
  237. if (Y_LIKELY(Type == rhs.Type)) {
  238. switch (Type) {
  239. #define FOREACH_PARAMTYPE_MACRO(n, t, v) \
  240. case PT_##v: \
  241. return Param.Get<t>() <= rhs.Param.Get<t>();
  242. FOREACH_PARAMTYPE(FOREACH_PARAMTYPE_MACRO)
  243. #undef FOREACH_PARAMTYPE_MACRO
  244. case PT_UNKNOWN:
  245. return true; // All unknowns are equal
  246. default:
  247. Y_ABORT("unknown param type");
  248. }
  249. } else {
  250. return Type < rhs.Type;
  251. }
  252. }
  253. bool operator>(const TTypedParam& rhs) const {
  254. return !operator<=(rhs);
  255. }
  256. bool operator>=(const TTypedParam& rhs) const {
  257. return !operator<(rhs);
  258. }
  259. EParamTypePb GetType() const {
  260. return Type;
  261. }
  262. const TParam& GetParam() const {
  263. return Param;
  264. }
  265. };
  266. class TLiteral {
  267. private:
  268. TTypedParam Values[EParamTypePb_ARRAYSIZE];
  269. public:
  270. explicit TLiteral(const TString& text) {
  271. Y_UNUSED(text); /* That's for windows, where we have lwtrace disabled. */
  272. #define FOREACH_PARAMTYPE_MACRO(n, t, v) \
  273. try { \
  274. Values[PT_##v] = TTypedParam(TParamConv<t>::FromString(text)); \
  275. } catch (...) { \
  276. Values[PT_##v] = TTypedParam(); \
  277. } \
  278. /**/
  279. FOREACH_PARAMTYPE(FOREACH_PARAMTYPE_MACRO)
  280. #undef FOREACH_PARAMTYPE_MACRO
  281. }
  282. TLiteral() {
  283. }
  284. TLiteral(const TLiteral& o) {
  285. for (size_t i = 0; i < EParamTypePb_ARRAYSIZE; i++) {
  286. Values[i] = o.Values[i];
  287. }
  288. }
  289. TLiteral& operator=(const TLiteral& o) {
  290. for (size_t i = 0; i < EParamTypePb_ARRAYSIZE; i++) {
  291. Values[i] = o.Values[i];
  292. }
  293. return *this;
  294. }
  295. const TTypedParam& GetValue(EParamTypePb type) const {
  296. return Values[type];
  297. }
  298. bool operator==(const TTypedParam& rhs) const {
  299. return Values[rhs.GetType()] == rhs;
  300. }
  301. bool operator!=(const TTypedParam& rhs) const {
  302. return !operator==(rhs);
  303. }
  304. bool operator<(const TTypedParam& rhs) const {
  305. return Values[rhs.GetType()] < rhs;
  306. }
  307. bool operator<=(const TTypedParam& rhs) const {
  308. return Values[rhs.GetType()] <= rhs;
  309. }
  310. bool operator>(const TTypedParam& rhs) const {
  311. return !operator<=(rhs);
  312. }
  313. bool operator>=(const TTypedParam& rhs) const {
  314. return !operator<(rhs);
  315. }
  316. };
  317. inline bool operator==(const TTypedParam& lhs, const TLiteral& rhs) {
  318. return lhs == rhs.GetValue(lhs.GetType());
  319. }
  320. inline bool operator!=(const TTypedParam& lhs, const TLiteral& rhs) {
  321. return !operator==(lhs, rhs);
  322. }
  323. inline bool operator<(const TTypedParam& lhs, const TLiteral& rhs) {
  324. return lhs < rhs.GetValue(lhs.GetType());
  325. }
  326. inline bool operator<=(const TTypedParam& lhs, const TLiteral& rhs) {
  327. return lhs <= rhs.GetValue(lhs.GetType());
  328. }
  329. inline bool operator>(const TTypedParam& lhs, const TLiteral& rhs) {
  330. return !operator<=(lhs, rhs);
  331. }
  332. inline bool operator>=(const TTypedParam& lhs, const TLiteral& rhs) {
  333. return !operator<(lhs, rhs);
  334. }
  335. // Struct that holds and handles all parameter values of different supported types
  336. struct TParams {
  337. TParam Param[LWTRACE_MAX_PARAMS];
  338. };
  339. using TSerializedParams = google::protobuf::RepeatedPtrField<NLWTrace::TTraceParam>;
  340. // Represents a common class for all function "signatures" (parameter types and names).
  341. // Provides non-virtual interface to handle the signature and (emulated) virtual interface to handle TParams corresponding to the signature
  342. struct TSignature {
  343. const char** ParamTypes;
  344. const char* ParamNames[LWTRACE_MAX_PARAMS + 1];
  345. size_t ParamCount;
  346. // Virtual table
  347. void (*SerializeParamsFunc)(const TParams& params, TString* values);
  348. void (*CloneParamsFunc)(TParams& newParams, const TParams& oldParams);
  349. void (*DestroyParamsFunc)(TParams& params);
  350. void (*SerializeToPbFunc)(const TParams& params, TSerializedParams& arr);
  351. bool (*DeserializeFromPbFunc)(TParams& params, const TSerializedParams& arr);
  352. // Virtual calls emulation
  353. void SerializeParams(const TParams& params, TString* values) const {
  354. (*SerializeParamsFunc)(params, values);
  355. }
  356. void CloneParams(TParams& newParams, const TParams& oldParams) const {
  357. (*CloneParamsFunc)(newParams, oldParams);
  358. }
  359. void DestroyParams(TParams& params) const {
  360. (*DestroyParamsFunc)(params);
  361. }
  362. void SerializeToPb(const TParams& params, TSerializedParams& arr) const
  363. {
  364. (*SerializeToPbFunc)(params, arr);
  365. }
  366. bool DeserializeFromPb(TParams& params, const TSerializedParams& arr) const
  367. {
  368. return (*DeserializeFromPbFunc)(params, arr);
  369. }
  370. void ToProtobuf(TEventPb& pb) const;
  371. size_t FindParamIndex(const TString& param) const {
  372. for (size_t i = 0; i < ParamCount; i++) {
  373. if (ParamNames[i] == param) {
  374. return i;
  375. }
  376. }
  377. return size_t(-1);
  378. }
  379. };
  380. #ifndef LWTRACE_DISABLE
  381. // Implementation. Used for compilation error if not all expected parameters passed to a function call
  382. struct ERROR_not_enough_parameters : TNil {};
  383. // Struct that holds static string with a name of parameter type
  384. template <class T>
  385. struct TParamType {
  386. enum { Supported = 0 };
  387. static const char* NameString;
  388. };
  389. #define FOREACH_PARAMTYPE_MACRO(n, t, v) \
  390. template <> \
  391. struct TParamType<t> { \
  392. enum { Supported = 1 }; \
  393. static const char* NameString; \
  394. }; \
  395. /**/
  396. FOREACH_PARAMTYPE(FOREACH_PARAMTYPE_MACRO)
  397. FOR_NIL_PARAMTYPE(FOREACH_PARAMTYPE_MACRO)
  398. #undef FOREACH_PARAMTYPE_MACRO
  399. template <class T>
  400. struct TParamTraits;
  401. // Enum types traits impl.
  402. template <class TEnum, class = std::enable_if_t<std::is_enum_v<TEnum>>>
  403. struct TEnumParamTraitsImpl {
  404. using TStoreType = typename TParamTraits<std::underlying_type_t<TEnum>>::TStoreType;
  405. using TFuncParam = TEnum;
  406. inline static void ToString(typename TTypeTraits<TStoreType>::TFuncParam stored, TString* out) {
  407. if constexpr (google::protobuf::is_proto_enum<TEnum>::value) {
  408. const google::protobuf::EnumValueDescriptor* valueDescriptor = google::protobuf::GetEnumDescriptor<TEnum>()->FindValueByNumber(stored);
  409. if (valueDescriptor) {
  410. *out = TStringBuilder() << valueDescriptor->name() << " (" << stored << ")";
  411. } else {
  412. *out = TParamConv<TStoreType>::ToString(stored);
  413. }
  414. } else {
  415. *out = TParamConv<TStoreType>::ToString(stored);
  416. }
  417. }
  418. inline static TStoreType ToStoreType(TFuncParam v) {
  419. return static_cast<TStoreType>(v);
  420. }
  421. };
  422. template <class TCustomType>
  423. struct TCustomTraitsImpl {
  424. using TStoreType = typename TParamTraits<typename TCustomType::TStoreType>::TStoreType; //see STORE_TYPE_AS
  425. using TFuncParam = typename TCustomType::TFuncParam;
  426. inline static void ToString(typename TTypeTraits<TStoreType>::TFuncParam stored, TString* out) {
  427. TCustomType::ToString(stored, out);
  428. }
  429. inline static TStoreType ToStoreType(TFuncParam v) {
  430. return TCustomType::ToStoreType(v);
  431. }
  432. };
  433. template <class T, bool isEnum>
  434. struct TParamTraitsImpl;
  435. template <class TEnum>
  436. struct TParamTraitsImpl<TEnum, true> : TEnumParamTraitsImpl<TEnum> {
  437. };
  438. template <class TCustomType>
  439. struct TParamTraitsImpl<TCustomType, false> : TCustomTraitsImpl<TCustomType> {
  440. };
  441. template <class T>
  442. struct TParamTraits : TParamTraitsImpl<T, std::is_enum_v<T>> {
  443. };
  444. // Standard stored types traits.
  445. #define STORE_TYPE_AS(input_t, store_as_t) \
  446. template <> \
  447. struct TParamTraits<input_t> { \
  448. using TStoreType = store_as_t; \
  449. using TFuncParam = typename TTypeTraits<input_t>::TFuncParam; \
  450. \
  451. inline static void ToString(typename TTypeTraits<TStoreType>::TFuncParam stored, TString* out) { \
  452. *out = TParamConv<TStoreType>::ToString(stored); \
  453. } \
  454. \
  455. inline static TStoreType ToStoreType(TFuncParam v) { \
  456. return v; \
  457. } \
  458. }; \
  459. /**/
  460. STORE_TYPE_AS(ui8, ui64);
  461. STORE_TYPE_AS(i8, i64);
  462. STORE_TYPE_AS(ui16, ui64);
  463. STORE_TYPE_AS(i16, i64);
  464. STORE_TYPE_AS(ui32, ui64);
  465. STORE_TYPE_AS(i32, i64);
  466. STORE_TYPE_AS(bool, ui64);
  467. STORE_TYPE_AS(float, double);
  468. #define FOREACH_PARAMTYPE_MACRO(n, t, v) STORE_TYPE_AS(t, t)
  469. FOREACH_PARAMTYPE(FOREACH_PARAMTYPE_MACRO)
  470. #undef STORE_TYPE_AS
  471. #undef FOREACH_PARAMTYPE_MACRO
  472. // Nil type staits.
  473. template <>
  474. struct TParamTraits<TNil> {
  475. using TStoreType = TNil;
  476. using TFuncParam = TTypeTraits<TNil>::TFuncParam;
  477. inline static void ToString(typename TTypeTraits<TNil>::TFuncParam, TString*) {
  478. }
  479. inline static TNil ToStoreType(TFuncParam v) {
  480. return v;
  481. }
  482. };
  483. inline EParamTypePb ParamTypeToProtobuf(const char* paramType) {
  484. #define FOREACH_PARAMTYPE_MACRO(n, t, v) \
  485. if (strcmp(paramType, n) == 0) { \
  486. return PT_##v; \
  487. } \
  488. /**/
  489. FOREACH_PARAMTYPE(FOREACH_PARAMTYPE_MACRO)
  490. #undef FOREACH_PARAMTYPE_MACRO
  491. return PT_UNKNOWN;
  492. }
  493. template <typename T>
  494. inline void SaveParamToPb(TSerializedParams& msg, const TParam& param);
  495. template <>
  496. inline void SaveParamToPb<TNil>(TSerializedParams& msg, const TParam& param)
  497. {
  498. Y_UNUSED(msg);
  499. Y_UNUSED(param);
  500. }
  501. template <>
  502. inline void SaveParamToPb<i64>(TSerializedParams& msg, const TParam& param)
  503. {
  504. msg.Add()->SetIntValue(param.Get<typename TParamTraits<i64>::TStoreType>());
  505. }
  506. template <>
  507. inline void SaveParamToPb<ui64>(TSerializedParams& msg, const TParam& param)
  508. {
  509. msg.Add()->SetUintValue(param.Get<typename TParamTraits<ui64>::TStoreType>());
  510. }
  511. template <>
  512. inline void SaveParamToPb<double>(TSerializedParams& msg, const TParam& param)
  513. {
  514. msg.Add()->SetDoubleValue(param.Get<typename TParamTraits<double>::TStoreType>());
  515. }
  516. template <>
  517. inline void SaveParamToPb<TString>(TSerializedParams& msg, const TParam& param)
  518. {
  519. msg.Add()->SetStrValue(param.Get<typename TParamTraits<TString>::TStoreType>());
  520. }
  521. template <>
  522. inline void SaveParamToPb<TSymbol>(TSerializedParams& msg, const TParam& param)
  523. {
  524. msg.Add()->SetStrValue(*param.Get<typename TParamTraits<TSymbol>::TStoreType>().Str);
  525. }
  526. template <>
  527. inline void SaveParamToPb<TCheck>(TSerializedParams& msg, const TParam& param)
  528. {
  529. msg.Add()->SetIntValue(param.Get<typename TParamTraits<TCheck>::TStoreType>().Value);
  530. }
  531. template <typename T>
  532. inline void LoadParamFromPb(const TTraceParam& msg, TParam& param);
  533. template <>
  534. inline void LoadParamFromPb<i64>(const TTraceParam& msg, TParam& param)
  535. {
  536. param.DefaultConstruct<i64>();
  537. param.Get<i64>() = msg.GetIntValue();
  538. }
  539. template <>
  540. inline void LoadParamFromPb<ui64>(const TTraceParam& msg, TParam& param)
  541. {
  542. param.DefaultConstruct<ui64>();
  543. param.Get<ui64>() = msg.GetUintValue();
  544. }
  545. template <>
  546. inline void LoadParamFromPb<double>(const TTraceParam& msg, TParam& param)
  547. {
  548. param.DefaultConstruct<double>();
  549. param.Get<double>() = msg.GetDoubleValue();
  550. }
  551. template <>
  552. inline void LoadParamFromPb<TCheck>(const TTraceParam& msg, TParam& param)
  553. {
  554. param.CopyConstruct<TCheck>(TCheck(msg.GetIntValue()));
  555. }
  556. template <>
  557. inline void LoadParamFromPb<TSymbol>(const TTraceParam& msg, TParam& param)
  558. {
  559. Y_UNUSED(msg);
  560. Y_UNUSED(param);
  561. static TString unsupported("unsupported");
  562. // so far TSymbol deserialization is not supported
  563. // since it is not used for probes, it is ok
  564. param.CopyConstruct<TSymbol>(TSymbol(&unsupported));
  565. }
  566. template <>
  567. inline void LoadParamFromPb<TString>(const TTraceParam& msg, TParam& param)
  568. {
  569. param.DefaultConstruct<TString>();
  570. param.Get<TString>() = msg.GetStrValue();
  571. }
  572. template <>
  573. inline void LoadParamFromPb<TNil>(const TTraceParam& msg, TParam& param)
  574. {
  575. Y_UNUSED(msg);
  576. Y_UNUSED(param);
  577. }
  578. // Class representing a specific signature
  579. template <LWTRACE_TEMPLATE_PARAMS>
  580. struct TUserSignature {
  581. #define FOREACH_PARAMNUM_MACRO(i) static_assert(TParamType<typename TParamTraits<TP##i>::TStoreType>::Supported == 1, "expect TParamType< typename TParamTraits<TP ## i>::TStoreType >::Supported == 1");
  582. FOREACH_PARAMNUM(FOREACH_PARAMNUM_MACRO) // ERROR: unsupported type used as probe/event parameter type
  583. #undef FOREACH_PARAMNUM_MACRO
  584. static const char* ParamTypes[];
  585. static const int ParamCount = LWTRACE_COUNT_PARAMS;
  586. // Implementation of virtual function (TSignature derived classes vtable emulation)
  587. inline static void SerializeParams(const TParams& params, TString* values) {
  588. #define FOREACH_PARAMNUM_MACRO(i) TParamTraits<TP##i>::ToString(params.Param[i].Get<typename TParamTraits<TP##i>::TStoreType>(), values + i);
  589. FOREACH_PARAMNUM(FOREACH_PARAMNUM_MACRO);
  590. #undef FOREACH_PARAMNUM_MACRO
  591. }
  592. // Implementation of virtual function (TSignature derived classes vtable emulation)
  593. inline static void CloneParams(TParams& newParams, const TParams& oldParams) {
  594. #define FOREACH_PARAMNUM_MACRO(i) newParams.Param[i].CopyConstruct<typename TParamTraits<TP##i>::TStoreType>(oldParams.Param[i].Get<typename TParamTraits<TP##i>::TStoreType>());
  595. FOREACH_PARAMNUM(FOREACH_PARAMNUM_MACRO);
  596. #undef FOREACH_PARAMNUM_MACRO
  597. }
  598. // Implementation of virtual function (TSignature derived classes vtable emulation)
  599. inline static void DestroyParams(TParams& params) {
  600. #define FOREACH_PARAMNUM_MACRO(i) params.Param[i].Destruct<typename TParamTraits<TP##i>::TStoreType>();
  601. FOREACH_PARAMNUM(FOREACH_PARAMNUM_MACRO);
  602. #undef FOREACH_PARAMNUM_MACRO
  603. }
  604. // Implementation of virtual function (TSignature derived classes vtable emulation)
  605. inline static void SerializeToPb(const TParams& params, TSerializedParams& arr)
  606. {
  607. #define FOREACH_PARAMNUM_MACRO(i) \
  608. SaveParamToPb<typename TParamTraits<TP##i>::TStoreType>( \
  609. arr, \
  610. params.Param[i]); \
  611. // FOREACH_PARAMNUM_MACRO
  612. FOREACH_PARAMNUM(FOREACH_PARAMNUM_MACRO);
  613. #undef FOREACH_PARAMNUM_MACRO
  614. }
  615. // Implementation of virtual function (TSignature derived classes vtable emulation)
  616. inline static bool DeserializeFromPb(TParams& params, const TSerializedParams& arr) {
  617. if (arr.size() != ParamCount) {
  618. return false;
  619. }
  620. if (!ParamCount) {
  621. return true;
  622. }
  623. int paramIdx = 0;
  624. #define FOREACH_PARAMNUM_MACRO(i) \
  625. if (paramIdx >= arr.size()) { \
  626. return true; \
  627. }; \
  628. LoadParamFromPb<typename TParamTraits<TP##i>::TStoreType>( \
  629. arr.Get(paramIdx), \
  630. params.Param[paramIdx]); \
  631. ++paramIdx; \
  632. // FOREACH_PARAMNUM_MACRO
  633. FOREACH_PARAMNUM(FOREACH_PARAMNUM_MACRO);
  634. #undef FOREACH_PARAMNUM_MACRO
  635. return true;
  636. }
  637. };
  638. // Array of static strings pointers for names of parameter types in a specific signature
  639. template <LWTRACE_TEMPLATE_PARAMS_NODEF>
  640. const char* TUserSignature<LWTRACE_TEMPLATE_ARGS>::ParamTypes[] = {
  641. #define FOREACH_PARAMNUM_MACRO(i) TParamType<typename TParamTraits<TP##i>::TStoreType>::NameString,
  642. FOREACH_PARAMNUM(FOREACH_PARAMNUM_MACRO) nullptr
  643. #undef FOREACH_PARAMNUM_MACRO
  644. };
  645. inline void TSignature::ToProtobuf(TEventPb& pb) const {
  646. for (size_t i = 0; i < ParamCount; i++) {
  647. pb.AddParamTypes(ParamTypeToProtobuf(ParamTypes[i]));
  648. pb.AddParamNames(ParamNames[i]);
  649. }
  650. }
  651. #else
  652. inline void TSignature::ToProtobuf(TEventPb&) const {
  653. }
  654. inline EParamTypePb ParamTypeToProtobuf(const char*) {
  655. return PT_UNKNOWN;
  656. }
  657. #endif
  658. }