import { stream as e } from "../utils/stream.js";
import { assertUnreachable as t } from "../utils/errors.js";
import { isOperationCancelled as n } from "../utils/promise-utils.js";
import { MultiMap as r } from "../utils/collections.js";
//#region ../../node_modules/langium/lib/validation/validation-registry.js
function i(e) {
	return { code: e };
}
var a;
(function(e) {
	e.defaults = [
		"fast",
		"slow",
		"built-in"
	], e.all = e.defaults;
})(a ||= {});
var o = class {
	constructor(e) {
		this.entries = new r(), this.knownCategories = new Set(a.defaults), this.entriesBefore = [], this.entriesAfter = [], this.reflection = e.shared.AstReflection;
	}
	register(e, n = this, r = "fast") {
		if (r === "built-in") throw Error("The 'built-in' category is reserved for lexer, parser, and linker errors.");
		this.knownCategories.add(r);
		for (let [i, a] of Object.entries(e)) {
			let e = a;
			if (Array.isArray(e)) for (let t of e) {
				let e = {
					check: this.wrapValidationException(t, n),
					category: r
				};
				this.addEntry(i, e);
			}
			else if (typeof e == "function") {
				let t = {
					check: this.wrapValidationException(e, n),
					category: r
				};
				this.addEntry(i, t);
			} else t(e);
		}
	}
	wrapValidationException(e, t) {
		return async (n, r, i) => {
			await this.handleException(() => e.call(t, n, r, i), "An error occurred during validation", r, n);
		};
	}
	async handleException(e, t, r, i) {
		try {
			await e();
		} catch (e) {
			if (n(e)) throw e;
			console.error(`${t}:`, e), e instanceof Error && e.stack && console.error(e.stack), r("error", `${t}: ${e instanceof Error ? e.message : String(e)}`, { node: i });
		}
	}
	addEntry(e, t) {
		if (e === "AstNode") {
			this.entries.add("AstNode", t);
			return;
		}
		for (let n of this.reflection.getAllSubTypes(e)) this.entries.add(n, t);
	}
	getChecks(t, n) {
		let r = e(this.entries.get(t)).concat(this.entries.get("AstNode"));
		return n && (r = r.filter((e) => n.includes(e.category))), r.map((e) => e.check);
	}
	registerBeforeDocument(e, t = this) {
		this.entriesBefore.push(this.wrapPreparationException(e, "An error occurred during set-up of the validation", t));
	}
	registerAfterDocument(e, t = this) {
		this.entriesAfter.push(this.wrapPreparationException(e, "An error occurred during tear-down of the validation", t));
	}
	wrapPreparationException(e, t, n) {
		return async (r, i, a, o) => {
			await this.handleException(() => e.call(n, r, i, a, o), t, i, r);
		};
	}
	get checksBefore() {
		return this.entriesBefore;
	}
	get checksAfter() {
		return this.entriesAfter;
	}
	getAllValidationCategories(e) {
		return this.knownCategories;
	}
};
//#endregion
export { o as ValidationRegistry, i as diagnosticData };
