import { stream as e } from "../utils/stream.js";
import { cancellation_exports as t } from "../utils/cancellation.js";
import { TextDocument as n } from "../../../vscode-languageserver-textdocument/lib/esm/main.js";
import { URI as r } from "../../../vscode-uri/lib/esm/index.js";
import { UriTrie as i } from "../utils/uri-utils.js";
//#region ../../node_modules/langium/lib/workspace/documents.js
var a;
(function(e) {
	e[e.Changed = 0] = "Changed", e[e.Parsed = 1] = "Parsed", e[e.IndexedContent = 2] = "IndexedContent", e[e.ComputedScopes = 3] = "ComputedScopes", e[e.Linked = 4] = "Linked", e[e.IndexedReferences = 5] = "IndexedReferences", e[e.Validated = 6] = "Validated";
})(a ||= {});
var o = class {
	constructor(e) {
		this.serviceRegistry = e.ServiceRegistry, this.textDocuments = e.workspace.TextDocuments, this.fileSystemProvider = e.workspace.FileSystemProvider;
	}
	async fromUri(e, n = t.CancellationToken.None) {
		let r = await this.fileSystemProvider.readFile(e);
		return this.createAsync(e, r, n);
	}
	fromTextDocument(e, n, i) {
		return n ??= r.parse(e.uri), t.CancellationToken.is(i) ? this.createAsync(n, e, i) : this.create(n, e, i);
	}
	fromString(e, n, r) {
		return t.CancellationToken.is(r) ? this.createAsync(n, e, r) : this.create(n, e, r);
	}
	fromModel(e, t) {
		return this.create(t, { $model: e });
	}
	create(e, t, n) {
		if (typeof t == "string") {
			let r = this.parse(e, t, n);
			return this.createLangiumDocument(r, e, void 0, t);
		} else if ("$model" in t) {
			let n = {
				value: t.$model,
				parserErrors: [],
				lexerErrors: []
			};
			return this.createLangiumDocument(n, e);
		} else {
			let r = this.parse(e, t.getText(), n);
			return this.createLangiumDocument(r, e, t);
		}
	}
	async createAsync(e, t, n) {
		if (typeof t == "string") {
			let r = await this.parseAsync(e, t, n);
			return this.createLangiumDocument(r, e, void 0, t);
		} else {
			let r = await this.parseAsync(e, t.getText(), n);
			return this.createLangiumDocument(r, e, t);
		}
	}
	createLangiumDocument(e, t, n, r) {
		let i;
		if (n) i = {
			parseResult: e,
			uri: t,
			state: a.Parsed,
			references: [],
			textDocument: n
		};
		else {
			let n = this.createTextDocumentGetter(t, r);
			i = {
				parseResult: e,
				uri: t,
				state: a.Parsed,
				references: [],
				get textDocument() {
					return n();
				}
			};
		}
		return e.value.$document = i, i;
	}
	async update(e, t) {
		let n = e.parseResult.value.$cstNode?.root.fullText, r = this.textDocuments?.get(e.uri.toString()), i = r ? r.getText() : await this.fileSystemProvider.readFile(e.uri);
		if (r) Object.defineProperty(e, "textDocument", { value: r });
		else {
			let t = this.createTextDocumentGetter(e.uri, i);
			Object.defineProperty(e, "textDocument", { get: t });
		}
		return n !== i && (e.parseResult = await this.parseAsync(e.uri, i, t), e.parseResult.value.$document = e), e.state = a.Parsed, e;
	}
	parse(e, t, n) {
		return this.serviceRegistry.getServices(e).parser.LangiumParser.parse(t, n);
	}
	parseAsync(e, t, n) {
		return this.serviceRegistry.getServices(e).parser.AsyncParser.parse(t, n);
	}
	createTextDocumentGetter(e, t) {
		let r = this.serviceRegistry, i;
		return () => i ??= n.create(e.toString(), r.getServices(e).LanguageMetaData.languageId, 0, t ?? "");
	}
}, s = class {
	constructor(e) {
		this.documentTrie = new i(), this.services = e, this.langiumDocumentFactory = e.workspace.LangiumDocumentFactory, this.documentBuilder = () => e.workspace.DocumentBuilder;
	}
	get all() {
		return e(this.documentTrie.all());
	}
	addDocument(e) {
		let t = e.uri.toString();
		if (this.documentTrie.has(t)) throw Error(`A document with the URI '${t}' is already present.`);
		this.documentTrie.insert(t, e);
	}
	getDocument(e) {
		let t = e.toString();
		return this.documentTrie.find(t);
	}
	getDocuments(e) {
		let t = e.toString();
		return this.documentTrie.findAll(t);
	}
	async getOrCreateDocument(e, t) {
		let n = this.getDocument(e);
		return n || (n = await this.langiumDocumentFactory.fromUri(e, t), this.addDocument(n), n);
	}
	createDocument(e, t, n) {
		if (n) return this.langiumDocumentFactory.fromString(t, e, n).then((e) => (this.addDocument(e), e));
		{
			let n = this.langiumDocumentFactory.fromString(t, e);
			return this.addDocument(n), n;
		}
	}
	hasDocument(e) {
		return this.documentTrie.has(e.toString());
	}
	invalidateDocument(e) {
		let t = e.toString(), n = this.documentTrie.find(t);
		return n && this.documentBuilder().resetToState(n, a.Changed), n;
	}
	deleteDocument(e) {
		let t = e.toString(), n = this.documentTrie.find(t);
		return n && (n.state = a.Changed, this.documentTrie.delete(t)), n;
	}
	deleteDocuments(e) {
		let t = e.toString(), n = this.documentTrie.findAll(t);
		for (let e of n) e.state = a.Changed;
		return this.documentTrie.delete(t), n;
	}
};
//#endregion
export { o as DefaultLangiumDocumentFactory, s as DefaultLangiumDocuments, a as DocumentState };
