import drop_default from "../../../../../lodash-es/drop.js";
import forEach_default from "../../../../../lodash-es/forEach.js";
import { Alternation, Alternative, NonTerminal, Option, Repetition, RepetitionMandatory, RepetitionMandatoryWithSeparator, RepetitionWithSeparator, Terminal } from "../../../../../@chevrotain/gast/lib/src/model.js";
var RestWalker = class {
	walk(d, f = []) {
		forEach_default(d.definition, (o, p) => {
			let m = drop_default(d.definition, p + 1);
			/* istanbul ignore else */
			if (o instanceof NonTerminal) this.walkProdRef(o, m, f);
			else if (o instanceof Terminal) this.walkTerminal(o, m, f);
			else if (o instanceof Alternative) this.walkFlat(o, m, f);
			else if (o instanceof Option) this.walkOption(o, m, f);
			else if (o instanceof RepetitionMandatory) this.walkAtLeastOne(o, m, f);
			else if (o instanceof RepetitionMandatoryWithSeparator) this.walkAtLeastOneSep(o, m, f);
			else if (o instanceof RepetitionWithSeparator) this.walkManySep(o, m, f);
			else if (o instanceof Repetition) this.walkMany(o, m, f);
			else if (o instanceof Alternation) this.walkOr(o, m, f);
			else throw Error("non exhaustive match");
		});
	}
	walkTerminal(e, o, s) {}
	walkProdRef(e, o, s) {}
	walkFlat(e, o, s) {
		let c = o.concat(s);
		this.walk(e, c);
	}
	walkOption(e, o, s) {
		let c = o.concat(s);
		this.walk(e, c);
	}
	walkAtLeastOne(e, o, s) {
		let c = [new Option({ definition: e.definition })].concat(o, s);
		this.walk(e, c);
	}
	walkAtLeastOneSep(e, o, s) {
		let c = restForRepetitionWithSeparator(e, o, s);
		this.walk(e, c);
	}
	walkMany(e, o, s) {
		let c = [new Option({ definition: e.definition })].concat(o, s);
		this.walk(e, c);
	}
	walkManySep(e, o, s) {
		let c = restForRepetitionWithSeparator(e, o, s);
		this.walk(e, c);
	}
	walkOr(e, s, l) {
		let u = s.concat(l);
		forEach_default(e.definition, (e) => {
			let o = new Alternative({ definition: [e] });
			this.walk(o, u);
		});
	}
};
function restForRepetitionWithSeparator(e, o, s) {
	return [new Option({ definition: [new Terminal({ terminalType: e.separator })].concat(e.definition) })].concat(o, s);
}
export { RestWalker };
