// SPDX-License-Identifier: Apache-2.0 OR MIT

#[cfg(feature = "parsing")]
use crate::error::Result;
use crate::expr::Expr;
use crate::generics::TypeParamBound;
use crate::ident::Ident;
use crate::lifetime::Lifetime;
use crate::punctuated::Punctuated;
use crate::token;
use crate::ty::{ReturnType, Type};

ast_struct! {
    /// A path at which a named item is exported (e.g. `std::collections::HashMap`).
    #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
    pub struct Path {
        pub leading_colon: Option<Token![::]>,
        pub segments: Punctuated<PathSegment, Token![::]>,
    }
}

impl<T> From<T> for Path
where
    T: Into<PathSegment>,
{
    fn from(segment: T) -> Self {
        let mut path = Path {
            leading_colon: None,
            segments: Punctuated::new(),
        };
        path.segments.push_value(segment.into());
        path
    }
}

impl Path {
    /// Determines whether this is a path of length 1 equal to the given
    /// ident.
    ///
    /// For them to compare equal, it must be the case that:
    ///
    /// - the path has no leading colon,
    /// - the number of path segments is 1,
    /// - the first path segment has no angle bracketed or parenthesized
    ///   path arguments, and
    /// - the ident of the first path segment is equal to the given one.
    ///
    /// # Example
    ///
    /// ```
    /// use proc_macro2::TokenStream;
    /// use syn::{Attribute, Error, Meta, Result};
    ///
    /// fn get_serde_meta_item(attr: &Attribute) -> Result<Option<&TokenStream>> {
    ///     if attr.path().is_ident("serde") {
    ///         match &attr.meta {
    ///             Meta::List(meta) => Ok(Some(&meta.tokens)),
    ///             bad => Err(Error::new_spanned(bad, "unrecognized attribute")),
    ///         }
    ///     } else {
    ///         Ok(None)
    ///     }
    /// }
    /// ```
    pub fn is_ident<I>(&self, ident: &I) -> bool
    where
        I: ?Sized,
        Ident: PartialEq<I>,
    {
        match self.get_ident() {
            Some(id) => id == ident,
            None => false,
        }
    }

    /// If this path consists of a single ident, returns the ident.
    ///
    /// A path is considered an ident if:
    ///
    /// - the path has no leading colon,
    /// - the number of path segments is 1, and
    /// - the first path segment has no angle bracketed or parenthesized
    ///   path arguments.
    pub fn get_ident(&self) -> Option<&Ident> {
        if self.leading_colon.is_none()
            && self.segments.len() == 1
            && self.segments[0].arguments.is_none()
        {
            Some(&self.segments[0].ident)
        } else {
            None
        }
    }

    /// An error if this path is not a single ident, as defined in `get_ident`.
    #[cfg(feature = "parsing")]
    #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
    pub fn require_ident(&self) -> Result<&Ident> {
        self.get_ident().ok_or_else(|| {
            crate::error::new2(
                self.segments.first().unwrap().ident.span(),
                self.segments.last().unwrap().ident.span(),
                "expected this path to be an identifier",
            )
        })
    }
}

ast_struct! {
    /// A segment of a path together with any path arguments on that segment.
    #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
    pub struct PathSegment {
        pub ident: Ident,
        pub arguments: PathArguments,
    }
}

impl<T> From<T> for PathSegment
where
    T: Into<Ident>,
{
    fn from(ident: T) -> Self {
        PathSegment {
            ident: ident.into(),
            arguments: PathArguments::None,
        }
    }
}

ast_enum! {
    /// Angle bracketed or parenthesized arguments of a path segment.
    ///
    /// ## Angle bracketed
    ///
    /// The `<'a, T>` in `std::slice::iter<'a, T>`.
    ///
    /// ## Parenthesized
    ///
    /// The `(A, B) -> C` in `Fn(A, B) -> C`.
    #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
    pub enum PathArguments {
        None,
        /// The `<'a, T>` in `std::slice::iter<'a, T>`.
        AngleBracketed(AngleBracketedGenericArguments),
        /// The `(A, B) -> C` in `Fn(A, B) -> C`.
        Parenthesized(ParenthesizedGenericArguments),
    }
}

impl Default for PathArguments {
    fn default() -> Self {
        PathArguments::None
    }
}

impl PathArguments {
    pub fn is_empty(&self) -> bool {
        match self {
            PathArguments::None => true,
            PathArguments::AngleBracketed(bracketed) => bracketed.args.is_empty(),
            PathArguments::Parenthesized(_) => false,
        }
    }

    pub fn is_none(&self) -> bool {
        match self {
            PathArguments::None => true,
            PathArguments::AngleBracketed(_) | PathArguments::Parenthesized(_) => false,
        }
    }
}

ast_enum! {
    /// An individual generic argument, like `'a`, `T`, or `Item = T`.
    #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
    #[non_exhaustive]
    pub enum GenericArgument {
        /// A lifetime argument.
        Lifetime(Lifetime),
        /// A type argument.
        Type(Type),
        /// A const expression. Must be inside of a block.
        ///
        /// NOTE: Identity expressions are represented as Type arguments, as
        /// they are indistinguishable syntactically.
        Const(Expr),
        /// A binding (equality constraint) on an associated type: the `Item =
        /// u8` in `Iterator<Item = u8>`.
        AssocType(AssocType),
        /// An equality constraint on an associated constant: the `PANIC =
        /// false` in `Trait<PANIC = false>`.
        AssocConst(AssocConst),
        /// An associated type bound: `Iterator<Item: Display>`.
        Constraint(Constraint),
    }
}

ast_struct! {
    /// Angle bracketed arguments of a path segment: the `<K, V>` in `HashMap<K,
    /// V>`.
    #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
    pub struct AngleBracketedGenericArguments {
        pub colon2_token: Option<Token![::]>,
        pub lt_token: Token![<],
        pub args: Punctuated<GenericArgument, Token![,]>,
        pub gt_token: Token![>],
    }
}

ast_struct! {
    /// A binding (equality constraint) on an associated type: the `Item = u8`
    /// in `Iterator<Item = u8>`.
    #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
    pub struct AssocType {
        pub ident: Ident,
        pub generics: Option<AngleBracketedGenericArguments>,
        pub eq_token: Token![=],
        pub ty: Type,
    }
}

ast_struct! {
    /// An equality constraint on an associated constant: the `PANIC = false` in
    /// `Trait<PANIC = false>`.
    #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
    pub struct AssocConst {
        pub ident: Ident,
        pub generics: Option<AngleBracketedGenericArguments>,
        pub eq_token: Token![=],
        pub value: Expr,
    }
}

ast_struct! {
    /// An associated type bound: `Iterator<Item: Display>`.
    #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
    pub struct Constraint {
        pub ident: Ident,
        pub generics: Option<AngleBracketedGenericArguments>,
        pub colon_token: Token![:],
        pub bounds: Punctuated<TypeParamBound, Token![+]>,
    }
}

ast_struct! {
    /// Arguments of a function path segment: the `(A, B) -> C` in `Fn(A,B) ->
    /// C`.
    #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
    pub struct ParenthesizedGenericArguments {
        pub paren_token: token::Paren,
        /// `(A, B)`
        pub inputs: Punctuated<Type, Token![,]>,
        /// `C`
        pub output: ReturnType,
    }
}

ast_struct! {
    /// The explicit Self type in a qualified path: the `T` in `<T as
    /// Display>::fmt`.
    ///
    /// The actual path, including the trait and the associated item, is stored
    /// separately. The `position` field represents the index of the associated
    /// item qualified with this Self type.
    ///
    /// ```text
    /// <Vec<T> as a::b::Trait>::AssociatedItem
    ///  ^~~~~~    ~~~~~~~~~~~~~~^
    ///  ty        position = 3
    ///
    /// <Vec<T>>::AssociatedItem
    ///  ^~~~~~   ^
    ///  ty       position = 0
    /// ```
    #[cfg_attr(docsrs, doc(cfg(any(feature = "full", feature = "derive"))))]
    pub struct QSelf {
        pub lt_token: Token![<],
        pub ty: Box<Type>,
        pub position: usize,
        pub as_token: Option<Token![as]>,
        pub gt_token: Token![>],
    }
}

#[cfg(feature = "parsing")]
pub(crate) mod parsing {
    use crate::error::Result;
    #[cfg(feature = "full")]
    use crate::expr::ExprBlock;
    use crate::expr::{Expr, ExprPath};
    use crate::ext::IdentExt as _;
    #[cfg(feature = "full")]
    use crate::generics::TypeParamBound;
    use crate::ident::Ident;
    use crate::lifetime::Lifetime;
    use crate::lit::Lit;
    use crate::parse::{Parse, ParseStream};
    #[cfg(feature = "full")]
    use crate::path::Constraint;
    use crate::path::{
        AngleBracketedGenericArguments, AssocConst, AssocType, GenericArgument,
        ParenthesizedGenericArguments, Path, PathArguments, PathSegment, QSelf,
    };
    use crate::punctuated::Punctuated;
    use crate::token;
    use crate::ty::{ReturnType, Type};
    #[cfg(not(feature = "full"))]
    use crate::verbatim;

    #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
    impl Parse for Path {
        fn parse(input: ParseStream) -> Result<Self> {
            Self::parse_helper(input, false)
        }
    }

    #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
    impl Parse for GenericArgument {
        fn parse(input: ParseStream) -> Result<Self> {
            if input.peek(Lifetime) && !input.peek2(Token![+]) {
                return Ok(GenericArgument::Lifetime(input.parse()?));
            }

            if input.peek(Lit) || input.peek(token::Brace) {
                return const_argument(input).map(GenericArgument::Const);
            }

            let mut argument: Type = input.parse()?;

            match argument {
                Type::Path(mut ty)
                    if ty.qself.is_none()
                        && ty.path.leading_colon.is_none()
                        && ty.path.segments.len() == 1
                        && match &ty.path.segments[0].arguments {
                            PathArguments::None | PathArguments::AngleBracketed(_) => true,
                            PathArguments::Parenthesized(_) => false,
                        } =>
                {
                    if let Some(eq_token) = input.parse::<Option<Token![=]>>()? {
                        let segment = ty.path.segments.pop().unwrap().into_value();
                        let ident = segment.ident;
                        let generics = match segment.arguments {
                            PathArguments::None => None,
                            PathArguments::AngleBracketed(arguments) => Some(arguments),
                            PathArguments::Parenthesized(_) => unreachable!(),
                        };
                        return if input.peek(Lit) || input.peek(token::Brace) {
                            Ok(GenericArgument::AssocConst(AssocConst {
                                ident,
                                generics,
                                eq_token,
                                value: const_argument(input)?,
                            }))
                        } else {
                            Ok(GenericArgument::AssocType(AssocType {
                                ident,
                                generics,
                                eq_token,
                                ty: input.parse()?,
                            }))
                        };
                    }

                    #[cfg(feature = "full")]
                    if let Some(colon_token) = input.parse::<Option<Token![:]>>()? {
                        let segment = ty.path.segments.pop().unwrap().into_value();
                        return Ok(GenericArgument::Constraint(Constraint {
                            ident: segment.ident,
                            generics: match segment.arguments {
                                PathArguments::None => None,
                                PathArguments::AngleBracketed(arguments) => Some(arguments),
                                PathArguments::Parenthesized(_) => unreachable!(),
                            },
                            colon_token,
                            bounds: {
                                let mut bounds = Punctuated::new();
                                loop {
                                    if input.peek(Token![,]) || input.peek(Token![>]) {
                                        break;
                                    }
                                    bounds.push_value({
                                        let allow_precise_capture = false;
                                        let allow_const = true;
                                        TypeParamBound::parse_single(
                                            input,
                                            allow_precise_capture,
                                            allow_const,
                                        )?
                                    });
                                    if !input.peek(Token![+]) {
                                        break;
                                    }
                                    let punct: Token![+] = input.parse()?;
                                    bounds.push_punct(punct);
                                }
                                bounds
                            },
                        }));
                    }

                    argument = Type::Path(ty);
                }
                _ => {}
            }

            Ok(GenericArgument::Type(argument))
        }
    }

    pub(crate) fn const_argument(input: ParseStream) -> Result<Expr> {
        let lookahead = input.lookahead1();

        if input.peek(Lit) {
            let lit = input.parse()?;
            return Ok(Expr::Lit(lit));
        }

        if input.peek(Ident) {
            let ident: Ident = input.parse()?;
            return Ok(Expr::Path(ExprPath {
                attrs: Vec::new(),
                qself: None,
                path: Path::from(ident),
            }));
        }

        if input.peek(token::Brace) {
            #[cfg(feature = "full")]
            {
                let block: ExprBlock = input.parse()?;
                return Ok(Expr::Block(block));
            }

            #[cfg(not(feature = "full"))]
            {
                let begin = input.fork();
                let content;
                braced!(content in input);
                content.parse::<Expr>()?;
                let verbatim = verbatim::between(&begin, input);
                return Ok(Expr::Verbatim(verbatim));
            }
        }

        Err(lookahead.error())
    }

    impl AngleBracketedGenericArguments {
        /// Parse `::<…>` with mandatory leading `::`.
        ///
        /// The ordinary [`Parse`] impl for `AngleBracketedGenericArguments`
        /// parses optional leading `::`.
        #[cfg(feature = "full")]
        #[cfg_attr(docsrs, doc(cfg(all(feature = "parsing", feature = "full"))))]
        pub fn parse_turbofish(input: ParseStream) -> Result<Self> {
            let colon2_token: Token![::] = input.parse()?;
            Self::do_parse(Some(colon2_token), input)
        }

        pub(crate) fn do_parse(
            colon2_token: Option<Token![::]>,
            input: ParseStream,
        ) -> Result<Self> {
            Ok(AngleBracketedGenericArguments {
                colon2_token,
                lt_token: input.parse()?,
                args: {
                    let mut args = Punctuated::new();
                    loop {
                        if input.peek(Token![>]) {
                            break;
                        }
                        let value: GenericArgument = input.parse()?;
                        args.push_value(value);
                        if input.peek(Token![>]) {
                            break;
                        }
                        let punct: Token![,] = input.parse()?;
                        args.push_punct(punct);
                    }
                    args
                },
                gt_token: input.parse()?,
            })
        }
    }

    #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
    impl Parse for AngleBracketedGenericArguments {
        fn parse(input: ParseStream) -> Result<Self> {
            let colon2_token: Option<Token![::]> = input.parse()?;
            Self::do_parse(colon2_token, input)
        }
    }

    #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
    impl Parse for ParenthesizedGenericArguments {
        fn parse(input: ParseStream) -> Result<Self> {
            let content;
            Ok(ParenthesizedGenericArguments {
                paren_token: parenthesized!(content in input),
                inputs: content.parse_terminated(Type::parse, Token![,])?,
                output: input.call(ReturnType::without_plus)?,
            })
        }
    }

    #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
    impl Parse for PathSegment {
        fn parse(input: ParseStream) -> Result<Self> {
            Self::parse_helper(input, false)
        }
    }

    impl PathSegment {
        fn parse_helper(input: ParseStream, expr_style: bool) -> Result<Self> {
            if input.peek(Token![super])
                || input.peek(Token![self])
                || input.peek(Token![crate])
                || cfg!(feature = "full") && input.peek(Token![try])
            {
                let ident = input.call(Ident::parse_any)?;
                return Ok(PathSegment::from(ident));
            }

            let ident = if input.peek(Token![Self]) {
                input.call(Ident::parse_any)?
            } else {
                input.parse()?
            };

            if !expr_style
                && input.peek(Token![<])
                && !input.peek(Token![<=])
                && !input.peek(Token![<<=])
                || input.peek(Token![::]) && input.peek3(Token![<])
            {
                Ok(PathSegment {
                    ident,
                    arguments: PathArguments::AngleBracketed(input.parse()?),
                })
            } else {
                Ok(PathSegment::from(ident))
            }
        }
    }

    impl Path {
        /// Parse a `Path` containing no path arguments on any of its segments.
        ///
        /// # Example
        ///
        /// ```
        /// use syn::{Path, Result, Token};
        /// use syn::parse::{Parse, ParseStream};
        ///
        /// // A simplified single `use` statement like:
        /// //
        /// //     use std::collections::HashMap;
        /// //
        /// // Note that generic parameters are not allowed in a `use` statement
        /// // so the following must not be accepted.
        /// //
        /// //     use a::<b>::c;
        /// struct SingleUse {
        ///     use_token: Token![use],
        ///     path: Path,
        /// }
        ///
        /// impl Parse for SingleUse {
        ///     fn parse(input: ParseStream) -> Result<Self> {
        ///         Ok(SingleUse {
        ///             use_token: input.parse()?,
        ///             path: input.call(Path::parse_mod_style)?,
        ///         })
        ///     }
        /// }
        /// ```
        #[cfg_attr(docsrs, doc(cfg(feature = "parsing")))]
        pub fn parse_mod_style(input: ParseStream) -> Result<Self> {
            Ok(Path {
                leading_colon: input.parse()?,
                segments: {
                    let mut segments = Punctuated::new();
                    loop {
                        if !input.peek(Ident)
                            && !input.peek(Token![super])
                            && !input.peek(Token![self])
                            && !input.peek(Token![Self])
                            && !input.peek(Token![crate])
                        {
                            break;
                        }
                        let ident = Ident::parse_any(input)?;
                        segments.push_value(PathSegment::from(ident));
                        if !input.peek(Token![::]) {
                            break;
                        }
                        let punct = input.parse()?;
                        segments.push_punct(punct);
                    }
                    if segments.is_empty() {
                        return Err(input.parse::<Ident>().unwrap_err());
                    } else if segments.trailing_punct() {
                        return Err(input.error("expected path segment after `::`"));
                    }
                    segments
                },
            })
        }

        pub(crate) fn parse_helper(input: ParseStream, expr_style: bool) -> Result<Self> {
            let mut path = Path {
                leading_colon: input.parse()?,
                segments: {
                    let mut segments = Punctuated::new();
                    let value = PathSegment::parse_helper(input, expr_style)?;
                    segments.push_value(value);
                    segments
                },
            };
            Path::parse_rest(input, &mut path, expr_style)?;
            Ok(path)
        }

        pub(crate) fn parse_rest(
            input: ParseStream,
            path: &mut Self,
            expr_style: bool,
        ) -> Result<()> {
            while input.peek(Token![::]) && !input.peek3(token::Paren) {
                let punct: Token![::] = input.parse()?;
                path.segments.push_punct(punct);
                let value = PathSegment::parse_helper(input, expr_style)?;
                path.segments.push_value(value);
            }
            Ok(())
        }

        pub(crate) fn is_mod_style(&self) -> bool {
            self.segments
                .iter()
                .all(|segment| segment.arguments.is_none())
        }
    }

    pub(crate) fn qpath(input: ParseStream, expr_style: bool) -> Result<(Option<QSelf>, Path)> {
        if input.peek(Token![<]) {
            let lt_token: Token![<] = input.parse()?;
            let this: Type = input.parse()?;
            let path = if input.peek(Token![as]) {
                let as_token: Token![as] = input.parse()?;
                let path: Path = input.parse()?;
                Some((as_token, path))
            } else {
                None
            };
            let gt_token: Token![>] = input.parse()?;
            let colon2_token: Token![::] = input.parse()?;
            let mut rest = Punctuated::new();
            loop {
                let path = PathSegment::parse_helper(input, expr_style)?;
                rest.push_value(path);
                if !input.peek(Token![::]) {
                    break;
                }
                let punct: Token![::] = input.parse()?;
                rest.push_punct(punct);
            }
            let (position, as_token, path) = match path {
                Some((as_token, mut path)) => {
                    let pos = path.segments.len();
                    path.segments.push_punct(colon2_token);
                    path.segments.extend(rest.into_pairs());
                    (pos, Some(as_token), path)
                }
                None => {
                    let path = Path {
                        leading_colon: Some(colon2_token),
                        segments: rest,
                    };
                    (0, None, path)
                }
            };
            let qself = QSelf {
                lt_token,
                ty: Box::new(this),
                position,
                as_token,
                gt_token,
            };
            Ok((Some(qself), path))
        } else {
            let path = Path::parse_helper(input, expr_style)?;
            Ok((None, path))
        }
    }
}

#[cfg(feature = "printing")]
pub(crate) mod printing {
    use crate::generics;
    use crate::path::{
        AngleBracketedGenericArguments, AssocConst, AssocType, Constraint, GenericArgument,
        ParenthesizedGenericArguments, Path, PathArguments, PathSegment, QSelf,
    };
    use crate::print::TokensOrDefault;
    #[cfg(feature = "parsing")]
    use crate::spanned::Spanned;
    #[cfg(feature = "parsing")]
    use proc_macro2::Span;
    use proc_macro2::TokenStream;
    use quote::ToTokens;
    use std::cmp;

    pub(crate) enum PathStyle {
        Expr,
        Mod,
        AsWritten,
    }

    impl Copy for PathStyle {}

    impl Clone for PathStyle {
        fn clone(&self) -> Self {
            *self
        }
    }

    #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
    impl ToTokens for Path {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            print_path(tokens, self, PathStyle::AsWritten);
        }
    }

    pub(crate) fn print_path(tokens: &mut TokenStream, path: &Path, style: PathStyle) {
        path.leading_colon.to_tokens(tokens);
        for segment in path.segments.pairs() {
            print_path_segment(tokens, segment.value(), style);
            segment.punct().to_tokens(tokens);
        }
    }

    #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
    impl ToTokens for PathSegment {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            print_path_segment(tokens, self, PathStyle::AsWritten);
        }
    }

    fn print_path_segment(tokens: &mut TokenStream, segment: &PathSegment, style: PathStyle) {
        segment.ident.to_tokens(tokens);
        print_path_arguments(tokens, &segment.arguments, style);
    }

    #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
    impl ToTokens for PathArguments {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            print_path_arguments(tokens, self, PathStyle::AsWritten);
        }
    }

    fn print_path_arguments(tokens: &mut TokenStream, arguments: &PathArguments, style: PathStyle) {
        match arguments {
            PathArguments::None => {}
            PathArguments::AngleBracketed(arguments) => {
                print_angle_bracketed_generic_arguments(tokens, arguments, style);
            }
            PathArguments::Parenthesized(arguments) => {
                print_parenthesized_generic_arguments(tokens, arguments, style);
            }
        }
    }

    #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
    impl ToTokens for GenericArgument {
        #[allow(clippy::match_same_arms)]
        fn to_tokens(&self, tokens: &mut TokenStream) {
            match self {
                GenericArgument::Lifetime(lt) => lt.to_tokens(tokens),
                GenericArgument::Type(ty) => ty.to_tokens(tokens),
                GenericArgument::Const(expr) => {
                    generics::printing::print_const_argument(expr, tokens);
                }
                GenericArgument::AssocType(assoc) => assoc.to_tokens(tokens),
                GenericArgument::AssocConst(assoc) => assoc.to_tokens(tokens),
                GenericArgument::Constraint(constraint) => constraint.to_tokens(tokens),
            }
        }
    }

    #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
    impl ToTokens for AngleBracketedGenericArguments {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            print_angle_bracketed_generic_arguments(tokens, self, PathStyle::AsWritten);
        }
    }

    pub(crate) fn print_angle_bracketed_generic_arguments(
        tokens: &mut TokenStream,
        arguments: &AngleBracketedGenericArguments,
        style: PathStyle,
    ) {
        if let PathStyle::Mod = style {
            return;
        }

        conditionally_print_turbofish(tokens, &arguments.colon2_token, style);
        arguments.lt_token.to_tokens(tokens);

        // Print lifetimes before types/consts/bindings, regardless of their
        // order in args.
        let mut trailing_or_empty = true;
        for param in arguments.args.pairs() {
            match param.value() {
                GenericArgument::Lifetime(_) => {
                    param.to_tokens(tokens);
                    trailing_or_empty = param.punct().is_some();
                }
                GenericArgument::Type(_)
                | GenericArgument::Const(_)
                | GenericArgument::AssocType(_)
                | GenericArgument::AssocConst(_)
                | GenericArgument::Constraint(_) => {}
            }
        }
        for param in arguments.args.pairs() {
            match param.value() {
                GenericArgument::Type(_)
                | GenericArgument::Const(_)
                | GenericArgument::AssocType(_)
                | GenericArgument::AssocConst(_)
                | GenericArgument::Constraint(_) => {
                    if !trailing_or_empty {
                        <Token![,]>::default().to_tokens(tokens);
                    }
                    param.to_tokens(tokens);
                    trailing_or_empty = param.punct().is_some();
                }
                GenericArgument::Lifetime(_) => {}
            }
        }

        arguments.gt_token.to_tokens(tokens);
    }

    #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
    impl ToTokens for AssocType {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            self.ident.to_tokens(tokens);
            self.generics.to_tokens(tokens);
            self.eq_token.to_tokens(tokens);
            self.ty.to_tokens(tokens);
        }
    }

    #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
    impl ToTokens for AssocConst {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            self.ident.to_tokens(tokens);
            self.generics.to_tokens(tokens);
            self.eq_token.to_tokens(tokens);
            generics::printing::print_const_argument(&self.value, tokens);
        }
    }

    #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
    impl ToTokens for Constraint {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            self.ident.to_tokens(tokens);
            self.generics.to_tokens(tokens);
            self.colon_token.to_tokens(tokens);
            self.bounds.to_tokens(tokens);
        }
    }

    #[cfg_attr(docsrs, doc(cfg(feature = "printing")))]
    impl ToTokens for ParenthesizedGenericArguments {
        fn to_tokens(&self, tokens: &mut TokenStream) {
            print_parenthesized_generic_arguments(tokens, self, PathStyle::AsWritten);
        }
    }

    fn print_parenthesized_generic_arguments(
        tokens: &mut TokenStream,
        arguments: &ParenthesizedGenericArguments,
        style: PathStyle,
    ) {
        if let PathStyle::Mod = style {
            return;
        }

        conditionally_print_turbofish(tokens, &None, style);
        arguments.paren_token.surround(tokens, |tokens| {
            arguments.inputs.to_tokens(tokens);
        });
        arguments.output.to_tokens(tokens);
    }

    pub(crate) fn print_qpath(
        tokens: &mut TokenStream,
        qself: &Option<QSelf>,
        path: &Path,
        style: PathStyle,
    ) {
        let qself = match qself {
            Some(qself) => qself,
            None => {
                print_path(tokens, path, style);
                return;
            }
        };
        qself.lt_token.to_tokens(tokens);
        qself.ty.to_tokens(tokens);

        let pos = cmp::min(qself.position, path.segments.len());
        let mut segments = path.segments.pairs();
        if pos > 0 {
            TokensOrDefault(&qself.as_token).to_tokens(tokens);
            path.leading_colon.to_tokens(tokens);
            for (i, segment) in segments.by_ref().take(pos).enumerate() {
                print_path_segment(tokens, segment.value(), PathStyle::AsWritten);
                if i + 1 == pos {
                    qself.gt_token.to_tokens(tokens);
                }
                segment.punct().to_tokens(tokens);
            }
        } else {
            qself.gt_token.to_tokens(tokens);
            path.leading_colon.to_tokens(tokens);
        }
        for segment in segments {
            print_path_segment(tokens, segment.value(), style);
            segment.punct().to_tokens(tokens);
        }
    }

    fn conditionally_print_turbofish(
        tokens: &mut TokenStream,
        colon2_token: &Option<Token![::]>,
        style: PathStyle,
    ) {
        match style {
            PathStyle::Expr => TokensOrDefault(colon2_token).to_tokens(tokens),
            PathStyle::Mod => unreachable!(),
            PathStyle::AsWritten => colon2_token.to_tokens(tokens),
        }
    }

    #[cfg(feature = "parsing")]
    #[cfg_attr(docsrs, doc(cfg(all(feature = "parsing", feature = "printing"))))]
    impl Spanned for QSelf {
        fn span(&self) -> Span {
            struct QSelfDelimiters<'a>(&'a QSelf);

            impl<'a> ToTokens for QSelfDelimiters<'a> {
                fn to_tokens(&self, tokens: &mut TokenStream) {
                    self.0.lt_token.to_tokens(tokens);
                    self.0.gt_token.to_tokens(tokens);
                }
            }

            QSelfDelimiters(self).span()
        }
    }
}
