package {{ doc.package }};

{% for f in cls.all_fields -%}
{% if f.range.startswith('BigDecimal') %}
import java.math.BigDecimal;{% endif -%}
{% if f.range.startswith('Instant') %}
import java.time.Instant;{% endif -%}
{% if f.range.startswith('LocalDate') %}
import java.time.LocalDate;{% endif -%}
{% if f.range.startswith('ZonedDateTime') %}
import java.time.ZonedDateTime;{% endif -%}
{% if f.range.startswith('List') %}
import java.util.List;{% endif -%}
{%- endfor %}
{% if not cls.mixin -%}
import java.util.Objects;{%- endif %}

{% if cls.description -%}
/**
 * {{ cls.description }}
 */{% endif %}
{% if cls.mixin -%}
public interface {{ cls.name }} {
{% for f in cls.all_fields %}
    public {{f.range}} {{ f.name }}();

{%- endfor %}
}
{% else -%}
public record {{ cls.name }}({% for f in cls.all_fields -%}
    {{f.range}} {{ f.name }}{{ ", " if not loop.last else "" }}
{%- endfor %}){{ " implements" if cls.mixins else "" }} {% for f in cls.mixins -%}
    {{ f }}{{ ", " if not loop.last else "" }}
{%- endfor %} {

    public static Builder builder() {
        return new Builder();
    }

    public static class Builder {
{% for f in cls.all_fields %}
        private {{ f.range }} {{ f.name }} = {{ f.default_value }};
{%- endfor %}
{% for f in cls.all_fields %}

        public Builder {{ f.name }}({{ f.range }} {{ f.name }}) {
            this.{{ f.name }} = Objects.requireNonNull({{ f.name }});
            return this;
        }
{%- endfor %}

    public {{ cls.name }} build() {
            return new {{ cls.name }}(
               {%- for f in cls.all_fields -%}
               {{ f.name }}{{ ", " if not loop.last else "" }}
               {%- endfor -%}
            );
        }
    }
}
{% endif -%}
