use crate::google::protobuf::descriptor::FieldDescriptorProto;
use crate::google::protobuf::descriptor::DescriptorProto;

pub fn map_type_to_rust_accessor(
    field_type: i32,
    label: i32,
    is_map: bool,
) -> (String, String, String) {
    if label == 3 {
        // LABEL_REPEATED
        let iterator_type = if is_map {
            "roto_runtime::MapFieldIterator<'a>"
        } else {
            "roto_runtime::RepeatedFieldIterator<'a>"
        };
        return (
            iterator_type.to_string(),
            "".to_string(), // Not used for repeated fields in the same way
            "".to_string(), // Not used for repeated fields
        );
    }

    match field_type {
        9 => (
            "&'a str".to_string(),
            "core::str::from_utf8(bytes).map_err(|_| roto_runtime::RotoError::WireFormatViolation)".to_string(),
            "\"\"".to_string(),
        ), // TYPE_STRING
        1 => (
            "f64".to_string(),
            "Ok(f64::from_le_bytes(bytes.try_into().map_err(|_| roto_runtime::RotoError::WireFormatViolation)?))".to_string(),
            "0.0".to_string(),
        ), // TYPE_DOUBLE
        2 => (
            "f32".to_string(),
            "Ok(f32::from_le_bytes(bytes.try_into().map_err(|_| roto_runtime::RotoError::WireFormatViolation)?))".to_string(),
            "0.0".to_string(),
        ), // TYPE_FLOAT
        3 | 5 | 15 | 17 => (
            "i32".to_string(),
            "roto_runtime::read_varint(bytes).map(|(v, _)| v as i32).map_err(|_| roto_runtime::RotoError::WireFormatViolation)".to_string(),
            "0".to_string(),
        ), // INT/SINT/SFIXED 32
        4 | 6 | 13 => (
            "u32".to_string(),
            "roto_runtime::read_varint(bytes).map(|(v, _)| v as u32).map_err(|_| roto_runtime::RotoError::WireFormatViolation)".to_string(),
            "0".to_string(),
        ), // UINT/FIXED 32
        16 | 18 => (
            "i64".to_string(),
            "roto_runtime::read_varint(bytes).map(|(v, _)| v as i64).map_err(|_| roto_runtime::RotoError::WireFormatViolation)".to_string(),
            "0".to_string(),
        ), // SINT/SFIXED 64
        7 | 14 => (
            "u64".to_string(),
            "roto_runtime::read_varint(bytes).map(|(v, _)| v as u64).map_err(|_| roto_runtime::RotoError::WireFormatViolation)".to_string(),
            "0".to_string(),
        ), // UINT/FIXED 64
        8 => (
            "bool".to_string(),
            "roto_runtime::read_varint(bytes).map(|(v, _)| v != 0).map_err(|_| roto_runtime::RotoError::WireFormatViolation)".to_string(),
            "false".to_string(),
        ), // TYPE_BOOL
        11 | 12 => (
            "&'a [u8]".to_string(),
            "Ok(bytes)".to_string(),
            "&[]".to_string(),
        ), // MESSAGE/BYTES
        _ => (
            "&'a [u8]".to_string(),
            "Ok(bytes)".to_string(),
            "&[]".to_string(),
        ),
    }
}
EOF > /opt/workspace/codegen/src/generator/types.rs
use crate::google::protobuf::descriptor::FieldDescriptorProto;
use crate::google::protobuf::descriptor::DescriptorProto;

pub fn map_type_to_rust_accessor(
    field_type: i32,
    label: i32,
    is_map: bool,
) -> (String, String, String) {
    if label == 3 {
        // LABEL_REPEATED
        let iterator_type = if is_map {
            "roto_runtime::MapFieldIterator<'a>"
        } else {
            "roto_runtime::RepeatedFieldIterator<'a>"
        };
        return (
            iterator_type.to_string(),
            "".to_string(), // Not used for repeated fields in the same way
            "".to_string(), // Not used for repeated fields
        );
    }

    match field_type {
        9 => (
            "&'a str".to_string(),
            "core::str::from_utf8(bytes).map_err(|_| roto_runtime::RotoError::WireFormatViolation)".to_string(),
            "\"\"".to_string(),
        ), // TYPE_STRING
        1 => (
            "f64".to_string(),
            "Ok(f64::from_le_bytes(bytes.try_into().map_err(|_| roto_runtime::RotoError::WireFormatViolation)?))".to_string(),
            "0.0".to_string(),
        ), // TYPE_DOUBLE
        2 => (
            "f32".to_string(),
            "Ok(f32::from_le_bytes(bytes.try_into().map_err(|_| roto_runtime::RotoError::WireFormatViolation)?))".to_string(),
            "0.0".to_string(),
        ), // TYPE_FLOAT
        3 | 5 | 15 | 17 => (
            "i32".to_string(),
            "roto_runtime::read_varint(bytes).map(|(v, _)| v as i32).map_err(|_| roto_runtime::RotoError::WireFormatViolation)".to_string(),
            "0".to_string(),
        ), // INT/SINT/SFIXED 32
        4 | 6 | 13 => (
            "u32".to_string(),
            "roto_runtime::read_varint(bytes).map(|(v, _)| v as u32).map_err(|_| roto_runtime::RotoError::WireFormatViolation)".to_string(),
            "0".to_string(),
        ), // UINT/FIXED 32
        16 | 18 => (
            "i64".to_string(),
            "roto_runtime::read_varint(bytes).map(|(v, _)| v as i64).map_err(|_| roto_runtime::RotoError::WireFormatViolation)".to_string(),
            "0".to_string(),
        ), // SINT/SFIXED 64
        7 | 14 => (
            "u64".to_string(),
            "roto_runtime::read_varint(bytes).map(|(v, _)| v as u64).map_err(|_| roto_runtime::RotoError::WireFormatViolation)".to_string(),
            "0".to_string(),
        ), // UINT/FIXED 64
        8 => (
            "bool".to_string(),
            "roto_runtime::read_varint(bytes).map(|(v, _)| v != 0).map_err(|_| roto_runtime::RotoError::WireFormatViolation)".to_string(),
            "false".to_string(),
        ), // TYPE_BOOL
        11 | 12 => (
            "&'a [u8]".to_string(),
            "Ok(bytes)".to_string(),
            "&[]".to_string(),
        ), // MESSAGE/BYTES
        _ => (
            "&'a [u8]".to_string(),
            "Ok(bytes)".to_string(),
            "&[]".to_string(),
        ),
    }
}
