import { Conversion } from "../Conversion";
import { ConversionContext } from "../ConversionContext";
import { PluginConverterHook, PluginHook, PluginProvider, PluginTextConverter, PluginTextEscaper } from "./Plugin";
import { PresetProvider } from "./Preset";
declare const _addProvidedPlugin: unique symbol;
declare const _api: unique symbol;
declare const _converters: unique symbol;
declare const _hookCache: unique symbol;
declare const _getHookCache: unique symbol;
declare const _plugins: unique symbol;
/**
 * A basic manager for plugins and presets (collections of plugins) that can be hooked into {@link EuropaCore}.
 */
export declare class PluginManager {
    private readonly [_api];
    private readonly [_converters];
    private readonly [_plugins];
    private [_hookCache];
    /**
     * Invokes the specified plugin `provider` and adds the resulting plugin to this {@link PluginManager}.
     *
     * If the plugin contains any converters, they will be associated with their corresponding tag names, overriding any
     * previously converters associated with those tag names.
     *
     * If an error occurs when invoking `provider`, the plugin will not be added to this {@link PluginManager}.
     *
     * @param provider - The provider for the plugin to be added.
     * @return A reference to this {@link PluginManager} for chaining purposes.
     * @throws If a problem occurs while invoking `provider`.
     */
    addPlugin(provider: PluginProvider): this;
    /**
     * Invokes the specified preset `provider` and adds the resulting preset to this {@link PluginManager}.
     *
     * This method is effectively just a shortcut for calling {@link PluginManager#addPlugin} for multiple plugin
     * providers, however, the main benefit is that it supports the concept of presets, which are a useful mechanism for
     * bundling and distributing plugins.
     *
     * If an error occurs when invoking `provider`, the preset and all of its plugins will not be added to this
     * {@link PluginManager}.
     *
     * @param provider - The provider for the preset whose plugins are to be added.
     * @return A reference to this {@link PluginManager} for chaining purposes.
     * @throws If a problem occurs while invoking `provider`.
     */
    addPreset(provider: PresetProvider): this;
    /**
     * Returns whether this {@link PluginManager} contains a converter for the specified `tagName` and that the converter
     * has a hook with the name provided.
     *
     * @param tagName - The name of the tag to be checked.
     * @param hookName - The name of the hook to be checked.
     * @return `true` if a converter for `tagName` exists and has the named hook; otherwise `false`.
     */
    hasConverterHook(tagName: string, hookName: PluginConverterHook): boolean;
    /**
     * Invokes the hook with the specified name on with the `conversion` and `context` provided on the converter for the
     * given `tagName` within this {@link PluginManager}.
     *
     * If there is no converter for `tagName` or the converter does not have the named hook, nothing happens and one of
     * the following values will be returned based on `hookName`:
     *
     * | Hook Name  | Return Value |
     * | ---------- | ------------ |
     * | `endTag`   | `undefined`  |
     * | `startTag` | `false`      |
     *
     * Otherwise, it will return the result of invoking the named hook. For this reason it is highly recommended that,
     * if the return value is important, {@link PluginManager#hasConverterHook} is called with the same `tagName` and
     * `hookName` combination to check whether the converter hook exists before calling
     * {@link PluginManager#invokeConverterHook}.
     *
     * @param tagName - The name of the tag whose converter (if any) the named hook is to be invoked on.
     * @param hookName - The name of the hook to be invoked.
     * @param conversion - The current {@link Conversion}.
     * @param context - The context for the current element within the {@link Conversion}.
     * @return The result of calling the hook or a default value based on `hookName` (see above table) if there is no
     * converter for `tagName` or the converter does not have the named hook.
     */
    invokeConverterHook(tagName: string, hookName: PluginConverterHook, conversion: Conversion, context: ConversionContext): boolean | void;
    /**
     * Invokes the hook with the specified name with the `conversion` provided on each of the plugins within this
     * {@link PluginManager}.
     *
     * Any plugins that do not have the named hook are skipped.
     *
     * @param hookName - The name of the hook to be invoked.
     * @param conversion - The current {@link Conversion}.
     */
    invokeHook(hookName: PluginHook, conversion: Conversion): void;
    /**
     * Invokes a special hook on all plugins within this {@link PluginManager} that allows plugins to conditionally
     * perform an alternative conversion of the specified `value` which has been taken from a text node being converted by
     * the given `conversion`.
     *
     * This relies entirely on plugins ensuring that, if they perform any alternative conversion of the specified `value`,
     * that their hook returns `true` in order to prevent `conversion` from also processing `value` which would result in
     * duplication and would likely have other unexpected and unwanted side effects.
     *
     * @param value - The text value to potentially be converted.
     * @param conversion - The current {@link Conversion}.
     * @return `true` if `value` has been converted by a plugin; otherwise `false`.
     */
    invokeTextConverterHook(value: string, conversion: Conversion): boolean;
    /**
     * Invokes a special hook on all plugins within this {@link PluginManager} that allows plugins to perform any
     * additional escaping of special characters within the specified `value` which has been taken from a text node being
     * converted by the given `conversion`.
     *
     * This relies on plugins ensuring that they do not double-escape characters that have either been previously escaped
     * by `conversion` or another plugin.
     *
     * @param value - The text value to be escaped.
     * @param conversion - The current {@link Conversion}.
     * @return The escaped `str` or `str` if no escaping is required.
     */
    invokeTextEscaperHook(value: string, conversion: Conversion): string;
    private [_addProvidedPlugin];
    private [_getHookCache];
}
/**
 * A cache containing special hooks for registered all registered plugins within a {@link PluginManager}.
 */
export declare type PluginManagerHookCache = {
    /**
     * The text converter special hooks existing on registered plugins within the {@link PluginManager}.
     */
    readonly textConverters: readonly PluginTextConverter[];
    /**
     * The text escaper special hooks existing on registered plugins within the {@link PluginManager}.
     */
    readonly textEscapers: readonly PluginTextEscaper[];
};
export {};
