import { JSONValue } from '@lumino/coreutils';
import { Disposable, DisposableCollection } from '../disposable';
import { Emitter, Event } from '../event';
import { Deferred } from '../promise-util';
import URI from '../uri';
import { OverridePreferenceName, PreferenceLanguageOverrideService } from './preference-language-override-service';
import { PreferenceProvider, PreferenceProviderDataChange, PreferenceProviderDataChanges, PreferenceResolveResult } from './preference-provider';
import { PreferenceSchemaService } from './preference-schema';
import { PreferenceScope } from './preference-scope';
import { PreferenceConfigurations } from './preference-configurations';
/**
 * Representation of a preference change. A preference value can be set to `undefined` for a specific scope.
 * This means that the value from a more general scope will be used.
 */
export interface PreferenceChange extends Omit<PreferenceProviderDataChange, 'newValue' | 'oldValue'> {
    /**
     * Tests wether the given resource is affected by the preference change.
     * @param resourceUri the uri of the resource to test.
     */
    affects(resourceUri?: string): boolean;
}
export declare class PreferenceChangeImpl implements PreferenceChange {
    protected readonly change: PreferenceProviderDataChange;
    constructor(change: PreferenceProviderDataChange);
    get preferenceName(): string;
    get scope(): PreferenceScope;
    get domain(): string[] | undefined;
    affects(resourceUri?: string): boolean;
}
/**
 * A key-value storage for {@link PreferenceChange}s. Used to aggregate multiple simultaneous preference changes.
 */
export interface PreferenceChanges {
    [preferenceName: string]: PreferenceChange;
}
export declare const PreferenceService: unique symbol;
/**
 * Service to manage preferences including, among others, getting and setting preference values as well
 * as listening to preference changes.
 *
 * Depending on your use case you might also want to look at {@link createPreferenceProxy} with which
 * you can easily create a typesafe schema-based interface for your preferences. Internally the proxy
 * uses the PreferenceService so both approaches are compatible.
 */
export interface PreferenceService extends Disposable {
    /**
     * Promise indicating whether the service successfully initialized.
     */
    readonly ready: Promise<void>;
    /**
     * Indicates whether the service has successfully initialized. Will be `true` when {@link PreferenceService.ready the `ready` Promise} resolves.
     */
    readonly isReady: boolean;
    /**
     * Retrieve the stored value for the given preference.
     *
     * @param preferenceName the preference identifier.
     *
     * @returns the value stored for the given preference when it exists, `undefined` otherwise.
     */
    get<T>(preferenceName: string): T | undefined;
    /**
     * Retrieve the stored value for the given preference.
     *
     * @param preferenceName the preference identifier.
     * @param defaultValue the value to return when no value for the given preference is stored.
     *
     * @returns the value stored for the given preference when it exists, otherwise the given default value.
     */
    get<T>(preferenceName: string, defaultValue: T): T;
    /**
     * Retrieve the stored value for the given preference and resourceUri.
     *
     * @param preferenceName the preference identifier.
     * @param defaultValue the value to return when no value for the given preference is stored.
     * @param resourceUri the uri of the resource for which the preference is stored. This used to retrieve
     * a potentially different value for the same preference for different resources, for example `files.encoding`.
     *
     * @returns the value stored for the given preference and resourceUri when it exists, otherwise the given
     * default value.
     */
    get<T>(preferenceName: string, defaultValue: T, resourceUri?: string): T;
    /**
     * Retrieve the stored value for the given preference and resourceUri.
     *
     * @param preferenceName the preference identifier.
     * @param defaultValue the value to return when no value for the given preference is stored.
     * @param resourceUri the uri of the resource for which the preference is stored. This used to retrieve
     * a potentially different value for the same preference for different resources, for example `files.encoding`.
     *
     * @returns the value stored for the given preference and resourceUri when it exists, otherwise the given
     * default value.
     */
    get<T>(preferenceName: string, defaultValue?: T, resourceUri?: string): T | undefined;
    /**
     * Sets the given preference to the given value.
     *
     * @param preferenceName the preference identifier.
     * @param value the new value of the preference.
     * @param scope the scope for which the value shall be set, i.e. user, workspace etc.
     * When the folder scope is specified a resourceUri must be provided.
     * @param resourceUri the uri of the resource for which the preference is stored. This used to store
     * a potentially different value for the same preference for different resources, for example `files.encoding`.
     *
     * @returns a promise which resolves to `undefined` when setting the preference was successful. Otherwise it rejects
     * with an error.
     */
    set(preferenceName: string, value: any, scope?: PreferenceScope, resourceUri?: string): Promise<void>;
    /**
     * Determines and applies the changes necessary to apply `value` to either the `resourceUri` supplied or the active session.
     * If there is no setting for the `preferenceName`, the change will be applied in user scope.
     * If there is a setting conflicting with the specified `value`, the change will be applied in the most specific scope with a conflicting value.
     *
     * @param preferenceName the identifier of the preference to modify.
     * @param value the value to which to set the preference. `undefined` will reset the preference to its default value.
     * @param resourceUri the uri of the resource to which the change is to apply. If none is provided, folder scope will be ignored.
     */
    updateValue(preferenceName: string, value: any, resourceUri?: string): Promise<void>;
    /**
     * Registers a callback which will be called whenever a preference is changed.
     */
    onPreferenceChanged: Event<PreferenceChange>;
    /**
     * Registers a callback which will be called whenever one or more preferences are changed.
     */
    onPreferencesChanged: Event<PreferenceChanges>;
    /**
     * Retrieve the stored value for the given preference and resourceUri in all available scopes.
     *
     * @param preferenceName the preference identifier.
     * @param resourceUri the uri of the resource for which the preference is stored.
     * @param forceLanguageOverride if `true` and `preferenceName` is a language override, only values for the specified override will be returned.
     * Otherwise, values for the override will be returned where defined, and values from the base preference will be returned otherwise.
     *
     * @return an object containing the value of the given preference for all scopes.
     */
    inspect<T extends JSONValue>(preferenceName: string, resourceUri?: string, forceLanguageOverride?: boolean): PreferenceInspection<T> | undefined;
    /**
     * For behavior, see {@link PreferenceService.inspect}.
     *
     * @returns the value in the scope specified.
     */
    inspectInScope<T extends JSONValue>(preferenceName: string, scope: PreferenceScope, resourceUri?: string, forceLanguageOverride?: boolean): T | undefined;
    /**
     * Returns a new preference identifier based on the given OverridePreferenceName.
     *
     * @param options the override specification.
     *
     * @returns the calculated string based on the given OverridePreferenceName.
     */
    overridePreferenceName(options: OverridePreferenceName): string;
    /**
     * Tries to split the given preference identifier into the original OverridePreferenceName attributes
     * with which this identifier was created. Returns `undefined` if this is not possible, for example
     * when the given preference identifier was not generated by `overridePreferenceName`.
     *
     * This method is checked when resolving preferences. Therefore together with "overridePreferenceName"
     * this can be used to handle specialized preferences, e.g. "[markdown].editor.autoIndent" and "editor.autoIndent".
     *
     * @param preferenceName the preferenceName which might have been created via {@link PreferenceService.overridePreferenceName}.
     *
     * @returns the OverridePreferenceName which was used to create the given `preferenceName` if this was the case,
     * `undefined` otherwise.
     */
    overriddenPreferenceName(preferenceName: string): OverridePreferenceName | undefined;
    /**
     * Retrieve the stored value for the given preference and resourceUri.
     *
     * @param preferenceName the preference identifier.
     * @param defaultValue the value to return when no value for the given preference is stored.
     * @param resourceUri the uri of the resource for which the preference is stored. This used to retrieve
     * a potentially different value for the same preference for different resources, for example `files.encoding`.
     *
     * @returns an object containing the value stored for the given preference and resourceUri when it exists,
     * otherwise the given default value. If determinable the object will also contain the uri of the configuration
     * resource in which the preference was stored.
     */
    resolve<T>(preferenceName: string, defaultValue?: T, resourceUri?: string): PreferenceResolveResult<T>;
    /**
     * Returns the uri of the configuration resource for the given scope and optional resource uri.
     *
     * @param scope the PreferenceScope to query for.
     * @param resourceUri the optional uri of the resource-specific preference handling
     * @param sectionName the optional preference section to query for.
     *
     * @returns the uri of the configuration resource for the given scope and optional resource uri it it exists,
     * `undefined` otherwise.
     */
    getConfigUri(scope: PreferenceScope, resourceUri?: string, sectionName?: string): URI | undefined;
}
/**
 * Return type of the {@link PreferenceService.inspect} call.
 */
export interface PreferenceInspection<T = JSONValue> {
    /**
     * The preference identifier.
     */
    preferenceName: string;
    /**
     * Value in default scope.
     */
    defaultValue: T | undefined;
    /**
     * Value in user scope.
     */
    globalValue: T | undefined;
    /**
     * Value in workspace scope.
     */
    workspaceValue: T | undefined;
    /**
     * Value in folder scope.
     */
    workspaceFolderValue: T | undefined;
    /**
     * The value that is active, i.e. the value set in the lowest scope available.
     */
    value: T | undefined;
}
export type PreferenceInspectionScope = keyof Omit<PreferenceInspection<unknown>, 'preferenceName'>;
/**
 * We cannot load providers directly in the case if they depend on `PreferenceService` somehow.
 * It allows to load them lazily after DI is configured.
 */
export declare const PreferenceProviderProvider: unique symbol;
export type PreferenceProviderProvider = (scope: PreferenceScope, uri?: URI) => PreferenceProvider | undefined;
export declare class PreferenceServiceImpl implements PreferenceService {
    protected readonly onPreferenceChangedEmitter: Emitter<PreferenceChange>;
    readonly onPreferenceChanged: Event<PreferenceChange>;
    protected readonly onPreferencesChangedEmitter: Emitter<PreferenceChanges>;
    readonly onPreferencesChanged: Event<PreferenceChanges>;
    protected readonly toDispose: DisposableCollection;
    protected readonly schemaService: PreferenceSchemaService;
    protected readonly providerProvider: PreferenceProviderProvider;
    protected readonly configurations: PreferenceConfigurations;
    protected readonly preferenceOverrideService: PreferenceLanguageOverrideService;
    protected readonly preferenceProviders: Map<PreferenceScope, PreferenceProvider>;
    protected initializeProviders(): Promise<void>;
    protected init(): void;
    dispose(): void;
    protected readonly _ready: Deferred<void>;
    get ready(): Promise<void>;
    protected _isReady: boolean;
    get isReady(): boolean;
    protected reconcilePreferences(changes: PreferenceProviderDataChanges): void;
    protected getAffectedPreferenceNames(change: PreferenceProviderDataChange, accept: (affectedPreferenceName: string) => void): void;
    protected getProvider(scope: PreferenceScope): PreferenceProvider | undefined;
    has(preferenceName: string, resourceUri?: string): boolean;
    get<T>(preferenceName: string): T | undefined;
    get<T>(preferenceName: string, defaultValue: T): T;
    get<T>(preferenceName: string, defaultValue: T, resourceUri: string): T;
    get<T>(preferenceName: string, defaultValue?: T, resourceUri?: string): T | undefined;
    resolve<T>(preferenceName: string, defaultValue?: T, resourceUri?: string): PreferenceResolveResult<T>;
    set(preferenceName: string, value: any, scope: PreferenceScope | undefined, resourceUri?: string): Promise<void>;
    getBoolean(preferenceName: string): boolean | undefined;
    getBoolean(preferenceName: string, defaultValue: boolean): boolean;
    getBoolean(preferenceName: string, defaultValue: boolean, resourceUri: string): boolean;
    getString(preferenceName: string): string | undefined;
    getString(preferenceName: string, defaultValue: string): string;
    getString(preferenceName: string, defaultValue: string, resourceUri: string): string;
    getNumber(preferenceName: string): number | undefined;
    getNumber(preferenceName: string, defaultValue: number): number;
    getNumber(preferenceName: string, defaultValue: number, resourceUri: string): number;
    inspect<T extends JSONValue>(preferenceName: string, resourceUri?: string, forceLanguageOverride?: boolean): PreferenceInspection<T> | undefined;
    inspectInScope<T extends JSONValue>(preferenceName: string, scope: PreferenceScope, resourceUri?: string, forceLanguageOverride?: boolean): T | undefined;
    protected getScopedValueFromInspection<T>(inspection: PreferenceInspection<T>, scope: PreferenceScope): T | undefined;
    updateValue(preferenceName: string, value: any, resourceUri?: string): Promise<void>;
    protected getScopesToChange(inspection: PreferenceInspection<any>, intendedValue: any): PreferenceScope[];
    overridePreferenceName(options: OverridePreferenceName): string;
    overriddenPreferenceName(preferenceName: string): OverridePreferenceName | undefined;
    protected doHas(preferenceName: string, resourceUri?: string): boolean;
    protected doInspectInScope<T>(preferenceName: string, scope: PreferenceScope, resourceUri?: string): T | undefined;
    protected doGet<T>(preferenceName: string, defaultValue?: T, resourceUri?: string): T | undefined;
    protected doResolve<T>(preferenceName: string, defaultValue?: T, resourceUri?: string): PreferenceResolveResult<T>;
    getConfigUri(scope: PreferenceScope, resourceUri?: string, sectionName?: string): URI | undefined;
}
//# sourceMappingURL=preference-service.d.ts.map