ResolvingDecoder.cc 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683
  1. /**
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * https://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. #include <algorithm>
  19. #include <map>
  20. #include <memory>
  21. #include <string>
  22. #include <utility>
  23. #include "Decoder.hh"
  24. #include "Encoder.hh"
  25. #include "Generic.hh"
  26. #include "NodeImpl.hh"
  27. #include "Stream.hh"
  28. #include "Symbol.hh"
  29. #include "Types.hh"
  30. #include "ValidSchema.hh"
  31. #include "ValidatingCodec.hh"
  32. namespace avro {
  33. using std::make_shared;
  34. namespace parsing {
  35. using std::make_shared;
  36. using std::shared_ptr;
  37. using std::static_pointer_cast;
  38. using std::find_if;
  39. using std::istringstream;
  40. using std::make_pair;
  41. using std::map;
  42. using std::ostringstream;
  43. using std::pair;
  44. using std::reverse;
  45. using std::stack;
  46. using std::string;
  47. using std::unique_ptr;
  48. using std::vector;
  49. typedef pair<NodePtr, NodePtr> NodePair;
  50. class ResolvingGrammarGenerator : public ValidatingGrammarGenerator {
  51. ProductionPtr doGenerate2(const NodePtr &writer,
  52. const NodePtr &reader, map<NodePair, ProductionPtr> &m,
  53. map<NodePtr, ProductionPtr> &m2);
  54. ProductionPtr resolveRecords(const NodePtr &writer,
  55. const NodePtr &reader, map<NodePair, ProductionPtr> &m,
  56. map<NodePtr, ProductionPtr> &m2);
  57. ProductionPtr resolveUnion(const NodePtr &writer,
  58. const NodePtr &reader, map<NodePair, ProductionPtr> &m,
  59. map<NodePtr, ProductionPtr> &m2);
  60. static vector<pair<string, size_t>> fields(const NodePtr &n) {
  61. vector<pair<string, size_t>> result;
  62. size_t c = n->names();
  63. for (size_t i = 0; i < c; ++i) {
  64. result.emplace_back(n->nameAt(i), i);
  65. }
  66. return result;
  67. }
  68. static int bestBranch(const NodePtr &writer, const NodePtr &reader);
  69. ProductionPtr getWriterProduction(const NodePtr &n,
  70. map<NodePtr, ProductionPtr> &m2);
  71. public:
  72. Symbol generate(
  73. const ValidSchema &writer, const ValidSchema &reader);
  74. };
  75. Symbol ResolvingGrammarGenerator::generate(
  76. const ValidSchema &writer, const ValidSchema &reader) {
  77. map<NodePtr, ProductionPtr> m2;
  78. const NodePtr &rr = reader.root();
  79. const NodePtr &rw = writer.root();
  80. ProductionPtr backup = ValidatingGrammarGenerator::doGenerate(rw, m2);
  81. fixup(backup, m2);
  82. map<NodePair, ProductionPtr> m;
  83. ProductionPtr main = doGenerate2(rw, rr, m, m2);
  84. fixup(main, m);
  85. return Symbol::rootSymbol(main, backup);
  86. }
  87. int ResolvingGrammarGenerator::bestBranch(const NodePtr &writer,
  88. const NodePtr &reader) {
  89. Type t = writer->type();
  90. const size_t c = reader->leaves();
  91. for (size_t j = 0; j < c; ++j) {
  92. NodePtr r = reader->leafAt(j);
  93. if (r->type() == AVRO_SYMBOLIC) {
  94. r = resolveSymbol(r);
  95. }
  96. if (t == r->type()) {
  97. if (r->hasName()) {
  98. if (r->name() == writer->name()) {
  99. return j;
  100. }
  101. } else {
  102. return j;
  103. }
  104. }
  105. }
  106. for (size_t j = 0; j < c; ++j) {
  107. const NodePtr &r = reader->leafAt(j);
  108. Type rt = r->type();
  109. switch (t) {
  110. case AVRO_INT:
  111. if (rt == AVRO_LONG || rt == AVRO_DOUBLE || rt == AVRO_FLOAT) {
  112. return j;
  113. }
  114. break;
  115. case AVRO_LONG:
  116. case AVRO_FLOAT:
  117. if (rt == AVRO_DOUBLE) {
  118. return j;
  119. }
  120. break;
  121. default:
  122. break;
  123. }
  124. }
  125. return -1;
  126. }
  127. static shared_ptr<vector<uint8_t>> getAvroBinary(
  128. const GenericDatum &defaultValue) {
  129. EncoderPtr e = binaryEncoder();
  130. unique_ptr<OutputStream> os = memoryOutputStream();
  131. e->init(*os);
  132. GenericWriter::write(*e, defaultValue);
  133. e->flush();
  134. return snapshot(*os);
  135. }
  136. template<typename T1, typename T2>
  137. struct equalsFirst {
  138. const T1 &v_;
  139. explicit equalsFirst(const T1 &v) : v_(v) {}
  140. bool operator()(const pair<T1, T2> &p) {
  141. return p.first == v_;
  142. }
  143. };
  144. ProductionPtr ResolvingGrammarGenerator::getWriterProduction(
  145. const NodePtr &n, map<NodePtr, ProductionPtr> &m2) {
  146. const NodePtr &nn = (n->type() == AVRO_SYMBOLIC) ? static_cast<const NodeSymbolic &>(*n).getNode() : n;
  147. map<NodePtr, ProductionPtr>::const_iterator it2 = m2.find(nn);
  148. if (it2 != m2.end()) {
  149. return it2->second;
  150. } else {
  151. ProductionPtr result = ValidatingGrammarGenerator::doGenerate(nn, m2);
  152. fixup(result, m2);
  153. return result;
  154. }
  155. }
  156. ProductionPtr ResolvingGrammarGenerator::resolveRecords(
  157. const NodePtr &writer, const NodePtr &reader,
  158. map<NodePair, ProductionPtr> &m,
  159. map<NodePtr, ProductionPtr> &m2) {
  160. ProductionPtr result = make_shared<Production>();
  161. vector<pair<string, size_t>> wf = fields(writer);
  162. vector<pair<string, size_t>> rf = fields(reader);
  163. vector<size_t> fieldOrder;
  164. fieldOrder.reserve(reader->names());
  165. /*
  166. * We look for all writer fields in the reader. If found, recursively
  167. * resolve the corresponding fields. Then erase the reader field.
  168. * If no matching field is found for reader, arrange to skip the writer
  169. * field.
  170. */
  171. for (vector<pair<string, size_t>>::const_iterator it = wf.begin();
  172. it != wf.end(); ++it) {
  173. auto it2 = find_if(rf.begin(), rf.end(),
  174. equalsFirst<string, size_t>(it->first));
  175. if (it2 != rf.end()) {
  176. ProductionPtr p = doGenerate2(writer->leafAt(it->second),
  177. reader->leafAt(it2->second), m, m2);
  178. copy(p->rbegin(), p->rend(), back_inserter(*result));
  179. fieldOrder.push_back(it2->second);
  180. rf.erase(it2);
  181. } else {
  182. ProductionPtr p = getWriterProduction(
  183. writer->leafAt(it->second), m2);
  184. result->push_back(Symbol::skipStart());
  185. if (p->size() == 1) {
  186. result->push_back((*p)[0]);
  187. } else {
  188. result->push_back(Symbol::indirect(p));
  189. }
  190. }
  191. }
  192. /*
  193. * Examine the reader fields left out, (i.e. those didn't have corresponding
  194. * writer field).
  195. */
  196. for (vector<pair<string, size_t>>::const_iterator it = rf.begin();
  197. it != rf.end(); ++it) {
  198. NodePtr s = reader->leafAt(it->second);
  199. fieldOrder.push_back(it->second);
  200. if (s->type() == AVRO_SYMBOLIC) {
  201. s = resolveSymbol(s);
  202. }
  203. shared_ptr<vector<uint8_t>> defaultBinary =
  204. getAvroBinary(reader->defaultValueAt(it->second));
  205. result->push_back(Symbol::defaultStartAction(defaultBinary));
  206. map<NodePair, shared_ptr<Production>>::const_iterator it2 =
  207. m.find(NodePair(s, s));
  208. ProductionPtr p = (it2 == m.end()) ? doGenerate2(s, s, m, m2) : it2->second;
  209. copy(p->rbegin(), p->rend(), back_inserter(*result));
  210. result->push_back(Symbol::defaultEndAction());
  211. }
  212. reverse(result->begin(), result->end());
  213. result->push_back(Symbol::sizeListAction(fieldOrder));
  214. result->push_back(Symbol::recordAction());
  215. return result;
  216. }
  217. ProductionPtr ResolvingGrammarGenerator::resolveUnion(
  218. const NodePtr &writer, const NodePtr &reader,
  219. map<NodePair, ProductionPtr> &m,
  220. map<NodePtr, ProductionPtr> &m2) {
  221. vector<ProductionPtr> v;
  222. size_t c = writer->leaves();
  223. v.reserve(c);
  224. for (size_t i = 0; i < c; ++i) {
  225. ProductionPtr p = doGenerate2(writer->leafAt(i), reader, m, m2);
  226. v.push_back(p);
  227. }
  228. ProductionPtr result = make_shared<Production>();
  229. result->push_back(Symbol::alternative(v));
  230. result->push_back(Symbol::writerUnionAction());
  231. return result;
  232. }
  233. ProductionPtr ResolvingGrammarGenerator::doGenerate2(
  234. const NodePtr &w, const NodePtr &r,
  235. map<NodePair, ProductionPtr> &m,
  236. map<NodePtr, ProductionPtr> &m2) {
  237. const NodePtr writer = w->type() == AVRO_SYMBOLIC ? resolveSymbol(w) : w;
  238. const NodePtr reader = r->type() == AVRO_SYMBOLIC ? resolveSymbol(r) : r;
  239. Type writerType = writer->type();
  240. Type readerType = reader->type();
  241. if (writerType == readerType) {
  242. switch (writerType) {
  243. case AVRO_NULL:
  244. return make_shared<Production>(1, Symbol::nullSymbol());
  245. case AVRO_BOOL:
  246. return make_shared<Production>(1, Symbol::boolSymbol());
  247. case AVRO_INT:
  248. return make_shared<Production>(1, Symbol::intSymbol());
  249. case AVRO_LONG:
  250. return make_shared<Production>(1, Symbol::longSymbol());
  251. case AVRO_FLOAT:
  252. return make_shared<Production>(1, Symbol::floatSymbol());
  253. case AVRO_DOUBLE:
  254. return make_shared<Production>(1, Symbol::doubleSymbol());
  255. case AVRO_STRING:
  256. return make_shared<Production>(1, Symbol::stringSymbol());
  257. case AVRO_BYTES:
  258. return make_shared<Production>(1, Symbol::bytesSymbol());
  259. case AVRO_FIXED:
  260. if (writer->name() == reader->name() && writer->fixedSize() == reader->fixedSize()) {
  261. ProductionPtr result = make_shared<Production>();
  262. result->push_back(Symbol::sizeCheckSymbol(reader->fixedSize()));
  263. result->push_back(Symbol::fixedSymbol());
  264. m[make_pair(writer, reader)] = result;
  265. return result;
  266. }
  267. break;
  268. case AVRO_RECORD:
  269. if (writer->name() == reader->name()) {
  270. const pair<NodePtr, NodePtr> key(writer, reader);
  271. map<NodePair, ProductionPtr>::const_iterator kp = m.find(key);
  272. if (kp != m.end()) {
  273. return (kp->second) ? kp->second : make_shared<Production>(1, Symbol::placeholder(key));
  274. }
  275. m[key] = ProductionPtr();
  276. ProductionPtr result = resolveRecords(writer, reader, m, m2);
  277. m[key] = result;
  278. return make_shared<Production>(1, Symbol::indirect(result));
  279. }
  280. break;
  281. case AVRO_ENUM:
  282. if (writer->name() == reader->name()) {
  283. ProductionPtr result = make_shared<Production>();
  284. result->push_back(Symbol::enumAdjustSymbol(writer, reader));
  285. result->push_back(Symbol::enumSymbol());
  286. m[make_pair(writer, reader)] = result;
  287. return result;
  288. }
  289. break;
  290. case AVRO_ARRAY: {
  291. ProductionPtr p = getWriterProduction(writer->leafAt(0), m2);
  292. ProductionPtr p2 = doGenerate2(writer->leafAt(0), reader->leafAt(0), m, m2);
  293. ProductionPtr result = make_shared<Production>();
  294. result->push_back(Symbol::arrayEndSymbol());
  295. result->push_back(Symbol::repeater(p2, p, true));
  296. result->push_back(Symbol::arrayStartSymbol());
  297. return result;
  298. }
  299. case AVRO_MAP: {
  300. ProductionPtr pp =
  301. doGenerate2(writer->leafAt(1), reader->leafAt(1), m, m2);
  302. ProductionPtr v(new Production(*pp));
  303. v->push_back(Symbol::stringSymbol());
  304. ProductionPtr pp2 = getWriterProduction(writer->leafAt(1), m2);
  305. ProductionPtr v2(new Production(*pp2));
  306. v2->push_back(Symbol::stringSymbol());
  307. ProductionPtr result = make_shared<Production>();
  308. result->push_back(Symbol::mapEndSymbol());
  309. result->push_back(Symbol::repeater(v, v2, false));
  310. result->push_back(Symbol::mapStartSymbol());
  311. return result;
  312. }
  313. case AVRO_UNION:
  314. return resolveUnion(writer, reader, m, m2);
  315. case AVRO_SYMBOLIC: {
  316. shared_ptr<NodeSymbolic> w2 =
  317. static_pointer_cast<NodeSymbolic>(writer);
  318. shared_ptr<NodeSymbolic> r2 =
  319. static_pointer_cast<NodeSymbolic>(reader);
  320. NodePair p(w2->getNode(), r2->getNode());
  321. auto it = m.find(p);
  322. if (it != m.end() && it->second) {
  323. return it->second;
  324. } else {
  325. m[p] = ProductionPtr();
  326. return make_shared<Production>(1, Symbol::placeholder(p));
  327. }
  328. }
  329. default:
  330. throw Exception("Unknown node type");
  331. }
  332. } else if (writerType == AVRO_UNION) {
  333. return resolveUnion(writer, reader, m, m2);
  334. } else {
  335. switch (readerType) {
  336. case AVRO_LONG:
  337. if (writerType == AVRO_INT) {
  338. return make_shared<Production>(1,
  339. Symbol::resolveSymbol(Symbol::Kind::Int, Symbol::Kind::Long));
  340. }
  341. break;
  342. case AVRO_FLOAT:
  343. if (writerType == AVRO_INT || writerType == AVRO_LONG) {
  344. return make_shared<Production>(1,
  345. Symbol::resolveSymbol(writerType == AVRO_INT ? Symbol::Kind::Int : Symbol::Kind::Long, Symbol::Kind::Float));
  346. }
  347. break;
  348. case AVRO_DOUBLE:
  349. if (writerType == AVRO_INT || writerType == AVRO_LONG
  350. || writerType == AVRO_FLOAT) {
  351. return make_shared<Production>(1,
  352. Symbol::resolveSymbol(writerType == AVRO_INT ? Symbol::Kind::Int : writerType == AVRO_LONG ? Symbol::Kind::Long : Symbol::Kind::Float, Symbol::Kind::Double));
  353. }
  354. break;
  355. case AVRO_UNION: {
  356. int j = bestBranch(writer, reader);
  357. if (j >= 0) {
  358. ProductionPtr p = doGenerate2(writer, reader->leafAt(j), m, m2);
  359. ProductionPtr result = make_shared<Production>();
  360. result->push_back(Symbol::unionAdjustSymbol(j, p));
  361. result->push_back(Symbol::unionSymbol());
  362. return result;
  363. }
  364. } break;
  365. case AVRO_NULL:
  366. case AVRO_BOOL:
  367. case AVRO_INT:
  368. case AVRO_STRING:
  369. case AVRO_BYTES:
  370. case AVRO_ENUM:
  371. case AVRO_ARRAY:
  372. case AVRO_MAP:
  373. case AVRO_RECORD:
  374. break;
  375. default:
  376. throw Exception("Unknown node type");
  377. }
  378. }
  379. return make_shared<Production>(1, Symbol::error(writer, reader));
  380. }
  381. class ResolvingDecoderHandler {
  382. shared_ptr<vector<uint8_t>> defaultData_;
  383. unique_ptr<InputStream> inp_;
  384. DecoderPtr backup_;
  385. DecoderPtr &base_;
  386. const DecoderPtr binDecoder;
  387. public:
  388. explicit ResolvingDecoderHandler(DecoderPtr &base) : base_(base),
  389. binDecoder(binaryDecoder()) {}
  390. size_t handle(const Symbol &s) {
  391. switch (s.kind()) {
  392. case Symbol::Kind::WriterUnion:
  393. return base_->decodeUnionIndex();
  394. case Symbol::Kind::DefaultStart:
  395. defaultData_ = s.extra<shared_ptr<vector<uint8_t>>>();
  396. backup_ = base_;
  397. inp_ = memoryInputStream(&(*defaultData_)[0], defaultData_->size());
  398. base_ = binDecoder;
  399. base_->init(*inp_);
  400. return 0;
  401. case Symbol::Kind::DefaultEnd:
  402. base_ = backup_;
  403. backup_.reset();
  404. return 0;
  405. default:
  406. return 0;
  407. }
  408. }
  409. void reset() {
  410. if (backup_ != nullptr) {
  411. base_ = backup_;
  412. backup_.reset();
  413. }
  414. }
  415. };
  416. template<typename Parser>
  417. class ResolvingDecoderImpl : public ResolvingDecoder {
  418. DecoderPtr base_;
  419. ResolvingDecoderHandler handler_;
  420. Parser parser_;
  421. void init(InputStream &is) final;
  422. void decodeNull() final;
  423. bool decodeBool() final;
  424. int32_t decodeInt() final;
  425. int64_t decodeLong() final;
  426. float decodeFloat() final;
  427. double decodeDouble() final;
  428. void decodeString(string &value) final;
  429. void skipString() final;
  430. void decodeBytes(vector<uint8_t> &value) final;
  431. void skipBytes() final;
  432. void decodeFixed(size_t n, vector<uint8_t> &value) final;
  433. void skipFixed(size_t n) final;
  434. size_t decodeEnum() final;
  435. size_t arrayStart() final;
  436. size_t arrayNext() final;
  437. size_t skipArray() final;
  438. size_t mapStart() final;
  439. size_t mapNext() final;
  440. size_t skipMap() final;
  441. size_t decodeUnionIndex() final;
  442. const vector<size_t> &fieldOrder() final;
  443. void drain() final {
  444. parser_.processImplicitActions();
  445. base_->drain();
  446. }
  447. public:
  448. ResolvingDecoderImpl(const ValidSchema &writer, const ValidSchema &reader,
  449. DecoderPtr base) : base_(std::move(base)),
  450. handler_(base_),
  451. parser_(ResolvingGrammarGenerator().generate(writer, reader),
  452. &(*base_), handler_) {
  453. }
  454. };
  455. template<typename P>
  456. void ResolvingDecoderImpl<P>::init(InputStream &is) {
  457. handler_.reset();
  458. base_->init(is);
  459. parser_.reset();
  460. }
  461. template<typename P>
  462. void ResolvingDecoderImpl<P>::decodeNull() {
  463. parser_.advance(Symbol::Kind::Null);
  464. base_->decodeNull();
  465. }
  466. template<typename P>
  467. bool ResolvingDecoderImpl<P>::decodeBool() {
  468. parser_.advance(Symbol::Kind::Bool);
  469. return base_->decodeBool();
  470. }
  471. template<typename P>
  472. int32_t ResolvingDecoderImpl<P>::decodeInt() {
  473. parser_.advance(Symbol::Kind::Int);
  474. return base_->decodeInt();
  475. }
  476. template<typename P>
  477. int64_t ResolvingDecoderImpl<P>::decodeLong() {
  478. Symbol::Kind k = parser_.advance(Symbol::Kind::Long);
  479. return k == Symbol::Kind::Int ? base_->decodeInt() : base_->decodeLong();
  480. }
  481. template<typename P>
  482. float ResolvingDecoderImpl<P>::decodeFloat() {
  483. Symbol::Kind k = parser_.advance(Symbol::Kind::Float);
  484. return k == Symbol::Kind::Int ? base_->decodeInt() : k == Symbol::Kind::Long ? base_->decodeLong() : base_->decodeFloat();
  485. }
  486. template<typename P>
  487. double ResolvingDecoderImpl<P>::decodeDouble() {
  488. Symbol::Kind k = parser_.advance(Symbol::Kind::Double);
  489. return k == Symbol::Kind::Int ? base_->decodeInt() : k == Symbol::Kind::Long ? base_->decodeLong() : k == Symbol::Kind::Float ? base_->decodeFloat() : base_->decodeDouble();
  490. }
  491. template<typename P>
  492. void ResolvingDecoderImpl<P>::decodeString(string &value) {
  493. parser_.advance(Symbol::Kind::String);
  494. base_->decodeString(value);
  495. }
  496. template<typename P>
  497. void ResolvingDecoderImpl<P>::skipString() {
  498. parser_.advance(Symbol::Kind::String);
  499. base_->skipString();
  500. }
  501. template<typename P>
  502. void ResolvingDecoderImpl<P>::decodeBytes(vector<uint8_t> &value) {
  503. parser_.advance(Symbol::Kind::Bytes);
  504. base_->decodeBytes(value);
  505. }
  506. template<typename P>
  507. void ResolvingDecoderImpl<P>::skipBytes() {
  508. parser_.advance(Symbol::Kind::Bytes);
  509. base_->skipBytes();
  510. }
  511. template<typename P>
  512. void ResolvingDecoderImpl<P>::decodeFixed(size_t n, vector<uint8_t> &value) {
  513. parser_.advance(Symbol::Kind::Fixed);
  514. parser_.assertSize(n);
  515. return base_->decodeFixed(n, value);
  516. }
  517. template<typename P>
  518. void ResolvingDecoderImpl<P>::skipFixed(size_t n) {
  519. parser_.advance(Symbol::Kind::Fixed);
  520. parser_.assertSize(n);
  521. base_->skipFixed(n);
  522. }
  523. template<typename P>
  524. size_t ResolvingDecoderImpl<P>::decodeEnum() {
  525. parser_.advance(Symbol::Kind::Enum);
  526. size_t n = base_->decodeEnum();
  527. return parser_.enumAdjust(n);
  528. }
  529. template<typename P>
  530. size_t ResolvingDecoderImpl<P>::arrayStart() {
  531. parser_.advance(Symbol::Kind::ArrayStart);
  532. size_t result = base_->arrayStart();
  533. parser_.pushRepeatCount(result);
  534. if (result == 0) {
  535. parser_.popRepeater();
  536. parser_.advance(Symbol::Kind::ArrayEnd);
  537. }
  538. return result;
  539. }
  540. template<typename P>
  541. size_t ResolvingDecoderImpl<P>::arrayNext() {
  542. parser_.processImplicitActions();
  543. size_t result = base_->arrayNext();
  544. parser_.nextRepeatCount(result);
  545. if (result == 0) {
  546. parser_.popRepeater();
  547. parser_.advance(Symbol::Kind::ArrayEnd);
  548. }
  549. return result;
  550. }
  551. template<typename P>
  552. size_t ResolvingDecoderImpl<P>::skipArray() {
  553. parser_.advance(Symbol::Kind::ArrayStart);
  554. size_t n = base_->skipArray();
  555. if (n == 0) {
  556. parser_.pop();
  557. } else {
  558. parser_.pushRepeatCount(n);
  559. parser_.skip(*base_);
  560. }
  561. parser_.advance(Symbol::Kind::ArrayEnd);
  562. return 0;
  563. }
  564. template<typename P>
  565. size_t ResolvingDecoderImpl<P>::mapStart() {
  566. parser_.advance(Symbol::Kind::MapStart);
  567. size_t result = base_->mapStart();
  568. parser_.pushRepeatCount(result);
  569. if (result == 0) {
  570. parser_.popRepeater();
  571. parser_.advance(Symbol::Kind::MapEnd);
  572. }
  573. return result;
  574. }
  575. template<typename P>
  576. size_t ResolvingDecoderImpl<P>::mapNext() {
  577. parser_.processImplicitActions();
  578. size_t result = base_->mapNext();
  579. parser_.nextRepeatCount(result);
  580. if (result == 0) {
  581. parser_.popRepeater();
  582. parser_.advance(Symbol::Kind::MapEnd);
  583. }
  584. return result;
  585. }
  586. template<typename P>
  587. size_t ResolvingDecoderImpl<P>::skipMap() {
  588. parser_.advance(Symbol::Kind::MapStart);
  589. size_t n = base_->skipMap();
  590. if (n == 0) {
  591. parser_.pop();
  592. } else {
  593. parser_.pushRepeatCount(n);
  594. parser_.skip(*base_);
  595. }
  596. parser_.advance(Symbol::Kind::MapEnd);
  597. return 0;
  598. }
  599. template<typename P>
  600. size_t ResolvingDecoderImpl<P>::decodeUnionIndex() {
  601. parser_.advance(Symbol::Kind::Union);
  602. return parser_.unionAdjust();
  603. }
  604. template<typename P>
  605. const vector<size_t> &ResolvingDecoderImpl<P>::fieldOrder() {
  606. parser_.advance(Symbol::Kind::Record);
  607. return parser_.sizeList();
  608. }
  609. } // namespace parsing
  610. ResolvingDecoderPtr resolvingDecoder(const ValidSchema &writer,
  611. const ValidSchema &reader, const DecoderPtr &base) {
  612. return make_shared<parsing::ResolvingDecoderImpl<parsing::SimpleParser<parsing::ResolvingDecoderHandler>>>(
  613. writer, reader, base);
  614. }
  615. } // namespace avro