//! 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),
    /// Add missing colon:
    /// `format!("{foo?}")` -> `format!("{foo:?}")`
    AddMissingColon(Range<usize>),
    /// Use Rust format string:
    /// `format!("{x=}")` -> `dbg!(x)`
    UseRustDebugPrintingMacro,
}

/// 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

                // validate snippet because a proc macro may have
                // respanned it to something completely different (fixes #114865)
                let prefix_len = nr_hashes + 2; // r + hashes + opening "
                let suffix_len = nr_hashes + 1; // closing " + hashes
                let snippet_bytes = snippet.as_bytes();
                let content_end = snippet.len() - suffix_len;
                if snippet.len() >= prefix_len + suffix_len // is sufficiently long
                    && snippet_bytes[0] == b'r'
                    && snippet_bytes[1..1 + nr_hashes].iter().all(|&c| c == b'#')
                    && snippet_bytes[1 + nr_hashes] == b'"'
                    && snippet_bytes[content_end] == b'"'
                    && snippet_bytes[content_end + 1..].iter().all(|&c| c == b'#')
                {
                    let snippet_without_quotes = &snippet[prefix_len..content_end];
                    let input_without_newline =
                        if appended_newline { &input[..input.len() - 1] } else { input };
                    if snippet_without_quotes == input_without_newline {
                        (true, snippet.len() - suffix_len, vec![])
                    } else {
                        (false, snippet.len(), vec![])
                    }
                } else {
                    (false, snippet.len(), 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 snippet_without_quotes = &snippet[1..snippet.len() - 1];
                    let (mut ok, mut vec) = (true, vec![]);
                    let mut chars = input.chars();
                    rustc_literal_escaper::unescape_str(snippet_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)), Some((_, _, nc))) = (self.peek(), self.peek_ahead()) {
            match (c, nc) {
                ('?', '}') => self.missing_colon_before_debug_formatter(),
                ('?', _) => self.suggest_format_debug(),
                ('<' | '^' | '>', _) => self.suggest_format_align(c),
                (',', _) => self.suggest_unsupported_python_numeric_grouping(),
                ('=', '}') => self.suggest_rust_debug_printing_macro(),
                _ => 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 or keyword, except that it can't be a bare `_` 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 missing_colon_before_debug_formatter(&mut self) {
        if let Some((range, _)) = self.consume_pos('?') {
            let span = range.clone();
            self.errors.insert(
                0,
                ParseError {
                    description: "expected `}`, found `?`".to_owned(),
                    note: Some(format!("to print `{{`, you can escape it using `{{{{`",)),
                    label: "expected `:` before `?` to format with `Debug`".to_owned(),
                    span: range,
                    secondary_label: None,
                    suggestion: Suggestion::AddMissingColon(span),
                },
            );
        }
    }

    fn suggest_rust_debug_printing_macro(&mut self) {
        if let Some((range, _)) = self.consume_pos('=') {
            self.errors.insert(
                0,
                ParseError {
                    description:
                        "python's f-string debug `=` is not supported in rust, use `dbg(x)` instead"
                            .to_owned(),
                    note: Some(format!("to print `{{`, you can escape it using `{{{{`",)),
                    label: "expected `}`".to_owned(),
                    span: range,
                    secondary_label: self
                        .last_open_brace
                        .clone()
                        .map(|sp| ("because of this opening brace".to_owned(), sp)),
                    suggestion: Suggestion::UseRustDebugPrintingMacro,
                },
            );
        }
    }

    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: Some(
                                    "consider moving this expression to a local variable and then \
                                     using the local here instead"
                                        .to_owned(),
                                ),
                                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: Some(
                                    "consider moving this expression to a local variable and then \
                                     using the local here instead"
                                        .to_owned(),
                                ),
                                label: "not supported".to_string(),
                                span: arg.position_span.start..field.position_span.end,
                                secondary_label: None,
                                suggestion: Suggestion::UsePositional,
                            },
                        );
                    }
                    _ => {}
                };
            }
        }
    }

    fn suggest_unsupported_python_numeric_grouping(&mut self) {
        if let Some((range, _)) = self.consume_pos(',') {
            self.errors.insert(
                0,
                ParseError {
                    description:
                        "python's numeric grouping `,` is not supported in rust format strings"
                            .to_owned(),
                    note: Some(format!("to print `{{`, you can escape it using `{{{{`",)),
                    label: "expected `}`".to_owned(),
                    span: range,
                    secondary_label: self
                        .last_open_brace
                        .clone()
                        .map(|sp| ("because of this opening brace".to_owned(), sp)),
                    suggestion: Suggestion::None,
                },
            );
        }
    }
}

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

#[cfg(test)]
mod tests;
