in lang/c++/impl/parsing/JsonCodec.cc [63:142]
ProductionPtr JsonGrammarGenerator::doGenerate(const NodePtr &n,
std::map<NodePtr, ProductionPtr> &m) {
switch (n->type()) {
case AVRO_NULL:
case AVRO_BOOL:
case AVRO_INT:
case AVRO_LONG:
case AVRO_FLOAT:
case AVRO_DOUBLE:
case AVRO_STRING:
case AVRO_BYTES:
case AVRO_FIXED:
case AVRO_ARRAY:
case AVRO_MAP:
case AVRO_SYMBOLIC:
return ValidatingGrammarGenerator::doGenerate(n, m);
case AVRO_RECORD: {
ProductionPtr result = make_shared<Production>();
m.erase(n);
size_t c = n->leaves();
result->reserve(2 + 2 * c);
result->push_back(Symbol::recordStartSymbol());
for (size_t i = 0; i < c; ++i) {
const NodePtr &leaf = n->leafAt(i);
ProductionPtr v = doGenerate(leaf, m);
result->push_back(Symbol::fieldSymbol(n->nameAt(i)));
copy(v->rbegin(), v->rend(), back_inserter(*result));
}
result->push_back(Symbol::recordEndSymbol());
reverse(result->begin(), result->end());
m[n] = result;
return make_shared<Production>(1, Symbol::indirect(result));
}
case AVRO_ENUM: {
vector<string> nn;
size_t c = n->names();
nn.reserve(c);
for (size_t i = 0; i < c; ++i) {
nn.push_back(n->nameAt(i));
}
ProductionPtr result = make_shared<Production>();
result->push_back(Symbol::nameListSymbol(nn));
result->push_back(Symbol::enumSymbol());
m[n] = result;
return result;
}
case AVRO_UNION: {
size_t c = n->leaves();
vector<ProductionPtr> vv;
vv.reserve(c);
vector<string> names;
names.reserve(c);
for (size_t i = 0; i < c; ++i) {
const NodePtr &nn = n->leafAt(i);
ProductionPtr v = doGenerate(nn, m);
if (nn->type() != AVRO_NULL) {
ProductionPtr v2 = make_shared<Production>();
v2->push_back(Symbol::recordEndSymbol());
copy(v->begin(), v->end(), back_inserter(*v2));
v.swap(v2);
}
vv.push_back(v);
names.push_back(nameOf(nn));
}
ProductionPtr result = make_shared<Production>();
result->push_back(Symbol::alternative(vv));
result->push_back(Symbol::nameListSymbol(names));
result->push_back(Symbol::unionSymbol());
return result;
}
default:
throw Exception("Unknown node type");
}
}