ProductionPtr ValidatingGrammarGenerator::doGenerate()

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");
    }
}