function parse_descriptor(options, document) {

    /** @type {Map<string, Index|WorkerIndex>} */
    const index = new Map();
    let field = document.index || document.field || document;

    if (is_string(field)) {
        field = [field];
    }

    for (let i = 0, key, opt; i < field.length; i++) {

        key = field[i];

        if (!is_string(key)) {
            opt = key;
            key = key.field;
        }

        opt = /** @type IndexOptions */is_object(opt) ? Object.assign({}, options, opt) : options;

        if (this.worker) {
            let encoder = opt.encoder;

            encoder = encoder && encoder.encode ? encoder : new Encoder("string" == typeof encoder ? Charset[encoder] : encoder || {});

            const worker = new WorkerIndex(opt, /** @type {Encoder} */encoder);
            if (worker) {

                index.set(key, worker);
            } else {

                this.worker = !1;
            }
        }

        if (!this.worker) {
            index.set(key, new Index( /** @type IndexOptions */opt, this.reg));
        }

        if (opt.custom) {
            this.tree[i] = opt.custom;
        } else {
            this.tree[i] = parse_tree(key, this.marker);
            if (opt.filter) {
                if ("string" == typeof this.tree[i]) {

                    this.tree[i] = new String(this.tree[i]);
                }
                this.tree[i]._filter = opt.filter;
            }
        }

        this.field[i] = key;
    }

    if (this.storetree) {

        let stores = document.store;
        if (is_string(stores)) stores = [stores];

        for (let i = 0, store, field; i < stores.length; i++) {
            store = /** @type Array<StoreOptions> */stores[i];
            field = store.field || store;
            if (store.custom) {
                this.storetree[i] = store.custom;
                store.custom._field = field;
            } else {
                this.storetree[i] = parse_tree(field, this.marker);
                if (store.filter) {
                    if ("string" == typeof this.storetree[i]) {

                        this.storetree[i] = new String(this.storetree[i]);
                    }
                    this.storetree[i]._filter = store.filter;
                }
            }
        }
    }

    return index;
}
@this {Document}
@return {Map<string, Index|WorkerIndex>}