in lang/c++/impl/parsing/ResolvingDecoder.cc [246:401]
ProductionPtr ResolvingGrammarGenerator::doGenerate2(
const NodePtr &w, const NodePtr &r,
map<NodePair, ProductionPtr> &m,
map<NodePtr, ProductionPtr> &m2) {
const NodePtr writer = w->type() == AVRO_SYMBOLIC ? resolveSymbol(w) : w;
const NodePtr reader = r->type() == AVRO_SYMBOLIC ? resolveSymbol(r) : r;
Type writerType = writer->type();
Type readerType = reader->type();
if (writerType == readerType) {
switch (writerType) {
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:
if (writer->name().equalOrAliasedBy(reader->name()) && writer->fixedSize() == reader->fixedSize()) {
ProductionPtr result = make_shared<Production>();
result->push_back(Symbol::sizeCheckSymbol(reader->fixedSize()));
result->push_back(Symbol::fixedSymbol());
m[make_pair(writer, reader)] = result;
return result;
}
break;
case AVRO_RECORD:
if (writer->name().equalOrAliasedBy(reader->name())) {
const pair<NodePtr, NodePtr> key(writer, reader);
map<NodePair, ProductionPtr>::const_iterator kp = m.find(key);
if (kp != m.end()) {
return (kp->second) ? kp->second : make_shared<Production>(1, Symbol::placeholder(key));
}
m[key] = ProductionPtr();
ProductionPtr result = resolveRecords(writer, reader, m, m2);
m[key] = result;
return make_shared<Production>(1, Symbol::indirect(result));
}
break;
case AVRO_ENUM:
if (writer->name().equalOrAliasedBy(reader->name())) {
ProductionPtr result = make_shared<Production>();
result->push_back(Symbol::enumAdjustSymbol(writer, reader));
result->push_back(Symbol::enumSymbol());
m[make_pair(writer, reader)] = result;
return result;
}
break;
case AVRO_ARRAY: {
ProductionPtr p = getWriterProduction(writer->leafAt(0), m2);
ProductionPtr p2 = doGenerate2(writer->leafAt(0), reader->leafAt(0), m, m2);
ProductionPtr result = make_shared<Production>();
result->push_back(Symbol::arrayEndSymbol());
result->push_back(Symbol::repeater(p2, p, true));
result->push_back(Symbol::arrayStartSymbol());
return result;
}
case AVRO_MAP: {
ProductionPtr pp =
doGenerate2(writer->leafAt(1), reader->leafAt(1), m, m2);
ProductionPtr v(new Production(*pp));
v->push_back(Symbol::stringSymbol());
ProductionPtr pp2 = getWriterProduction(writer->leafAt(1), m2);
ProductionPtr v2(new Production(*pp2));
v2->push_back(Symbol::stringSymbol());
ProductionPtr result = make_shared<Production>();
result->push_back(Symbol::mapEndSymbol());
result->push_back(Symbol::repeater(v, v2, false));
result->push_back(Symbol::mapStartSymbol());
return result;
}
case AVRO_UNION:
return resolveUnion(writer, reader, m, m2);
case AVRO_SYMBOLIC: {
shared_ptr<NodeSymbolic> w2 =
static_pointer_cast<NodeSymbolic>(writer);
shared_ptr<NodeSymbolic> r2 =
static_pointer_cast<NodeSymbolic>(reader);
NodePair p(w2->getNode(), r2->getNode());
auto it = m.find(p);
if (it != m.end() && it->second) {
return it->second;
} else {
m[p] = ProductionPtr();
return make_shared<Production>(1, Symbol::placeholder(p));
}
}
default:
throw Exception("Unknown node type");
}
} else if (writerType == AVRO_UNION) {
return resolveUnion(writer, reader, m, m2);
} else {
switch (readerType) {
case AVRO_LONG:
if (writerType == AVRO_INT) {
return make_shared<Production>(1,
Symbol::resolveSymbol(Symbol::Kind::Int, Symbol::Kind::Long));
}
break;
case AVRO_FLOAT:
if (writerType == AVRO_INT || writerType == AVRO_LONG) {
return make_shared<Production>(1,
Symbol::resolveSymbol(writerType == AVRO_INT ? Symbol::Kind::Int : Symbol::Kind::Long, Symbol::Kind::Float));
}
break;
case AVRO_DOUBLE:
if (writerType == AVRO_INT || writerType == AVRO_LONG
|| writerType == AVRO_FLOAT) {
return make_shared<Production>(1,
Symbol::resolveSymbol(writerType == AVRO_INT ? Symbol::Kind::Int : writerType == AVRO_LONG ? Symbol::Kind::Long
: Symbol::Kind::Float,
Symbol::Kind::Double));
}
break;
case AVRO_UNION: {
auto j = bestBranch(writer, reader);
if (j) {
ProductionPtr p = doGenerate2(writer, reader->leafAt(*j), m, m2);
ProductionPtr result = make_shared<Production>();
result->push_back(Symbol::unionAdjustSymbol(*j, p));
result->push_back(Symbol::unionSymbol());
return result;
}
} break;
case AVRO_NULL:
case AVRO_BOOL:
case AVRO_INT:
case AVRO_STRING:
case AVRO_BYTES:
case AVRO_ENUM:
case AVRO_ARRAY:
case AVRO_MAP:
case AVRO_RECORD:
break;
default:
throw Exception("Unknown node type");
}
}
return make_shared<Production>(1, Symbol::error(writer, reader));
}