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

/// Quasi-quotation macro that accepts input like the [`quote!`] macro but uses
/// type inference to figure out a return type for those tokens.
///
/// [`quote!`]: https://docs.rs/quote/1.0/quote/index.html
///
/// The return type can be any syntax tree node that implements the [`Parse`]
/// trait.
///
/// [`Parse`]: crate::parse::Parse
///
/// ```
/// use quote::quote;
/// use syn::{parse_quote, Stmt};
///
/// fn main() {
///     let name = quote!(v);
///     let ty = quote!(u8);
///
///     let stmt: Stmt = parse_quote! {
///         let #name: #ty = Default::default();
///     };
///
///     println!("{:#?}", stmt);
/// }
/// ```
///
/// *This macro is available only if Syn is built with both the `"parsing"` and
/// `"printing"` features.*
///
/// # Example
///
/// The following helper function adds a bound `T: HeapSize` to every type
/// parameter `T` in the input generics.
///
/// ```
/// use syn::{parse_quote, Generics, GenericParam};
///
/// // Add a bound `T: HeapSize` to every type parameter T.
/// fn add_trait_bounds(mut generics: Generics) -> Generics {
///     for param in &mut generics.params {
///         if let GenericParam::Type(type_param) = param {
///             type_param.bounds.push(parse_quote!(HeapSize));
///         }
///     }
///     generics
/// }
/// ```
///
/// # Special cases
///
/// This macro can parse the following additional types as a special case even
/// though they do not implement the `Parse` trait.
///
/// - [`Attribute`] — parses one attribute, allowing either outer like `#[...]`
///   or inner like `#![...]`
/// - [`Vec<Attribute>`] — parses multiple attributes, including mixed kinds in
///   any order
/// - [`Punctuated<T, P>`] — parses zero or more `T` separated by punctuation
///   `P` with optional trailing punctuation
/// - [`Vec<Arm>`] — parses arms separated by optional commas according to the
///   same grammar as the inside of a `match` expression
/// - [`Vec<Stmt>`] — parses the same as `Block::parse_within`
/// - [`Pat`], [`Box<Pat>`] — parses the same as
///   `Pat::parse_multi_with_leading_vert`
/// - [`Field`] — parses a named or unnamed struct field
///
/// [`Vec<Attribute>`]: Attribute
/// [`Vec<Arm>`]: Arm
/// [`Vec<Stmt>`]: Block::parse_within
/// [`Pat`]: Pat::parse_multi_with_leading_vert
/// [`Box<Pat>`]: Pat::parse_multi_with_leading_vert
///
/// # Panics
///
/// Panics if the tokens fail to parse as the expected syntax tree type. The
/// caller is responsible for ensuring that the input tokens are syntactically
/// valid.
#[cfg_attr(docsrs, doc(cfg(all(feature = "parsing", feature = "printing"))))]
#[macro_export]
macro_rules! parse_quote {
    ($($tt:tt)*) => {
        $crate::__private::parse_quote($crate::__private::quote::quote!($($tt)*))
    };
}

/// This macro is [`parse_quote!`] + [`quote_spanned!`][quote::quote_spanned].
///
/// Please refer to each of their documentation.
///
/// # Example
///
/// ```
/// use quote::{quote, quote_spanned};
/// use syn::spanned::Spanned;
/// use syn::{parse_quote_spanned, ReturnType, Signature};
///
/// // Changes `fn()` to `fn() -> Pin<Box<dyn Future<Output = ()>>>`,
/// // and `fn() -> T` to `fn() -> Pin<Box<dyn Future<Output = T>>>`,
/// // without introducing any call_site() spans.
/// fn make_ret_pinned_future(sig: &mut Signature) {
///     let ret = match &sig.output {
///         ReturnType::Default => quote_spanned!(sig.paren_token.span=> ()),
///         ReturnType::Type(_, ret) => quote!(#ret),
///     };
///     sig.output = parse_quote_spanned! {ret.span()=>
///         -> ::std::pin::Pin<::std::boxed::Box<dyn ::std::future::Future<Output = #ret>>>
///     };
/// }
/// ```
#[cfg_attr(docsrs, doc(cfg(all(feature = "parsing", feature = "printing"))))]
#[macro_export]
macro_rules! parse_quote_spanned {
    ($span:expr=> $($tt:tt)*) => {
        $crate::__private::parse_quote($crate::__private::quote::quote_spanned!($span=> $($tt)*))
    };
}

////////////////////////////////////////////////////////////////////////////////
// Can parse any type that implements Parse.

use crate::error::Result;
use crate::parse::{Parse, ParseStream, Parser};
use proc_macro2::TokenStream;

// Not public API.
#[doc(hidden)]
#[track_caller]
pub fn parse<T: ParseQuote>(token_stream: TokenStream) -> T {
    let parser = T::parse;
    match parser.parse2(token_stream) {
        Ok(t) => t,
        Err(err) => panic!("{}", err),
    }
}

#[doc(hidden)]
pub trait ParseQuote: Sized {
    fn parse(input: ParseStream) -> Result<Self>;
}

impl<T: Parse> ParseQuote for T {
    fn parse(input: ParseStream) -> Result<Self> {
        <T as Parse>::parse(input)
    }
}

////////////////////////////////////////////////////////////////////////////////
// Any other types that we want `parse_quote!` to be able to parse.

use crate::punctuated::Punctuated;
#[cfg(any(feature = "full", feature = "derive"))]
use crate::{attr, Attribute, Field, FieldMutability, Ident, Type, Visibility};
#[cfg(feature = "full")]
use crate::{Arm, Block, Pat, Stmt};

#[cfg(any(feature = "full", feature = "derive"))]
impl ParseQuote for Attribute {
    fn parse(input: ParseStream) -> Result<Self> {
        if input.peek(Token![#]) && input.peek2(Token![!]) {
            attr::parsing::single_parse_inner(input)
        } else {
            attr::parsing::single_parse_outer(input)
        }
    }
}

#[cfg(any(feature = "full", feature = "derive"))]
impl ParseQuote for Vec<Attribute> {
    fn parse(input: ParseStream) -> Result<Self> {
        let mut attrs = Vec::new();
        while !input.is_empty() {
            attrs.push(ParseQuote::parse(input)?);
        }
        Ok(attrs)
    }
}

#[cfg(any(feature = "full", feature = "derive"))]
impl ParseQuote for Field {
    fn parse(input: ParseStream) -> Result<Self> {
        let attrs = input.call(Attribute::parse_outer)?;
        let vis: Visibility = input.parse()?;

        let ident: Option<Ident>;
        let colon_token: Option<Token![:]>;
        let is_named = input.peek(Ident) && input.peek2(Token![:]) && !input.peek2(Token![::]);
        if is_named {
            ident = Some(input.parse()?);
            colon_token = Some(input.parse()?);
        } else {
            ident = None;
            colon_token = None;
        }

        let ty: Type = input.parse()?;

        Ok(Field {
            attrs,
            vis,
            mutability: FieldMutability::None,
            ident,
            colon_token,
            ty,
        })
    }
}

#[cfg(feature = "full")]
impl ParseQuote for Pat {
    fn parse(input: ParseStream) -> Result<Self> {
        Pat::parse_multi_with_leading_vert(input)
    }
}

#[cfg(feature = "full")]
impl ParseQuote for Box<Pat> {
    fn parse(input: ParseStream) -> Result<Self> {
        <Pat as ParseQuote>::parse(input).map(Box::new)
    }
}

impl<T: Parse, P: Parse> ParseQuote for Punctuated<T, P> {
    fn parse(input: ParseStream) -> Result<Self> {
        Self::parse_terminated(input)
    }
}

#[cfg(feature = "full")]
impl ParseQuote for Vec<Stmt> {
    fn parse(input: ParseStream) -> Result<Self> {
        Block::parse_within(input)
    }
}

#[cfg(feature = "full")]
impl ParseQuote for Vec<Arm> {
    fn parse(input: ParseStream) -> Result<Self> {
        Arm::parse_multiple(input)
    }
}
