use crate::CompilerState;
use leo_ast::{Function, Program, ProgramId, Variant};
use leo_span::Symbol;
use indexmap::{IndexMap, IndexSet};
pub struct CodeGeneratingVisitor<'a> {
pub state: &'a CompilerState,
pub next_register: u64,
pub current_function: Option<&'a Function>,
pub variable_mapping: IndexMap<Symbol, String>,
pub composite_mapping: IndexMap<Symbol, (bool, String)>,
pub global_mapping: IndexMap<Symbol, String>,
pub variant: Option<Variant>,
pub program: &'a Program,
pub program_id: Option<ProgramId>,
pub finalize_caller: Option<Symbol>,
pub next_label: u64,
pub conditional_depth: u64,
pub internal_record_inputs: IndexSet<String>,
}
impl CodeGeneratingVisitor<'_> {
pub(crate) fn next_register(&mut self) -> String {
self.next_register += 1;
format!("r{}", self.next_register - 1)
}
pub(crate) fn legalize_struct_name(input: String) -> String {
Self::transform_generic_struct_name(&input).unwrap_or(input)
}
fn transform_generic_struct_name(input: &str) -> Option<String> {
use base62::encode;
use regex::Regex;
use sha2::{Digest, Sha256};
let re = Regex::new(r#"^([a-zA-Z_][\w]*)::\[(.*?)\]$"#).unwrap();
let captures = re.captures(input)?;
let ident = captures.get(1)?.as_str();
let mut hasher = Sha256::new();
hasher.update(input.as_bytes());
let hash = hasher.finalize();
let hash_prefix = &hash[..8]; let hash_number = u64::from_be_bytes([
hash_prefix[0],
hash_prefix[1],
hash_prefix[2],
hash_prefix[3],
hash_prefix[4],
hash_prefix[5],
hash_prefix[6],
hash_prefix[7],
]);
let hash_base62 = encode(hash_number);
let fixed_suffix_len = 2 + hash_base62.len(); let max_ident_len = 31 - fixed_suffix_len;
Some(format!("{ident:.max_ident_len$}__{hash_base62}"))
}
}