{{~if __namespace_with_top_module != ''~}}
package {{__namespace_with_top_module}};
{{~end~}}

import luban.*;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;

{{~
    parent_def_type = __this.parent_def_type
    export_fields = __this.export_fields
    hierarchy_export_fields = __this.hierarchy_export_fields
~}}

{{~if __this.comment != '' ~}}
/**
 * {{escape_comment __this.comment}}
 */
{{~end~}}
public {{class_modifier __this}} class {{__name}} extends {{if parent_def_type}}{{__this.parent_def_type.full_name_with_top_module}}{{else}}AbstractBean{{end}} {
    public {{__name}}(JsonObject _buf) { 
        {{~if parent_def_type~}}
        super(_buf);
        {{~end~}}
        {{~ for field in export_fields ~}}
        {{deserialize_field (format_field_name __code_style field.name) '_buf' field.name field.ctype}}
        {{~end~}}
    }

    public static {{__name}} deserialize(JsonObject _buf) {
        {{~if __this.is_abstract_type~}}
        switch (_buf.get("$type").getAsString()) {
        {{~for child in __this.hierarchy_not_abstract_children~}}
            case "{{impl_data_type child __this}}": return new {{child.full_name_with_top_module}}(_buf);
        {{~end~}}
            default: throw new SerializationException();
        }
        {{~else~}}
            return new {{__this.full_name_with_top_module}}(_buf);
        {{~end~}}
    }

    {{~ for field in export_fields ~}}
{{~if field.comment != '' ~}}
    /**
     * {{escape_comment field.comment}}
     */
{{~end~}}
    public final {{declaring_type_name field.ctype}} {{format_field_name __code_style field.name}};
    {{~end~}}

{{~if !__this.is_abstract_type~}}
    public static final int __ID__ = {{__this.id}};
    
    @Override
    public int getTypeId() { return __ID__; }
{{~end~}}

    @Override
    public String toString() {
        return "{{full_name}}{ "
    {{~for field in hierarchy_export_fields ~}}
        + "{{format_field_name __code_style field.name}}:" + {{format_field_name __code_style field.name}} + ","
    {{~end~}}
        + "}";
    }
}
