skiff_validator.cpp 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  1. #include "skiff.h"
  2. #include "skiff_validator.h"
  3. #include <vector>
  4. #include <stack>
  5. namespace NSkiff {
  6. ////////////////////////////////////////////////////////////////////////////////
  7. struct IValidatorNode;
  8. using TValidatorNodeList = std::vector<std::shared_ptr<IValidatorNode>>;
  9. using TSkiffSchemaList = std::vector<std::shared_ptr<TSkiffSchema>>;
  10. static std::shared_ptr<IValidatorNode> CreateUsageValidatorNode(const std::shared_ptr<TSkiffSchema>& skiffSchema);
  11. static TValidatorNodeList CreateUsageValidatorNodeList(const TSkiffSchemaList& skiffSchemaList);
  12. ////////////////////////////////////////////////////////////////////////////////
  13. template <typename T>
  14. inline void ThrowUnexpectedParseWrite(T wireType)
  15. {
  16. ythrow TSkiffException() << "Unexpected parse/write of \"" << ::ToString(wireType) << "\" token";
  17. }
  18. ////////////////////////////////////////////////////////////////////////////////
  19. struct IValidatorNode
  20. {
  21. virtual ~IValidatorNode() = default;
  22. virtual void OnBegin(TValidatorNodeStack* /*validatorNodeStack*/)
  23. { }
  24. virtual void OnChildDone(TValidatorNodeStack* /*validatorNodeStack*/)
  25. {
  26. Y_ABORT();
  27. }
  28. virtual void OnSimpleType(TValidatorNodeStack* /*validatorNodeStack*/, EWireType wireType)
  29. {
  30. ThrowUnexpectedParseWrite(wireType);
  31. }
  32. virtual void BeforeVariant8Tag()
  33. {
  34. ThrowUnexpectedParseWrite(EWireType::Variant8);
  35. }
  36. virtual void OnVariant8Tag(TValidatorNodeStack* /*validatorNodeStack*/, ui8 /*tag*/)
  37. {
  38. IValidatorNode::BeforeVariant8Tag();
  39. }
  40. virtual void BeforeVariant16Tag()
  41. {
  42. ThrowUnexpectedParseWrite(EWireType::Variant16);
  43. }
  44. virtual void OnVariant16Tag(TValidatorNodeStack* /*validatorNodeStack*/, ui16 /*tag*/)
  45. {
  46. IValidatorNode::BeforeVariant16Tag();
  47. }
  48. };
  49. ////////////////////////////////////////////////////////////////////////////////
  50. class TValidatorNodeStack
  51. {
  52. public:
  53. explicit TValidatorNodeStack(std::shared_ptr<IValidatorNode> validator)
  54. : RootValidator_(std::move(validator))
  55. { }
  56. void PushValidator(IValidatorNode* validator)
  57. {
  58. ValidatorStack_.push(validator);
  59. validator->OnBegin(this);
  60. }
  61. void PopValidator()
  62. {
  63. Y_ABORT_UNLESS(!ValidatorStack_.empty());
  64. ValidatorStack_.pop();
  65. if (!ValidatorStack_.empty()) {
  66. ValidatorStack_.top()->OnChildDone(this);
  67. }
  68. }
  69. void PushRootIfRequired()
  70. {
  71. if (ValidatorStack_.empty()) {
  72. PushValidator(RootValidator_.get());
  73. }
  74. }
  75. IValidatorNode* Top() const
  76. {
  77. Y_ABORT_UNLESS(!ValidatorStack_.empty());
  78. return ValidatorStack_.top();
  79. }
  80. bool IsFinished() const
  81. {
  82. return ValidatorStack_.empty();
  83. }
  84. private:
  85. const std::shared_ptr<IValidatorNode> RootValidator_;
  86. std::stack<IValidatorNode*> ValidatorStack_;
  87. };
  88. ////////////////////////////////////////////////////////////////////////////////
  89. class TNothingTypeValidator
  90. : public IValidatorNode
  91. {
  92. public:
  93. void OnBegin(TValidatorNodeStack* validatorNodeStack) override
  94. {
  95. validatorNodeStack->PopValidator();
  96. }
  97. };
  98. ////////////////////////////////////////////////////////////////////////////////
  99. class TSimpleTypeUsageValidator
  100. : public IValidatorNode
  101. {
  102. public:
  103. explicit TSimpleTypeUsageValidator(EWireType type)
  104. : Type_(type)
  105. { }
  106. void OnSimpleType(TValidatorNodeStack* validatorNodeStack, EWireType type) override
  107. {
  108. if (type != Type_) {
  109. ThrowUnexpectedParseWrite(type);
  110. }
  111. validatorNodeStack->PopValidator();
  112. }
  113. private:
  114. const EWireType Type_;
  115. };
  116. ////////////////////////////////////////////////////////////////////////////////
  117. template <typename TTag>
  118. void ValidateVariantTag(TValidatorNodeStack* validatorNodeStack, TTag tag, const TValidatorNodeList& children)
  119. {
  120. if (tag == EndOfSequenceTag<TTag>()) {
  121. // Root validator is pushed into the stack before variant tag
  122. // if the stack is empty.
  123. validatorNodeStack->PopValidator();
  124. } else if (tag >= children.size()) {
  125. ythrow TSkiffException() << "Variant tag \"" << tag << "\" "
  126. << "exceeds number of children \"" << children.size();
  127. } else {
  128. validatorNodeStack->PushValidator(children[tag].get());
  129. }
  130. }
  131. class TVariant8TypeUsageValidator
  132. : public IValidatorNode
  133. {
  134. public:
  135. explicit TVariant8TypeUsageValidator(TValidatorNodeList children)
  136. : Children_(std::move(children))
  137. { }
  138. void BeforeVariant8Tag() override
  139. { }
  140. void OnVariant8Tag(TValidatorNodeStack* validatorNodeStack, ui8 tag) override
  141. {
  142. ValidateVariantTag(validatorNodeStack, tag, Children_);
  143. }
  144. void OnChildDone(TValidatorNodeStack* validatorNodeStack) override
  145. {
  146. validatorNodeStack->PopValidator();
  147. }
  148. private:
  149. const TValidatorNodeList Children_;
  150. };
  151. ////////////////////////////////////////////////////////////////////////////////
  152. class TVariant16TypeUsageValidator
  153. : public IValidatorNode
  154. {
  155. public:
  156. explicit TVariant16TypeUsageValidator(TValidatorNodeList children)
  157. : Children_(std::move(children))
  158. { }
  159. void BeforeVariant16Tag() override
  160. { }
  161. void OnVariant16Tag(TValidatorNodeStack* validatorNodeStack, ui16 tag) override
  162. {
  163. ValidateVariantTag(validatorNodeStack, tag, Children_);
  164. }
  165. void OnChildDone(TValidatorNodeStack* validatorNodeStack) override
  166. {
  167. validatorNodeStack->PopValidator();
  168. }
  169. private:
  170. const TValidatorNodeList Children_;
  171. };
  172. ////////////////////////////////////////////////////////////////////////////////
  173. class TRepeatedVariant8TypeUsageValidator
  174. : public IValidatorNode
  175. {
  176. public:
  177. explicit TRepeatedVariant8TypeUsageValidator(TValidatorNodeList children)
  178. : Children_(std::move(children))
  179. { }
  180. void BeforeVariant8Tag() override
  181. { }
  182. void OnVariant8Tag(TValidatorNodeStack* validatorNodeStack, ui8 tag) override
  183. {
  184. ValidateVariantTag(validatorNodeStack, tag, Children_);
  185. }
  186. void OnChildDone(TValidatorNodeStack* /*validatorNodeStack*/) override
  187. { }
  188. private:
  189. const TValidatorNodeList Children_;
  190. };
  191. ////////////////////////////////////////////////////////////////////////////////
  192. class TRepeatedVariant16TypeUsageValidator
  193. : public IValidatorNode
  194. {
  195. public:
  196. explicit TRepeatedVariant16TypeUsageValidator(TValidatorNodeList children)
  197. : Children_(std::move(children))
  198. { }
  199. void BeforeVariant16Tag() override
  200. { }
  201. void OnVariant16Tag(TValidatorNodeStack* validatorNodeStack, ui16 tag) override
  202. {
  203. ValidateVariantTag(validatorNodeStack, tag, Children_);
  204. }
  205. void OnChildDone(TValidatorNodeStack* /*validatorNodeStack*/) override
  206. { }
  207. private:
  208. const TValidatorNodeList Children_;
  209. };
  210. ////////////////////////////////////////////////////////////////////////////////
  211. class TTupleTypeUsageValidator
  212. : public IValidatorNode
  213. {
  214. public:
  215. explicit TTupleTypeUsageValidator(TValidatorNodeList children)
  216. : Children_(std::move(children))
  217. { }
  218. void OnBegin(TValidatorNodeStack* validatorNodeStack) override
  219. {
  220. Position_ = 0;
  221. if (!Children_.empty()) {
  222. validatorNodeStack->PushValidator(Children_[0].get());
  223. }
  224. }
  225. void OnChildDone(TValidatorNodeStack* validatorNodeStack) override
  226. {
  227. Position_++;
  228. if (Position_ < Children_.size()) {
  229. validatorNodeStack->PushValidator(Children_[Position_].get());
  230. } else {
  231. validatorNodeStack->PopValidator();
  232. }
  233. }
  234. private:
  235. const TValidatorNodeList Children_;
  236. ui32 Position_ = 0;
  237. };
  238. ////////////////////////////////////////////////////////////////////////////////
  239. TSkiffValidator::TSkiffValidator(std::shared_ptr<TSkiffSchema> skiffSchema)
  240. : Context_(std::make_unique<TValidatorNodeStack>(CreateUsageValidatorNode(std::move(skiffSchema))))
  241. { }
  242. TSkiffValidator::~TSkiffValidator()
  243. { }
  244. void TSkiffValidator::BeforeVariant8Tag()
  245. {
  246. Context_->PushRootIfRequired();
  247. Context_->Top()->BeforeVariant8Tag();
  248. }
  249. void TSkiffValidator::OnVariant8Tag(ui8 tag)
  250. {
  251. Context_->PushRootIfRequired();
  252. Context_->Top()->OnVariant8Tag(Context_.get(), tag);
  253. }
  254. void TSkiffValidator::BeforeVariant16Tag()
  255. {
  256. Context_->PushRootIfRequired();
  257. Context_->Top()->BeforeVariant16Tag();
  258. }
  259. void TSkiffValidator::OnVariant16Tag(ui16 tag)
  260. {
  261. Context_->PushRootIfRequired();
  262. Context_->Top()->OnVariant16Tag(Context_.get(), tag);
  263. }
  264. void TSkiffValidator::OnSimpleType(EWireType value)
  265. {
  266. Context_->PushRootIfRequired();
  267. Context_->Top()->OnSimpleType(Context_.get(), value);
  268. }
  269. void TSkiffValidator::ValidateFinished()
  270. {
  271. if (!Context_->IsFinished()) {
  272. ythrow TSkiffException() << "Parse/write is not finished";
  273. }
  274. }
  275. ////////////////////////////////////////////////////////////////////////////////
  276. TValidatorNodeList CreateUsageValidatorNodeList(const TSkiffSchemaList& skiffSchemaList)
  277. {
  278. TValidatorNodeList result;
  279. result.reserve(skiffSchemaList.size());
  280. for (const auto& skiffSchema : skiffSchemaList) {
  281. result.push_back(CreateUsageValidatorNode(skiffSchema));
  282. }
  283. return result;
  284. }
  285. std::shared_ptr<IValidatorNode> CreateUsageValidatorNode(const std::shared_ptr<TSkiffSchema>& skiffSchema)
  286. {
  287. switch (skiffSchema->GetWireType()) {
  288. case EWireType::Int8:
  289. case EWireType::Int16:
  290. case EWireType::Int32:
  291. case EWireType::Int64:
  292. case EWireType::Int128:
  293. case EWireType::Uint8:
  294. case EWireType::Uint16:
  295. case EWireType::Uint32:
  296. case EWireType::Uint64:
  297. case EWireType::Uint128:
  298. case EWireType::Double:
  299. case EWireType::Boolean:
  300. case EWireType::String32:
  301. case EWireType::Yson32:
  302. return std::make_shared<TSimpleTypeUsageValidator>(skiffSchema->GetWireType());
  303. case EWireType::Nothing:
  304. return std::make_shared<TNothingTypeValidator>();
  305. case EWireType::Tuple:
  306. return std::make_shared<TTupleTypeUsageValidator>(CreateUsageValidatorNodeList(skiffSchema->GetChildren()));
  307. case EWireType::Variant8:
  308. return std::make_shared<TVariant8TypeUsageValidator>(CreateUsageValidatorNodeList(skiffSchema->GetChildren()));
  309. case EWireType::Variant16:
  310. return std::make_shared<TVariant16TypeUsageValidator>(CreateUsageValidatorNodeList(skiffSchema->GetChildren()));
  311. case EWireType::RepeatedVariant8:
  312. return std::make_shared<TRepeatedVariant8TypeUsageValidator>(CreateUsageValidatorNodeList(skiffSchema->GetChildren()));
  313. case EWireType::RepeatedVariant16:
  314. return std::make_shared<TRepeatedVariant16TypeUsageValidator>(CreateUsageValidatorNodeList(skiffSchema->GetChildren()));
  315. }
  316. Y_ABORT();
  317. }
  318. ////////////////////////////////////////////////////////////////////////////////
  319. } // namespace NSkiff