// Copyright (C) 2016, 2017, 2018, 2019  Stefan Vargyas
// 
// This file is part of Json-Type.
// 
// Json-Type is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// 
// Json-Type is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with Json-Type.  If not, see <http://www.gnu.org/licenses/>.

#include "config.h"

#include <stdlib.h>
#include <string.h>

#include "common.h"
#include "json-intf.h"

enum json_intf_type_t
{
    json_obj_intf_type,
    json_ast_intf_type,
    json_type_intf_type,
    json_type_lib_intf_type,
    json_filter_lib_intf_type,
    json_esc_intf_type
};

struct json_intf_t
{
    enum json_intf_type_t type;

    union {
        struct json_obj_t*        obj;
        struct json_ast_t*        ast;
        struct json_type_t*       type;
        struct json_type_lib_t*   type_lib;
        struct json_filter_lib_t* filter_lib;
        struct json_esc_t*        esc;
    } ptr;

    void (*config_set_param)(struct json_intf_t*,
        enum json_intf_config_param_t, bool);
    enum json_parse_status_t (*parse)(struct json_intf_t*,
        const uchar_t*, size_t);
    enum json_parse_status_t (*parse_done)(struct json_intf_t*);
    bool (*get_is_error)(struct json_intf_t*);
    struct json_text_pos_t (*get_token_pos)(struct json_intf_t*);
    const uchar_t* (*get_token_delim)(struct json_intf_t*);
    struct json_error_pos_t (*get_error_pos)(struct json_intf_t*);
    const struct json_file_info_t* (*get_error_file)(
        struct json_intf_t*);
    void (*print_error_desc)(struct json_intf_t*, FILE*);
#ifdef JSON_DEBUG
    void (*print_error_debug)(struct json_intf_t*, FILE*);
#endif
    void (*destroy)(struct json_intf_t*);
};

enum {
    json_intf_basic_first_param = json_intf_allow_empty_input_config,
    json_intf_basic_last_param = json_intf_quote_text_config,
    json_intf_filter_first_param = json_intf_verbose_error_config,
    json_intf_filter_last_param = json_intf_verbose_error_config,
};

#define JSON_INTF_ASSERT_PARAM_(c, p, w)           \
    ASSERT(param c (enum json_intf_config_param_t) \
        json_intf_ ## p ## _ ## w ## _param)

#define JSON_INTF_ASSERT_LAST_(p) \
    JSON_INTF_ASSERT_PARAM_(<=, p, last)
#define JSON_INTF_ASSERT_FIRST_(p) \
    JSON_INTF_ASSERT_PARAM_(>=, p, first)

#define JSON_INTF_ASSERT_FIRST_BASIC_()          \
    (                                            \
        STATIC(TYPEOF_IS_UNSIGNED_INT(param)),   \
        STATIC(json_intf_basic_first_param == 0) \
    )
#define JSON_INTF_ASSERT_FIRST_FILTER_() \
    JSON_INTF_ASSERT_FIRST_(filter)

#define JSON_INTF_PARAM_(m, p)                   \
    ({                                           \
        JSON_INTF_ASSERT_LAST_(p);               \
        JSON_INTF_ASSERT_FIRST_ ## m();          \
        param - json_intf_ ## p ## _first_param; \
    })
#define JSON_INTF_BASIC_PARAM() \
    JSON_INTF_PARAM_(BASIC_, basic)
#define JSON_INTF_FILTER_PARAM() \
    JSON_INTF_PARAM_(FILTER_, filter)

#define JSON_INTF_OP_ERROR(r)                    \
    ({                                           \
        UNEXPECT_ERR("operation not appliable"); \
        r;                                       \
    })

#define JSON_INTF_OBJ_IS(n)          \
    (                                \
        intf->type ==                \
            json_ ## n ## _intf_type \
    )

#define JSON_INTF_OBJ(n)             \
    ({                               \
        ASSERT(JSON_INTF_OBJ_IS(n)); \
        intf->ptr.n;                 \
    })

static void json_intf_config_set_param_obj(
    struct json_intf_t* intf, enum json_intf_config_param_t param,
    bool val)
{
    json_config_set_param(
        JSON_INTF_OBJ(obj), JSON_INTF_BASIC_PARAM(), val);
}

static void json_intf_config_set_param_ast(
    struct json_intf_t* intf, enum json_intf_config_param_t param,
    bool val)
{
    json_ast_config_set_param(
        JSON_INTF_OBJ(ast), JSON_INTF_BASIC_PARAM(), val);
}

static void json_intf_config_set_param_type(
    struct json_intf_t* intf, enum json_intf_config_param_t param,
    bool val)
{
    json_type_config_set_param(
        JSON_INTF_OBJ(type), JSON_INTF_BASIC_PARAM(), val);
}

static void json_intf_config_set_param_type_lib(
    struct json_intf_t* intf UNUSED,
    enum json_intf_config_param_t param UNUSED,
    bool val UNUSED)
{
    // stev: nop!
}

static void json_intf_config_set_param_filter_lib(
    struct json_intf_t* intf, enum json_intf_config_param_t param,
    bool val)
{
    json_filter_lib_config_set_param(
        JSON_INTF_OBJ(filter_lib), JSON_INTF_FILTER_PARAM(), val);
}

static void json_intf_config_set_param_esc(
    struct json_intf_t* intf, enum json_intf_config_param_t param,
    bool val)
{
    json_esc_config_set_param(
        JSON_INTF_OBJ(esc), JSON_INTF_BASIC_PARAM(), val);
}

static enum json_parse_status_t json_intf_parse_obj(
    struct json_intf_t* intf, const uchar_t* buf, size_t len)
{
    return json_parse(JSON_INTF_OBJ(obj), buf, len);
}

static enum json_parse_status_t json_intf_parse_ast(
    struct json_intf_t* intf, const uchar_t* buf, size_t len)
{
    return json_ast_parse(JSON_INTF_OBJ(ast), buf, len);
}

static enum json_parse_status_t json_intf_parse_type(
    struct json_intf_t* intf, const uchar_t* buf, size_t len)
{
    return json_type_parse(JSON_INTF_OBJ(type), buf, len);
}

static enum json_parse_status_t json_intf_parse_type_lib(
    struct json_intf_t* intf, const uchar_t* buf, size_t len)
{
    return json_type_lib_parse(JSON_INTF_OBJ(type_lib), buf, len);
}

static enum json_parse_status_t json_intf_parse_filter_lib(
    struct json_intf_t* intf UNUSED, const uchar_t* buf UNUSED,
    size_t len UNUSED)
{
    return JSON_INTF_OP_ERROR(json_parse_status_ok);
}

static enum json_parse_status_t json_intf_parse_esc(
    struct json_intf_t* intf, const uchar_t* buf, size_t len)
{
    return json_esc_parse(JSON_INTF_OBJ(esc), buf, len);
}

static enum json_parse_status_t json_intf_parse_done_obj(
    struct json_intf_t* intf)
{
    return json_parse_done(JSON_INTF_OBJ(obj));
}

static enum json_parse_status_t json_intf_parse_done_ast(
    struct json_intf_t* intf)
{
    return json_ast_parse_done(JSON_INTF_OBJ(ast));
}

static enum json_parse_status_t json_intf_parse_done_type(
    struct json_intf_t* intf)
{
    return json_type_parse_done(JSON_INTF_OBJ(type));
}

static enum json_parse_status_t json_intf_parse_done_type_lib(
    struct json_intf_t* intf)
{
    return json_type_lib_parse_done(JSON_INTF_OBJ(type_lib));
}

static enum json_parse_status_t json_intf_parse_done_filter_lib(
    struct json_intf_t* intf UNUSED)
{
    return JSON_INTF_OP_ERROR(json_parse_status_ok);
}

static enum json_parse_status_t json_intf_parse_done_esc(
    struct json_intf_t* intf)
{
    return json_esc_parse_done(JSON_INTF_OBJ(esc));
}

static bool json_intf_get_is_error_obj(
    struct json_intf_t* intf)
{
    return json_get_is_error(JSON_INTF_OBJ(obj));
}

static bool json_intf_get_is_error_ast(
    struct json_intf_t* intf)
{
    return json_ast_get_is_error(JSON_INTF_OBJ(ast));
}

static bool json_intf_get_is_error_type(
    struct json_intf_t* intf)
{
    return json_type_get_is_error(JSON_INTF_OBJ(type));
}

static bool json_intf_get_is_error_type_lib(
    struct json_intf_t* intf)
{
    return json_type_lib_get_is_error(JSON_INTF_OBJ(type_lib));
}

static bool json_intf_get_is_error_filter_lib(
    struct json_intf_t* intf)
{
    return json_filter_lib_get_is_error(JSON_INTF_OBJ(filter_lib));
}

static bool json_intf_get_is_error_esc(
    struct json_intf_t* intf)
{
    return json_esc_get_is_error(JSON_INTF_OBJ(esc));
}

static struct json_text_pos_t json_intf_get_token_pos_obj(
    struct json_intf_t* intf)
{
    return json_get_token_pos(JSON_INTF_OBJ(obj));
}

static struct json_text_pos_t json_intf_get_token_pos_ast(
    struct json_intf_t* intf UNUSED)
{
    return JSON_INTF_OP_ERROR(((struct json_text_pos_t) {0, 0}));
}

static struct json_text_pos_t json_intf_get_token_pos_type(
    struct json_intf_t* intf)
{
    return json_type_get_token_pos(JSON_INTF_OBJ(type));
}

static struct json_text_pos_t json_intf_get_token_pos_type_lib(
    struct json_intf_t* intf UNUSED)
{
    return JSON_INTF_OP_ERROR(((struct json_text_pos_t) {0, 0}));
}

static struct json_text_pos_t json_intf_get_token_pos_filter_lib(
    struct json_intf_t* intf UNUSED)
{
    return JSON_INTF_OP_ERROR(((struct json_text_pos_t) {0, 0}));
}

static struct json_text_pos_t json_intf_get_token_pos_esc(
    struct json_intf_t* intf UNUSED)
{
    return JSON_INTF_OP_ERROR(((struct json_text_pos_t) {0, 0}));
}

static const uchar_t* json_intf_get_token_delim_obj(
    struct json_intf_t* intf)
{
    return json_get_token_delim(JSON_INTF_OBJ(obj));
}

static const uchar_t* json_intf_get_token_delim_ast(
    struct json_intf_t* intf UNUSED)
{
    return JSON_INTF_OP_ERROR(NULL);
}

static const uchar_t* json_intf_get_token_delim_type(
    struct json_intf_t* intf)
{
    return json_type_get_token_delim(JSON_INTF_OBJ(type));
}

static const uchar_t* json_intf_get_token_delim_type_lib(
    struct json_intf_t* intf UNUSED)
{
    return JSON_INTF_OP_ERROR(NULL);
}

static const uchar_t* json_intf_get_token_delim_filter_lib(
    struct json_intf_t* intf UNUSED)
{
    return JSON_INTF_OP_ERROR(NULL);
}

static const uchar_t* json_intf_get_token_delim_esc(
    struct json_intf_t* intf UNUSED)
{
    return JSON_INTF_OP_ERROR(NULL);
}

static struct json_error_pos_t json_intf_get_error_pos_obj(
    struct json_intf_t* intf)
{
    return json_get_error_pos(JSON_INTF_OBJ(obj));
}

static struct json_error_pos_t json_intf_get_error_pos_ast(
    struct json_intf_t* intf)
{
    return json_ast_get_error_pos(JSON_INTF_OBJ(ast));
}

static struct json_error_pos_t json_intf_get_error_pos_type(
    struct json_intf_t* intf)
{
    return json_type_get_error_pos(JSON_INTF_OBJ(type));
}

static struct json_error_pos_t json_intf_get_error_pos_type_lib(
    struct json_intf_t* intf)
{
    return json_type_lib_get_error_pos(JSON_INTF_OBJ(type_lib));
}

static struct json_error_pos_t json_intf_get_error_pos_filter_lib(
    struct json_intf_t* intf)
{
    return json_filter_lib_get_error_pos(JSON_INTF_OBJ(filter_lib));
}

static struct json_error_pos_t json_intf_get_error_pos_esc(
    struct json_intf_t* intf)
{
    return json_esc_get_error_pos(JSON_INTF_OBJ(esc));
}

static const struct json_file_info_t* json_intf_get_error_file_obj(
    struct json_intf_t* intf)
{
    return json_get_error_file(JSON_INTF_OBJ(obj));
}

static const struct json_file_info_t* json_intf_get_error_file_ast(
    struct json_intf_t* intf)
{
    return json_ast_get_error_file(JSON_INTF_OBJ(ast));
}

static const struct json_file_info_t* json_intf_get_error_file_type(
    struct json_intf_t* intf)
{
    return json_type_get_error_file(JSON_INTF_OBJ(type));
}

static const struct json_file_info_t* json_intf_get_error_file_type_lib(
    struct json_intf_t* intf)
{
    return json_type_lib_get_error_file(JSON_INTF_OBJ(type_lib));
}

static const struct json_file_info_t* json_intf_get_error_file_filter_lib(
    struct json_intf_t* intf)
{
    return json_filter_lib_get_error_file(JSON_INTF_OBJ(filter_lib));
}

static const struct json_file_info_t* json_intf_get_error_file_esc(
    struct json_intf_t* intf)
{
    return json_esc_get_error_file(JSON_INTF_OBJ(esc));
}

static void json_intf_print_error_desc_obj(
    struct json_intf_t* intf, FILE* file)
{
    json_print_error_desc(JSON_INTF_OBJ(obj), file);
}

static void json_intf_print_error_desc_ast(
    struct json_intf_t* intf, FILE* file)
{
    json_ast_print_error_desc(JSON_INTF_OBJ(ast), file);
}

static void json_intf_print_error_desc_type(
    struct json_intf_t* intf, FILE* file)
{
    json_type_print_error_desc(JSON_INTF_OBJ(type), file);
}

static void json_intf_print_error_desc_type_lib(
    struct json_intf_t* intf, FILE* file)
{
    json_type_lib_print_error_desc(JSON_INTF_OBJ(type_lib), file);
}

static void json_intf_print_error_desc_filter_lib(
    struct json_intf_t* intf, FILE* file)
{
    json_filter_lib_print_error_desc(JSON_INTF_OBJ(filter_lib), file);
}

static void json_intf_print_error_desc_esc(
    struct json_intf_t* intf, FILE* file)
{
    json_esc_print_error_desc(JSON_INTF_OBJ(esc), file);
}

#ifdef JSON_DEBUG

static void json_intf_print_error_debug_obj(
    struct json_intf_t* intf, FILE* file)
{
    json_print_error_debug(JSON_INTF_OBJ(obj), file);
}

static void json_intf_print_error_debug_ast(
    struct json_intf_t* intf, FILE* file)
{
    json_ast_print_error_debug(JSON_INTF_OBJ(ast), file);
}

static void json_intf_print_error_debug_type(
    struct json_intf_t* intf, FILE* file)
{
    json_type_print_error_debug(JSON_INTF_OBJ(type), file);
}

static void json_intf_print_error_debug_type_lib(
    struct json_intf_t* intf, FILE* file)
{
    json_type_lib_print_error_debug(JSON_INTF_OBJ(type_lib), file);
}

static void json_intf_print_error_debug_filter_lib(
    struct json_intf_t* intf UNUSED, FILE* file UNUSED)
{
    // stev: nop
}

static void json_intf_print_error_debug_esc(
    struct json_intf_t* intf, FILE* file)
{
    json_esc_print_error_debug(JSON_INTF_OBJ(esc), file);
}

#endif

static void json_intf_destroy_obj(struct json_intf_t* intf)
{
    json_obj_destroy(JSON_INTF_OBJ(obj));
}

static void json_intf_destroy_ast(struct json_intf_t* intf)
{
    json_ast_destroy(JSON_INTF_OBJ(ast));
}

static void json_intf_destroy_type(struct json_intf_t* intf)
{
    json_type_destroy(JSON_INTF_OBJ(type));
}

static void json_intf_destroy_type_lib(struct json_intf_t* intf)
{
    json_type_lib_destroy(JSON_INTF_OBJ(type_lib));
}

static void json_intf_destroy_filter_lib(struct json_intf_t* intf)
{
    json_filter_lib_destroy(JSON_INTF_OBJ(filter_lib));
}

static void json_intf_destroy_esc(struct json_intf_t* intf)
{
    json_esc_destroy(JSON_INTF_OBJ(esc));
}

#ifdef JSON_DEBUG
#define JSON_INTF_INIT_OBJ_DEBUG(n) \
    intf->print_error_debug = json_intf_print_error_debug_ ## n;
#else
#define JSON_INTF_INIT_OBJ_DEBUG(n)
#endif

#define JSON_INTF_INIT_OBJ_(n, c, ...)                             \
    do {                                                           \
        intf->type = json_ ## n ## _intf_type;                     \
        intf->ptr.n = json_ ## n ## _create ## c(__VA_ARGS__);     \
        intf->config_set_param = json_intf_config_set_param_ ## n; \
        intf->parse = json_intf_parse_ ## n;                       \
        intf->parse_done = json_intf_parse_done_ ## n;             \
        intf->get_token_pos = json_intf_get_token_pos_ ## n;       \
        intf->get_token_delim = json_intf_get_token_delim_ ## n;   \
        intf->get_is_error = json_intf_get_is_error_ ## n;         \
        intf->get_error_pos = json_intf_get_error_pos_ ## n;       \
        intf->get_error_file = json_intf_get_error_file_ ## n;     \
        intf->print_error_desc = json_intf_print_error_desc_ ## n; \
        intf->destroy = json_intf_destroy_ ## n;                   \
        JSON_INTF_INIT_OBJ_DEBUG(n)                                \
    } while (0)

#define JSON_INTF_INIT_OBJ(n, ...) \
    JSON_INTF_INIT_OBJ_(n, , ## __VA_ARGS__)
#define JSON_INTF_INIT_OBJ2(n, c, ...) \
    JSON_INTF_INIT_OBJ_(n, _ ## c, ## __VA_ARGS__)

#define JSON_INTF_MAP_PARAM_(t, n, p)     \
    (                                     \
        json_intf_ ## p ## _config ==     \
        json_intf_ ## t ## _first_param + \
        json_ ## n ## p ## _config        \
    )
#define JSON_INTF_MAP_BASIC_PARAM(p) \
    JSON_INTF_MAP_PARAM_(basic, , p)
#define JSON_INTF_MAP_FILTER_PARAM(p) \
    JSON_INTF_MAP_PARAM_(filter, filter_, p)

static struct json_intf_t* json_intf_create(void)
{
    struct json_intf_t* intf;

    // stev: verify the mapping of config parameters
    STATIC(
        JSON_INTF_MAP_BASIC_PARAM(allow_empty_input) &&
        JSON_INTF_MAP_BASIC_PARAM(allow_raw_strings) &&
        JSON_INTF_MAP_BASIC_PARAM(allow_literal_value) &&
        JSON_INTF_MAP_BASIC_PARAM(allow_multi_objects) &&
        JSON_INTF_MAP_BASIC_PARAM(allow_surrogate_pairs) &&
        JSON_INTF_MAP_BASIC_PARAM(disallow_unicode_esc) &&
        JSON_INTF_MAP_BASIC_PARAM(disallow_non_ascii) &&
        JSON_INTF_MAP_BASIC_PARAM(validate_utf8) &&
        JSON_INTF_MAP_BASIC_PARAM(trim_spaces) &&
        JSON_INTF_MAP_BASIC_PARAM(quote_text) &&

        JSON_INTF_MAP_FILTER_PARAM(verbose_error)
    );

    intf = malloc(sizeof(struct json_intf_t));
    if (intf == NULL)
        OOM_ERROR("malloc failed creating json_intf_t");

    memset(intf, 0, sizeof(struct json_intf_t));

    return intf;
}

struct json_intf_t* json_intf_create_obj(
    const struct json_handler_t* handler, void* obj,
    const struct json_obj_sizes_t* sizes)
{
    struct json_intf_t* intf;

    intf = json_intf_create();
    JSON_INTF_INIT_OBJ(obj, handler, obj, sizes);

    return intf;
}

struct json_intf_t* json_intf_create_ast(
    const struct json_ast_sizes_t* sizes)
{
    struct json_intf_t* intf;

    intf = json_intf_create();
    JSON_INTF_INIT_OBJ(ast, sizes);

    return intf;
}

struct json_intf_t* json_intf_create_type_from_def(
    const uchar_t* type_def, const char* type_name,
    const struct json_handler_t* handler, void* obj,
    const struct json_type_sizes_t* sizes)
{
    struct json_intf_t* intf;

    intf = json_intf_create();
    JSON_INTF_INIT_OBJ2(
        type, from_def, type_def, type_name,
        handler, obj, sizes);

    return intf;
}

struct json_intf_t* json_intf_create_type_from_lib(
    const char* type_lib, const char* type_name,
    const struct json_handler_t* handler, void* obj,
    const struct json_type_sizes_t* sizes)
{
    struct json_intf_t* intf;

    intf = json_intf_create();
    JSON_INTF_INIT_OBJ2(
        type, from_lib, type_lib, type_name,
        handler, obj, sizes);

    return intf;
}

struct json_intf_t* json_intf_create_text_type_lib(
    const struct json_type_lib_sizes_t* sizes)
{
    struct json_intf_t* intf;

    intf = json_intf_create();
    JSON_INTF_INIT_OBJ2(type_lib, from_source_text, sizes);

    return intf;
}

struct json_intf_t* json_intf_create_sobj_type_lib(
    const char* lib_name, const struct json_type_lib_sizes_t* sizes)
{
    struct json_intf_t* intf;

    intf = json_intf_create();
    JSON_INTF_INIT_OBJ2(type_lib, from_shared_obj, lib_name, sizes);

    return intf;
}

struct json_intf_t* json_intf_create_filter_lib(
    const struct options_filter_t* opts)
{
    struct json_intf_t* intf;

    intf = json_intf_create();
    JSON_INTF_INIT_OBJ(filter_lib, opts);

    return intf;
}

struct json_intf_t* json_intf_create_esc(
    const struct json_esc_sizes_t* sizes)
{
    struct json_intf_t* intf;

    intf = json_intf_create();
    JSON_INTF_INIT_OBJ(esc, sizes);

    return intf;
}

void json_intf_destroy(struct json_intf_t* intf)
{
    intf->destroy(intf);
    free(intf);
}

void json_intf_config_set_param(struct json_intf_t* intf,
    enum json_intf_config_param_t param, bool val)
{ intf->config_set_param(intf, param, val); }

enum json_parse_status_t json_intf_parse(struct json_intf_t* intf,
    const uchar_t* buf, size_t len)
{ return intf->parse(intf, buf, len); }

enum json_parse_status_t json_intf_parse_done(struct json_intf_t* intf)
{ return intf->parse_done(intf); }

struct json_text_pos_t json_intf_get_token_pos(struct json_intf_t* intf)
{ return intf->get_token_pos(intf); }

const uchar_t* json_intf_get_token_delim(struct json_intf_t* intf)
{ return intf->get_token_delim(intf); }

bool json_intf_get_is_error(struct json_intf_t* intf)
{ return intf->get_is_error(intf); }

struct json_error_pos_t json_intf_get_error_pos(struct json_intf_t* intf)
{ return intf->get_error_pos(intf); }

const struct json_file_info_t* json_intf_get_error_file(
    struct json_intf_t* intf)
{ return intf->get_error_file(intf); }

void json_intf_print_error_desc(struct json_intf_t* intf, FILE* file)
{ intf->print_error_desc(intf, file); }

#ifdef JSON_DEBUG
void json_intf_print_error_debug(struct json_intf_t* intf, FILE* file)
{ intf->print_error_debug(intf, file); }
#endif

#define JSON_INTF_OBJ_AS(n)                                           \
    ({                                                                \
        if (!JSON_INTF_OBJ_IS(n))                                     \
            UNEXPECT_ERR("object interface is not of type '%s'", #n); \
        intf->ptr.n;                                                  \
    })

struct json_obj_t* json_intf_get_as_obj(struct json_intf_t* intf)
{
    return JSON_INTF_OBJ_AS(obj);
}

struct json_ast_t* json_intf_get_as_ast(struct json_intf_t* intf)
{
    return JSON_INTF_OBJ_AS(ast);
}

struct json_type_t* json_intf_get_as_type(struct json_intf_t* intf)
{
    return JSON_INTF_OBJ_AS(type);
}

struct json_type_lib_t* json_intf_get_as_type_lib(struct json_intf_t* intf)
{
    return JSON_INTF_OBJ_AS(type_lib);
}

struct json_filter_lib_t* json_intf_get_as_filter_lib(struct json_intf_t* intf)
{
    return JSON_INTF_OBJ_AS(filter_lib);
}

struct json_esc_t* json_intf_get_as_esc(struct json_intf_t* intf)
{
    return JSON_INTF_OBJ_AS(esc);
}

