src/vs/workbench/api/common/extHostTextEditor.ts/ExtHostTextEditor/constructor
class ExtHostTextEditor:	constructor(
		readonly id: string,
		private readonly _proxy: MainThreadTextEditorsShape,
		private readonly _logService: ILogService,
		document: Lazy<vscode.TextDocument>,
		selections: Selection[], options: IResolvedTextEditorConfiguration,
		visibleRanges: Range[], viewColumn: vscode.ViewColumn | undefined
	) {
		this._selections = selections;
		this._options = new ExtHostTextEditorOptions(this._proxy, this.id, options, _logService);
		this._visibleRanges = visibleRanges;
		this._viewColumn = viewColumn;

		const that = this;

		this.value = Object.freeze({
			get document(): vscode.TextDocument {
				return document.getValue();
			},
			set document(_value) {
				throw readonly('document');
			},
			// --- selection
			get selection(): Selection {
				return that._selections && that._selections[0];
			},
			set selection(value: Selection) {
				if (!(value instanceof Selection)) {
					throw illegalArgument('selection');
				}
				that._selections = [value];
				that._trySetSelection();
			},
			get selections(): Selection[] {
				return that._selections;
			},
			set selections(value: Selection[]) {
				if (!Array.isArray(value) || value.some(a => !(a instanceof Selection))) {
					throw illegalArgument('selections');
				}
				that._selections = value;
				that._trySetSelection();
			},
			// --- visible ranges
			get visibleRanges(): Range[] {
				return that._visibleRanges;
			},
			set visibleRanges(_value: Range[]) {
				throw readonly('visibleRanges');
			},
			// --- options
			get options(): vscode.TextEditorOptions {
				return that._options.value;
			},
			set options(value: vscode.TextEditorOptions) {
				if (!that._disposed) {
					that._options.assign(value);
				}
			},
			// --- view column
			get viewColumn(): vscode.ViewColumn | undefined {
				return that._viewColumn;
			},
			set viewColumn(_value) {
				throw readonly('viewColumn');
			},
			// --- edit
			edit(callback: (edit: TextEditorEdit) => void, options: { undoStopBefore: boolean; undoStopAfter: boolean } = { undoStopBefore: true, undoStopAfter: true }): Promise<boolean> {
				if (that._disposed) {
					return Promise.reject(new Error('TextEditor#edit not possible on closed editors'));
				}
				const edit = new TextEditorEdit(document.getValue(), options);
				callback(edit);
				return that._applyEdit(edit);
			},
			// --- snippet edit
			insertSnippet(snippet: SnippetString, where?: Position | readonly Position[] | Range | readonly Range[], options: { undoStopBefore: boolean; undoStopAfter: boolean } = { undoStopBefore: true, undoStopAfter: true }): Promise<boolean> {
				if (that._disposed) {
					return Promise.reject(new Error('TextEditor#insertSnippet not possible on closed editors'));
				}
				let ranges: IRange[];

				if (!where || (Array.isArray(where) && where.length === 0)) {
					ranges = that._selections.map(range => TypeConverters.Range.from(range));

				} else if (where instanceof Position) {
					const { lineNumber, column } = TypeConverters.Position.from(where);
					ranges = [{ startLineNumber: lineNumber, startColumn: column, endLineNumber: lineNumber, endColumn: column }];

				} else if (where instanceof Range) {
					ranges = [TypeConverters.Range.from(where)];
				} else {
					ranges = [];
					for (const posOrRange of where) {
						if (posOrRange instanceof Range) {
							ranges.push(TypeConverters.Range.from(posOrRange));
						} else {
							const { lineNumber, column } = TypeConverters.Position.from(posOrRange);
							ranges.push({ startLineNumber: lineNumber, startColumn: column, endLineNumber: lineNumber, endColumn: column });
						}
					}
				}
				return _proxy.$tryInsertSnippet(id, document.getValue().version, snippet.value, ranges, options);
			},
			setDecorations(decorationType: vscode.TextEditorDecorationType, ranges: Range[] | vscode.DecorationOptions[]): void {
				const willBeEmpty = (ranges.length === 0);
				if (willBeEmpty && !that._hasDecorationsForKey.has(decorationType.key)) {
					// avoid no-op call to the renderer
					return;
				}
				if (willBeEmpty) {
					that._hasDecorationsForKey.delete(decorationType.key);
				} else {
					that._hasDecorationsForKey.add(decorationType.key);
				}
				that._runOnProxy(() => {
					if (TypeConverters.isDecorationOptionsArr(ranges)) {
						return _proxy.$trySetDecorations(
							id,
							decorationType.key,
							TypeConverters.fromRangeOrRangeWithMessage(ranges)
						);
					} else {
						const _ranges: number[] = new Array<number>(4 * ranges.length);
						for (let i = 0, len = ranges.length; i < len; i++) {
							const range = ranges[i];
							_ranges[4 * i] = range.start.line + 1;
							_ranges[4 * i + 1] = range.start.character + 1;
							_ranges[4 * i + 2] = range.end.line + 1;
							_ranges[4 * i + 3] = range.end.character + 1;
						}
						return _proxy.$trySetDecorationsFast(
							id,
							decorationType.key,
							_ranges
						);
					}
				});
			},
			revealRange(range: Range, revealType: vscode.TextEditorRevealType): void {
				that._runOnProxy(() => _proxy.$tryRevealRange(
					id,
					TypeConverters.Range.from(range),
					(revealType || TextEditorRevealType.Default)
				));
			},
			show(column: vscode.ViewColumn) {
				_proxy.$tryShowEditor(id, TypeConverters.ViewColumn.from(column));
			},
			hide() {
				_proxy.$tryHideEditor(id);
			}
		});
	}