{{#models}}{{#model}}
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "{{classname}}.h"

{{#isEnum}}
char* OpenAPI_{{classname}}_ToString(OpenAPI_{{classVarName}}_e {{classname}})
{
    const char *{{classname}}Array[] =  { "NULL"{{#allowableValues}}{{#values}}, "{{.}}"{{/values}}{{/allowableValues}} };
    size_t sizeofArray = sizeof({{classname}}Array) / sizeof({{classname}}Array[0]);
    if ({{classname}} < sizeofArray)
        return (char *){{classname}}Array[{{classname}}];
    else
        return (char *)"Unknown";
}

OpenAPI_{{classVarName}}_e OpenAPI_{{classname}}_FromString(char* {{classname}})
{
    int stringToReturn = 0;
    const char *{{classname}}Array[] =  { "NULL"{{#allowableValues}}{{#values}}, "{{.}}"{{/values}}{{/allowableValues}} };
    size_t sizeofArray = sizeof({{classname}}Array) / sizeof({{classname}}Array[0]);
    while (stringToReturn < sizeofArray) {
        if (strcmp({{classname}}, {{classname}}Array[stringToReturn]) == 0) {
            return stringToReturn;
        }
        stringToReturn++;
    }
    return 0;
}
{{/isEnum}}
{{^isEnum}}
{{#vars}}
    {{^isContainer}}
        {{#isPrimitiveType}}
            {{#isEnum}}
char *OpenAPI_{{name}}{{classname}}_ToString(OpenAPI_{{classVarName}}_{{name}}_e {{name}})
{
    const char *{{name}}Array[] =  { "NULL"{{#allowableValues}}{{#values}}, "{{.}}"{{/values}}{{/allowableValues}} };
    size_t sizeofArray = sizeof({{name}}Array) / sizeof({{name}}Array[0]);
    if ({{name}} < sizeofArray)
        return (char *){{name}}Array[{{name}}];
    else
        return (char *)"Unknown";
}

OpenAPI_{{classVarName}}_{{name}}_e OpenAPI_{{name}}{{classname}}_FromString(char* {{name}})
{
    int stringToReturn = 0;
    const char *{{name}}Array[] =  { "NULL"{{#allowableValues}}{{#values}}, "{{.}}"{{/values}}{{/allowableValues}} };
    size_t sizeofArray = sizeof({{name}}Array) / sizeof({{name}}Array[0]);
    while (stringToReturn < sizeofArray) {
        if (strcmp({{name}}, {{name}}Array[stringToReturn]) == 0) {
            return stringToReturn;
        }
        stringToReturn++;
    }
    return 0;
}
            {{/isEnum}}
        {{/isPrimitiveType}}
    {{/isContainer}}
{{/vars}}
OpenAPI_{{classname}}_t *OpenAPI_{{classname}}_create(
{{#vars}}
    {{^isContainer}}
        {{^isPrimitiveType}}
            {{#isEnum}}
    OpenAPI_{{datatype}}_e {{name}}{{^-last}},{{/-last}}
            {{/isEnum}}
            {{^isEnum}}
                {{#isModel}}
    OpenAPI_{{datatype}}_t *{{name}}{{^-last}},{{/-last}}
                {{/isModel}}
                {{^isModel}}
                    {{#isUuid}}
    {{datatype}} *{{name}}{{^-last}},{{/-last}}
                    {{/isUuid}}
                    {{#isEmail}}
    {{datatype}} *{{name}}{{^-last}},{{/-last}}
                    {{/isEmail}}
                    {{#isFreeFormObject}}
    OpenAPI_{{datatype}}_t *{{name}}{{^-last}},{{/-last}}
                    {{/isFreeFormObject}}
                    {{#isAnyType}}
    OpenAPI_{{datatype}}_t *{{name}}{{^-last}},{{/-last}}
                    {{/isAnyType}}
                {{/isModel}}
            {{/isEnum}}
        {{/isPrimitiveType}}
        {{#isPrimitiveType}}
            {{#isEnum}}
    OpenAPI_{{classVarName}}_{{name}}_e {{name}}{{^-last}},{{/-last}}
            {{/isEnum}}
            {{^isEnum}}
                {{#isString}}
    {{datatype}} *{{name}}{{^-last}},{{/-last}}
                {{/isString}}
                {{#isByteArray}}
    {{datatype}} *{{name}}{{^-last}},{{/-last}}
                {{/isByteArray}}
                {{#isNumeric}}
                    {{^required}}
    bool is_{{name}},
                    {{/required}}
    {{datatype}} {{name}}{{^-last}},{{/-last}}
                {{/isNumeric}}
                {{#isBoolean}}
                    {{^required}}
    bool is_{{name}},
                    {{/required}}
    {{datatype}} {{name}}{{^-last}},{{/-last}}
                {{/isBoolean}}
            {{/isEnum}}
            {{#isBinary}}
    OpenAPI_{{datatype}} {{name}}{{^-last}},{{/-last}}
            {{/isBinary}}
            {{#isDate}}
    {{datatype}} *{{name}}{{^-last}},{{/-last}}
            {{/isDate}}
            {{#isDateTime}}
    {{datatype}} *{{name}}{{^-last}},{{/-last}}
            {{/isDateTime}}
        {{/isPrimitiveType}}
    {{/isContainer}}
    {{#isContainer}}
        {{#isArray}}
    OpenAPI_{{datatype}}_t *{{name}}{{^-last}},{{/-last}}
        {{/isArray}}
        {{#isMap}}
    OpenAPI_{{datatype}} {{name}}{{^-last}},{{/-last}}
        {{/isMap}}
    {{/isContainer}}
{{/vars}})
{
    OpenAPI_{{classname}}_t *{{classname}}_local_var = ogs_malloc(sizeof(OpenAPI_{{classname}}_t));
    ogs_assert({{classname}}_local_var);

{{#vars}}
    {{^isContainer}}
        {{#isPrimitiveType}}
            {{^isEnum}}
                {{#isNumeric}}
                    {{^required}}
    {{classname}}_local_var->is_{{{name}}} = is_{{{name}}};
                    {{/required}}
                {{/isNumeric}}
                {{#isBoolean}}
                    {{^required}}
    {{classname}}_local_var->is_{{{name}}} = is_{{{name}}};
                    {{/required}}
                {{/isBoolean}}
            {{/isEnum}}
        {{/isPrimitiveType}}
    {{/isContainer}}
    {{classname}}_local_var->{{{name}}} = {{{name}}};
{{/vars}}

    return {{classname}}_local_var;
}

void OpenAPI_{{classname}}_free(OpenAPI_{{classname}}_t *{{classname}})
{
    OpenAPI_lnode_t *node = NULL;

    if (NULL == {{classname}}) {
        return;
    }
{{#vars}}
    {{^isContainer}}
        {{^isPrimitiveType}}
            {{^isEnum}}
                {{#isModel}}
    if ({{{classname}}}->{{{name}}}) {
        OpenAPI_{{{complexType}}}_free({{{classname}}}->{{{name}}});
        {{classname}}->{{name}} = NULL;
    }
                {{/isModel}}
                {{^isModel}}
                    {{#isUuid}}
    if ({{{classname}}}->{{{name}}}) {
        ogs_free({{{classname}}}->{{{name}}});
        {{classname}}->{{name}} = NULL;
    }
                    {{/isUuid}}
                    {{#isEmail}}
    if ({{{classname}}}->{{{name}}}) {
        ogs_free({{{classname}}}->{{{name}}});
        {{classname}}->{{name}} = NULL;
    }
                    {{/isEmail}}
                    {{#isFreeFormObject}}
    if ({{{classname}}}->{{{name}}}) {
        OpenAPI_{{{datatype}}}_free({{{classname}}}->{{{name}}});
        {{classname}}->{{name}} = NULL;
    }
                    {{/isFreeFormObject}}
                    {{#isAnyType}}
    if ({{{classname}}}->{{{name}}}) {
        OpenAPI_{{{datatype}}}_free({{{classname}}}->{{{name}}});
        {{classname}}->{{name}} = NULL;
    }
                    {{/isAnyType}}
                {{/isModel}}
            {{/isEnum}}
        {{/isPrimitiveType}}
        {{#isPrimitiveType}}
            {{^isEnum}}
                {{#isString}}
    if ({{{classname}}}->{{{name}}}) {
        ogs_free({{{classname}}}->{{{name}}});
        {{classname}}->{{name}} = NULL;
    }
                {{/isString}}
                {{#isByteArray}}
    if ({{{classname}}}->{{{name}}}) {
        ogs_free({{{classname}}}->{{{name}}});
        {{classname}}->{{name}} = NULL;
    }
                {{/isByteArray}}
            {{/isEnum}}
            {{#isBinary}}
    if ({{{classname}}}->{{{name}}}) {
        ogs_free({{{classname}}}->{{{name}}}->data);
        {{classname}}->{{name}} = NULL;
    }
            {{/isBinary}}
            {{#isDate}}
    if ({{{classname}}}->{{{name}}}) {
        ogs_free({{{classname}}}->{{{name}}});
        {{classname}}->{{name}} = NULL;
    }
            {{/isDate}}
            {{#isDateTime}}
    if ({{{classname}}}->{{{name}}}) {
        ogs_free({{{classname}}}->{{{name}}});
        {{classname}}->{{name}} = NULL;
    }
            {{/isDateTime}}
        {{/isPrimitiveType}}
    {{/isContainer}}
    {{#isContainer}}
        {{#isArray}}
    if ({{{classname}}}->{{{name}}}) {
            {{^isEnum}}
        OpenAPI_list_for_each({{classname}}->{{name}}, node) {
                {{#isPrimitiveType}}
            ogs_free(node->data);
                {{/isPrimitiveType}}
                {{^isPrimitiveType}}
            OpenAPI_{{complexType}}_free(node->data);
                {{/isPrimitiveType}}
        }
            {{/isEnum}}
        OpenAPI_list_free({{classname}}->{{name}});
        {{classname}}->{{name}} = NULL;
    }
        {{/isArray}}
        {{#isMap}}
    if ({{{classname}}}->{{{name}}}) {
        OpenAPI_list_for_each({{classname}}->{{name}}, node) {
            OpenAPI_map_t *localKeyValue = (OpenAPI_map_t*)node->data;
            ogs_free(localKeyValue->key);
            {{^isEnum}}
                {{#isPrimitiveType}}
            ogs_free(localKeyValue->value);
                {{/isPrimitiveType}}
                {{^isPrimitiveType}}
            OpenAPI_{{complexType}}_free(localKeyValue->value);
                {{/isPrimitiveType}}
            {{/isEnum}}
            OpenAPI_map_free(localKeyValue);
        }
        OpenAPI_list_free({{classname}}->{{name}});
        {{classname}}->{{name}} = NULL;
    }
        {{/isMap}}
    {{/isContainer}}
{{/vars}}
    ogs_free({{classname}});
}

cJSON *OpenAPI_{{classname}}_convertToJSON(OpenAPI_{{classname}}_t *{{classname}})
{
    cJSON *item = NULL;
    OpenAPI_lnode_t *node = NULL;

    if ({{classname}} == NULL) {
        ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
        return NULL;
    }

    item = cJSON_CreateObject();
{{#vars}}
    {{#required}}
        {{^isEnum}}
            {{^isNumeric}}
            {{^isBoolean}}
    if (!{{{classname}}}->{{{name}}}) {
        ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
        return NULL;
    }
            {{/isBoolean}}
            {{/isNumeric}}
        {{/isEnum}}
        {{#isEnum}}
            {{#isPrimitiveType}}
    if ({{{classname}}}->{{{name}}} == OpenAPI_{{classVarName}}_{{enumName}}_NULL) {
        ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
        return NULL;
    }
            {{/isPrimitiveType}}
            {{^isPrimitiveType}}
    if ({{{classname}}}->{{{name}}} == OpenAPI_{{{complexType}}}_NULL) {
        ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
        return NULL;
    }
            {{/isPrimitiveType}}
        {{/isEnum}}
    {{/required}}
    {{^required}}
        {{^isEnum}}
            {{#isNumeric}}
    if ({{{classname}}}->is_{{{name}}}) {
            {{/isNumeric}}
            {{#isBoolean}}
    if ({{{classname}}}->is_{{{name}}}) {
            {{/isBoolean}}
            {{^isNumeric}}
            {{^isBoolean}}
    if ({{{classname}}}->{{{name}}}) {
            {{/isBoolean}}
            {{/isNumeric}}
        {{/isEnum}}
        {{#isEnum}}
            {{#isPrimitiveType}}
    if ({{{classname}}}->{{{name}}} != OpenAPI_{{classVarName}}_{{enumName}}_NULL) {
            {{/isPrimitiveType}}
            {{^isPrimitiveType}}
    if ({{{classname}}}->{{{name}}} != OpenAPI_{{{complexType}}}_NULL) {
            {{/isPrimitiveType}}
        {{/isEnum}}
    {{/required}}
    {{^isContainer}}
        {{#isPrimitiveType}}
            {{#isEnum}}
    if (cJSON_AddStringToObject(item, "{{{baseName}}}", OpenAPI_{{{name}}}{{classname}}_ToString({{{classname}}}->{{{name}}})) == NULL) {
        ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
        goto end;
    }
            {{/isEnum}}
            {{^isEnum}}
                {{#isString}}
    if (cJSON_AddStringToObject(item, "{{{baseName}}}", {{{classname}}}->{{{name}}}) == NULL) {
        ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
        goto end;
    }
                {{/isString}}
                {{#isByteArray}}
    if (cJSON_AddStringToObject(item, "{{{baseName}}}", {{{classname}}}->{{{name}}}) == NULL) {
        ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
        goto end;
    }
                {{/isByteArray}}
                {{#isNumeric}}
    if (cJSON_AddNumberToObject(item, "{{{baseName}}}", {{{classname}}}->{{{name}}}) == NULL) {
        ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
        goto end;
    }
                {{/isNumeric}}
                {{#isBoolean}}
    if (cJSON_AddBoolToObject(item, "{{{baseName}}}", {{{classname}}}->{{{name}}}) == NULL) {
        ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
        goto end;
    }
                {{/isBoolean}}
            {{/isEnum}}
            {{#isBinary}}
    char* encoded_str_{{{name}}} = OpenAPI_base64encode({{{classname}}}->{{{name}}}->data,{{{classname}}}->{{{name}}}->len);
    if (cJSON_AddStringToObject(item, "{{{baseName}}}", encoded_str_{{{name}}}) == NULL) {
        ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
        goto end;
    }
    ogs_free(encoded_str_{{{name}}});
            {{/isBinary}}
            {{#isDate}}
    if (cJSON_AddStringToObject(item, "{{{baseName}}}", {{{classname}}}->{{{name}}}) == NULL) {
        ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
        goto end;
    }
            {{/isDate}}
            {{#isDateTime}}
    if (cJSON_AddStringToObject(item, "{{{baseName}}}", {{{classname}}}->{{{name}}}) == NULL) {
        ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
        goto end;
    }
            {{/isDateTime}}
        {{/isPrimitiveType}}
        {{^isPrimitiveType}}
            {{#isEnum}}
    if (cJSON_AddStringToObject(item, "{{{baseName}}}", OpenAPI_{{{complexType}}}_ToString({{{classname}}}->{{{name}}})) == NULL) {
        ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
        goto end;
    }
            {{/isEnum}}
            {{^isEnum}}
                {{#isModel}}
    cJSON *{{{name}}}_local_JSON = OpenAPI_{{complexType}}{{#isFreeFormObject}}object{{/isFreeFormObject}}_convertToJSON({{{classname}}}->{{{name}}});
    if ({{{name}}}_local_JSON == NULL) {
        ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
        goto end;
    }
    cJSON_AddItemToObject(item, "{{{baseName}}}", {{{name}}}_local_JSON);
    if (item->child == NULL) {
        ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
        goto end;
    }
                {{/isModel}}
                {{^isModel}}
                    {{#isUuid}}
    if (cJSON_AddStringToObject(item, "{{{baseName}}}", {{{classname}}}->{{{name}}}) == NULL) {
        ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
        goto end;
    }
                    {{/isUuid}}
                    {{#isEmail}}
    if (cJSON_AddStringToObject(item, "{{{baseName}}}", {{{classname}}}->{{{name}}}) == NULL) {
        ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
        goto end;
    }
                    {{/isEmail}}
                    {{#isFreeFormObject}}
    cJSON *{{{name}}}_object = OpenAPI_object_convertToJSON({{{classname}}}->{{{name}}});
    if ({{{name}}}_object == NULL) {
        ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
        goto end;
    }
    cJSON_AddItemToObject(item, "{{{baseName}}}", {{{name}}}_object);
    if (item->child == NULL) {
        ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
        goto end;
    }
                    {{/isFreeFormObject}}
                    {{#isAnyType}}
    cJSON *{{{name}}}_object = OpenAPI_any_type_convertToJSON({{{classname}}}->{{{name}}});
    if ({{{name}}}_object == NULL) {
        ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
        goto end;
    }
    cJSON_AddItemToObject(item, "{{{baseName}}}", {{{name}}}_object);
    if (item->child == NULL) {
        ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
        goto end;
    }
                    {{/isAnyType}}
                {{/isModel}}
            {{/isEnum}}
        {{/isPrimitiveType}}
    {{/isContainer}}
    {{#isContainer}}
        {{#isArray}}
    cJSON *{{{name}}}List = cJSON_AddArrayToObject(item, "{{{baseName}}}");
    if ({{{name}}}List == NULL) {
        ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
        goto end;
    }
    OpenAPI_list_for_each({{classname}}->{{{name}}}, node) {
            {{#isEnum}}
        if (cJSON_AddStringToObject({{{name}}}List, "", OpenAPI_{{{complexType}}}_ToString((intptr_t)node->data)) == NULL) {
            ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
            goto end;
        }
            {{/isEnum}}
            {{^isEnum}}
                {{#items}}
                    {{#isPrimitiveType}}
                        {{#isString}}
        if (cJSON_AddStringToObject({{{name}}}List, "", (char*)node->data) == NULL) {
            ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
            goto end;
        }
                        {{/isString}}
                        {{#isByteArray}}
        if (cJSON_AddStringToObject({{{name}}}List, "", (char*)node->data) == NULL) {
            ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
            goto end;
        }
                        {{/isByteArray}}
                        {{#isNumeric}}
        if (cJSON_AddNumberToObject({{{name}}}List, "", (uintptr_t)node->data) == NULL) {
            ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
            goto end;
        }
                        {{/isNumeric}}
                        {{#isBoolean}}
        if (cJSON_AddBoolToObject({{{name}}}List, "", (uintptr_t)node->data) == NULL) {
            ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
            goto end;
        }
                        {{/isBoolean}}
                    {{/isPrimitiveType}}
                    {{^isPrimitiveType}}
        cJSON *itemLocal = OpenAPI_{{complexType}}_convertToJSON(node->data);
        if (itemLocal == NULL) {
            ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
            goto end;
        }
        cJSON_AddItemToArray({{{name}}}List, itemLocal);
                    {{/isPrimitiveType}}
                {{/items}}
            {{/isEnum}}
    }
        {{/isArray}}
        {{#isMap}}
    cJSON *{{{name}}} = cJSON_AddObjectToObject(item, "{{{baseName}}}");
    if ({{{name}}} == NULL) {
        ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
        goto end;
    }
    cJSON *localMapObject = {{{name}}};
    if ({{{classname}}}->{{{name}}}) {
        OpenAPI_list_for_each({{{classname}}}->{{{name}}}, node) {
            OpenAPI_map_t *localKeyValue = (OpenAPI_map_t*)node->data;
            {{#isEnum}}
            if (cJSON_AddStringToObject(localMapObject, localKeyValue->key, OpenAPI_{{{complexType}}}_ToString((intptr_t)localKeyValue->value)) == NULL) {
                ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
                goto end;
            }
            {{/isEnum}}
            {{^isEnum}}
                {{#items}}
                    {{#isPrimitiveType}}
                        {{#isString}}
            if (cJSON_AddStringToObject(localMapObject, localKeyValue->key, (char*)localKeyValue->value) == NULL) {
                ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
                goto end;
            }
                        {{/isString}}
                        {{#isByteArray}}
            if(cJSON_AddStringToObject(localMapObject, localKeyValue->key, (char*)localKeyValue->value) == NULL) {
                ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
                goto end;
            }
                        {{/isByteArray}}
                        {{#isNumeric}}
            if (cJSON_AddNumberToObject(localMapObject, localKeyValue->key, (uintptr_t)localKeyValue->value) == NULL) {
                ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
                goto end;
            }
                        {{/isNumeric}}
                        {{#isBoolean}}
            if (cJSON_AddBoolToObject(localMapObject, localKeyValue->key, (uintptr_t)localKeyValue->value) == NULL) {
                ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
                goto end;
            }
                        {{/isBoolean}}
                    {{/isPrimitiveType}}
                    {{^isPrimitiveType}}
            cJSON *itemLocal = localKeyValue->value ?
                OpenAPI_{{complexType}}_convertToJSON(localKeyValue->value) :
                cJSON_CreateNull();
            if (itemLocal == NULL) {
                ogs_error("OpenAPI_{{classname}}_convertToJSON() failed [{{{name}}}]");
                goto end;
            }
            cJSON_AddItemToObject(localMapObject, localKeyValue->key, itemLocal);
                    {{/isPrimitiveType}}
                {{/items}}
            {{/isEnum}}
        }
    }
        {{/isMap}}
    {{/isContainer}}
    {{^required}}
    }
    {{/required}}

{{/vars}}
end:
    return item;
}

OpenAPI_{{classname}}_t *OpenAPI_{{classname}}_parseFromJSON(cJSON *{{classname}}JSON)
{
    OpenAPI_{{classname}}_t *{{classname}}_local_var = NULL;
    OpenAPI_lnode_t *node = NULL;
{{#vars}}
    cJSON *{{{name}}} = NULL;
    {{^isContainer}}
        {{#isPrimitiveType}}
            {{#isEnum}}
    OpenAPI_{{classVarName}}_{{name}}_e {{name}}Variable = 0;
            {{/isEnum}}
            {{#isBinary}}
    OpenAPI_binary_t *decoded_str_{{{name}}} = NULL;
            {{/isBinary}}
        {{/isPrimitiveType}}
        {{^isPrimitiveType}}
            {{#isEnum}}
    OpenAPI_{{complexType}}_e {{name}}Variable = 0;
            {{/isEnum}}
            {{^isEnum}}
                {{#isModel}}
    {{^isFreeFormObject}}OpenAPI_{{complexType}}{{/isFreeFormObject}}{{#isFreeFormObject}}OpenAPI_object{{/isFreeFormObject}}_t *{{name}}_local_nonprim = NULL;
                {{/isModel}}
                {{^isModel}}
                    {{#isFreeFormObject}}
    OpenAPI_object_t *{{name}}_local_object = NULL;
                    {{/isFreeFormObject}}
                    {{#isAnyType}}
    OpenAPI_any_type_t *{{name}}_local_object = NULL;
                    {{/isAnyType}}
                {{/isModel}}
            {{/isEnum}}
        {{/isPrimitiveType}}
    {{/isContainer}}
    {{#isContainer}}
        {{#isArray}}
    OpenAPI_list_t *{{{name}}}List = NULL;
        {{/isArray}}
        {{#isMap}}
    OpenAPI_list_t *{{{name}}}List = NULL;
        {{/isMap}}
    {{/isContainer}}
{{/vars}}
{{#vars}}
    {{{name}}} = cJSON_GetObjectItemCaseSensitive({{classname}}JSON, "{{{baseName}}}");
    {{#required}}
    if (!{{{name}}}) {
        ogs_error("OpenAPI_{{classname}}_parseFromJSON() failed [{{{name}}}]");
        goto end;
    }
    {{/required}}
    {{^required}}
    if ({{{name}}}) {
    {{/required}}
    {{^isContainer}}
        {{#isPrimitiveType}}
            {{#isEnum}}
    if (!cJSON_IsString({{{name}}})) {
        ogs_error("OpenAPI_{{classname}}_parseFromJSON() failed [{{{name}}}]");
        goto end;
    }
    {{name}}Variable = OpenAPI_{{name}}{{classname}}_FromString({{{name}}}->valuestring);
            {{/isEnum}}
            {{^isEnum}}
                {{#isString}}
    if (!cJSON_IsString({{{name}}}){{^required}} && !cJSON_IsNull({{{name}}}){{/required}}) {
        ogs_error("OpenAPI_{{classname}}_parseFromJSON() failed [{{{name}}}]");
        goto end;
    }
                {{/isString}}
                {{#isByteArray}}
    if (!cJSON_IsString({{{name}}}){{^required}} && !cJSON_IsNull({{{name}}}){{/required}}) {
        ogs_error("OpenAPI_{{classname}}_parseFromJSON() failed [{{{name}}}]");
        goto end;
    }
                {{/isByteArray}}
                {{#isNumeric}}
    if (!cJSON_IsNumber({{{name}}})) {
        ogs_error("OpenAPI_{{classname}}_parseFromJSON() failed [{{{name}}}]");
        goto end;
    }
                {{/isNumeric}}
                {{#isBoolean}}
    if (!cJSON_IsBool({{{name}}})) {
        ogs_error("OpenAPI_{{classname}}_parseFromJSON() failed [{{{name}}}]");
        goto end;
    }
                {{/isBoolean}}
            {{/isEnum}}
            {{#isBinary}}
    decoded_str_{{{name}}} = ogs_malloc(sizeof(OpenAPI_binary_t));
    ogs_assert(decoded_str_{{{name}}});
    if (!cJSON_IsString({{{name}}})) {
        ogs_error("OpenAPI_{{classname}}_parseFromJSON() failed [{{{name}}}]");
        goto end;
    }
    decoded_str_{{{name}}}->data = OpenAPI_base64decode({{{name}}}->valuestring, strlen({{{name}}}->valuestring), &decoded_str_{{{name}}}->len);
    if (!decoded_str_{{{name}}}->data) {
        ogs_error("OpenAPI_{{classname}}_parseFromJSON() failed [{{{name}}}]");
        goto end;
    }
            {{/isBinary}}
            {{#isDate}}
    if (!cJSON_IsString({{{name}}})) {
        ogs_error("OpenAPI_{{classname}}_parseFromJSON() failed [{{{name}}}]");
        goto end;
    }
            {{/isDate}}
            {{#isDateTime}}
    if (!cJSON_IsString({{{name}}}) && !cJSON_IsNull({{{name}}})) {
        ogs_error("OpenAPI_{{classname}}_parseFromJSON() failed [{{{name}}}]");
        goto end;
    }
            {{/isDateTime}}
        {{/isPrimitiveType}}
        {{^isPrimitiveType}}
            {{#isEnum}}
    if (!cJSON_IsString({{{name}}})) {
        ogs_error("OpenAPI_{{classname}}_parseFromJSON() failed [{{{name}}}]");
        goto end;
    }
    {{name}}Variable = OpenAPI_{{complexType}}_FromString({{{name}}}->valuestring);
            {{/isEnum}}
            {{^isEnum}}
                {{#isModel}}
    {{{name}}}_local_nonprim = OpenAPI_{{complexType}}{{#isFreeFormObject}}object{{/isFreeFormObject}}_parseFromJSON({{{name}}});
                {{/isModel}}
                {{^isModel}}
                    {{#isUuid}}
    if (!cJSON_IsString({{{name}}})) {
        ogs_error("OpenAPI_{{classname}}_parseFromJSON() failed [{{{name}}}]");
        goto end;
    }
                    {{/isUuid}}
                    {{#isEmail}}
    if (!cJSON_IsString({{{name}}})) {
        ogs_error("OpenAPI_{{classname}}_parseFromJSON() failed [{{{name}}}]");
        goto end;
    }
                    {{/isEmail}}
                    {{#isFreeFormObject}}
    if (!cJSON_IsObject({{{name}}})) {
        ogs_error("OpenAPI_{{classname}}_parseFromJSON() failed [{{{name}}}]");
        goto end;
    }
    {{{name}}}_local_object = OpenAPI_object_parseFromJSON({{{name}}});
                    {{/isFreeFormObject}}
                    {{#isAnyType}}
    {{{name}}}_local_object = OpenAPI_any_type_parseFromJSON({{{name}}});
                    {{/isAnyType}}
                {{/isModel}}
            {{/isEnum}}
        {{/isPrimitiveType}}
    {{/isContainer}}
    {{#isContainer}}
        {{#isArray}}
        cJSON *{{{name}}}_local = NULL;
        if (!cJSON_IsArray({{{name}}})) {
            ogs_error("OpenAPI_{{classname}}_parseFromJSON() failed [{{{name}}}]");
            goto end;
        }

        {{{name}}}List = OpenAPI_list_create();

        cJSON_ArrayForEach({{{name}}}_local, {{{name}}}) {
            {{#isEnum}}
            if (!cJSON_IsString({{{name}}}_local)) {
                ogs_error("OpenAPI_{{classname}}_parseFromJSON() failed [{{{name}}}]");
                goto end;
            }
            OpenAPI_list_add({{{name}}}List, (void *)OpenAPI_{{{complexType}}}_FromString({{{name}}}_local->valuestring));
            {{/isEnum}}
            {{^isEnum}}
                {{#isPrimitiveType}}
            double *localDouble = NULL;
            int *localInt = NULL;
                {{/isPrimitiveType}}
                {{#items}}
                    {{#isPrimitiveType}}
                        {{#isString}}
            if (!cJSON_IsString({{{name}}}_local)) {
                ogs_error("OpenAPI_{{classname}}_parseFromJSON() failed [{{{name}}}]");
                goto end;
            }
            OpenAPI_list_add({{{name}}}List, ogs_strdup({{{name}}}_local->valuestring));
                        {{/isString}}
                        {{#isByteArray}}
            if (!cJSON_IsString({{{name}}}_local)) {
                ogs_error("OpenAPI_{{classname}}_parseFromJSON() failed [{{{name}}}]");
                goto end;
            }
            OpenAPI_list_add({{{name}}}List, ogs_strdup({{{name}}}_local->valuestring));
                        {{/isByteArray}}
                        {{#isNumeric}}
            if (!cJSON_IsNumber({{{name}}}_local)) {
                ogs_error("OpenAPI_{{classname}}_parseFromJSON() failed [{{{name}}}]");
                goto end;
            }
            localDouble = (double *)ogs_calloc(1, sizeof(double));
            if (!localDouble) {
                ogs_error("OpenAPI_{{classname}}_parseFromJSON() failed [{{{name}}}]");
                goto end;
            }
            *localDouble = {{{name}}}_local->valuedouble;
            OpenAPI_list_add({{{name}}}List, localDouble);
                        {{/isNumeric}}
                        {{#isBoolean}}
            if (!cJSON_IsBool({{{name}}}_local)) {
                ogs_error("OpenAPI_{{classname}}_parseFromJSON() failed [{{{name}}}]");
                goto end;
            }
            localInt = (int *)ogs_calloc(1, sizeof(int));
            if (!localInt) {
                ogs_error("OpenAPI_{{classname}}_parseFromJSON() failed [{{{name}}}]");
                goto end;
            }
            *localInt = {{{name}}}_local->valueint;
            OpenAPI_list_add({{{name}}}List, localInt);
                        {{/isBoolean}}
                    {{/isPrimitiveType}}
                    {{^isPrimitiveType}}
            if (!cJSON_IsObject({{{name}}}_local)) {
                ogs_error("OpenAPI_{{classname}}_parseFromJSON() failed [{{{name}}}]");
                goto end;
            }
            OpenAPI_{{complexType}}_t *{{{name}}}Item = OpenAPI_{{complexType}}_parseFromJSON({{{name}}}_local);
            if (!{{{name}}}Item) {
                ogs_error("No {{{name}}}Item");
                OpenAPI_list_free({{{name}}}List);
                goto end;
            }
            OpenAPI_list_add({{{name}}}List, {{{name}}}Item);
                    {{/isPrimitiveType}}
                {{/items}}
            {{/isEnum}}
        }
        {{/isArray}}
        {{#isMap}}
        cJSON *{{{name}}}_local_map = NULL;
        if (!cJSON_IsObject({{{name}}}) && !cJSON_IsNull({{{name}}})) {
            ogs_error("OpenAPI_{{classname}}_parseFromJSON() failed [{{{name}}}]");
            goto end;
        }
        if (cJSON_IsObject({{{name}}})) {
            {{{name}}}List = OpenAPI_list_create();
            OpenAPI_map_t *localMapKeyPair = NULL;
            cJSON_ArrayForEach({{{name}}}_local_map, {{{name}}}) {
                cJSON *localMapObject = {{{name}}}_local_map;
            {{#isEnum}}
                if (!cJSON_IsString(localMapObject)) {
                    ogs_error("OpenAPI_{{classname}}_parseFromJSON() failed [{{{name}}}]");
                    goto end;
                }
                localMapKeyPair = OpenAPI_map_create(ogs_strdup(localMapObject->string), (void *)OpenAPI_{{{complexType}}}_FromString(localMapObject->string));
            {{/isEnum}}
            {{^isEnum}}
                {{#isPrimitiveType}}
                double *localDouble = NULL;
                int *localInt = NULL;
                {{/isPrimitiveType}}
                {{#items}}
                    {{#isPrimitiveType}}
                        {{#isString}}
                if (!cJSON_IsString(localMapObject)) {
                    ogs_error("OpenAPI_{{classname}}_parseFromJSON() failed [{{{name}}}]");
                    goto end;
                }
                localMapKeyPair = OpenAPI_map_create(ogs_strdup(localMapObject->string), ogs_strdup(localMapObject->valuestring));
                        {{/isString}}
                        {{#isByteArray}}
                if (!cJSON_IsString(localMapObject)) {
                    ogs_error("OpenAPI_{{classname}}_parseFromJSON() failed [{{{name}}}]");
                    goto end;
                }
                localMapKeyPair = OpenAPI_map_create(ogs_strdup(localMapObject->string), ogs_strdup(localMapObject->valuestring));
                        {{/isByteArray}}
                        {{#isNumeric}}
                if (!cJSON_IsNumber(localMapObject)) {
                    ogs_error("OpenAPI_{{classname}}_parseFromJSON() failed [{{{name}}}]");
                    goto end;
                }
                localDouble = (double *)ogs_calloc(1, sizeof(double));
                if (!localDouble) {
                    ogs_error("OpenAPI_{{classname}}_parseFromJSON() failed [{{{name}}}]");
                    goto end;
                }
                *localDouble = localMapObject->valuedouble;
                localMapKeyPair = OpenAPI_map_create(ogs_strdup(localMapObject->string), localDouble);
                        {{/isNumeric}}
                        {{#isBoolean}}
                if (!cJSON_IsBool(localMapObject)) {
                    ogs_error("OpenAPI_{{classname}}_parseFromJSON() failed [{{{name}}}]");
                    goto end;
                }
                localInt = (int *)ogs_calloc(1, sizeof(int));
                if (!localInt) {
                    ogs_error("OpenAPI_{{classname}}_parseFromJSON() failed [{{{name}}}]");
                    goto end;
                }
                *localInt = localMapObject->valueint;
                localMapKeyPair = OpenAPI_map_create(ogs_strdup(localMapObject->string), localInt);
                        {{/isBoolean}}
                    {{/isPrimitiveType}}
                    {{^isPrimitiveType}}
                if (cJSON_IsObject(localMapObject)) {
                    localMapKeyPair = OpenAPI_map_create(
                        ogs_strdup(localMapObject->string), OpenAPI_{{complexType}}_parseFromJSON(localMapObject));
                } else if (cJSON_IsNull(localMapObject)) {
                    localMapKeyPair = OpenAPI_map_create(ogs_strdup(localMapObject->string), NULL);
                } else {
                    ogs_error("OpenAPI_{{classname}}_parseFromJSON() failed [{{{name}}}]");
                    goto end;
                }
                    {{/isPrimitiveType}}
                {{/items}}
            {{/isEnum}}
                OpenAPI_list_add({{{name}}}List, localMapKeyPair);
            }
        }
        {{/isMap}}
    {{/isContainer}}
    {{^required}}
    }
    {{/required}}

{{/vars}}
    {{classname}}_local_var = OpenAPI_{{classname}}_create (
{{#vars}}
    {{^isContainer}}
        {{^isPrimitiveType}}
            {{#isEnum}}
        {{^required}}{{{name}}} ? {{/required}}{{{name}}}Variable{{^required}} : 0{{/required}}{{^-last}},{{/-last}}
            {{/isEnum}}
            {{^isEnum}}
                {{#isModel}}
        {{^required}}{{{name}}} ? {{/required}}{{{name}}}_local_nonprim{{^required}} : NULL{{/required}}{{^-last}},{{/-last}}
                {{/isModel}}
                {{^isModel}}
                    {{#isUuid}}
        {{^required}}{{{name}}} ? {{/required}}ogs_strdup({{{name}}}->valuestring){{^required}} : NULL{{/required}}{{^-last}},{{/-last}}
                    {{/isUuid}}
                    {{#isEmail}}
        {{^required}}{{{name}}} ? {{/required}}ogs_strdup({{{name}}}->valuestring){{^required}} : NULL{{/required}}{{^-last}},{{/-last}}
                    {{/isEmail}}
                    {{#isFreeFormObject}}
        {{^required}}{{{name}}} ? {{/required}}{{{name}}}_local_object{{^required}} : NULL{{/required}}{{^-last}},{{/-last}}
                    {{/isFreeFormObject}}
                    {{#isAnyType}}
        {{^required}}{{{name}}} ? {{/required}}{{{name}}}_local_object{{^required}} : NULL{{/required}}{{^-last}},{{/-last}}
                    {{/isAnyType}}
                {{/isModel}}
            {{/isEnum}}
        {{/isPrimitiveType}}
        {{#isPrimitiveType}}
            {{#isEnum}}
        {{^required}}{{{name}}} ? {{/required}}{{name}}Variable{{^required}} : 0{{/required}}{{^-last}},{{/-last}}
            {{/isEnum}}
            {{^isEnum}}
                {{#isNumeric}}
        {{^required}}{{{name}}} ? true : false,{{/required}}
        {{^required}}{{{name}}} ? {{/required}}{{{name}}}->valuedouble{{^required}} : 0{{/required}}{{^-last}},{{/-last}}
                {{/isNumeric}}
                {{#isBoolean}}
        {{^required}}{{{name}}} ? true : false,{{/required}}
        {{^required}}{{{name}}} ? {{/required}}{{{name}}}->valueint{{^required}} : 0{{/required}}{{^-last}},{{/-last}}
                {{/isBoolean}}
                {{#isString}}
        {{^required}}{{{name}}} && !cJSON_IsNull({{{name}}}) ? {{/required}}ogs_strdup({{{name}}}->valuestring){{^required}} : NULL{{/required}}{{^-last}},{{/-last}}
                {{/isString}}
                {{#isByteArray}}
        {{^required}}{{{name}}} && !cJSON_IsNull({{{name}}}) ? {{/required}}ogs_strdup({{{name}}}->valuestring){{^required}} : NULL{{/required}}{{^-last}},{{/-last}}
                {{/isByteArray}}
            {{/isEnum}}
            {{#isBinary}}
        {{^required}}{{{name}}} ? {{/required}}decoded_str_{{{name}}}{{^required}} : NULL{{/required}}{{^-last}},{{/-last}}
            {{/isBinary}}
            {{#isDate}}
        {{^required}}{{{name}}} ? {{/required}}ogs_strdup({{{name}}}->valuestring){{^required}} : NULL{{/required}}{{^-last}},{{/-last}}
            {{/isDate}}
            {{#isDateTime}}
        {{^required}}{{{name}}} && !cJSON_IsNull({{{name}}}) ? {{/required}}ogs_strdup({{{name}}}->valuestring){{^required}} : NULL{{/required}}{{^-last}},{{/-last}}
            {{/isDateTime}}
        {{/isPrimitiveType}}
    {{/isContainer}}
    {{#isContainer}}
        {{#isArray}}
        {{^required}}{{{name}}} ? {{/required}}{{{name}}}List{{^required}} : NULL{{/required}}{{^-last}},{{/-last}}
        {{/isArray}}
        {{#isMap}}
        {{^required}}{{{name}}} ? {{/required}}{{{name}}}List{{^required}} : NULL{{/required}}{{^-last}},{{/-last}}
        {{/isMap}}
    {{/isContainer}}
{{/vars}}
    );

    return {{classname}}_local_var;
end:
{{#vars}}
    {{^isContainer}}
        {{^isPrimitiveType}}
            {{^isEnum}}
                {{#isModel}}
    if ({{{name}}}_local_nonprim) {
        OpenAPI_{{{complexType}}}_free({{{name}}}_local_nonprim);
        {{{name}}}_local_nonprim = NULL;
    }
                {{/isModel}}
                {{^isModel}}
                    {{#isFreeFormObject}}
    if ({{{name}}}_local_object) {
        OpenAPI_{{{datatype}}}_free({{{name}}}_local_object);
        {{{name}}}_local_object = NULL;
    }
                    {{/isFreeFormObject}}
                    {{#isAnyType}}
    if ({{name}}_local_object) {
        OpenAPI_{{{datatype}}}_free({{name}}_local_object);
        {{name}}_local_object = NULL;
    }
                    {{/isAnyType}}
                {{/isModel}}
            {{/isEnum}}
        {{/isPrimitiveType}}
    {{/isContainer}}
    {{#isContainer}}
        {{#isArray}}
    if ({{{name}}}List) {
            {{^isEnum}}
        OpenAPI_list_for_each({{{name}}}List, node) {
                {{#isPrimitiveType}}
            ogs_free(node->data);
                {{/isPrimitiveType}}
                {{^isPrimitiveType}}
            OpenAPI_{{complexType}}_free(node->data);
                {{/isPrimitiveType}}
        }
            {{/isEnum}}
        OpenAPI_list_free({{{name}}}List);
        {{{name}}}List = NULL;
    }
        {{/isArray}}
        {{#isMap}}
    if ({{{name}}}List) {
        OpenAPI_list_for_each({{{name}}}List, node) {
            OpenAPI_map_t *localKeyValue = (OpenAPI_map_t*) node->data;
            ogs_free(localKeyValue->key);
            {{^isEnum}}
                {{#isPrimitiveType}}
            ogs_free(localKeyValue->value);
                {{/isPrimitiveType}}
                {{^isPrimitiveType}}
            OpenAPI_{{complexType}}_free(localKeyValue->value);
                {{/isPrimitiveType}}
            {{/isEnum}}
            OpenAPI_map_free(localKeyValue);
        }
        OpenAPI_list_free({{{name}}}List);
        {{{name}}}List = NULL;
    }
        {{/isMap}}
    {{/isContainer}}
{{/vars}}
    return NULL;
}

OpenAPI_{{classname}}_t *OpenAPI_{{classname}}_copy(OpenAPI_{{classname}}_t *dst, OpenAPI_{{classname}}_t *src)
{
    cJSON *item = NULL;
    char *content = NULL;

    ogs_assert(src);
    item = OpenAPI_{{classname}}_convertToJSON(src);
    if (!item) {
        ogs_error("OpenAPI_{{classname}}_convertToJSON() failed");
        return NULL;
    }

    content = cJSON_Print(item);
    cJSON_Delete(item);

    if (!content) {
        ogs_error("cJSON_Print() failed");
        return NULL;
    }

    item = cJSON_Parse(content);
    ogs_free(content);
    if (!item) {
        ogs_error("cJSON_Parse() failed");
        return NULL;
    }

    OpenAPI_{{classname}}_free(dst);
    dst = OpenAPI_{{classname}}_parseFromJSON(item);
    cJSON_Delete(item);

    return dst;
}
{{/isEnum}}
{{/model}}{{/models}}
