//! Macro support for format strings
//!
//! These structures are used when parsing format strings for the compiler.
//! Parsing does not happen at runtime: structures of `std::fmt::rt` are
//! generated instead.

// tidy-alphabetical-start
// We want to be able to build this crate with a stable compiler,
// so no `#![feature]` attributes should be added.
#![deny(unstable_features)]
#![doc(test(attr(deny(warnings), allow(internal_features))))]
// tidy-alphabetical-end

use std::ops::Range;

pub use Alignment::*;
pub use Count::*;
pub use Position::*;

/// The type of format string that we are parsing.
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum ParseMode {
    /// A normal format string as per `format_args!`.
    Format,
    /// An inline assembly template string for `asm!`.
    InlineAsm,
    /// A format string for use in diagnostic attributes.
    ///
    /// Similar to `format_args!`, however only named ("captured") arguments
    /// are allowed, and no format modifiers are permitted.
    Diagnostic,
}

/// A piece is a portion of the format string which represents the next part
/// to emit. These are emitted as a stream by the `Parser` class.
#[derive(Clone, Debug, PartialEq)]
pub enum Piece<'input> {
    /// A literal string which should directly be emitted
    Lit(&'input str),
    /// This describes that formatting should process the next argument (as
    /// specified inside) for emission.
    NextArgument(Box<Argument<'input>>),
}

/// Representation of an argument specification.
#[derive(Clone, Debug, PartialEq)]
pub struct Argument<'input> {
    /// Where to find this argument
    pub position: Position<'input>,
    /// The span of the position indicator. Includes any whitespace in implicit
    /// positions (`{  }`).
    pub position_span: Range<usize>,
    /// How to format the argument
    pub format: FormatSpec<'input>,
}

impl<'input> Argument<'input> {
    pub fn is_identifier(&self) -> bool {
        matches!(self.position, Position::ArgumentNamed(_)) && self.format == FormatSpec::default()
    }
}

/// Specification for the formatting of an argument in the format string.
#[derive(Clone, Debug, PartialEq, Default)]
pub struct FormatSpec<'input> {
    /// Optionally specified character to fill alignment with.
    pub fill: Option<char>,
    /// Span of the optionally specified fill character.
    pub fill_span: Option<Range<usize>>,
    /// Optionally specified alignment.
    pub align: Alignment,
    /// The `+` or `-` flag.
    pub sign: Option<Sign>,
    /// The `#` flag.
    pub alternate: bool,
    /// The `0` flag.
    pub zero_pad: bool,
    /// The `x` or `X` flag. (Only for `Debug`.)
    pub debug_hex: Option<DebugHex>,
    /// The integer precision to use.
    pub precision: Count<'input>,
    /// The span of the precision formatting flag (for diagnostics).
    pub precision_span: Option<Range<usize>>,
    /// The string width requested for the resulting format.
    pub width: Count<'input>,
    /// The span of the width formatting flag (for diagnostics).
    pub width_span: Option<Range<usize>>,
    /// The descriptor string representing the name of the format desired for
    /// this argument, this can be empty or any number of characters, although
    /// it is required to be one word.
    pub ty: &'input str,
    /// The span of the descriptor string (for diagnostics).
    pub ty_span: Option<Range<usize>>,
}

/// Enum describing where an argument for a format can be located.
#[derive(Clone, Debug, PartialEq)]
pub enum Position<'input> {
    /// The argument is implied to be located at an index
    ArgumentImplicitlyIs(usize),
    /// The argument is located at a specific index given in the format,
    ArgumentIs(usize),
    /// The argument has a name.
    ArgumentNamed(&'input str),
}

impl Position<'_> {
    pub fn index(&self) -> Option<usize> {
        match self {
            ArgumentIs(i, ..) | ArgumentImplicitlyIs(i) => Some(*i),
            _ => None,
        }
    }
}

/// Enum of alignments which are supported.
#[derive(Copy, Clone, Debug, PartialEq, Default)]
pub enum Alignment {
    /// The value will be aligned to the left.
    AlignLeft,
    /// The value will be aligned to the right.
    AlignRight,
    /// The value will be aligned in the center.
    AlignCenter,
    /// The value will take on a default alignment.
    #[default]
    AlignUnknown,
}

/// Enum for the sign flags.
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum Sign {
    /// The `+` flag.
    Plus,
    /// The `-` flag.
    Minus,
}

/// Enum for the debug hex flags.
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum DebugHex {
    /// The `x` flag in `{:x?}`.
    Lower,
    /// The `X` flag in `{:X?}`.
    Upper,
}

/// A count is used for the precision and width parameters of an integer, and
/// can reference either an argument or a literal integer.
#[derive(Clone, Debug, PartialEq, Default)]
pub enum Count<'input> {
    /// The count is specified explicitly.
    CountIs(u16),
    /// The count is specified by the argument with the given name.
    CountIsName(&'input str, Range<usize>),
    /// The count is specified by the argument at the given index.
    CountIsParam(usize),
    /// The count is specified by a star (like in `{:.*}`) that refers to the argument at the given index.
    CountIsStar(usize),
    /// The count is implied and cannot be explicitly specified.
    #[default]
    CountImplied,
}

pub struct ParseError {
    pub description: String,
    pub note: Option<String>,
    pub label: String,
    pub span: Range<usize>,
    pub secondary_label: Option<(String, Range<usize>)>,
    pub suggestion: Suggestion,
}

pub enum Suggestion {
    None,
    /// Replace inline argument with positional argument:
    /// `format!("{foo.bar}")` -> `format!("{}", foo.bar)`
    UsePositional,
    /// Remove `r#` from identifier:
    /// `format!("{r#foo}")` -> `format!("{foo}")`
    RemoveRawIdent(Range<usize>),
    /// Reorder format parameter:
    /// `format!("{foo:?#}")` -> `format!("{foo:#?}")`
    /// `format!("{foo:?x}")` -> `format!("{foo:x?}")`
    /// `format!("{foo:?X}")` -> `format!("{foo:X?}")`
    ReorderFormatParameter(Range<usize>, String),
}

/// The parser structure for interpreting the input format string. This is
/// modeled as an iterator over `Piece` structures to form a stream of tokens
/// being output.
///
/// This is a recursive-descent parser for the sake of simplicity, and if
/// necessary there's probably lots of room for improvement performance-wise.
pub struct Parser<'input> {
    mode: ParseMode,
    /// Input to be parsed
    input: &'input str,
    /// Tuples of the span in the code snippet (input as written before being unescaped), the pos in input, and the char in input
    input_vec: Vec<(Range<usize>, usize, char)>,
    /// Index into input_vec
    input_vec_index: usize,
    /// Error messages accumulated during parsing
    pub errors: Vec<ParseError>,
    /// Current position of implicit positional argument pointer
    pub curarg: usize,
    /// Start and end byte offset of every successfully parsed argument
    pub arg_places: Vec<Range<usize>>,
    /// Span of the last opening brace seen, used for error reporting
    last_open_brace: Option<Range<usize>>,
    /// Whether this formatting string was written directly in the source. This controls whether we
    /// can use spans to refer into it and give better error messages.
    /// N.B: This does _not_ control whether implicit argument captures can be used.
    pub is_source_literal: bool,
    /// Index to the end of the literal snippet
    end_of_snippet: usize,
    /// Start position of the current line.
    cur_line_start: usize,
    /// Start and end byte offset of every line of the format string. Excludes
    /// newline characters and leading whitespace.
    pub line_spans: Vec<Range<usize>>,
}

impl<'input> Iterator for Parser<'input> {
    type Item = Piece<'input>;

    fn next(&mut self) -> Option<Piece<'input>> {
        if let Some((Range { start, end }, idx, ch)) = self.peek() {
            match ch {
                '{' => {
                    self.input_vec_index += 1;
                    if let Some((_, i, '{')) = self.peek() {
                        self.input_vec_index += 1;
                        // double open brace escape: "{{"
                        // next state after this is either end-of-input or seen-a-brace
                        Some(Piece::Lit(self.string(i)))
                    } else {
                        // single open brace
                        self.last_open_brace = Some(start..end);
                        let arg = self.argument();
                        self.ws();
                        if let Some((close_brace_range, _)) = self.consume_pos('}') {
                            if self.is_source_literal {
                                self.arg_places.push(start..close_brace_range.end);
                            }
                        } else {
                            self.missing_closing_brace(&arg);
                        }

                        Some(Piece::NextArgument(Box::new(arg)))
                    }
                }
                '}' => {
                    self.input_vec_index += 1;
                    if let Some((_, i, '}')) = self.peek() {
                        self.input_vec_index += 1;
                        // double close brace escape: "}}"
                        // next state after this is either end-of-input or start
                        Some(Piece::Lit(self.string(i)))
                    } else {
                        // error: single close brace without corresponding open brace
                        self.errors.push(ParseError {
                            description: "unmatched `}` found".into(),
                            note: Some(
                                "if you intended to print `}`, you can escape it using `}}`".into(),
                            ),
                            label: "unmatched `}`".into(),
                            span: start..end,
                            secondary_label: None,
                            suggestion: Suggestion::None,
                        });
                        None
                    }
                }
                _ => Some(Piece::Lit(self.string(idx))),
            }
        } else {
            // end of input
            if self.is_source_literal {
                let span = self.cur_line_start..self.end_of_snippet;
                if self.line_spans.last() != Some(&span) {
                    self.line_spans.push(span);
                }
            }
            None
        }
    }
}

impl<'input> Parser<'input> {
    /// Creates a new parser for the given unescaped input string and
    /// optional code snippet (the input as written before being unescaped),
    /// where `style` is `Some(nr_hashes)` when the snippet is a raw string with that many hashes.
    /// If the input comes via `println` or `panic`, then it has a newline already appended,
    /// which is reflected in the `appended_newline` parameter.
    pub fn new(
        input: &'input str,
        style: Option<usize>,
        snippet: Option<String>,
        appended_newline: bool,
        mode: ParseMode,
    ) -> Self {
        let quote_offset = style.map_or(1, |nr_hashes| nr_hashes + 2);

        let (is_source_literal, end_of_snippet, pre_input_vec) = if let Some(snippet) = snippet {
            if let Some(nr_hashes) = style {
                // snippet is a raw string, which starts with 'r', a number of hashes, and a quote
                // and ends with a quote and the same number of hashes
                (true, snippet.len() - nr_hashes - 1, vec![])
            } else {
                // snippet is not a raw string
                if snippet.starts_with('"') {
                    // snippet looks like an ordinary string literal
                    // check whether it is the escaped version of input
                    let without_quotes = &snippet[1..snippet.len() - 1];
                    let (mut ok, mut vec) = (true, vec![]);
                    let mut chars = input.chars();
                    rustc_literal_escaper::unescape_str(without_quotes, |range, res| match res {
                        Ok(ch) if ok && chars.next().is_some_and(|c| ch == c) => {
                            vec.push((range, ch));
                        }
                        _ => {
                            ok = false;
                            vec = vec![];
                        }
                    });
                    let end = vec.last().map(|(r, _)| r.end).unwrap_or(0);
                    if ok {
                        if appended_newline {
                            if chars.as_str() == "\n" {
                                vec.push((end..end + 1, '\n'));
                                (true, 1 + end, vec)
                            } else {
                                (false, snippet.len(), vec![])
                            }
                        } else if chars.as_str() == "" {
                            (true, 1 + end, vec)
                        } else {
                            (false, snippet.len(), vec![])
                        }
                    } else {
                        (false, snippet.len(), vec![])
                    }
                } else {
                    // snippet is not a raw string and does not start with '"'
                    (false, snippet.len(), vec![])
                }
            }
        } else {
            // snippet is None
            (false, input.len() - if appended_newline { 1 } else { 0 }, vec![])
        };

        let input_vec: Vec<(Range<usize>, usize, char)> = if pre_input_vec.is_empty() {
            // Snippet is *not* input before unescaping, so spans pointing at it will be incorrect.
            // This can happen with proc macros that respan generated literals.
            input
                .char_indices()
                .map(|(idx, c)| {
                    let i = idx + quote_offset;
                    (i..i + c.len_utf8(), idx, c)
                })
                .collect()
        } else {
            // Snippet is input before unescaping
            input
                .char_indices()
                .zip(pre_input_vec)
                .map(|((i, c), (r, _))| (r.start + quote_offset..r.end + quote_offset, i, c))
                .collect()
        };

        Parser {
            mode,
            input,
            input_vec,
            input_vec_index: 0,
            errors: vec![],
            curarg: 0,
            arg_places: vec![],
            last_open_brace: None,
            is_source_literal,
            end_of_snippet,
            cur_line_start: quote_offset,
            line_spans: vec![],
        }
    }

    /// Peeks at the current position, without incrementing the pointer.
    pub fn peek(&self) -> Option<(Range<usize>, usize, char)> {
        self.input_vec.get(self.input_vec_index).cloned()
    }

    /// Peeks at the current position + 1, without incrementing the pointer.
    pub fn peek_ahead(&self) -> Option<(Range<usize>, usize, char)> {
        self.input_vec.get(self.input_vec_index + 1).cloned()
    }

    /// Optionally consumes the specified character. If the character is not at
    /// the current position, then the current iterator isn't moved and `false` is
    /// returned, otherwise the character is consumed and `true` is returned.
    fn consume(&mut self, c: char) -> bool {
        self.consume_pos(c).is_some()
    }

    /// Optionally consumes the specified character. If the character is not at
    /// the current position, then the current iterator isn't moved and `None` is
    /// returned, otherwise the character is consumed and the current position is
    /// returned.
    fn consume_pos(&mut self, ch: char) -> Option<(Range<usize>, usize)> {
        if let Some((r, i, c)) = self.peek()
            && ch == c
        {
            self.input_vec_index += 1;
            return Some((r, i));
        }

        None
    }

    /// Called if a closing brace was not found.
    fn missing_closing_brace(&mut self, arg: &Argument<'_>) {
        let (range, description) = if let Some((r, _, c)) = self.peek() {
            (r.start..r.start, format!("expected `}}`, found `{}`", c.escape_debug()))
        } else {
            (
                // point at closing `"`
                self.end_of_snippet..self.end_of_snippet,
                "expected `}` but string was terminated".to_owned(),
            )
        };

        let (note, secondary_label) = if arg.format.fill == Some('}') {
            (
                Some("the character `}` is interpreted as a fill character because of the `:` that precedes it".to_owned()),
                arg.format.fill_span.clone().map(|sp| ("this is not interpreted as a formatting closing brace".to_owned(), sp)),
            )
        } else {
            (
                Some("if you intended to print `{`, you can escape it using `{{`".to_owned()),
                self.last_open_brace
                    .clone()
                    .map(|sp| ("because of this opening brace".to_owned(), sp)),
            )
        };

        self.errors.push(ParseError {
            description,
            note,
            label: "expected `}`".to_owned(),
            span: range.start..range.start,
            secondary_label,
            suggestion: Suggestion::None,
        });

        if let Some((_, _, c)) = self.peek() {
            match c {
                '?' => self.suggest_format_debug(),
                '<' | '^' | '>' => self.suggest_format_align(c),
                _ => self.suggest_positional_arg_instead_of_captured_arg(arg),
            }
        }
    }

    /// Consumes all whitespace characters until the first non-whitespace character
    fn ws(&mut self) {
        let rest = &self.input_vec[self.input_vec_index..];
        let step = rest.iter().position(|&(_, _, c)| !c.is_whitespace()).unwrap_or(rest.len());
        self.input_vec_index += step;
    }

    /// Parses all of a string which is to be considered a "raw literal" in a
    /// format string. This is everything outside of the braces.
    fn string(&mut self, start: usize) -> &'input str {
        while let Some((r, i, c)) = self.peek() {
            match c {
                '{' | '}' => {
                    return &self.input[start..i];
                }
                '\n' if self.is_source_literal => {
                    self.input_vec_index += 1;
                    self.line_spans.push(self.cur_line_start..r.start);
                    self.cur_line_start = r.end;
                }
                _ => {
                    self.input_vec_index += 1;
                    if self.is_source_literal && r.start == self.cur_line_start && c.is_whitespace()
                    {
                        self.cur_line_start = r.end;
                    }
                }
            }
        }
        &self.input[start..]
    }

    /// Parses an `Argument` structure, or what's contained within braces inside the format string.
    fn argument(&mut self) -> Argument<'input> {
        let start_idx = self.input_vec_index;

        let position = self.position();
        self.ws();

        let end_idx = self.input_vec_index;

        let format = match self.mode {
            ParseMode::Format => self.format(),
            ParseMode::InlineAsm => self.inline_asm(),
            ParseMode::Diagnostic => self.diagnostic(),
        };

        // Resolve position after parsing format spec.
        let position = position.unwrap_or_else(|| {
            let i = self.curarg;
            self.curarg += 1;
            ArgumentImplicitlyIs(i)
        });

        let position_span =
            self.input_vec_index2range(start_idx).start..self.input_vec_index2range(end_idx).start;
        Argument { position, position_span, format }
    }

    /// Parses a positional argument for a format. This could either be an
    /// integer index of an argument, a named argument, or a blank string.
    /// Returns `Some(parsed_position)` if the position is not implicitly
    /// consuming a macro argument, `None` if it's the case.
    fn position(&mut self) -> Option<Position<'input>> {
        if let Some(i) = self.integer() {
            Some(ArgumentIs(i.into()))
        } else {
            match self.peek() {
                Some((range, _, c)) if rustc_lexer::is_id_start(c) => {
                    let start = range.start;
                    let word = self.word();

                    // Recover from `r#ident` in format strings.
                    if word == "r"
                        && let Some((r, _, '#')) = self.peek()
                        && self.peek_ahead().is_some_and(|(_, _, c)| rustc_lexer::is_id_start(c))
                    {
                        self.input_vec_index += 1;
                        let prefix_end = r.end;
                        let word = self.word();
                        let prefix_span = start..prefix_end;
                        let full_span =
                            start..self.input_vec_index2range(self.input_vec_index).start;
                        self.errors.insert(0, ParseError {
                                    description: "raw identifiers are not supported".to_owned(),
                                    note: Some("identifiers in format strings can be keywords and don't need to be prefixed with `r#`".to_string()),
                                    label: "raw identifier used here".to_owned(),
                                    span: full_span,
                                    secondary_label: None,
                                    suggestion: Suggestion::RemoveRawIdent(prefix_span),
                                });
                        return Some(ArgumentNamed(word));
                    }

                    Some(ArgumentNamed(word))
                }
                // This is an `ArgumentNext`.
                // Record the fact and do the resolution after parsing the
                // format spec, to make things like `{:.*}` work.
                _ => None,
            }
        }
    }

    fn input_vec_index2pos(&self, index: usize) -> usize {
        if let Some((_, pos, _)) = self.input_vec.get(index) { *pos } else { self.input.len() }
    }

    fn input_vec_index2range(&self, index: usize) -> Range<usize> {
        if let Some((r, _, _)) = self.input_vec.get(index) {
            r.clone()
        } else {
            self.end_of_snippet..self.end_of_snippet
        }
    }

    /// Parses a format specifier at the current position, returning all of the
    /// relevant information in the `FormatSpec` struct.
    fn format(&mut self) -> FormatSpec<'input> {
        let mut spec = FormatSpec::default();

        if !self.consume(':') {
            return spec;
        }

        // fill character
        if let (Some((r, _, c)), Some((_, _, '>' | '<' | '^'))) = (self.peek(), self.peek_ahead()) {
            self.input_vec_index += 1;
            spec.fill = Some(c);
            spec.fill_span = Some(r);
        }
        // Alignment
        if self.consume('<') {
            spec.align = AlignLeft;
        } else if self.consume('>') {
            spec.align = AlignRight;
        } else if self.consume('^') {
            spec.align = AlignCenter;
        }
        // Sign flags
        if self.consume('+') {
            spec.sign = Some(Sign::Plus);
        } else if self.consume('-') {
            spec.sign = Some(Sign::Minus);
        }
        // Alternate marker
        if self.consume('#') {
            spec.alternate = true;
        }
        // Width and precision
        let mut havewidth = false;

        if let Some((range, _)) = self.consume_pos('0') {
            // small ambiguity with '0$' as a format string. In theory this is a
            // '0' flag and then an ill-formatted format string with just a '$'
            // and no count, but this is better if we instead interpret this as
            // no '0' flag and '0$' as the width instead.
            if let Some((r, _)) = self.consume_pos('$') {
                spec.width = CountIsParam(0);
                spec.width_span = Some(range.start..r.end);
                havewidth = true;
            } else {
                spec.zero_pad = true;
            }
        }

        if !havewidth {
            let start_idx = self.input_vec_index;
            spec.width = self.count();
            if spec.width != CountImplied {
                let end = self.input_vec_index2range(self.input_vec_index).start;
                spec.width_span = Some(self.input_vec_index2range(start_idx).start..end);
            }
        }

        if let Some((range, _)) = self.consume_pos('.') {
            if self.consume('*') {
                // Resolve `CountIsNextParam`.
                // We can do this immediately as `position` is resolved later.
                let i = self.curarg;
                self.curarg += 1;
                spec.precision = CountIsStar(i);
            } else {
                spec.precision = self.count();
            }
            spec.precision_span =
                Some(range.start..self.input_vec_index2range(self.input_vec_index).start);
        }

        let start_idx = self.input_vec_index;
        // Optional radix followed by the actual format specifier
        if self.consume('x') {
            if self.consume('?') {
                spec.debug_hex = Some(DebugHex::Lower);
                spec.ty = "?";
            } else {
                spec.ty = "x";
            }
        } else if self.consume('X') {
            if self.consume('?') {
                spec.debug_hex = Some(DebugHex::Upper);
                spec.ty = "?";
            } else {
                spec.ty = "X";
            }
        } else if let Some((range, _)) = self.consume_pos('?') {
            spec.ty = "?";
            if let Some((r, _, c @ ('#' | 'x' | 'X'))) = self.peek() {
                self.errors.insert(
                    0,
                    ParseError {
                        description: format!("expected `}}`, found `{c}`"),
                        note: None,
                        label: "expected `'}'`".into(),
                        span: r.clone(),
                        secondary_label: None,
                        suggestion: Suggestion::ReorderFormatParameter(
                            range.start..r.end,
                            format!("{c}?"),
                        ),
                    },
                );
            }
        } else {
            spec.ty = self.word();
            if !spec.ty.is_empty() {
                let start = self.input_vec_index2range(start_idx).start;
                let end = self.input_vec_index2range(self.input_vec_index).start;
                spec.ty_span = Some(start..end);
            }
        }
        spec
    }

    /// Parses an inline assembly template modifier at the current position, returning the modifier
    /// in the `ty` field of the `FormatSpec` struct.
    fn inline_asm(&mut self) -> FormatSpec<'input> {
        let mut spec = FormatSpec::default();

        if !self.consume(':') {
            return spec;
        }

        let start_idx = self.input_vec_index;
        spec.ty = self.word();
        if !spec.ty.is_empty() {
            let start = self.input_vec_index2range(start_idx).start;
            let end = self.input_vec_index2range(self.input_vec_index).start;
            spec.ty_span = Some(start..end);
        }

        spec
    }

    /// Always returns an empty `FormatSpec`
    fn diagnostic(&mut self) -> FormatSpec<'input> {
        let mut spec = FormatSpec::default();

        let Some((Range { start, .. }, start_idx)) = self.consume_pos(':') else {
            return spec;
        };

        spec.ty = self.string(start_idx);
        spec.ty_span = {
            let end = self.input_vec_index2range(self.input_vec_index).start;
            Some(start..end)
        };
        spec
    }

    /// Parses a `Count` parameter at the current position. This does not check
    /// for 'CountIsNextParam' because that is only used in precision, not
    /// width.
    fn count(&mut self) -> Count<'input> {
        if let Some(i) = self.integer() {
            if self.consume('$') { CountIsParam(i.into()) } else { CountIs(i) }
        } else {
            let start_idx = self.input_vec_index;
            let word = self.word();
            if word.is_empty() {
                CountImplied
            } else if let Some((r, _)) = self.consume_pos('$') {
                CountIsName(word, self.input_vec_index2range(start_idx).start..r.start)
            } else {
                self.input_vec_index = start_idx;
                CountImplied
            }
        }
    }

    /// Parses a word starting at the current position. A word is the same as a
    /// Rust identifier, except that it can't start with `_` character.
    fn word(&mut self) -> &'input str {
        let index = self.input_vec_index;
        match self.peek() {
            Some((ref r, i, c)) if rustc_lexer::is_id_start(c) => {
                self.input_vec_index += 1;
                (r.start, i)
            }
            _ => {
                return "";
            }
        };
        let (err_end, end): (usize, usize) = loop {
            if let Some((ref r, i, c)) = self.peek() {
                if rustc_lexer::is_id_continue(c) {
                    self.input_vec_index += 1;
                } else {
                    break (r.start, i);
                }
            } else {
                break (self.end_of_snippet, self.input.len());
            }
        };

        let word = &self.input[self.input_vec_index2pos(index)..end];
        if word == "_" {
            self.errors.push(ParseError {
                description: "invalid argument name `_`".into(),
                note: Some("argument name cannot be a single underscore".into()),
                label: "invalid argument name".into(),
                span: self.input_vec_index2range(index).start..err_end,
                secondary_label: None,
                suggestion: Suggestion::None,
            });
        }
        word
    }

    fn integer(&mut self) -> Option<u16> {
        let mut cur: u16 = 0;
        let mut found = false;
        let mut overflow = false;
        let start_index = self.input_vec_index;
        while let Some((_, _, c)) = self.peek() {
            if let Some(i) = c.to_digit(10) {
                self.input_vec_index += 1;
                let (tmp, mul_overflow) = cur.overflowing_mul(10);
                let (tmp, add_overflow) = tmp.overflowing_add(i as u16);
                if mul_overflow || add_overflow {
                    overflow = true;
                }
                cur = tmp;
                found = true;
            } else {
                break;
            }
        }

        if overflow {
            let overflowed_int = &self.input[self.input_vec_index2pos(start_index)
                ..self.input_vec_index2pos(self.input_vec_index)];
            self.errors.push(ParseError {
                description: format!(
                    "integer `{}` does not fit into the type `u16` whose range is `0..={}`",
                    overflowed_int,
                    u16::MAX
                ),
                note: None,
                label: "integer out of range for `u16`".into(),
                span: self.input_vec_index2range(start_index).start
                    ..self.input_vec_index2range(self.input_vec_index).end,
                secondary_label: None,
                suggestion: Suggestion::None,
            });
        }

        found.then_some(cur)
    }

    fn suggest_format_debug(&mut self) {
        if let (Some((range, _)), Some(_)) = (self.consume_pos('?'), self.consume_pos(':')) {
            let word = self.word();
            self.errors.insert(
                0,
                ParseError {
                    description: "expected format parameter to occur after `:`".to_owned(),
                    note: Some(format!("`?` comes after `:`, try `{}:{}` instead", word, "?")),
                    label: "expected `?` to occur after `:`".to_owned(),
                    span: range,
                    secondary_label: None,
                    suggestion: Suggestion::None,
                },
            );
        }
    }

    fn suggest_format_align(&mut self, alignment: char) {
        if let Some((range, _)) = self.consume_pos(alignment) {
            self.errors.insert(
                0,
                ParseError {
                    description:
                        "expected alignment specifier after `:` in format string; example: `{:>?}`"
                            .to_owned(),
                    note: None,
                    label: format!("expected `{}` to occur after `:`", alignment),
                    span: range,
                    secondary_label: None,
                    suggestion: Suggestion::None,
                },
            );
        }
    }

    fn suggest_positional_arg_instead_of_captured_arg(&mut self, arg: &Argument<'_>) {
        // If the argument is not an identifier, it is not a field access.
        if !arg.is_identifier() {
            return;
        }

        if let Some((_range, _pos)) = self.consume_pos('.') {
            let field = self.argument();
            // We can only parse simple `foo.bar` field access or `foo.0` tuple index access, any
            // deeper nesting, or another type of expression, like method calls, are not supported
            if !self.consume('}') {
                return;
            }
            if let ArgumentNamed(_) = arg.position {
                match field.position {
                    ArgumentNamed(_) => {
                        self.errors.insert(
                            0,
                            ParseError {
                                description: "field access isn't supported".to_string(),
                                note: None,
                                label: "not supported".to_string(),
                                span: arg.position_span.start..field.position_span.end,
                                secondary_label: None,
                                suggestion: Suggestion::UsePositional,
                            },
                        );
                    }
                    ArgumentIs(_) => {
                        self.errors.insert(
                            0,
                            ParseError {
                                description: "tuple index access isn't supported".to_string(),
                                note: None,
                                label: "not supported".to_string(),
                                span: arg.position_span.start..field.position_span.end,
                                secondary_label: None,
                                suggestion: Suggestion::UsePositional,
                            },
                        );
                    }
                    _ => {}
                };
            }
        }
    }
}

// Assert a reasonable size for `Piece`
#[cfg(all(test, target_pointer_width = "64"))]
rustc_index::static_assert_size!(Piece<'_>, 16);

#[cfg(test)]
mod tests;
