src/vs/workbench/api/common/extHostNotebookRenderers.ts/ExtHostNotebookRenderers/createRendererMessaging
class ExtHostNotebookRenderers:	public createRendererMessaging(manifest: IExtensionDescription, rendererId: string): vscode.NotebookRendererMessaging {
		if (!manifest.contributes?.notebookRenderer?.some(r => r.id === rendererId)) {
			throw new Error(`Extensions may only call createRendererMessaging() for renderers they contribute (got ${rendererId})`);
		}

		// In the stable API, the editor is given as an empty object, and this map
		// is used to maintain references. This can be removed after editor finalization.
		const notebookEditorVisible = isProposedApiEnabled(manifest, 'notebookEditor');
		const notebookEditorAliases = new WeakMap<{}, vscode.NotebookEditor>();

		const messaging: vscode.NotebookRendererMessaging = {
			onDidReceiveMessage: (listener, thisArg, disposables) => {
				const wrappedListener = notebookEditorVisible ? listener : (evt: { editor: vscode.NotebookEditor; message: any }) => {
					const obj = {};
					notebookEditorAliases.set(obj, evt.editor);
					listener({ editor: obj as vscode.NotebookEditor, message: evt.message });
				};

				return this.getOrCreateEmitterFor(rendererId).event(wrappedListener, thisArg, disposables);
			},
			postMessage: (message, editorOrAlias) => {
				if (ExtHostNotebookEditor.apiEditorsToExtHost.has(message)) { // back compat for swapped args
					[message, editorOrAlias] = [editorOrAlias, message];
				}


				const editor = notebookEditorVisible ? editorOrAlias : notebookEditorAliases.get(editorOrAlias!);
				const extHostEditor = editor && ExtHostNotebookEditor.apiEditorsToExtHost.get(editor);
				return this.proxy.$postMessage(extHostEditor?.id, rendererId, message);
			},
		};

		return messaging;
	}