You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: translate.rs
    path of file: ./repos/rust-peg/peg-macros
    
    the code of the file until where you have to start completion: use proc_macro2::{Group, Ident, Literal, Span, TokenStream, TokenTree};
use std::collections::{HashMap, HashSet};

use quote::{format_ident, quote, quote_spanned};

pub use self::Expr::*;
use crate::analysis;
use crate::ast::*;

pub fn report_error(span: Span, msg: String) -> TokenStream {
    quote_spanned!(span=>compile_error!(#msg);)
}

pub fn report_error_expr(span: Span, msg: String) -> TokenStream {
    // panic!() to avoid "Mismatched types" error
    quote_spanned!(span=> { compile_error!(#msg); panic!() })
}

/// Test if the group begins with a specific marker character, and if so, return the remaining tokens.
fn group_check_prefix(group: &Group, prefix: char) -> Option<TokenStream> {
    let mut iter = group.stream().into_iter();
    match iter.next() {
        Some(TokenTree::Punct(p)) if p.as_char() == prefix => Some(iter.collect()),
        _ => None,
    }
}

fn extra_args_def(grammar: &Grammar) -> TokenStream {
    let args: Vec<TokenStream> = grammar
        .args
        .iter()
        .map(|&(ref name, ref tp)| quote!(, #name: #tp))
        .collect();
    quote!(#(#args)*)
}

fn extra_args_call(grammar: &Grammar) -> TokenStream {
    let args: Vec<TokenStream> = grammar
        .args
        .iter()
        .map(|&(ref name, _)| quote!(, #name))
        .collect();
    quote!(#(#args)*)
}

#[derive(Clone)]
struct Context<'a> {
    rules: &'a HashMap<String, &'a Rule>,
    rules_from_args: HashSet<String>,
    grammar_lifetime_params: &'a [TokenStream],
    input_ty: TokenStream,
    parse_state_ty: TokenStream,
    extra_args_call: TokenStream,
    extra_args_def: TokenStream,
}

pub(crate) fn compile_grammar(grammar: &Grammar) -> TokenStream {
    let analysis = analysis::check(grammar);

    let grammar_lifetime_params = ty_params_slice(&grammar.lifetime_params);

    let context = &Context {
        rules: &analysis.rules,
        rules_from_args: HashSet::new(),
        grammar_lifetime_params,
        input_ty: quote!(&'input Input<#(#grammar_lifetime_params),*>),
        parse_state_ty: quote!(&mut ParseState<'input #(, #grammar_lifetime_params)*>),
        extra_args_call: extra_args_call(grammar),
        extra_args_def: extra_args_def(grammar),
    };

    let mut seen_rule_names = HashSet::new();

    let mut items = vec![];
    for item in &grammar.items {
        match item {
            Item::Use(tt) => items.push(tt.clone()),
            Item::Rule(rule
    
fn compile_rule(context: &Context, rule: &Rule) -> TokenStream {
    let span = rule.span.resolved_at(Span::mixed_site());
    let name = format_ident!("__parse_{}", rule.name, span = span);
    let ret_ty = rule.ret_type.clone().unwrap_or_else(|| quote!(()));
    let ty_params = ty_params_slice(&rule.ty_params);

    let Context {
        input_ty,
        parse_state_ty,
        grammar_lifetime_params,
        extra_args_def,
        ..
    } = context;

    let mut context = context.clone();
    context
        .rules_from_args
        .extend(rule.params.iter().map(|param| param.name.to_string()));

    let body = compile_expr(&context, &rule.expr, rule.ret_type.is_some());

    let wrapped_body = if cfg!(feature = "trace") {
        let str_rule_name = rule.name.to_string();
        quote_spanned! { span => {
            let loc = ::peg::Parse::position_repr(__input, __pos);
            println!("[PEG_TRACE] Attempting to match rule `{}` at {}", #str_rule_name, loc);
            let __peg_result: ::peg::RuleResult<#ret_ty> = {#body};
            match __peg_result {
                ::peg::RuleResult::Matched(epos, _) => {
                    let eloc = ::peg::Parse::position_repr(__input, epos);
                    println!("[PEG_TRACE] Matched rule `{}` at {} to {}", #str_rule_name, loc, eloc);
                }
                ::peg::RuleResult::Failed => {
                    println!("[PEG_TRACE] Failed to match rule `{}` at {}", #str_rule_name, loc);
                }
            }

            __peg_result
        }}
    } else {
        body
    };

    let rule_params = rule_params_list(&context, rule);

    let fn_body = match &rule.cache {
        None => wrapped_body,
        Some(cache_type) => {
            let cache_field = format_ident!("{}_cache", rule.name);

            let cache_trace = if cfg!(feature = "trace") {
                let str_rule_name = rule.name.to_string();
                quote_spanned! { span =>
                    let loc = ::peg::Parse::position_repr(__input, __pos);
                    match &entry {
                        &::peg::RuleResult::Matched(..) => println!("[PEG_TRACE] Cached match of rule {} at {}", #str_rule_name, loc),
                        &Failed => println!("[PEG_TRACE] Cached fail of rule {} at {}", #str_rule_name, loc),
                    };
                }
            } else {
                quote!()
            };

            match cache_type {
                Cache::Simple => quote_spanned! { span =>
                    if let Some(entry) = __state.#cache_field.get(&__pos) {
                        #cache_trace
                        return entry.clone();
                    }

                    let __rule_result = #wrapped_body;
                    __state.#cache_field.insert(__pos, __rule_result.clone());
                    __rule_result
                },
                Cache::Recursive =>
                // `#[cache_left_rec] support for recursive rules using the technique described here:
                // <https://medium.com/@gvanrossum_83706/left-recursive-peg-grammars-65dab3c580e1>
                {
                    quote_spanned! { span =>
                        if let Some(entry) = __state.#cache_field.get(&__pos) {
                            #cache_trace
                            return entry.clone();
                        }

                        __state.#cache_field.insert(__pos, ::peg::RuleResult::Failed);
                        let mut __last_result = ::peg::RuleResult::Failed;
                        loop {
                            let __current_result = { #wrapped_body };
                            match __current_result {
                                ::peg::RuleResult::Failed => break,
                                ::peg::RuleResult::Matched(__current_endpos, _) =>
                                    match __last_result {
                                        ::peg::RuleResult::Matched(__last_endpos, _) if __current_endpos <= __last_endpos => break,
                                        _ => {
                                            __state.#cache_field.insert(__pos, __current_result.clone());
                                            __last_result = __current_result;
                                        },
                                    }
                            }
                        }

                        return __last_result;
                    }
                }
            }
        }
    };

    quote_spanned! { span =>
        fn #name<'input #(, #grammar_lifetime_params)* #(, #ty_params)*>(__input: #input_ty, __state: #parse_state_ty, __err_state: &mut ::peg::error::ErrorState, __pos: usize #extra_args_def #(, #rule_params)*) -> ::peg::RuleResult<#ret_ty> {
            #![allow(non_snake_case, unused, clippy::redundant_closure_call)]
            #fn_body
        }
    }
}