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: error.rs
    path of file: ./repos/anchor/lang/syn/src/parser
    
    the code of the file until where you have to start completion: use crate::{Error, ErrorArgs, ErrorCode};
use syn::parse::{Parse, Result as ParseResult};
use syn::Expr;

// Removes any internal #[msg] attributes, as they are inert.
pub fn parse(error_enum: &mut syn::ItemEnum, args: Option<ErrorArgs>) -> Error {
    let ident = error_enum.ident.clone();
    let mut last_discriminant = 0;
    let codes: Vec<ErrorCode> = error_enum
        .variants
        .iter_mut()
        .map(|variant: &mut syn::Variant| {
 
    
fn parse_error_attribute(variant: &syn::Variant) -> Option<String> {
    let attrs = variant
        .attrs
        .iter()
        .filter(|attr| attr.path.segments[0].ident != "doc")
        .collect::<Vec<_>>();
    match attrs.len() {
        0 => None,
        1 => {
            let attr = &attrs[0];
            let attr_str = attr.path.segments[0].ident.to_string();
            assert!(&attr_str == "msg", "Use msg to specify error strings");

            let mut tts = attr.tokens.clone().into_iter();
            let g_stream = match tts.next().expect("Must have a token group") {
                proc_macro2::TokenTree::Group(g) => g.stream(),
                _ => panic!("Invalid syntax"),
            };

            let msg = match g_stream.into_iter().next() {
                None => panic!("Must specify a message string"),
                Some(msg) => msg.to_string().replace('\"', ""),
            };

            Some(msg)
        }
        _ => {
            panic!("Too many attributes found. Use `msg` to specify error strings");
        }
    }
}