'use strict';

var rest = require('./rest.js');
var first = require('./first.js');
var constants = require('../constants.js');
var model = require('../../../../../../../@chevrotain_gast@11.0.3/node_modules/@chevrotain/gast/lib/src/model.js');
var forEach = require('../../../../../../../lodash-es@4.17.21/node_modules/lodash-es/forEach.js');
var assign = require('../../../../../../../lodash-es@4.17.21/node_modules/lodash-es/assign.js');

// This ResyncFollowsWalker computes all of the follows required for RESYNC
// (skipping reference production).
class ResyncFollowsWalker extends rest.RestWalker {
    constructor(topProd) {
        super();
        this.topProd = topProd;
        this.follows = {};
    }
    startWalking() {
        this.walk(this.topProd);
        return this.follows;
    }
    walkTerminal(terminal, currRest, prevRest) {
        // do nothing! just like in the public sector after 13:00
    }
    walkProdRef(refProd, currRest, prevRest) {
        const followName = buildBetweenProdsFollowPrefix(refProd.referencedRule, refProd.idx) +
            this.topProd.name;
        const fullRest = currRest.concat(prevRest);
        const restProd = new model.Alternative({ definition: fullRest });
        const t_in_topProd_follows = first.first(restProd);
        this.follows[followName] = t_in_topProd_follows;
    }
}
function computeAllProdsFollows(topProductions) {
    const reSyncFollows = {};
    forEach.default(topProductions, (topProd) => {
        const currRefsFollow = new ResyncFollowsWalker(topProd).startWalking();
        assign.default(reSyncFollows, currRefsFollow);
    });
    return reSyncFollows;
}
function buildBetweenProdsFollowPrefix(inner, occurenceInParent) {
    return inner.name + occurenceInParent + constants.IN;
}

exports.ResyncFollowsWalker = ResyncFollowsWalker;
exports.buildBetweenProdsFollowPrefix = buildBetweenProdsFollowPrefix;
exports.computeAllProdsFollows = computeAllProdsFollows;
