"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const lang_extensions = require("./lib-src-lang-lang_extensions.cjs");
const forEach = require("../lodash-es/forEach.cjs");
const isEmpty = require("../lodash-es/isEmpty.cjs");
const map = require("../lodash-es/map.cjs");
const isArray = require("../lodash-es/isArray.cjs");
const isUndefined = require("../lodash-es/isUndefined.cjs");
const keys = require("../lodash-es/keys.cjs");
const filter = require("../lodash-es/filter.cjs");
const isFunction = require("../lodash-es/isFunction.cjs");
const compact = require("../lodash-es/compact.cjs");
function defaultVisit(ctx, param) {
  const childrenNames = keys.default(ctx);
  const childrenNamesLength = childrenNames.length;
  for (let i = 0; i < childrenNamesLength; i++) {
    const currChildName = childrenNames[i];
    const currChildArray = ctx[currChildName];
    const currChildArrayLength = currChildArray.length;
    for (let j = 0; j < currChildArrayLength; j++) {
      const currChild = currChildArray[j];
      if (currChild.tokenTypeIdx === void 0) {
        this[currChild.name](currChild.children, param);
      }
    }
  }
}
function createBaseSemanticVisitorConstructor(grammarName, ruleNames) {
  const derivedConstructor = function() {
  };
  lang_extensions.defineNameProp(derivedConstructor, grammarName + "BaseSemantics");
  const semanticProto = {
    visit: function(cstNode, param) {
      if (isArray.default(cstNode)) {
        cstNode = cstNode[0];
      }
      if (isUndefined.default(cstNode)) {
        return void 0;
      }
      return this[cstNode.name](cstNode.children, param);
    },
    validateVisitor: function() {
      const semanticDefinitionErrors = validateVisitor(this, ruleNames);
      if (!isEmpty.default(semanticDefinitionErrors)) {
        const errorMessages = map.default(semanticDefinitionErrors, (currDefError) => currDefError.msg);
        throw Error(`Errors Detected in CST Visitor <${this.constructor.name}>:
	${errorMessages.join("\n\n").replace(/\n/g, "\n	")}`);
      }
    }
  };
  derivedConstructor.prototype = semanticProto;
  derivedConstructor.prototype.constructor = derivedConstructor;
  derivedConstructor._RULE_NAMES = ruleNames;
  return derivedConstructor;
}
function createBaseVisitorConstructorWithDefaults(grammarName, ruleNames, baseConstructor) {
  const derivedConstructor = function() {
  };
  lang_extensions.defineNameProp(derivedConstructor, grammarName + "BaseSemanticsWithDefaults");
  const withDefaultsProto = Object.create(baseConstructor.prototype);
  forEach.default(ruleNames, (ruleName) => {
    withDefaultsProto[ruleName] = defaultVisit;
  });
  derivedConstructor.prototype = withDefaultsProto;
  derivedConstructor.prototype.constructor = derivedConstructor;
  return derivedConstructor;
}
exports.CstVisitorDefinitionError = void 0;
(function(CstVisitorDefinitionError) {
  CstVisitorDefinitionError[CstVisitorDefinitionError["REDUNDANT_METHOD"] = 0] = "REDUNDANT_METHOD";
  CstVisitorDefinitionError[CstVisitorDefinitionError["MISSING_METHOD"] = 1] = "MISSING_METHOD";
})(exports.CstVisitorDefinitionError || (exports.CstVisitorDefinitionError = {}));
function validateVisitor(visitorInstance, ruleNames) {
  const missingErrors = validateMissingCstMethods(visitorInstance, ruleNames);
  return missingErrors;
}
function validateMissingCstMethods(visitorInstance, ruleNames) {
  const missingRuleNames = filter.default(ruleNames, (currRuleName) => {
    return isFunction.default(visitorInstance[currRuleName]) === false;
  });
  const errors = map.default(missingRuleNames, (currRuleName) => {
    return {
      msg: `Missing visitor method: <${currRuleName}> on ${visitorInstance.constructor.name} CST Visitor.`,
      type: exports.CstVisitorDefinitionError.MISSING_METHOD,
      methodName: currRuleName
    };
  });
  return compact.default(errors);
}
exports.createBaseSemanticVisitorConstructor = createBaseSemanticVisitorConstructor;
exports.createBaseVisitorConstructorWithDefaults = createBaseVisitorConstructorWithDefaults;
exports.defaultVisit = defaultVisit;
exports.validateMissingCstMethods = validateMissingCstMethods;
exports.validateVisitor = validateVisitor;
//# sourceMappingURL=lib-src-parse-cst-cst_visitor.cjs.map
