use std::cell::RefCell;
use std::collections::BTreeMap;
use std::ops::{Deref, DerefMut};
use std::sync::LazyLock;

use private::Sealed;
use rustc_ast::{AttrStyle, CRATE_NODE_ID, MetaItemLit, NodeId};
use rustc_errors::{Diag, Diagnostic, Level};
use rustc_feature::{AttrSuggestionStyle, AttributeTemplate};
use rustc_hir::attrs::AttributeKind;
use rustc_hir::lints::{AttributeLint, AttributeLintKind};
use rustc_hir::{AttrPath, CRATE_HIR_ID, HirId};
use rustc_session::Session;
use rustc_span::{ErrorGuaranteed, Span, Symbol};

use crate::AttributeParser;
use crate::attributes::allow_unstable::{
    AllowConstFnUnstableParser, AllowInternalUnstableParser, UnstableFeatureBoundParser,
};
use crate::attributes::body::CoroutineParser;
use crate::attributes::codegen_attrs::{
    ColdParser, CoverageParser, ExportNameParser, ForceTargetFeatureParser, NakedParser,
    NoMangleParser, ObjcClassParser, ObjcSelectorParser, OptimizeParser,
    RustcPassIndirectlyInNonRusticAbisParser, SanitizeParser, TargetFeatureParser,
    TrackCallerParser, UsedParser,
};
use crate::attributes::confusables::ConfusablesParser;
use crate::attributes::crate_level::{
    CrateNameParser, MoveSizeLimitParser, NoCoreParser, NoStdParser, PatternComplexityLimitParser,
    RecursionLimitParser, RustcCoherenceIsCoreParser, TypeLengthLimitParser,
    WindowsSubsystemParser,
};
use crate::attributes::debugger::DebuggerViualizerParser;
use crate::attributes::deprecation::DeprecationParser;
use crate::attributes::dummy::DummyParser;
use crate::attributes::inline::{InlineParser, RustcForceInlineParser};
use crate::attributes::link_attrs::{
    ExportStableParser, FfiConstParser, FfiPureParser, LinkNameParser, LinkOrdinalParser,
    LinkParser, LinkSectionParser, LinkageParser, StdInternalSymbolParser,
};
use crate::attributes::lint_helpers::{
    AsPtrParser, AutomaticallyDerivedParser, PassByValueParser, PubTransparentParser,
    RustcShouldNotBeCalledOnConstItems,
};
use crate::attributes::loop_match::{ConstContinueParser, LoopMatchParser};
use crate::attributes::macro_attrs::{
    AllowInternalUnsafeParser, MacroEscapeParser, MacroExportParser, MacroUseParser,
};
use crate::attributes::must_use::MustUseParser;
use crate::attributes::no_implicit_prelude::NoImplicitPreludeParser;
use crate::attributes::non_exhaustive::NonExhaustiveParser;
use crate::attributes::path::PathParser as PathAttributeParser;
use crate::attributes::pin_v2::PinV2Parser;
use crate::attributes::proc_macro_attrs::{
    ProcMacroAttributeParser, ProcMacroDeriveParser, ProcMacroParser, RustcBuiltinMacroParser,
};
use crate::attributes::prototype::CustomMirParser;
use crate::attributes::repr::{AlignParser, AlignStaticParser, ReprParser};
use crate::attributes::rustc_internal::{
    RustcLayoutScalarValidRangeEndParser, RustcLayoutScalarValidRangeStartParser, RustcMainParser,
    RustcObjectLifetimeDefaultParser, RustcSimdMonomorphizeLaneLimitParser,
};
use crate::attributes::semantics::MayDangleParser;
use crate::attributes::stability::{
    BodyStabilityParser, ConstStabilityIndirectParser, ConstStabilityParser, StabilityParser,
};
use crate::attributes::test_attrs::{IgnoreParser, ShouldPanicParser};
use crate::attributes::traits::{
    AllowIncoherentImplParser, CoinductiveParser, DenyExplicitImplParser,
    DoNotImplementViaObjectParser, FundamentalParser, MarkerParser, ParenSugarParser,
    PointeeParser, SkipDuringMethodDispatchParser, SpecializationTraitParser, TypeConstParser,
    UnsafeSpecializationMarkerParser,
};
use crate::attributes::transparency::TransparencyParser;
use crate::attributes::{AttributeParser as _, Combine, Single, WithoutArgs};
use crate::parser::{ArgParser, PathParser};
use crate::session_diagnostics::{
    AttributeParseError, AttributeParseErrorReason, ParsedDescription, UnknownMetaItem,
};
use crate::target_checking::AllowedTargets;

type GroupType<S> = LazyLock<GroupTypeInner<S>>;

pub(super) struct GroupTypeInner<S: Stage> {
    pub(super) accepters: BTreeMap<&'static [Symbol], Vec<GroupTypeInnerAccept<S>>>,
    pub(super) finalizers: Vec<FinalizeFn<S>>,
}

pub(super) struct GroupTypeInnerAccept<S: Stage> {
    pub(super) template: AttributeTemplate,
    pub(super) accept_fn: AcceptFn<S>,
    pub(super) allowed_targets: AllowedTargets,
}

type AcceptFn<S> =
    Box<dyn for<'sess, 'a> Fn(&mut AcceptContext<'_, 'sess, S>, &ArgParser<'a>) + Send + Sync>;
type FinalizeFn<S> =
    Box<dyn Send + Sync + Fn(&mut FinalizeContext<'_, '_, S>) -> Option<AttributeKind>>;

macro_rules! attribute_parsers {
    (
        pub(crate) static $name: ident = [$($names: ty),* $(,)?];
    ) => {
        mod early {
            use super::*;
            type Combine<T> = super::Combine<T, Early>;
            type Single<T> = super::Single<T, Early>;
            type WithoutArgs<T> = super::WithoutArgs<T, Early>;

            attribute_parsers!(@[Early] pub(crate) static $name = [$($names),*];);
        }
        mod late {
            use super::*;
            type Combine<T> = super::Combine<T, Late>;
            type Single<T> = super::Single<T, Late>;
            type WithoutArgs<T> = super::WithoutArgs<T, Late>;

            attribute_parsers!(@[Late] pub(crate) static $name = [$($names),*];);
        }
    };
    (
        @[$stage: ty] pub(crate) static $name: ident = [$($names: ty),* $(,)?];
    ) => {
        pub(crate) static $name: GroupType<$stage> = LazyLock::new(|| {
            let mut accepts = BTreeMap::<_, Vec<GroupTypeInnerAccept<$stage>>>::new();
            let mut finalizes = Vec::<FinalizeFn<$stage>>::new();
            $(
                {
                    thread_local! {
                        static STATE_OBJECT: RefCell<$names> = RefCell::new(<$names>::default());
                    };

                    for (path, template, accept_fn) in <$names>::ATTRIBUTES {
                        accepts.entry(*path).or_default().push(GroupTypeInnerAccept {
                            template: *template,
                            accept_fn: Box::new(|cx, args| {
                                STATE_OBJECT.with_borrow_mut(|s| {
                                    accept_fn(s, cx, args)
                                })
                            }),
                            allowed_targets: <$names as crate::attributes::AttributeParser<$stage>>::ALLOWED_TARGETS,
                        });
                    }

                    finalizes.push(Box::new(|cx| {
                        let state = STATE_OBJECT.take();
                        state.finalize(cx)
                    }));
                }
            )*

            GroupTypeInner { accepters:accepts, finalizers:finalizes }
        });
    };
}
attribute_parsers!(
    pub(crate) static ATTRIBUTE_PARSERS = [
        // tidy-alphabetical-start
        AlignParser,
        AlignStaticParser,
        BodyStabilityParser,
        ConfusablesParser,
        ConstStabilityParser,
        MacroUseParser,
        NakedParser,
        StabilityParser,
        UsedParser,
        // tidy-alphabetical-end

        // tidy-alphabetical-start
        Combine<AllowConstFnUnstableParser>,
        Combine<AllowInternalUnstableParser>,
        Combine<DebuggerViualizerParser>,
        Combine<ForceTargetFeatureParser>,
        Combine<LinkParser>,
        Combine<ReprParser>,
        Combine<TargetFeatureParser>,
        Combine<UnstableFeatureBoundParser>,
        // tidy-alphabetical-end

        // tidy-alphabetical-start
        Single<CoverageParser>,
        Single<CrateNameParser>,
        Single<CustomMirParser>,
        Single<DeprecationParser>,
        Single<DummyParser>,
        Single<ExportNameParser>,
        Single<IgnoreParser>,
        Single<InlineParser>,
        Single<LinkNameParser>,
        Single<LinkOrdinalParser>,
        Single<LinkSectionParser>,
        Single<LinkageParser>,
        Single<MacroExportParser>,
        Single<MoveSizeLimitParser>,
        Single<MustUseParser>,
        Single<ObjcClassParser>,
        Single<ObjcSelectorParser>,
        Single<OptimizeParser>,
        Single<PathAttributeParser>,
        Single<PatternComplexityLimitParser>,
        Single<ProcMacroDeriveParser>,
        Single<RecursionLimitParser>,
        Single<RustcBuiltinMacroParser>,
        Single<RustcForceInlineParser>,
        Single<RustcLayoutScalarValidRangeEndParser>,
        Single<RustcLayoutScalarValidRangeStartParser>,
        Single<RustcObjectLifetimeDefaultParser>,
        Single<RustcSimdMonomorphizeLaneLimitParser>,
        Single<SanitizeParser>,
        Single<ShouldPanicParser>,
        Single<SkipDuringMethodDispatchParser>,
        Single<TransparencyParser>,
        Single<TypeLengthLimitParser>,
        Single<WindowsSubsystemParser>,
        Single<WithoutArgs<AllowIncoherentImplParser>>,
        Single<WithoutArgs<AllowInternalUnsafeParser>>,
        Single<WithoutArgs<AsPtrParser>>,
        Single<WithoutArgs<AutomaticallyDerivedParser>>,
        Single<WithoutArgs<CoinductiveParser>>,
        Single<WithoutArgs<ColdParser>>,
        Single<WithoutArgs<ConstContinueParser>>,
        Single<WithoutArgs<ConstStabilityIndirectParser>>,
        Single<WithoutArgs<CoroutineParser>>,
        Single<WithoutArgs<DenyExplicitImplParser>>,
        Single<WithoutArgs<DoNotImplementViaObjectParser>>,
        Single<WithoutArgs<ExportStableParser>>,
        Single<WithoutArgs<FfiConstParser>>,
        Single<WithoutArgs<FfiPureParser>>,
        Single<WithoutArgs<FundamentalParser>>,
        Single<WithoutArgs<LoopMatchParser>>,
        Single<WithoutArgs<MacroEscapeParser>>,
        Single<WithoutArgs<MarkerParser>>,
        Single<WithoutArgs<MayDangleParser>>,
        Single<WithoutArgs<NoCoreParser>>,
        Single<WithoutArgs<NoImplicitPreludeParser>>,
        Single<WithoutArgs<NoMangleParser>>,
        Single<WithoutArgs<NoStdParser>>,
        Single<WithoutArgs<NonExhaustiveParser>>,
        Single<WithoutArgs<ParenSugarParser>>,
        Single<WithoutArgs<PassByValueParser>>,
        Single<WithoutArgs<PinV2Parser>>,
        Single<WithoutArgs<PointeeParser>>,
        Single<WithoutArgs<ProcMacroAttributeParser>>,
        Single<WithoutArgs<ProcMacroParser>>,
        Single<WithoutArgs<PubTransparentParser>>,
        Single<WithoutArgs<RustcCoherenceIsCoreParser>>,
        Single<WithoutArgs<RustcMainParser>>,
        Single<WithoutArgs<RustcPassIndirectlyInNonRusticAbisParser>>,
        Single<WithoutArgs<RustcShouldNotBeCalledOnConstItems>>,
        Single<WithoutArgs<SpecializationTraitParser>>,
        Single<WithoutArgs<StdInternalSymbolParser>>,
        Single<WithoutArgs<TrackCallerParser>>,
        Single<WithoutArgs<TypeConstParser>>,
        Single<WithoutArgs<UnsafeSpecializationMarkerParser>>,
        // tidy-alphabetical-end
    ];
);

mod private {
    pub trait Sealed {}
    impl Sealed for super::Early {}
    impl Sealed for super::Late {}
}

// allow because it's a sealed trait
#[allow(private_interfaces)]
pub trait Stage: Sized + 'static + Sealed {
    type Id: Copy;

    fn parsers() -> &'static GroupType<Self>;

    fn emit_err<'sess>(
        &self,
        sess: &'sess Session,
        diag: impl for<'x> Diagnostic<'x>,
    ) -> ErrorGuaranteed;

    fn should_emit(&self) -> ShouldEmit;

    fn id_is_crate_root(id: Self::Id) -> bool;
}

// allow because it's a sealed trait
#[allow(private_interfaces)]
impl Stage for Early {
    type Id = NodeId;

    fn parsers() -> &'static GroupType<Self> {
        &early::ATTRIBUTE_PARSERS
    }
    fn emit_err<'sess>(
        &self,
        sess: &'sess Session,
        diag: impl for<'x> Diagnostic<'x>,
    ) -> ErrorGuaranteed {
        self.should_emit().emit_err(sess.dcx().create_err(diag))
    }

    fn should_emit(&self) -> ShouldEmit {
        self.emit_errors
    }

    fn id_is_crate_root(id: Self::Id) -> bool {
        id == CRATE_NODE_ID
    }
}

// allow because it's a sealed trait
#[allow(private_interfaces)]
impl Stage for Late {
    type Id = HirId;

    fn parsers() -> &'static GroupType<Self> {
        &late::ATTRIBUTE_PARSERS
    }
    fn emit_err<'sess>(
        &self,
        tcx: &'sess Session,
        diag: impl for<'x> Diagnostic<'x>,
    ) -> ErrorGuaranteed {
        tcx.dcx().emit_err(diag)
    }

    fn should_emit(&self) -> ShouldEmit {
        ShouldEmit::ErrorsAndLints
    }

    fn id_is_crate_root(id: Self::Id) -> bool {
        id == CRATE_HIR_ID
    }
}

/// used when parsing attributes for miscellaneous things *before* ast lowering
pub struct Early {
    /// Whether to emit errors or delay them as a bug
    /// For most attributes, the attribute will be parsed again in the `Late` stage and in this case the errors should be delayed
    /// But for some, such as `cfg`, the attribute will be removed before the `Late` stage so errors must be emitted
    pub emit_errors: ShouldEmit,
}
/// used when parsing attributes during ast lowering
pub struct Late;

/// Context given to every attribute parser when accepting
///
/// Gives [`AttributeParser`]s enough information to create errors, for example.
pub struct AcceptContext<'f, 'sess, S: Stage> {
    pub(crate) shared: SharedContext<'f, 'sess, S>,

    /// The outer span of the attribute currently being parsed
    /// #[attribute(...)]
    /// ^^^^^^^^^^^^^^^^^ outer span
    /// For attributes in `cfg_attr`, the outer span and inner spans are equal.
    pub(crate) attr_span: Span,
    /// The inner span of the attribute currently being parsed
    /// #[attribute(...)]
    ///   ^^^^^^^^^^^^^^  inner span
    pub(crate) inner_span: Span,

    /// Whether it is an inner or outer attribute
    pub(crate) attr_style: AttrStyle,

    /// A description of the thing we are parsing using this attribute parser
    /// We are not only using these parsers for attributes, but also for macros such as the `cfg!()` macro.
    pub(crate) parsed_description: ParsedDescription,

    /// The expected structure of the attribute.
    ///
    /// Used in reporting errors to give a hint to users what the attribute *should* look like.
    pub(crate) template: &'f AttributeTemplate,

    /// The name of the attribute we're currently accepting.
    pub(crate) attr_path: AttrPath,
}

impl<'f, 'sess: 'f, S: Stage> SharedContext<'f, 'sess, S> {
    pub(crate) fn emit_err(&self, diag: impl for<'x> Diagnostic<'x>) -> ErrorGuaranteed {
        self.stage.emit_err(&self.sess, diag)
    }

    /// Emit a lint. This method is somewhat special, since lints emitted during attribute parsing
    /// must be delayed until after HIR is built. This method will take care of the details of
    /// that.
    pub(crate) fn emit_lint(&mut self, lint: AttributeLintKind, span: Span) {
        if !matches!(
            self.stage.should_emit(),
            ShouldEmit::ErrorsAndLints | ShouldEmit::EarlyFatal { also_emit_lints: true }
        ) {
            return;
        }
        let id = self.target_id;
        (self.emit_lint)(AttributeLint { id, span, kind: lint });
    }

    pub(crate) fn warn_unused_duplicate(&mut self, used_span: Span, unused_span: Span) {
        self.emit_lint(
            AttributeLintKind::UnusedDuplicate {
                this: unused_span,
                other: used_span,
                warning: false,
            },
            unused_span,
        )
    }

    pub(crate) fn warn_unused_duplicate_future_error(
        &mut self,
        used_span: Span,
        unused_span: Span,
    ) {
        self.emit_lint(
            AttributeLintKind::UnusedDuplicate {
                this: unused_span,
                other: used_span,
                warning: true,
            },
            unused_span,
        )
    }
}

impl<'f, 'sess: 'f, S: Stage> AcceptContext<'f, 'sess, S> {
    pub(crate) fn unknown_key(
        &self,
        span: Span,
        found: String,
        options: &'static [&'static str],
    ) -> ErrorGuaranteed {
        self.emit_err(UnknownMetaItem { span, item: found, expected: options })
    }

    /// error that a string literal was expected.
    /// You can optionally give the literal you did find (which you found not to be a string literal)
    /// which can make better errors. For example, if the literal was a byte string it will suggest
    /// removing the `b` prefix.
    pub(crate) fn expected_string_literal(
        &self,
        span: Span,
        actual_literal: Option<&MetaItemLit>,
    ) -> ErrorGuaranteed {
        self.emit_err(AttributeParseError {
            span,
            attr_span: self.attr_span,
            template: self.template.clone(),
            path: self.attr_path.clone(),
            description: self.parsed_description,
            reason: AttributeParseErrorReason::ExpectedStringLiteral {
                byte_string: actual_literal.and_then(|i| {
                    i.kind.is_bytestr().then(|| self.sess().source_map().start_point(i.span))
                }),
            },
            suggestions: self.suggestions(),
        })
    }

    pub(crate) fn expected_integer_literal(&self, span: Span) -> ErrorGuaranteed {
        self.emit_err(AttributeParseError {
            span,
            attr_span: self.attr_span,
            template: self.template.clone(),
            path: self.attr_path.clone(),
            description: self.parsed_description,
            reason: AttributeParseErrorReason::ExpectedIntegerLiteral,
            suggestions: self.suggestions(),
        })
    }

    pub(crate) fn expected_list(&self, span: Span) -> ErrorGuaranteed {
        self.emit_err(AttributeParseError {
            span,
            attr_span: self.attr_span,
            template: self.template.clone(),
            path: self.attr_path.clone(),
            description: self.parsed_description,
            reason: AttributeParseErrorReason::ExpectedList,
            suggestions: self.suggestions(),
        })
    }

    pub(crate) fn expected_no_args(&self, args_span: Span) -> ErrorGuaranteed {
        self.emit_err(AttributeParseError {
            span: args_span,
            attr_span: self.attr_span,
            template: self.template.clone(),
            path: self.attr_path.clone(),
            description: self.parsed_description,
            reason: AttributeParseErrorReason::ExpectedNoArgs,
            suggestions: self.suggestions(),
        })
    }

    /// emit an error that a `name` was expected here
    pub(crate) fn expected_identifier(&self, span: Span) -> ErrorGuaranteed {
        self.emit_err(AttributeParseError {
            span,
            attr_span: self.attr_span,
            template: self.template.clone(),
            path: self.attr_path.clone(),
            description: self.parsed_description,
            reason: AttributeParseErrorReason::ExpectedIdentifier,
            suggestions: self.suggestions(),
        })
    }

    /// emit an error that a `name = value` pair was expected at this span. The symbol can be given for
    /// a nicer error message talking about the specific name that was found lacking a value.
    pub(crate) fn expected_name_value(&self, span: Span, name: Option<Symbol>) -> ErrorGuaranteed {
        self.emit_err(AttributeParseError {
            span,
            attr_span: self.attr_span,
            template: self.template.clone(),
            path: self.attr_path.clone(),
            description: self.parsed_description,
            reason: AttributeParseErrorReason::ExpectedNameValue(name),
            suggestions: self.suggestions(),
        })
    }

    /// emit an error that a `name = value` pair was found where that name was already seen.
    pub(crate) fn duplicate_key(&self, span: Span, key: Symbol) -> ErrorGuaranteed {
        self.emit_err(AttributeParseError {
            span,
            attr_span: self.attr_span,
            template: self.template.clone(),
            path: self.attr_path.clone(),
            description: self.parsed_description,
            reason: AttributeParseErrorReason::DuplicateKey(key),
            suggestions: self.suggestions(),
        })
    }

    /// an error that should be emitted when a [`MetaItemOrLitParser`](crate::parser::MetaItemOrLitParser)
    /// was expected *not* to be a literal, but instead a meta item.
    pub(crate) fn unexpected_literal(&self, span: Span) -> ErrorGuaranteed {
        self.emit_err(AttributeParseError {
            span,
            attr_span: self.attr_span,
            template: self.template.clone(),
            path: self.attr_path.clone(),
            description: self.parsed_description,
            reason: AttributeParseErrorReason::UnexpectedLiteral,
            suggestions: self.suggestions(),
        })
    }

    pub(crate) fn expected_single_argument(&self, span: Span) -> ErrorGuaranteed {
        self.emit_err(AttributeParseError {
            span,
            attr_span: self.attr_span,
            template: self.template.clone(),
            path: self.attr_path.clone(),
            description: self.parsed_description,
            reason: AttributeParseErrorReason::ExpectedSingleArgument,
            suggestions: self.suggestions(),
        })
    }

    pub(crate) fn expected_at_least_one_argument(&self, span: Span) -> ErrorGuaranteed {
        self.emit_err(AttributeParseError {
            span,
            attr_span: self.attr_span,
            template: self.template.clone(),
            path: self.attr_path.clone(),
            description: self.parsed_description,
            reason: AttributeParseErrorReason::ExpectedAtLeastOneArgument,
            suggestions: self.suggestions(),
        })
    }

    /// produces an error along the lines of `expected one of [foo, meow]`
    pub(crate) fn expected_specific_argument(
        &self,
        span: Span,
        possibilities: &[Symbol],
    ) -> ErrorGuaranteed {
        self.emit_err(AttributeParseError {
            span,
            attr_span: self.attr_span,
            template: self.template.clone(),
            path: self.attr_path.clone(),
            description: self.parsed_description,
            reason: AttributeParseErrorReason::ExpectedSpecificArgument {
                possibilities,
                strings: false,
                list: false,
            },
            suggestions: self.suggestions(),
        })
    }

    /// produces an error along the lines of `expected one of [foo, meow] as an argument`.
    /// i.e. slightly different wording to [`expected_specific_argument`](Self::expected_specific_argument).
    pub(crate) fn expected_specific_argument_and_list(
        &self,
        span: Span,
        possibilities: &[Symbol],
    ) -> ErrorGuaranteed {
        self.emit_err(AttributeParseError {
            span,
            attr_span: self.attr_span,
            template: self.template.clone(),
            path: self.attr_path.clone(),
            description: self.parsed_description,
            reason: AttributeParseErrorReason::ExpectedSpecificArgument {
                possibilities,
                strings: false,
                list: true,
            },
            suggestions: self.suggestions(),
        })
    }

    /// produces an error along the lines of `expected one of ["foo", "meow"]`
    pub(crate) fn expected_specific_argument_strings(
        &self,
        span: Span,
        possibilities: &[Symbol],
    ) -> ErrorGuaranteed {
        self.emit_err(AttributeParseError {
            span,
            attr_span: self.attr_span,
            template: self.template.clone(),
            path: self.attr_path.clone(),
            description: self.parsed_description,
            reason: AttributeParseErrorReason::ExpectedSpecificArgument {
                possibilities,
                strings: true,
                list: false,
            },
            suggestions: self.suggestions(),
        })
    }

    pub(crate) fn warn_empty_attribute(&mut self, span: Span) {
        let attr_path = self.attr_path.clone();
        let valid_without_list = self.template.word;
        self.emit_lint(
            AttributeLintKind::EmptyAttribute { first_span: span, attr_path, valid_without_list },
            span,
        );
    }

    pub(crate) fn suggestions(&self) -> Vec<String> {
        let style = match self.parsed_description {
            // If the outer and inner spans are equal, we are parsing an embedded attribute
            ParsedDescription::Attribute if self.attr_span == self.inner_span => {
                AttrSuggestionStyle::EmbeddedAttribute
            }
            ParsedDescription::Attribute => AttrSuggestionStyle::Attribute(self.attr_style),
            ParsedDescription::Macro => AttrSuggestionStyle::Macro,
        };

        self.template.suggestions(style, &self.attr_path)
    }
}

impl<'f, 'sess, S: Stage> Deref for AcceptContext<'f, 'sess, S> {
    type Target = SharedContext<'f, 'sess, S>;

    fn deref(&self) -> &Self::Target {
        &self.shared
    }
}

impl<'f, 'sess, S: Stage> DerefMut for AcceptContext<'f, 'sess, S> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.shared
    }
}

/// Context given to every attribute parser during finalization.
///
/// Gives [`AttributeParser`](crate::attributes::AttributeParser)s enough information to create
/// errors, for example.
pub struct SharedContext<'p, 'sess, S: Stage> {
    /// The parse context, gives access to the session and the
    /// diagnostics context.
    pub(crate) cx: &'p mut AttributeParser<'sess, S>,
    /// The span of the syntactical component this attribute was applied to
    pub(crate) target_span: Span,
    /// The id ([`NodeId`] if `S` is `Early`, [`HirId`] if `S` is `Late`) of the syntactical component this attribute was applied to
    pub(crate) target_id: S::Id,

    pub(crate) emit_lint: &'p mut dyn FnMut(AttributeLint<S::Id>),
}

/// Context given to every attribute parser during finalization.
///
/// Gives [`AttributeParser`](crate::attributes::AttributeParser)s enough information to create
/// errors, for example.
pub(crate) struct FinalizeContext<'p, 'sess, S: Stage> {
    pub(crate) shared: SharedContext<'p, 'sess, S>,

    /// A list of all attribute on this syntax node.
    ///
    /// Useful for compatibility checks with other attributes in [`finalize`](crate::attributes::AttributeParser::finalize)
    ///
    /// Usually, you should use normal attribute parsing logic instead,
    /// especially when making a *denylist* of other attributes.
    pub(crate) all_attrs: &'p [PathParser<'p>],
}

impl<'p, 'sess: 'p, S: Stage> Deref for FinalizeContext<'p, 'sess, S> {
    type Target = SharedContext<'p, 'sess, S>;

    fn deref(&self) -> &Self::Target {
        &self.shared
    }
}

impl<'p, 'sess: 'p, S: Stage> DerefMut for FinalizeContext<'p, 'sess, S> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.shared
    }
}

impl<'p, 'sess: 'p, S: Stage> Deref for SharedContext<'p, 'sess, S> {
    type Target = AttributeParser<'sess, S>;

    fn deref(&self) -> &Self::Target {
        self.cx
    }
}

impl<'p, 'sess: 'p, S: Stage> DerefMut for SharedContext<'p, 'sess, S> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        self.cx
    }
}

#[derive(PartialEq, Clone, Copy, Debug)]
pub enum OmitDoc {
    Lower,
    Skip,
}

#[derive(Copy, Clone, Debug)]
pub enum ShouldEmit {
    /// The operations will emit errors, and lints, and errors are fatal.
    ///
    /// Only relevant when early parsing, in late parsing equivalent to `ErrorsAndLints`.
    /// Late parsing is never fatal, and instead tries to emit as many diagnostics as possible.
    EarlyFatal { also_emit_lints: bool },
    /// The operation will emit errors and lints.
    /// This is usually what you need.
    ErrorsAndLints,
    /// The operation will emit *not* errors and lints.
    /// Use this if you are *sure* that this operation will be called at a different time with `ShouldEmit::ErrorsAndLints`.
    Nothing,
}

impl ShouldEmit {
    pub(crate) fn emit_err(&self, diag: Diag<'_>) -> ErrorGuaranteed {
        match self {
            ShouldEmit::EarlyFatal { .. } if diag.level() == Level::DelayedBug => diag.emit(),
            ShouldEmit::EarlyFatal { .. } => diag.upgrade_to_fatal().emit(),
            ShouldEmit::ErrorsAndLints => diag.emit(),
            ShouldEmit::Nothing => diag.delay_as_bug(),
        }
    }
}
