declare module '@glimmer/interfaces/lib/serialize' {
    /**
     * This file describes the interface between compilation time
     * and runtime.
     *
     * # Locators
     *
     * Compile time and runtime must share the same Locator. A Locator is an
     * object that describes the location of a template, and is roughly a
     * module name. The compiler and runtime may use the Locator to locally
     * resolve names relative to the template the name was found in, but must
     * share resolution rules between compilation time and runtime.
     *
     * For example, given this template with Locator
     * `{ module: 'components/Articles/Container' }:
     *
     * ```
     * <TabBar />
     * ```
     *
     * The compiler may resolve `<TabBar>` to `components/Articles/TabBar`. The
     * important thing is that the compiler and runtime share resolution rules.
     *
     * # CompileTimeLookup
     *
     * When compiling an application, the `CompileTimeLookup` is responsible
     * for resolving helpers, modifiers, and components into "handles"
     * (numbers) that can be embedded into the program and used at runtime.
     *
     * # RuntimeResolver
     *
     * The `RuntimeResolver` has two responsibilities.
     *
     * 1. To turn handles created by the `CompileTimeLookup` into live helpers,
     *    modifiers, and components.
     * 2. To resolve dynamic components at runtime that come from
     *    calls to `{{component dynamic}}`.
     *
     * The `CompileTimeLookup` and `RuntimeResolver` must maintain symmetry
     * between:
     *
     * * `resolver.resolve(lookup.lookupComponentDefinition(name, referrer))`; and
     * * `resolver.lookupComponentDefinition(name, referrer))`
     *
     * # Coupling
     *
     * In practice, the `CompileTimeLookup` and `RuntimeResolver` are two parts
     * of one system. The goal of this system is to allow the `CompileTimeLookup`
     * to do as much resolution as possible ahead of time, while still allowing
     * the `RuntimeResolver` to do dynamic resolution when necessary.
     */

    import type {
      CapabilityMask,
      ComponentDefinitionState,
      ComponentInstanceState,
    } from "@glimmer/interfaces/lib/components.js";
    import type { Nullable } from "@glimmer/interfaces/lib/core.js";
    import type { InternalComponentManager } from "@glimmer/interfaces/lib/managers.js";
    import type { CompilableProgram, Template } from "@glimmer/interfaces/lib/template.js";

    export interface CompileTimeComponent {
      handle: number;
      capabilities: CapabilityMask;
      compilable: Nullable<CompilableProgram>;
    }

    export interface ResolvedComponentDefinition<
      D = ComponentDefinitionState,
      I = ComponentInstanceState,
      M extends InternalComponentManager<I, D> = InternalComponentManager<I, D>,
    > {
      state: D;
      manager: M;
      template: Template | null;
    }
}