in lang/c++/impl/parsing/ValidatingCodec.cc [60:151]
ProductionPtr ValidatingGrammarGenerator::doGenerate(const NodePtr &n,
map<NodePtr, ProductionPtr> &m) {
switch (n->type()) {
case AVRO_NULL:
return make_shared<Production>(1, Symbol::nullSymbol());
case AVRO_BOOL:
return make_shared<Production>(1, Symbol::boolSymbol());
case AVRO_INT:
return make_shared<Production>(1, Symbol::intSymbol());
case AVRO_LONG:
return make_shared<Production>(1, Symbol::longSymbol());
case AVRO_FLOAT:
return make_shared<Production>(1, Symbol::floatSymbol());
case AVRO_DOUBLE:
return make_shared<Production>(1, Symbol::doubleSymbol());
case AVRO_STRING:
return make_shared<Production>(1, Symbol::stringSymbol());
case AVRO_BYTES:
return make_shared<Production>(1, Symbol::bytesSymbol());
case AVRO_FIXED: {
ProductionPtr result = make_shared<Production>();
result->push_back(Symbol::sizeCheckSymbol(n->fixedSize()));
result->push_back(Symbol::fixedSymbol());
m[n] = result;
return result;
}
case AVRO_RECORD: {
ProductionPtr result = make_shared<Production>();
m.erase(n);
size_t c = n->leaves();
for (size_t i = 0; i < c; ++i) {
const NodePtr &leaf = n->leafAt(i);
ProductionPtr v = doGenerate(leaf, m);
copy(v->rbegin(), v->rend(), back_inserter(*result));
}
reverse(result->begin(), result->end());
m[n] = result;
return make_shared<Production>(1, Symbol::indirect(result));
}
case AVRO_ENUM: {
ProductionPtr result = make_shared<Production>();
result->push_back(Symbol::sizeCheckSymbol(n->names()));
result->push_back(Symbol::enumSymbol());
m[n] = result;
return result;
}
case AVRO_ARRAY: {
ProductionPtr result = make_shared<Production>();
result->push_back(Symbol::arrayEndSymbol());
result->push_back(Symbol::repeater(doGenerate(n->leafAt(0), m), true));
result->push_back(Symbol::arrayStartSymbol());
return result;
}
case AVRO_MAP: {
ProductionPtr pp = doGenerate(n->leafAt(1), m);
ProductionPtr v(new Production(*pp));
v->push_back(Symbol::stringSymbol());
ProductionPtr result = make_shared<Production>();
result->push_back(Symbol::mapEndSymbol());
result->push_back(Symbol::repeater(v, false));
result->push_back(Symbol::mapStartSymbol());
return result;
}
case AVRO_UNION: {
vector<ProductionPtr> vv;
size_t c = n->leaves();
vv.reserve(c);
for (size_t i = 0; i < c; ++i) {
vv.push_back(doGenerate(n->leafAt(i), m));
}
ProductionPtr result = make_shared<Production>();
result->push_back(Symbol::alternative(vv));
result->push_back(Symbol::unionSymbol());
return result;
}
case AVRO_SYMBOLIC: {
shared_ptr<NodeSymbolic> ns = static_pointer_cast<NodeSymbolic>(n);
NodePtr nn = ns->getNode();
auto it = m.find(nn);
if (it != m.end() && it->second) {
return it->second;
} else {
m[nn] = ProductionPtr();
return make_shared<Production>(1, Symbol::placeholder(nn));
}
}
default:
throw Exception("Unknown node type");
}
}