{{ self::ts_doc_block(doc, "") }}export type {{ name }} =
{%- for variant in variants %}
{%- if variant.is_unit() %}
  | { readonly tag: "{{ variant.name }}" }
{%- else %}
  | { readonly tag: "{{ variant.name }}"; {% for field in variant.fields %}readonly {{ field.name }}: {{ field.ts_type }}{% if !loop.last %}; {% endif %}{% endfor %} }
{%- endif %}
{%- endfor %};

const {{ name }}Codec: WireCodec<{{ name }}> = {
  size: (v) => {
    switch (v.tag) {
{%- for variant in variants %}
      case "{{ variant.name }}": return {{ variant.size_expr() }};
{%- endfor %}
    }
  },
  encode: (writer, v) => {
    switch (v.tag) {
{%- for variant in variants %}
      case "{{ variant.name }}":
        writer.writeI32({{ loop.index0 }});
{%- for field in variant.fields %}
        {{ field.wire_encode_expr("writer", "v") }};
{%- endfor %}
        break;
{%- endfor %}
    }
  },
  decode: (reader) => {
    const tag = reader.readI32();
    switch (tag) {
{%- for variant in variants %}
      case {{ loop.index0 }}:
{%- if variant.is_unit() %}
        return { tag: "{{ variant.name }}" };
{%- else %}
        return { tag: "{{ variant.name }}", {% for field in variant.fields %}{{ field.name }}: {{ field.wire_decode_expr() }}{% if !loop.last %}, {% endif %}{% endfor %} };
{%- endif %}
{%- endfor %}
      default: throw new Error(`Unknown {{ name }} wire tag: ${tag}`);
    }
  },
};
