public listen()

in server/src/common/proposed.notebooks.ts [194:310]


	public listen(connection: _Connection<_, _, _, _, _, _, _, NotebooksFeatureShape>): void {
		const cellTextDocumentConnection = new Connection();
		this.cellTextDocuments.listen(cellTextDocumentConnection);

		connection.notebooks.synchronization.onDidOpenNotebookDocument((params) => {
			this.notebookDocuments.set(params.notebookDocument.uri, params.notebookDocument);
			for (const cellTextDocument of params.cellTextDocuments) {
				cellTextDocumentConnection.openTextDocument({ textDocument: cellTextDocument });
			}
			this.updateCellMap(params.notebookDocument);
			this._onDidOpen.fire(params.notebookDocument);
		});
		connection.notebooks.synchronization.onDidChangeNotebookDocument((params) => {
			const notebookDocument = this.notebookDocuments.get(params.notebookDocument.uri);
			if (notebookDocument === undefined) {
				return;
			}
			notebookDocument.version = params.notebookDocument.version;
			const oldMetadata = notebookDocument.metadata;
			let metadataChanged: boolean = false;
			const change = params.change;
			if (change.metadata !== undefined) {
				metadataChanged = true;
				notebookDocument.metadata = change.metadata;
			}
			const opened: DocumentUri[] = [];
			const closed: DocumentUri[] = [];
			if (change.cellStructure !== undefined) {
				const array = change.cellStructure.array;
				notebookDocument.cells.splice(array.start, array.deleteCount, ...(array.cells !== undefined ? array.cells : []));
				// Additional open cell text documents.
				if (change.cellStructure.didOpen !== undefined) {
					for (const open of change.cellStructure.didOpen) {
						cellTextDocumentConnection.openTextDocument({ textDocument: open });
						opened.push(open.uri);
					}
				}
				// Additional closed cell test documents.
				if (change.cellStructure.didClose) {
					for (const close of change.cellStructure.didClose) {
						cellTextDocumentConnection.closeTextDocument({ textDocument: close });
						closed.push(close.uri);
					}
				}
			}
			const changed: Required<NotebookDocumentChangeEvent>['cells']['changed'] = [];
			if (change.cellData !== undefined) {
				const cellUpdates: Map<string, Proposed.NotebookCell> = new Map(change.cellData.map(cell => [cell.document, cell]));
				for (let i = 0; i <= notebookDocument.cells.length; i++) {
					const change = cellUpdates.get(notebookDocument.cells[i].document);
					if (change !== undefined) {
						const old = notebookDocument.cells.splice(i, 1, change);
						changed.push({ old: old[0], new: change });
						cellUpdates.delete(change.document);
						if (cellUpdates.size === 0) {
							break;
						}
					}
				}
			}
			const changedTextDocuments: DocumentUri[] = [];
			if (change.cellTextDocuments !== undefined) {
				for (const cellTextDocument of change.cellTextDocuments) {
					cellTextDocumentConnection.changeTextDocument({ textDocument: cellTextDocument.textDocument, contentChanges: cellTextDocument.contentChanges });
					changedTextDocuments.push(cellTextDocument.textDocument.uri);
				}
			}

			// Update internal data structure.
			this.updateCellMap(notebookDocument);

			const changeEvent: NotebookDocumentChangeEvent = { notebookDocument };
			if (metadataChanged) {
				changeEvent.metadata = { old: oldMetadata, new: notebookDocument.metadata };
			}

			const added: Proposed.NotebookCell[] = [];
			for (const open of opened) {
				added.push(this.getNotebookCell(open)!);
			}
			const removed: Proposed.NotebookCell[] = [];
			for (const close of closed) {
				removed.push(this.getNotebookCell(close)!);
			}
			const contentChanged: Proposed.NotebookCell[] = [];
			for (const change of changedTextDocuments) {
				contentChanged.push(this.getNotebookCell(change)!);
			}
			if (added.length > 0 || removed.length > 0 || changed.length > 0 || contentChanged.length > 0) {
				changeEvent.cells = { added, removed, changed, contentChanged };
			}
			if (changeEvent.metadata !== undefined || changeEvent.cells !== undefined) {
				this._onDidChange.fire(changeEvent);
			}
		});
		connection.notebooks.synchronization.onDidSaveNotebookDocument((params) => {
			const notebookDocument = this.notebookDocuments.get(params.notebookDocument.uri);
			if (notebookDocument === undefined) {
				return;
			}
			this._onDidSave.fire(notebookDocument);
		});
		connection.notebooks.synchronization.onDidCloseNotebookDocument((params) => {
			const notebookDocument = this.notebookDocuments.get(params.notebookDocument.uri);
			if (notebookDocument === undefined) {
				return;
			}
			this._onDidClose.fire(notebookDocument);
			for (const cellTextDocument of params.cellTextDocuments) {
				cellTextDocumentConnection.closeTextDocument({ textDocument: cellTextDocument });
			}
			this.notebookDocuments.delete(params.notebookDocument.uri);
			for (const cell of notebookDocument.cells) {
				this.notebookCellMap.delete(cell.document);
			}
		});
	}