"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const model = require("../@chevrotain/gast/lib-src-model.cjs");
const forEach = require("../lodash-es/forEach.cjs");
const drop = require("../lodash-es/drop.cjs");
class RestWalker {
  walk(prod, prevRest = []) {
    forEach.default(prod.definition, (subProd, index) => {
      const currRest = drop.default(prod.definition, index + 1);
      if (subProd instanceof model.NonTerminal) {
        this.walkProdRef(subProd, currRest, prevRest);
      } else if (subProd instanceof model.Terminal) {
        this.walkTerminal(subProd, currRest, prevRest);
      } else if (subProd instanceof model.Alternative) {
        this.walkFlat(subProd, currRest, prevRest);
      } else if (subProd instanceof model.Option) {
        this.walkOption(subProd, currRest, prevRest);
      } else if (subProd instanceof model.RepetitionMandatory) {
        this.walkAtLeastOne(subProd, currRest, prevRest);
      } else if (subProd instanceof model.RepetitionMandatoryWithSeparator) {
        this.walkAtLeastOneSep(subProd, currRest, prevRest);
      } else if (subProd instanceof model.RepetitionWithSeparator) {
        this.walkManySep(subProd, currRest, prevRest);
      } else if (subProd instanceof model.Repetition) {
        this.walkMany(subProd, currRest, prevRest);
      } else if (subProd instanceof model.Alternation) {
        this.walkOr(subProd, currRest, prevRest);
      } else {
        throw Error("non exhaustive match");
      }
    });
  }
  walkTerminal(terminal, currRest, prevRest) {
  }
  walkProdRef(refProd, currRest, prevRest) {
  }
  walkFlat(flatProd, currRest, prevRest) {
    const fullOrRest = currRest.concat(prevRest);
    this.walk(flatProd, fullOrRest);
  }
  walkOption(optionProd, currRest, prevRest) {
    const fullOrRest = currRest.concat(prevRest);
    this.walk(optionProd, fullOrRest);
  }
  walkAtLeastOne(atLeastOneProd, currRest, prevRest) {
    const fullAtLeastOneRest = [
      new model.Option({ definition: atLeastOneProd.definition })
    ].concat(currRest, prevRest);
    this.walk(atLeastOneProd, fullAtLeastOneRest);
  }
  walkAtLeastOneSep(atLeastOneSepProd, currRest, prevRest) {
    const fullAtLeastOneSepRest = restForRepetitionWithSeparator(atLeastOneSepProd, currRest, prevRest);
    this.walk(atLeastOneSepProd, fullAtLeastOneSepRest);
  }
  walkMany(manyProd, currRest, prevRest) {
    const fullManyRest = [
      new model.Option({ definition: manyProd.definition })
    ].concat(currRest, prevRest);
    this.walk(manyProd, fullManyRest);
  }
  walkManySep(manySepProd, currRest, prevRest) {
    const fullManySepRest = restForRepetitionWithSeparator(manySepProd, currRest, prevRest);
    this.walk(manySepProd, fullManySepRest);
  }
  walkOr(orProd, currRest, prevRest) {
    const fullOrRest = currRest.concat(prevRest);
    forEach.default(orProd.definition, (alt) => {
      const prodWrapper = new model.Alternative({ definition: [alt] });
      this.walk(prodWrapper, fullOrRest);
    });
  }
}
function restForRepetitionWithSeparator(repSepProd, currRest, prevRest) {
  const repSepRest = [
    new model.Option({
      definition: [
        new model.Terminal({ terminalType: repSepProd.separator })
      ].concat(repSepProd.definition)
    })
  ];
  const fullRepSepRest = repSepRest.concat(currRest, prevRest);
  return fullRepSepRest;
}
exports.RestWalker = RestWalker;
//# sourceMappingURL=lib-src-parse-grammar-rest.cjs.map
