use proc_macro2::{Delimiter, Span};
use error::Result;
use parse::{ParseBuffer, ParseStream};
use private;
use token;
#[doc(hidden)]
pub struct Parens<'a> {
    pub token: token::Paren,
    pub content: ParseBuffer<'a>,
}
#[doc(hidden)]
pub struct Braces<'a> {
    pub token: token::Brace,
    pub content: ParseBuffer<'a>,
}
#[doc(hidden)]
pub struct Brackets<'a> {
    pub token: token::Bracket,
    pub content: ParseBuffer<'a>,
}
#[cfg(any(feature = "full", feature = "derive"))]
#[doc(hidden)]
pub struct Group<'a> {
    pub token: token::Group,
    pub content: ParseBuffer<'a>,
}
#[doc(hidden)]
pub fn parse_parens(input: ParseStream) -> Result<Parens> {
    parse_delimited(input, Delimiter::Parenthesis).map(|(span, content)| Parens {
        token: token::Paren(span),
        content: content,
    })
}
#[doc(hidden)]
pub fn parse_braces(input: ParseStream) -> Result<Braces> {
    parse_delimited(input, Delimiter::Brace).map(|(span, content)| Braces {
        token: token::Brace(span),
        content: content,
    })
}
#[doc(hidden)]
pub fn parse_brackets(input: ParseStream) -> Result<Brackets> {
    parse_delimited(input, Delimiter::Bracket).map(|(span, content)| Brackets {
        token: token::Bracket(span),
        content: content,
    })
}
#[cfg(any(feature = "full", feature = "derive"))]
impl private {
    pub fn parse_group(input: ParseStream) -> Result<Group> {
        parse_delimited(input, Delimiter::None).map(|(span, content)| Group {
            token: token::Group(span),
            content: content,
        })
    }
}
fn parse_delimited(input: ParseStream, delimiter: Delimiter) -> Result<(Span, ParseBuffer)> {
    input.step(|cursor| {
        if let Some((content, span, rest)) = cursor.group(delimiter) {
            #[cfg(procmacro2_semver_exempt)]
            let scope = private::close_span_of_group(*cursor);
            #[cfg(not(procmacro2_semver_exempt))]
            let scope = span;
            let nested = private::advance_step_cursor(cursor, content);
            let unexpected = private::get_unexpected(input);
            let content = private::new_parse_buffer(scope, nested, unexpected);
            Ok(((span, content), rest))
        } else {
            let message = match delimiter {
                Delimiter::Parenthesis => "expected parentheses",
                Delimiter::Brace => "expected curly braces",
                Delimiter::Bracket => "expected square brackets",
                Delimiter::None => "expected invisible group",
            };
            Err(cursor.error(message))
        }
    })
}
#[macro_export]
macro_rules! parenthesized {
    ($content:ident in $cursor:expr) => {
        match $crate::group::parse_parens(&$cursor) {
            $crate::export::Ok(parens) => {
                $content = parens.content;
                parens.token
            }
            $crate::export::Err(error) => {
                return $crate::export::Err(error);
            }
        }
    };
}
#[macro_export]
macro_rules! braced {
    ($content:ident in $cursor:expr) => {
        match $crate::group::parse_braces(&$cursor) {
            $crate::export::Ok(braces) => {
                $content = braces.content;
                braces.token
            }
            $crate::export::Err(error) => {
                return $crate::export::Err(error);
            }
        }
    };
}
#[macro_export]
macro_rules! bracketed {
    ($content:ident in $cursor:expr) => {
        match $crate::group::parse_brackets(&$cursor) {
            $crate::export::Ok(brackets) => {
                $content = brackets.content;
                brackets.token
            }
            $crate::export::Err(error) => {
                return $crate::export::Err(error);
            }
        }
    };
}