//! Parsing interface for parsing a token stream into a syntax tree node.
//!
//! Parsing in Syn is built on parser functions that take in a [`ParseStream`]
//! and produce a [`Result<T>`] where `T` is some syntax tree node. Underlying
//! these parser functions is a lower level mechanism built around the
//! [`Cursor`] type. `Cursor` is a cheaply copyable cursor over a range of
//! tokens in a token stream.
//!
//! [`Result<T>`]: Result
//! [`Cursor`]: crate::buffer::Cursor
//!
//! # Example
//!
//! Here is a snippet of parsing code to get a feel for the style of the
//! library. We define data structures for a subset of Rust syntax including
//! enums (not shown) and structs, then provide implementations of the [`Parse`]
//! trait to parse these syntax tree data structures from a token stream.
//!
//! Once `Parse` impls have been defined, they can be called conveniently from a
//! procedural macro through [`parse_macro_input!`] as shown at the bottom of
//! the snippet. If the caller provides syntactically invalid input to the
//! procedural macro, they will receive a helpful compiler error message
//! pointing out the exact token that triggered the failure to parse.
//!
//! [`parse_macro_input!`]: crate::parse_macro_input!
//!
//! ```
//! # extern crate proc_macro;
//! #
//! use proc_macro::TokenStream;
//! use syn::{braced, parse_macro_input, token, Field, Ident, Result, Token};
//! use syn::parse::{Parse, ParseStream};
//! use syn::punctuated::Punctuated;
//!
//! enum Item {
//!     Struct(ItemStruct),
//!     Enum(ItemEnum),
//! }
//!
//! struct ItemStruct {
//!     struct_token: Token![struct],
//!     ident: Ident,
//!     brace_token: token::Brace,
//!     fields: Punctuated<Field, Token![,]>,
//! }
//! #
//! # enum ItemEnum {}
//!
//! impl Parse for Item {
//!     fn parse(input: ParseStream) -> Result<Self> {
//!         let lookahead = input.lookahead1();
//!         if lookahead.peek(Token![struct]) {
//!             input.parse().map(Item::Struct)
//!         } else if lookahead.peek(Token![enum]) {
//!             input.parse().map(Item::Enum)
//!         } else {
//!             Err(lookahead.error())
//!         }
//!     }
//! }
//!
//! impl Parse for ItemStruct {
//!     fn parse(input: ParseStream) -> Result<Self> {
//!         let content;
//!         Ok(ItemStruct {
//!             struct_token: input.parse()?,
//!             ident: input.parse()?,
//!             brace_token: braced!(content in input),
//!             fields: content.parse_terminated(Field::parse_named, Token![,])?,
//!         })
//!     }
//! }
//! #
//! # impl Parse for ItemEnum {
//! #     fn parse(input: ParseStream) -> Result<Self> {
//! #         unimplemented!()
//! #     }
//! # }
//!
//! # const IGNORE: &str = stringify! {
//! #[proc_macro]
//! # };
//! pub fn my_macro(tokens: TokenStream) -> TokenStream {
//!     let input = parse_macro_input!(tokens as Item);
//!
//!     /* ... */
//! #   TokenStream::new()
//! }
//! ```
//!
//! # The `syn::parse*` functions
//!
//! The [`syn::parse`], [`syn::parse2`], and [`syn::parse_str`] functions serve
//! as an entry point for parsing syntax tree nodes that can be parsed in an
//! obvious default way. These functions can return any syntax tree node that
//! implements the [`Parse`] trait, which includes most types in Syn.
//!
//! [`syn::parse`]: crate::parse()
//! [`syn::parse2`]: crate::parse2()
//! [`syn::parse_str`]: crate::parse_str()
//!
//! ```
//! use syn::Type;
//!
//! # fn run_parser() -> syn::Result<()> {
//! let t: Type = syn::parse_str("std::collections::HashMap<String, Value>")?;
//! #     Ok(())
//! # }
//! #
//! # run_parser().unwrap();
//! ```
//!
//! The [`parse_quote!`] macro also uses this approach.
//!
//! [`parse_quote!`]: crate::parse_quote!
//!
//! # The `Parser` trait
//!
//! Some types can be parsed in several ways depending on context. For example
//! an [`Attribute`] can be either "outer" like `#[...]` or "inner" like
//! `#![...]` and parsing the wrong one would be a bug. Similarly [`Punctuated`]
//! may or may not allow trailing punctuation, and parsing it the wrong way
//! would either reject valid input or accept invalid input.
//!
//! [`Attribute`]: crate::Attribute
//! [`Punctuated`]: crate::punctuated
//!
//! The `Parse` trait is not implemented in these cases because there is no good
//! behavior to consider the default.
//!
//! ```compile_fail
//! # extern crate proc_macro;
//! #
//! # use syn::punctuated::Punctuated;
//! # use syn::{PathSegment, Result, Token};
//! #
//! # fn f(tokens: proc_macro::TokenStream) -> Result<()> {
//! #
//! // Can't parse `Punctuated` without knowing whether trailing punctuation
//! // should be allowed in this context.
//! let path: Punctuated<PathSegment, Token![::]> = syn::parse(tokens)?;
//! #
//! #     Ok(())
//! # }
//! ```
//!
//! In these cases the types provide a choice of parser functions rather than a
//! single `Parse` implementation, and those parser functions can be invoked
//! through the [`Parser`] trait.
//!
//!
//! ```
//! # extern crate proc_macro;
//! #
//! use proc_macro::TokenStream;
//! use syn::parse::Parser;
//! use syn::punctuated::Punctuated;
//! use syn::{Attribute, Expr, PathSegment, Result, Token};
//!
//! fn call_some_parser_methods(input: TokenStream) -> Result<()> {
//!     // Parse a nonempty sequence of path segments separated by `::` punctuation
//!     // with no trailing punctuation.
//!     let tokens = input.clone();
//!     let parser = Punctuated::<PathSegment, Token![::]>::parse_separated_nonempty;
//!     let _path = parser.parse(tokens)?;
//!
//!     // Parse a possibly empty sequence of expressions terminated by commas with
//!     // an optional trailing punctuation.
//!     let tokens = input.clone();
//!     let parser = Punctuated::<Expr, Token![,]>::parse_terminated;
//!     let _args = parser.parse(tokens)?;
//!
//!     // Parse zero or more outer attributes but not inner attributes.
//!     let tokens = input.clone();
//!     let parser = Attribute::parse_outer;
//!     let _attrs = parser.parse(tokens)?;
//!
//!     Ok(())
//! }
//! ```

#[path = "discouraged.rs"]
pub mod discouraged;

use crate::buffer::{Cursor, TokenBuffer};
use crate::error;
use crate::lookahead;
#[cfg(feature = "proc-macro")]
use crate::proc_macro;
use crate::punctuated::Punctuated;
use crate::token::Token;
use proc_macro2::{self, Delimiter, Group, Literal, Punct, Span, TokenStream, TokenTree};
use std::cell::Cell;
use std::fmt::{self, Debug, Display};
#[cfg(feature = "extra-traits")]
use std::hash::{Hash, Hasher};
use std::marker::PhantomData;
use std::mem;
use std::ops::Deref;
use std::rc::Rc;
use std::str::FromStr;

pub use crate::error::{Error, Result};
pub use crate::lookahead::{Lookahead1, Peek};

/// Parsing interface implemented by all types that can be parsed in a default
/// way from a token stream.
///
/// Refer to the [module documentation] for details about implementing and using
/// the `Parse` trait.
///
/// [module documentation]: self
pub trait Parse: Sized {
    fn parse(input: ParseStream) -> Result<Self>;
}

/// Input to a Syn parser function.
///
/// See the methods of this type under the documentation of [`ParseBuffer`]. For
/// an overview of parsing in Syn, refer to the [module documentation].
///
/// [module documentation]: self
pub type ParseStream<'a> = &'a ParseBuffer<'a>;

/// Cursor position within a buffered token stream.
///
/// This type is more commonly used through the type alias [`ParseStream`] which
/// is an alias for `&ParseBuffer`.
///
/// `ParseStream` is the input type for all parser functions in Syn. They have
/// the signature `fn(ParseStream) -> Result<T>`.
///
/// ## Calling a parser function
///
/// There is no public way to construct a `ParseBuffer`. Instead, if you are
/// looking to invoke a parser function that requires `ParseStream` as input,
/// you will need to go through one of the public parsing entry points.
///
/// - The [`parse_macro_input!`] macro if parsing input of a procedural macro;
/// - One of [the `syn::parse*` functions][syn-parse]; or
/// - A method of the [`Parser`] trait.
///
/// [`parse_macro_input!`]: crate::parse_macro_input!
/// [syn-parse]: self#the-synparse-functions
pub struct ParseBuffer<'a> {
    scope: Span,
    // Instead of Cell<Cursor<'a>> so that ParseBuffer<'a> is covariant in 'a.
    // The rest of the code in this module needs to be careful that only a
    // cursor derived from this `cell` is ever assigned to this `cell`.
    //
    // Cell<Cursor<'a>> cannot be covariant in 'a because then we could take a
    // ParseBuffer<'a>, upcast to ParseBuffer<'short> for some lifetime shorter
    // than 'a, and then assign a Cursor<'short> into the Cell.
    //
    // By extension, it would not be safe to expose an API that accepts a
    // Cursor<'a> and trusts that it lives as long as the cursor currently in
    // the cell.
    cell: Cell<Cursor<'static>>,
    marker: PhantomData<Cursor<'a>>,
    unexpected: Cell<Option<Rc<Cell<Unexpected>>>>,
}

impl<'a> Drop for ParseBuffer<'a> {
    fn drop(&mut self) {
        if let Some(unexpected_span) = span_of_unexpected_ignoring_nones(self.cursor()) {
            let (inner, old_span) = inner_unexpected(self);
            if old_span.is_none() {
                inner.set(Unexpected::Some(unexpected_span));
            }
        }
    }
}

impl<'a> Display for ParseBuffer<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        Display::fmt(&self.cursor().token_stream(), f)
    }
}

impl<'a> Debug for ParseBuffer<'a> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        Debug::fmt(&self.cursor().token_stream(), f)
    }
}

/// Cursor state associated with speculative parsing.
///
/// This type is the input of the closure provided to [`ParseStream::step`].
///
/// [`ParseStream::step`]: ParseBuffer::step
///
/// # Example
///
/// ```
/// use proc_macro2::TokenTree;
/// use syn::Result;
/// use syn::parse::ParseStream;
///
/// // This function advances the stream past the next occurrence of `@`. If
/// // no `@` is present in the stream, the stream position is unchanged and
/// // an error is returned.
/// fn skip_past_next_at(input: ParseStream) -> Result<()> {
///     input.step(|cursor| {
///         let mut rest = *cursor;
///         while let Some((tt, next)) = rest.token_tree() {
///             match &tt {
///                 TokenTree::Punct(punct) if punct.as_char() == '@' => {
///                     return Ok(((), next));
///                 }
///                 _ => rest = next,
///             }
///         }
///         Err(cursor.error("no `@` was found after this point"))
///     })
/// }
/// #
/// # fn remainder_after_skipping_past_next_at(
/// #     input: ParseStream,
/// # ) -> Result<proc_macro2::TokenStream> {
/// #     skip_past_next_at(input)?;
/// #     input.parse()
/// # }
/// #
/// # use syn::parse::Parser;
/// # let remainder = remainder_after_skipping_past_next_at
/// #     .parse_str("a @ b c")
/// #     .unwrap();
/// # assert_eq!(remainder.to_string(), "b c");
/// ```
pub struct StepCursor<'c, 'a> {
    scope: Span,
    // This field is covariant in 'c.
    cursor: Cursor<'c>,
    // This field is contravariant in 'c. Together these make StepCursor
    // invariant in 'c. Also covariant in 'a. The user cannot cast 'c to a
    // different lifetime but can upcast into a StepCursor with a shorter
    // lifetime 'a.
    //
    // As long as we only ever construct a StepCursor for which 'c outlives 'a,
    // this means if ever a StepCursor<'c, 'a> exists we are guaranteed that 'c
    // outlives 'a.
    marker: PhantomData<fn(Cursor<'c>) -> Cursor<'a>>,
}

impl<'c, 'a> Deref for StepCursor<'c, 'a> {
    type Target = Cursor<'c>;

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

impl<'c, 'a> Copy for StepCursor<'c, 'a> {}

impl<'c, 'a> Clone for StepCursor<'c, 'a> {
    fn clone(&self) -> Self {
        *self
    }
}

impl<'c, 'a> StepCursor<'c, 'a> {
    /// Triggers an error at the current position of the parse stream.
    ///
    /// The `ParseStream::step` invocation will return this same error without
    /// advancing the stream state.
    pub fn error<T: Display>(self, message: T) -> Error {
        error::new_at(self.scope, self.cursor, message)
    }
}

pub(crate) fn advance_step_cursor<'c, 'a>(proof: StepCursor<'c, 'a>, to: Cursor<'c>) -> Cursor<'a> {
    // Refer to the comments within the StepCursor definition. We use the
    // fact that a StepCursor<'c, 'a> exists as proof that 'c outlives 'a.
    // Cursor is covariant in its lifetime parameter so we can cast a
    // Cursor<'c> to one with the shorter lifetime Cursor<'a>.
    let _ = proof;
    unsafe { mem::transmute::<Cursor<'c>, Cursor<'a>>(to) }
}

pub(crate) fn new_parse_buffer(
    scope: Span,
    cursor: Cursor,
    unexpected: Rc<Cell<Unexpected>>,
) -> ParseBuffer {
    ParseBuffer {
        scope,
        // See comment on `cell` in the struct definition.
        cell: Cell::new(unsafe { mem::transmute::<Cursor, Cursor<'static>>(cursor) }),
        marker: PhantomData,
        unexpected: Cell::new(Some(unexpected)),
    }
}

pub(crate) enum Unexpected {
    None,
    Some(Span),
    Chain(Rc<Cell<Unexpected>>),
}

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

impl Clone for Unexpected {
    fn clone(&self) -> Self {
        match self {
            Unexpected::None => Unexpected::None,
            Unexpected::Some(span) => Unexpected::Some(*span),
            Unexpected::Chain(next) => Unexpected::Chain(next.clone()),
        }
    }
}

// We call this on Cell<Unexpected> and Cell<Option<T>> where temporarily
// swapping in a None is cheap.
fn cell_clone<T: Default + Clone>(cell: &Cell<T>) -> T {
    let prev = cell.take();
    let ret = prev.clone();
    cell.set(prev);
    ret
}

fn inner_unexpected(buffer: &ParseBuffer) -> (Rc<Cell<Unexpected>>, Option<Span>) {
    let mut unexpected = get_unexpected(buffer);
    loop {
        match cell_clone(&unexpected) {
            Unexpected::None => return (unexpected, None),
            Unexpected::Some(span) => return (unexpected, Some(span)),
            Unexpected::Chain(next) => unexpected = next,
        }
    }
}

pub(crate) fn get_unexpected(buffer: &ParseBuffer) -> Rc<Cell<Unexpected>> {
    cell_clone(&buffer.unexpected).unwrap()
}

fn span_of_unexpected_ignoring_nones(mut cursor: Cursor) -> Option<Span> {
    if cursor.eof() {
        return None;
    }
    while let Some((inner, _span, rest)) = cursor.group(Delimiter::None) {
        if let Some(unexpected) = span_of_unexpected_ignoring_nones(inner) {
            return Some(unexpected);
        }
        cursor = rest;
    }
    if cursor.eof() {
        None
    } else {
        Some(cursor.span())
    }
}

impl<'a> ParseBuffer<'a> {
    /// Parses a syntax tree node of type `T`, advancing the position of our
    /// parse stream past it.
    pub fn parse<T: Parse>(&self) -> Result<T> {
        T::parse(self)
    }

    /// Calls the given parser function to parse a syntax tree node of type `T`
    /// from this stream.
    ///
    /// # Example
    ///
    /// The parser below invokes [`Attribute::parse_outer`] to parse a vector of
    /// zero or more outer attributes.
    ///
    /// [`Attribute::parse_outer`]: crate::Attribute::parse_outer
    ///
    /// ```
    /// use syn::{Attribute, Ident, Result, Token};
    /// use syn::parse::{Parse, ParseStream};
    ///
    /// // Parses a unit struct with attributes.
    /// //
    /// //     #[path = "s.tmpl"]
    /// //     struct S;
    /// struct UnitStruct {
    ///     attrs: Vec<Attribute>,
    ///     struct_token: Token![struct],
    ///     name: Ident,
    ///     semi_token: Token![;],
    /// }
    ///
    /// impl Parse for UnitStruct {
    ///     fn parse(input: ParseStream) -> Result<Self> {
    ///         Ok(UnitStruct {
    ///             attrs: input.call(Attribute::parse_outer)?,
    ///             struct_token: input.parse()?,
    ///             name: input.parse()?,
    ///             semi_token: input.parse()?,
    ///         })
    ///     }
    /// }
    /// ```
    pub fn call<T>(&self, function: fn(ParseStream) -> Result<T>) -> Result<T> {
        function(self)
    }

    /// Looks at the next token in the parse stream to determine whether it
    /// matches the requested type of token.
    ///
    /// Does not advance the position of the parse stream.
    ///
    /// # Syntax
    ///
    /// Note that this method does not use turbofish syntax. Pass the peek type
    /// inside of parentheses.
    ///
    /// - `input.peek(Token![struct])`
    /// - `input.peek(Token![==])`
    /// - `input.peek(Ident)`&emsp;*(does not accept keywords)*
    /// - `input.peek(Ident::peek_any)`
    /// - `input.peek(Lifetime)`
    /// - `input.peek(token::Brace)`
    ///
    /// # Example
    ///
    /// In this example we finish parsing the list of supertraits when the next
    /// token in the input is either `where` or an opening curly brace.
    ///
    /// ```
    /// use syn::{braced, token, Generics, Ident, Result, Token, TypeParamBound};
    /// use syn::parse::{Parse, ParseStream};
    /// use syn::punctuated::Punctuated;
    ///
    /// // Parses a trait definition containing no associated items.
    /// //
    /// //     trait Marker<'de, T>: A + B<'de> where Box<T>: Clone {}
    /// struct MarkerTrait {
    ///     trait_token: Token![trait],
    ///     ident: Ident,
    ///     generics: Generics,
    ///     colon_token: Option<Token![:]>,
    ///     supertraits: Punctuated<TypeParamBound, Token![+]>,
    ///     brace_token: token::Brace,
    /// }
    ///
    /// impl Parse for MarkerTrait {
    ///     fn parse(input: ParseStream) -> Result<Self> {
    ///         let trait_token: Token![trait] = input.parse()?;
    ///         let ident: Ident = input.parse()?;
    ///         let mut generics: Generics = input.parse()?;
    ///         let colon_token: Option<Token![:]> = input.parse()?;
    ///
    ///         let mut supertraits = Punctuated::new();
    ///         if colon_token.is_some() {
    ///             loop {
    ///                 supertraits.push_value(input.parse()?);
    ///                 if input.peek(Token![where]) || input.peek(token::Brace) {
    ///                     break;
    ///                 }
    ///                 supertraits.push_punct(input.parse()?);
    ///             }
    ///         }
    ///
    ///         generics.where_clause = input.parse()?;
    ///         let content;
    ///         let empty_brace_token = braced!(content in input);
    ///
    ///         Ok(MarkerTrait {
    ///             trait_token,
    ///             ident,
    ///             generics,
    ///             colon_token,
    ///             supertraits,
    ///             brace_token: empty_brace_token,
    ///         })
    ///     }
    /// }
    /// ```
    pub fn peek<T: Peek>(&self, token: T) -> bool {
        let _ = token;
        T::Token::peek(self.cursor())
    }

    /// Looks at the second-next token in the parse stream.
    ///
    /// This is commonly useful as a way to implement contextual keywords.
    ///
    /// # Example
    ///
    /// This example needs to use `peek2` because the symbol `union` is not a
    /// keyword in Rust. We can't use just `peek` and decide to parse a union if
    /// the very next token is `union`, because someone is free to write a `mod
    /// union` and a macro invocation that looks like `union::some_macro! { ...
    /// }`. In other words `union` is a contextual keyword.
    ///
    /// ```
    /// use syn::{Ident, ItemUnion, Macro, Result, Token};
    /// use syn::parse::{Parse, ParseStream};
    ///
    /// // Parses either a union or a macro invocation.
    /// enum UnionOrMacro {
    ///     // union MaybeUninit<T> { uninit: (), value: T }
    ///     Union(ItemUnion),
    ///     // lazy_static! { ... }
    ///     Macro(Macro),
    /// }
    ///
    /// impl Parse for UnionOrMacro {
    ///     fn parse(input: ParseStream) -> Result<Self> {
    ///         if input.peek(Token![union]) && input.peek2(Ident) {
    ///             input.parse().map(UnionOrMacro::Union)
    ///         } else {
    ///             input.parse().map(UnionOrMacro::Macro)
    ///         }
    ///     }
    /// }
    /// ```
    pub fn peek2<T: Peek>(&self, token: T) -> bool {
        fn peek2(buffer: &ParseBuffer, peek: fn(Cursor) -> bool) -> bool {
            if let Some(group) = buffer.cursor().group(Delimiter::None) {
                if group.0.skip().map_or(false, peek) {
                    return true;
                }
            }
            buffer.cursor().skip().map_or(false, peek)
        }

        let _ = token;
        peek2(self, T::Token::peek)
    }

    /// Looks at the third-next token in the parse stream.
    pub fn peek3<T: Peek>(&self, token: T) -> bool {
        fn peek3(buffer: &ParseBuffer, peek: fn(Cursor) -> bool) -> bool {
            if let Some(group) = buffer.cursor().group(Delimiter::None) {
                if group.0.skip().and_then(Cursor::skip).map_or(false, peek) {
                    return true;
                }
            }
            buffer
                .cursor()
                .skip()
                .and_then(Cursor::skip)
                .map_or(false, peek)
        }

        let _ = token;
        peek3(self, T::Token::peek)
    }

    /// Parses zero or more occurrences of `T` separated by punctuation of type
    /// `P`, with optional trailing punctuation.
    ///
    /// Parsing continues until the end of this parse stream. The entire content
    /// of this parse stream must consist of `T` and `P`.
    ///
    /// # Example
    ///
    /// ```
    /// # use quote::quote;
    /// #
    /// use syn::{parenthesized, token, Ident, Result, Token, Type};
    /// use syn::parse::{Parse, ParseStream};
    /// use syn::punctuated::Punctuated;
    ///
    /// // Parse a simplified tuple struct syntax like:
    /// //
    /// //     struct S(A, B);
    /// struct TupleStruct {
    ///     struct_token: Token![struct],
    ///     ident: Ident,
    ///     paren_token: token::Paren,
    ///     fields: Punctuated<Type, Token![,]>,
    ///     semi_token: Token![;],
    /// }
    ///
    /// impl Parse for TupleStruct {
    ///     fn parse(input: ParseStream) -> Result<Self> {
    ///         let content;
    ///         Ok(TupleStruct {
    ///             struct_token: input.parse()?,
    ///             ident: input.parse()?,
    ///             paren_token: parenthesized!(content in input),
    ///             fields: content.parse_terminated(Type::parse, Token![,])?,
    ///             semi_token: input.parse()?,
    ///         })
    ///     }
    /// }
    /// #
    /// # let input = quote! {
    /// #     struct S(A, B);
    /// # };
    /// # syn::parse2::<TupleStruct>(input).unwrap();
    /// ```
    ///
    /// # See also
    ///
    /// If your separator is anything more complicated than an invocation of the
    /// `Token!` macro, this method won't be applicable and you can instead
    /// directly use `Punctuated`'s parser functions: [`parse_terminated`],
    /// [`parse_separated_nonempty`] etc.
    ///
    /// [`parse_terminated`]: Punctuated::parse_terminated
    /// [`parse_separated_nonempty`]: Punctuated::parse_separated_nonempty
    ///
    /// ```
    /// use syn::{custom_keyword, Expr, Result, Token};
    /// use syn::parse::{Parse, ParseStream};
    /// use syn::punctuated::Punctuated;
    ///
    /// mod kw {
    ///     syn::custom_keyword!(fin);
    /// }
    ///
    /// struct Fin(kw::fin, Token![;]);
    ///
    /// impl Parse for Fin {
    ///     fn parse(input: ParseStream) -> Result<Self> {
    ///         Ok(Self(input.parse()?, input.parse()?))
    ///     }
    /// }
    ///
    /// struct Thing {
    ///     steps: Punctuated<Expr, Fin>,
    /// }
    ///
    /// impl Parse for Thing {
    ///     fn parse(input: ParseStream) -> Result<Self> {
    /// # if true {
    ///         Ok(Thing {
    ///             steps: Punctuated::parse_terminated(input)?,
    ///         })
    /// # } else {
    ///         // or equivalently, this means the same thing:
    /// #       Ok(Thing {
    ///             steps: input.call(Punctuated::parse_terminated)?,
    /// #       })
    /// # }
    ///     }
    /// }
    /// ```
    pub fn parse_terminated<T, P>(
        &self,
        parser: fn(ParseStream) -> Result<T>,
        separator: P,
    ) -> Result<Punctuated<T, P::Token>>
    where
        P: Peek,
        P::Token: Parse,
    {
        let _ = separator;
        Punctuated::parse_terminated_with(self, parser)
    }

    /// Returns whether there are tokens remaining in this stream.
    ///
    /// This method returns true at the end of the content of a set of
    /// delimiters, as well as at the very end of the complete macro input.
    ///
    /// # Example
    ///
    /// ```
    /// use syn::{braced, token, Ident, Item, Result, Token};
    /// use syn::parse::{Parse, ParseStream};
    ///
    /// // Parses a Rust `mod m { ... }` containing zero or more items.
    /// struct Mod {
    ///     mod_token: Token![mod],
    ///     name: Ident,
    ///     brace_token: token::Brace,
    ///     items: Vec<Item>,
    /// }
    ///
    /// impl Parse for Mod {
    ///     fn parse(input: ParseStream) -> Result<Self> {
    ///         let content;
    ///         Ok(Mod {
    ///             mod_token: input.parse()?,
    ///             name: input.parse()?,
    ///             brace_token: braced!(content in input),
    ///             items: {
    ///                 let mut items = Vec::new();
    ///                 while !content.is_empty() {
    ///                     items.push(content.parse()?);
    ///                 }
    ///                 items
    ///             },
    ///         })
    ///     }
    /// }
    /// ```
    pub fn is_empty(&self) -> bool {
        self.cursor().eof()
    }

    /// Constructs a helper for peeking at the next token in this stream and
    /// building an error message if it is not one of a set of expected tokens.
    ///
    /// # Example
    ///
    /// ```
    /// use syn::{ConstParam, Ident, Lifetime, LifetimeParam, Result, Token, TypeParam};
    /// use syn::parse::{Parse, ParseStream};
    ///
    /// // A generic parameter, a single one of the comma-separated elements inside
    /// // angle brackets in:
    /// //
    /// //     fn f<T: Clone, 'a, 'b: 'a, const N: usize>() { ... }
    /// //
    /// // On invalid input, lookahead gives us a reasonable error message.
    /// //
    /// //     error: expected one of: identifier, lifetime, `const`
    /// //       |
    /// //     5 |     fn f<!Sized>() {}
    /// //       |          ^
    /// enum GenericParam {
    ///     Type(TypeParam),
    ///     Lifetime(LifetimeParam),
    ///     Const(ConstParam),
    /// }
    ///
    /// impl Parse for GenericParam {
    ///     fn parse(input: ParseStream) -> Result<Self> {
    ///         let lookahead = input.lookahead1();
    ///         if lookahead.peek(Ident) {
    ///             input.parse().map(GenericParam::Type)
    ///         } else if lookahead.peek(Lifetime) {
    ///             input.parse().map(GenericParam::Lifetime)
    ///         } else if lookahead.peek(Token![const]) {
    ///             input.parse().map(GenericParam::Const)
    ///         } else {
    ///             Err(lookahead.error())
    ///         }
    ///     }
    /// }
    /// ```
    pub fn lookahead1(&self) -> Lookahead1<'a> {
        lookahead::new(self.scope, self.cursor())
    }

    /// Forks a parse stream so that parsing tokens out of either the original
    /// or the fork does not advance the position of the other.
    ///
    /// # Performance
    ///
    /// Forking a parse stream is a cheap fixed amount of work and does not
    /// involve copying token buffers. Where you might hit performance problems
    /// is if your macro ends up parsing a large amount of content more than
    /// once.
    ///
    /// ```
    /// # use syn::{Expr, Result};
    /// # use syn::parse::ParseStream;
    /// #
    /// # fn bad(input: ParseStream) -> Result<Expr> {
    /// // Do not do this.
    /// if input.fork().parse::<Expr>().is_ok() {
    ///     return input.parse::<Expr>();
    /// }
    /// # unimplemented!()
    /// # }
    /// ```
    ///
    /// As a rule, avoid parsing an unbounded amount of tokens out of a forked
    /// parse stream. Only use a fork when the amount of work performed against
    /// the fork is small and bounded.
    ///
    /// When complex speculative parsing against the forked stream is
    /// unavoidable, use [`parse::discouraged::Speculative`] to advance the
    /// original stream once the fork's parse is determined to have been
    /// successful.
    ///
    /// For a lower level way to perform speculative parsing at the token level,
    /// consider using [`ParseStream::step`] instead.
    ///
    /// [`parse::discouraged::Speculative`]: discouraged::Speculative
    /// [`ParseStream::step`]: ParseBuffer::step
    ///
    /// # Example
    ///
    /// The parse implementation shown here parses possibly restricted `pub`
    /// visibilities.
    ///
    /// - `pub`
    /// - `pub(crate)`
    /// - `pub(self)`
    /// - `pub(super)`
    /// - `pub(in some::path)`
    ///
    /// To handle the case of visibilities inside of tuple structs, the parser
    /// needs to distinguish parentheses that specify visibility restrictions
    /// from parentheses that form part of a tuple type.
    ///
    /// ```
    /// # struct A;
    /// # struct B;
    /// # struct C;
    /// #
    /// struct S(pub(crate) A, pub (B, C));
    /// ```
    ///
    /// In this example input the first tuple struct element of `S` has
    /// `pub(crate)` visibility while the second tuple struct element has `pub`
    /// visibility; the parentheses around `(B, C)` are part of the type rather
    /// than part of a visibility restriction.
    ///
    /// The parser uses a forked parse stream to check the first token inside of
    /// parentheses after the `pub` keyword. This is a small bounded amount of
    /// work performed against the forked parse stream.
    ///
    /// ```
    /// use syn::{parenthesized, token, Ident, Path, Result, Token};
    /// use syn::ext::IdentExt;
    /// use syn::parse::{Parse, ParseStream};
    ///
    /// struct PubVisibility {
    ///     pub_token: Token![pub],
    ///     restricted: Option<Restricted>,
    /// }
    ///
    /// struct Restricted {
    ///     paren_token: token::Paren,
    ///     in_token: Option<Token![in]>,
    ///     path: Path,
    /// }
    ///
    /// impl Parse for PubVisibility {
    ///     fn parse(input: ParseStream) -> Result<Self> {
    ///         let pub_token: Token![pub] = input.parse()?;
    ///
    ///         if input.peek(token::Paren) {
    ///             let ahead = input.fork();
    ///             let mut content;
    ///             parenthesized!(content in ahead);
    ///
    ///             if content.peek(Token![crate])
    ///                 || content.peek(Token![self])
    ///                 || content.peek(Token![super])
    ///             {
    ///                 return Ok(PubVisibility {
    ///                     pub_token,
    ///                     restricted: Some(Restricted {
    ///                         paren_token: parenthesized!(content in input),
    ///                         in_token: None,
    ///                         path: Path::from(content.call(Ident::parse_any)?),
    ///                     }),
    ///                 });
    ///             } else if content.peek(Token![in]) {
    ///                 return Ok(PubVisibility {
    ///                     pub_token,
    ///                     restricted: Some(Restricted {
    ///                         paren_token: parenthesized!(content in input),
    ///                         in_token: Some(content.parse()?),
    ///                         path: content.call(Path::parse_mod_style)?,
    ///                     }),
    ///                 });
    ///             }
    ///         }
    ///
    ///         Ok(PubVisibility {
    ///             pub_token,
    ///             restricted: None,
    ///         })
    ///     }
    /// }
    /// ```
    pub fn fork(&self) -> Self {
        ParseBuffer {
            scope: self.scope,
            cell: self.cell.clone(),
            marker: PhantomData,
            // Not the parent's unexpected. Nothing cares whether the clone
            // parses all the way unless we `advance_to`.
            unexpected: Cell::new(Some(Rc::new(Cell::new(Unexpected::None)))),
        }
    }

    /// Triggers an error at the current position of the parse stream.
    ///
    /// # Example
    ///
    /// ```
    /// use syn::{Expr, Result, Token};
    /// use syn::parse::{Parse, ParseStream};
    ///
    /// // Some kind of loop: `while` or `for` or `loop`.
    /// struct Loop {
    ///     expr: Expr,
    /// }
    ///
    /// impl Parse for Loop {
    ///     fn parse(input: ParseStream) -> Result<Self> {
    ///         if input.peek(Token![while])
    ///             || input.peek(Token![for])
    ///             || input.peek(Token![loop])
    ///         {
    ///             Ok(Loop {
    ///                 expr: input.parse()?,
    ///             })
    ///         } else {
    ///             Err(input.error("expected some kind of loop"))
    ///         }
    ///     }
    /// }
    /// ```
    pub fn error<T: Display>(&self, message: T) -> Error {
        error::new_at(self.scope, self.cursor(), message)
    }

    /// Speculatively parses tokens from this parse stream, advancing the
    /// position of this stream only if parsing succeeds.
    ///
    /// This is a powerful low-level API used for defining the `Parse` impls of
    /// the basic built-in token types. It is not something that will be used
    /// widely outside of the Syn codebase.
    ///
    /// # Example
    ///
    /// ```
    /// use proc_macro2::TokenTree;
    /// use syn::Result;
    /// use syn::parse::ParseStream;
    ///
    /// // This function advances the stream past the next occurrence of `@`. If
    /// // no `@` is present in the stream, the stream position is unchanged and
    /// // an error is returned.
    /// fn skip_past_next_at(input: ParseStream) -> Result<()> {
    ///     input.step(|cursor| {
    ///         let mut rest = *cursor;
    ///         while let Some((tt, next)) = rest.token_tree() {
    ///             match &tt {
    ///                 TokenTree::Punct(punct) if punct.as_char() == '@' => {
    ///                     return Ok(((), next));
    ///                 }
    ///                 _ => rest = next,
    ///             }
    ///         }
    ///         Err(cursor.error("no `@` was found after this point"))
    ///     })
    /// }
    /// #
    /// # fn remainder_after_skipping_past_next_at(
    /// #     input: ParseStream,
    /// # ) -> Result<proc_macro2::TokenStream> {
    /// #     skip_past_next_at(input)?;
    /// #     input.parse()
    /// # }
    /// #
    /// # use syn::parse::Parser;
    /// # let remainder = remainder_after_skipping_past_next_at
    /// #     .parse_str("a @ b c")
    /// #     .unwrap();
    /// # assert_eq!(remainder.to_string(), "b c");
    /// ```
    pub fn step<F, R>(&self, function: F) -> Result<R>
    where
        F: for<'c> FnOnce(StepCursor<'c, 'a>) -> Result<(R, Cursor<'c>)>,
    {
        // Since the user's function is required to work for any 'c, we know
        // that the Cursor<'c> they return is either derived from the input
        // StepCursor<'c, 'a> or from a Cursor<'static>.
        //
        // It would not be legal to write this function without the invariant
        // lifetime 'c in StepCursor<'c, 'a>. If this function were written only
        // in terms of 'a, the user could take our ParseBuffer<'a>, upcast it to
        // a ParseBuffer<'short> which some shorter lifetime than 'a, invoke
        // `step` on their ParseBuffer<'short> with a closure that returns
        // Cursor<'short>, and we would wrongly write that Cursor<'short> into
        // the Cell intended to hold Cursor<'a>.
        //
        // In some cases it may be necessary for R to contain a Cursor<'a>.
        // Within Syn we solve this using `advance_step_cursor` which uses the
        // existence of a StepCursor<'c, 'a> as proof that it is safe to cast
        // from Cursor<'c> to Cursor<'a>. If needed outside of Syn, it would be
        // safe to expose that API as a method on StepCursor.
        let (node, rest) = function(StepCursor {
            scope: self.scope,
            cursor: self.cell.get(),
            marker: PhantomData,
        })?;
        self.cell.set(rest);
        Ok(node)
    }

    /// Returns the `Span` of the next token in the parse stream, or
    /// `Span::call_site()` if this parse stream has completely exhausted its
    /// input `TokenStream`.
    pub fn span(&self) -> Span {
        let cursor = self.cursor();
        if cursor.eof() {
            self.scope
        } else {
            crate::buffer::open_span_of_group(cursor)
        }
    }

    /// Provides low-level access to the token representation underlying this
    /// parse stream.
    ///
    /// Cursors are immutable so no operations you perform against the cursor
    /// will affect the state of this parse stream.
    pub fn cursor(&self) -> Cursor<'a> {
        self.cell.get()
    }

    fn check_unexpected(&self) -> Result<()> {
        match inner_unexpected(self).1 {
            Some(span) => Err(Error::new(span, "unexpected token")),
            None => Ok(()),
        }
    }
}

#[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
impl<T: Parse> Parse for Box<T> {
    fn parse(input: ParseStream) -> Result<Self> {
        input.parse().map(Box::new)
    }
}

#[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
impl<T: Parse + Token> Parse for Option<T> {
    fn parse(input: ParseStream) -> Result<Self> {
        if T::peek(input.cursor()) {
            Ok(Some(input.parse()?))
        } else {
            Ok(None)
        }
    }
}

#[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
impl Parse for TokenStream {
    fn parse(input: ParseStream) -> Result<Self> {
        input.step(|cursor| Ok((cursor.token_stream(), Cursor::empty())))
    }
}

#[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
impl Parse for TokenTree {
    fn parse(input: ParseStream) -> Result<Self> {
        input.step(|cursor| match cursor.token_tree() {
            Some((tt, rest)) => Ok((tt, rest)),
            None => Err(cursor.error("expected token tree")),
        })
    }
}

#[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
impl Parse for Group {
    fn parse(input: ParseStream) -> Result<Self> {
        input.step(|cursor| {
            if let Some((group, rest)) = cursor.any_group_token() {
                if group.delimiter() != Delimiter::None {
                    return Ok((group, rest));
                }
            }
            Err(cursor.error("expected group token"))
        })
    }
}

#[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
impl Parse for Punct {
    fn parse(input: ParseStream) -> Result<Self> {
        input.step(|cursor| match cursor.punct() {
            Some((punct, rest)) => Ok((punct, rest)),
            None => Err(cursor.error("expected punctuation token")),
        })
    }
}

#[cfg_attr(doc_cfg, doc(cfg(feature = "parsing")))]
impl Parse for Literal {
    fn parse(input: ParseStream) -> Result<Self> {
        input.step(|cursor| match cursor.literal() {
            Some((literal, rest)) => Ok((literal, rest)),
            None => Err(cursor.error("expected literal token")),
        })
    }
}

/// Parser that can parse Rust tokens into a particular syntax tree node.
///
/// Refer to the [module documentation] for details about parsing in Syn.
///
/// [module documentation]: self
pub trait Parser: Sized {
    type Output;

    /// Parse a proc-macro2 token stream into the chosen syntax tree node.
    ///
    /// This function will check that the input is fully parsed. If there are
    /// any unparsed tokens at the end of the stream, an error is returned.
    fn parse2(self, tokens: TokenStream) -> Result<Self::Output>;

    /// Parse tokens of source code into the chosen syntax tree node.
    ///
    /// This function will check that the input is fully parsed. If there are
    /// any unparsed tokens at the end of the stream, an error is returned.
    #[cfg(feature = "proc-macro")]
    #[cfg_attr(doc_cfg, doc(cfg(feature = "proc-macro")))]
    fn parse(self, tokens: proc_macro::TokenStream) -> Result<Self::Output> {
        self.parse2(proc_macro2::TokenStream::from(tokens))
    }

    /// Parse a string of Rust code into the chosen syntax tree node.
    ///
    /// This function will check that the input is fully parsed. If there are
    /// any unparsed tokens at the end of the string, an error is returned.
    ///
    /// # Hygiene
    ///
    /// Every span in the resulting syntax tree will be set to resolve at the
    /// macro call site.
    fn parse_str(self, s: &str) -> Result<Self::Output> {
        self.parse2(proc_macro2::TokenStream::from_str(s)?)
    }

    // Not public API.
    #[doc(hidden)]
    #[cfg(any(feature = "full", feature = "derive"))]
    fn __parse_scoped(self, scope: Span, tokens: TokenStream) -> Result<Self::Output> {
        let _ = scope;
        self.parse2(tokens)
    }
}

fn tokens_to_parse_buffer(tokens: &TokenBuffer) -> ParseBuffer {
    let scope = Span::call_site();
    let cursor = tokens.begin();
    let unexpected = Rc::new(Cell::new(Unexpected::None));
    new_parse_buffer(scope, cursor, unexpected)
}

impl<F, T> Parser for F
where
    F: FnOnce(ParseStream) -> Result<T>,
{
    type Output = T;

    fn parse2(self, tokens: TokenStream) -> Result<T> {
        let buf = TokenBuffer::new2(tokens);
        let state = tokens_to_parse_buffer(&buf);
        let node = self(&state)?;
        state.check_unexpected()?;
        if let Some(unexpected_span) = span_of_unexpected_ignoring_nones(state.cursor()) {
            Err(Error::new(unexpected_span, "unexpected token"))
        } else {
            Ok(node)
        }
    }

    #[cfg(any(feature = "full", feature = "derive"))]
    fn __parse_scoped(self, scope: Span, tokens: TokenStream) -> Result<Self::Output> {
        let buf = TokenBuffer::new2(tokens);
        let cursor = buf.begin();
        let unexpected = Rc::new(Cell::new(Unexpected::None));
        let state = new_parse_buffer(scope, cursor, unexpected);
        let node = self(&state)?;
        state.check_unexpected()?;
        if let Some(unexpected_span) = span_of_unexpected_ignoring_nones(state.cursor()) {
            Err(Error::new(unexpected_span, "unexpected token"))
        } else {
            Ok(node)
        }
    }
}

#[cfg(any(feature = "full", feature = "derive"))]
pub(crate) fn parse_scoped<F: Parser>(f: F, scope: Span, tokens: TokenStream) -> Result<F::Output> {
    f.__parse_scoped(scope, tokens)
}

/// An empty syntax tree node that consumes no tokens when parsed.
///
/// This is useful for attribute macros that want to ensure they are not
/// provided any attribute args.
///
/// ```
/// # extern crate proc_macro;
/// #
/// use proc_macro::TokenStream;
/// use syn::parse_macro_input;
/// use syn::parse::Nothing;
///
/// # const IGNORE: &str = stringify! {
/// #[proc_macro_attribute]
/// # };
/// pub fn my_attr(args: TokenStream, input: TokenStream) -> TokenStream {
///     parse_macro_input!(args as Nothing);
///
///     /* ... */
/// #   TokenStream::new()
/// }
/// ```
///
/// ```text
/// error: unexpected token
///  --> src/main.rs:3:19
///   |
/// 3 | #[my_attr(asdf)]
///   |           ^^^^
/// ```
pub struct Nothing;

impl Parse for Nothing {
    fn parse(_input: ParseStream) -> Result<Self> {
        Ok(Nothing)
    }
}

#[cfg(feature = "extra-traits")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
impl Debug for Nothing {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.write_str("Nothing")
    }
}

#[cfg(feature = "extra-traits")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
impl Eq for Nothing {}

#[cfg(feature = "extra-traits")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
impl PartialEq for Nothing {
    fn eq(&self, _other: &Self) -> bool {
        true
    }
}

#[cfg(feature = "extra-traits")]
#[cfg_attr(doc_cfg, doc(cfg(feature = "extra-traits")))]
impl Hash for Nothing {
    fn hash<H: Hasher>(&self, _state: &mut H) {}
}
