var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
import { createDecorator } from '../../instantiation/common/instantiation.js';
export const IProgressService = createDecorator('progressService');
export const emptyProgressRunner = Object.freeze({
    total() { },
    worked() { },
    done() { }
});
export class Progress {
    constructor(callback, opts) {
        this.callback = callback;
        this.report = (opts === null || opts === void 0 ? void 0 : opts.async)
            ? this._reportAsync.bind(this)
            : this._reportSync.bind(this);
    }
    _reportSync(item) {
        this._value = item;
        this.callback(this._value);
    }
    _reportAsync(item) {
        if (!this._asyncQueue) {
            this._asyncQueue = [item];
        }
        else {
            this._asyncQueue.push(item);
        }
        this._processAsyncQueue();
    }
    _processAsyncQueue() {
        return __awaiter(this, void 0, void 0, function* () {
            if (this._processingAsyncQueue) {
                return;
            }
            try {
                this._processingAsyncQueue = true;
                while (this._asyncQueue && this._asyncQueue.length) {
                    const item = this._asyncQueue.shift();
                    this._value = item;
                    yield this.callback(this._value);
                }
            }
            finally {
                this._processingAsyncQueue = false;
                const drainListener = this._drainListener;
                this._drainListener = undefined;
                drainListener === null || drainListener === void 0 ? void 0 : drainListener();
            }
        });
    }
}
Progress.None = Object.freeze({ report() { } });
export const IEditorProgressService = createDecorator('editorProgressService');
