extension ILType {
{%- for m in maps %}
    fileprivate static let {{m|format_il_type}}: ILType =
        .createJsMapType(
            ofKeyType: .{{m.key_kind|format_il_type(primitive_with_suffix=True)}},
            ofValueType: .{{m.value_kind|format_il_type(primitive_with_suffix=True)}}
        )
{%- endfor %}
}

{%- for m in maps %}
    {%- if loop.first %}

/// Generate a map with only one element. As Fuzzilli runs, the OperationMutator
/// and VariadicInputReducer will modify the `CreateMap` operation to increase
/// or decrease the element count.
///
/// `findOrGenerateType` is preferred over specifying `inputs` because
/// Fuzzilli only uses CodeGenerators to produce types in `inputs`, while
/// `findOrGenerateType` uses a variety of sources (e.g. `builtins`, other
/// method properties and methods). An input is specified (i.e. `.one`)
/// to prevent the CodeGenerator from being scheduled first when there are
/// no visible variables, as `findOrGenerateType` causes a crash if there
/// are no visibile variables.
    {%- endif %}
private let Mojo{{m|format_unique_name}}Generator = CodeGenerator(
    "Mojo{{m|format_unique_name}}Generator",
    inputs: .one,
    produces: [.{{m|format_il_type}}]
) { b, _, _ in
    let key = b.findOrGenerateType(.{{m.key_kind|format_il_type(primitive_with_suffix=True)}})
    let val = b.findOrGenerateType(.{{m.value_kind|format_il_type(primitive_with_suffix=True)}})
    var keys: [Variable] = [key]
    var values: [Variable] = [val]
{%- if m.value_kind.is_nullable %}

    // Currently, maps do not encode in anyway that their element is an optional
    // type. Since this map has an optional value type, pre-populate it with
    // elements, with a chance of loading undefined for each.
    for _ in 0..<10 {
       keys.append(b.randomVariable(forUseAs: .{{m.key_kind|format_il_type}}))
       if probability(0.5) {
           values.append(b.loadUndefined())
       } else {
           values.append(b.randomVariable(forUseAs: .{{m.value_kind|format_il_type}}))
       }
    }
{%- endif %}
    b.createMap(
        withKeys: keys,
        withValues: values,
        keyGroupName: ObjectGroup.
            {{- m.key_kind|format_unique_name(primitive_with_suffix=True)|to_camel(True) -}}
            .name,
        valueGroupName: ObjectGroup.
            {{- m.value_kind|format_unique_name(primitive_with_suffix=True)|to_camel(True) -}}
            .name
    )
}
{%- endfor %}
