src/vs/workbench/contrib/codeEditor/browser/outline/documentSymbolsOutline.ts/DocumentSymbolsOutline/constructor
class DocumentSymbolsOutline:	constructor(
		private readonly _editor: ICodeEditor,
		target: OutlineTarget,
		firstLoadBarrier: Barrier,
		@ILanguageFeaturesService private readonly _languageFeaturesService: ILanguageFeaturesService,
		@ICodeEditorService private readonly _codeEditorService: ICodeEditorService,
		@IOutlineModelService private readonly _outlineModelService: IOutlineModelService,
		@IConfigurationService private readonly _configurationService: IConfigurationService,
		@IMarkerDecorationsService private readonly _markerDecorationsService: IMarkerDecorationsService,
		@ITextResourceConfigurationService textResourceConfigurationService: ITextResourceConfigurationService,
		@IInstantiationService instantiationService: IInstantiationService,
	) {

		this._breadcrumbsDataSource = new DocumentSymbolBreadcrumbsSource(_editor, textResourceConfigurationService);
		const delegate = new DocumentSymbolVirtualDelegate();
		const renderers = [new DocumentSymbolGroupRenderer(), instantiationService.createInstance(DocumentSymbolRenderer, true)];
		const treeDataSource: IDataSource<this, DocumentSymbolItem> = {
			getChildren: (parent) => {
				if (parent instanceof OutlineElement || parent instanceof OutlineGroup) {
					return parent.children.values();
				}
				if (parent === this && this._outlineModel) {
					return this._outlineModel.children.values();
				}
				return [];
			}
		};
		const comparator = new DocumentSymbolComparator();
		const initialState = textResourceConfigurationService.getValue<OutlineConfigCollapseItemsValues>(_editor.getModel()?.uri, OutlineConfigKeys.collapseItems);
		const options = {
			collapseByDefault: target === OutlineTarget.Breadcrumbs || (target === OutlineTarget.OutlinePane && initialState === OutlineConfigCollapseItemsValues.Collapsed),
			expandOnlyOnTwistieClick: true,
			multipleSelectionSupport: false,
			identityProvider: new DocumentSymbolIdentityProvider(),
			keyboardNavigationLabelProvider: new DocumentSymbolNavigationLabelProvider(),
			accessibilityProvider: new DocumentSymbolAccessibilityProvider(localize('document', "Document Symbols")),
			filter: target === OutlineTarget.OutlinePane
				? instantiationService.createInstance(DocumentSymbolFilter, 'outline')
				: target === OutlineTarget.Breadcrumbs
					? instantiationService.createInstance(DocumentSymbolFilter, 'breadcrumbs')
					: undefined
		};

		this.config = {
			breadcrumbsDataSource: this._breadcrumbsDataSource,
			delegate,
			renderers,
			treeDataSource,
			comparator,
			options,
			quickPickDataSource: { getQuickPickElements: () => { throw new Error('not implemented'); } }
		};


		// update as language, model, providers changes
		this._disposables.add(_languageFeaturesService.documentSymbolProvider.onDidChange(_ => this._createOutline()));
		this._disposables.add(this._editor.onDidChangeModel(_ => this._createOutline()));
		this._disposables.add(this._editor.onDidChangeModelLanguage(_ => this._createOutline()));

		// update soon'ish as model content change
		const updateSoon = new TimeoutTimer();
		this._disposables.add(updateSoon);
		this._disposables.add(this._editor.onDidChangeModelContent(event => {
			const model = this._editor.getModel();
			if (model) {
				const timeout = _outlineModelService.getDebounceValue(model);
				updateSoon.cancelAndSet(() => this._createOutline(event), timeout);
			}
		}));

		// stop when editor dies
		this._disposables.add(this._editor.onDidDispose(() => this._outlineDisposables.clear()));

		// initial load
		this._createOutline().finally(() => firstLoadBarrier.open());
	}