//! 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, 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)), 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;
