
#include "yaml_private.h"

/*
 * API functions.
 */

YAML_DECLARE(int)
yaml_parser_load(yaml_parser_t *parser, yaml_document_t *document);

/*
 * Error handling.
 */

static int
yaml_parser_set_composer_error(yaml_parser_t *parser,
        const char *problem, yaml_mark_t problem_mark);

static int
yaml_parser_set_composer_error_context(yaml_parser_t *parser,
        const char *context, yaml_mark_t context_mark,
        const char *problem, yaml_mark_t problem_mark);


/*
 * Alias handling.
 */

static int
yaml_parser_register_anchor(yaml_parser_t *parser,
        int index, yaml_char_t *anchor);

/*
 * Clean up functions.
 */

static void
yaml_parser_delete_aliases(yaml_parser_t *parser);

/*
 * Composer functions.
 */

static int
yaml_parser_load_document(yaml_parser_t *parser, yaml_event_t *first_event);

static int
yaml_parser_load_node(yaml_parser_t *parser, yaml_event_t *first_event);

static int
yaml_parser_load_alias(yaml_parser_t *parser, yaml_event_t *first_event);

static int
yaml_parser_load_scalar(yaml_parser_t *parser, yaml_event_t *first_event);

static int
yaml_parser_load_sequence(yaml_parser_t *parser, yaml_event_t *first_event);

static int
yaml_parser_load_mapping(yaml_parser_t *parser, yaml_event_t *first_event);

/*
 * Load the next document of the stream.
 */

YAML_DECLARE(int)
yaml_parser_load(yaml_parser_t *parser, yaml_document_t *document)
{
    yaml_event_t event;

    assert(parser);     /* Non-NULL parser object is expected. */
    assert(document);   /* Non-NULL document object is expected. */

    memset(document, 0, sizeof(yaml_document_t));
    if (!STACK_INIT(parser, document->nodes, INITIAL_STACK_SIZE))
        goto error;

    if (!parser->stream_start_produced) {
        if (!yaml_parser_parse(parser, &event)) goto error;
        assert(event.type == YAML_STREAM_START_EVENT);
                        /* STREAM-START is expected. */
    }

    if (parser->stream_end_produced) {
        return 1;
    }

    if (!yaml_parser_parse(parser, &event)) goto error;
    if (event.type == YAML_STREAM_END_EVENT) {
        return 1;
    }

    if (!STACK_INIT(parser, parser->aliases, INITIAL_STACK_SIZE))
        goto error;

    parser->document = document;

    if (!yaml_parser_load_document(parser, &event)) goto error;

    yaml_parser_delete_aliases(parser);
    parser->document = NULL;

    return 1;

error:

    yaml_parser_delete_aliases(parser);
    yaml_document_delete(document);
    parser->document = NULL;

    return 0;
}

/*
 * Set composer error.
 */

static int
yaml_parser_set_composer_error(yaml_parser_t *parser,
        const char *problem, yaml_mark_t problem_mark)
{
    parser->error = YAML_COMPOSER_ERROR;
    parser->problem = problem;
    parser->problem_mark = problem_mark;

    return 0;
}

/*
 * Set composer error with context.
 */

static int
yaml_parser_set_composer_error_context(yaml_parser_t *parser,
        const char *context, yaml_mark_t context_mark,
        const char *problem, yaml_mark_t problem_mark)
{
    parser->error = YAML_COMPOSER_ERROR;
    parser->context = context;
    parser->context_mark = context_mark;
    parser->problem = problem;
    parser->problem_mark = problem_mark;

    return 0;
}

/*
 * Delete the stack of aliases.
 */

static void
yaml_parser_delete_aliases(yaml_parser_t *parser)
{
    while (!STACK_EMPTY(parser, parser->aliases)) {
        yaml_free(POP(parser, parser->aliases).anchor);
    }
    STACK_DEL(parser, parser->aliases);
}

/*
 * Compose a document object.
 */

static int
yaml_parser_load_document(yaml_parser_t *parser, yaml_event_t *first_event)
{
    yaml_event_t event;

    assert(first_event->type == YAML_DOCUMENT_START_EVENT);
                        /* DOCUMENT-START is expected. */

    parser->document->version_directive
        = first_event->data.document_start.version_directive;
    parser->document->tag_directives.start
        = first_event->data.document_start.tag_directives.start;
    parser->document->tag_directives.end
        = first_event->data.document_start.tag_directives.end;
    parser->document->start_implicit
        = first_event->data.document_start.implicit;
    parser->document->start_mark = first_event->start_mark;

    if (!yaml_parser_parse(parser, &event)) return 0;

    if (!yaml_parser_load_node(parser, &event)) return 0;

    if (!yaml_parser_parse(parser, &event)) return 0;
    assert(event.type == YAML_DOCUMENT_END_EVENT);
                        /* DOCUMENT-END is expected. */

    parser->document->end_implicit = event.data.document_end.implicit;
    parser->document->end_mark = event.end_mark;

    return 1;
}

/*
 * Compose a node.
 */

static int
yaml_parser_load_node(yaml_parser_t *parser, yaml_event_t *first_event)
{
    switch (first_event->type) {
        case YAML_ALIAS_EVENT:
            return yaml_parser_load_alias(parser, first_event);
        case YAML_SCALAR_EVENT:
            return yaml_parser_load_scalar(parser, first_event);
        case YAML_SEQUENCE_START_EVENT:
            return yaml_parser_load_sequence(parser, first_event);
        case YAML_MAPPING_START_EVENT:
            return yaml_parser_load_mapping(parser, first_event);
        default:
            assert(0);  /* Could not happen. */
            return 0;
    }

    return 0;
}

/*
 * Add an anchor.
 */

static int
yaml_parser_register_anchor(yaml_parser_t *parser,
        int index, yaml_char_t *anchor)
{
    yaml_alias_data_t data;
    yaml_alias_data_t *alias_data;

    if (!anchor) return 1;

    data.anchor = anchor;
    data.index = index;
    data.mark = parser->document->nodes.start[index-1].start_mark;

    for (alias_data = parser->aliases.start;
            alias_data != parser->aliases.top; alias_data ++) {
        if (strcmp((char *)alias_data->anchor, (char *)anchor) == 0) {
            yaml_free(anchor);
            return yaml_parser_set_composer_error_context(parser,
                    "found duplicate anchor; first occurence",
                    alias_data->mark, "second occurence", data.mark);
        }
    }

    if (!PUSH(parser, parser->aliases, data)) {
        yaml_free(anchor);
        return 0;
    }

    return 1;
}

/*
 * Compose a node corresponding to an alias.
 */

static int
yaml_parser_load_alias(yaml_parser_t *parser, yaml_event_t *first_event)
{
    yaml_char_t *anchor = first_event->data.alias.anchor;
    yaml_alias_data_t *alias_data;

    for (alias_data = parser->aliases.start;
            alias_data != parser->aliases.top; alias_data ++) {
        if (strcmp((char *)alias_data->anchor, (char *)anchor) == 0) {
            yaml_free(anchor);
            return alias_data->index;
        }
    }

    yaml_free(anchor);
    return yaml_parser_set_composer_error(parser, "found undefined alias",
            first_event->start_mark);
}

/*
 * Compose a scalar node.
 */

static int
yaml_parser_load_scalar(yaml_parser_t *parser, yaml_event_t *first_event)
{
    yaml_node_t node;
    int index;
    yaml_char_t *tag = first_event->data.scalar.tag;

    if (!tag || strcmp((char *)tag, "!") == 0) {
        yaml_free(tag);
        tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_SCALAR_TAG);
        if (!tag) goto error;
    }

    SCALAR_NODE_INIT(node, tag, first_event->data.scalar.value,
            first_event->data.scalar.length, first_event->data.scalar.style,
            first_event->start_mark, first_event->end_mark);

    if (!PUSH(parser, parser->document->nodes, node)) goto error;

    index = parser->document->nodes.top - parser->document->nodes.start;

    if (!yaml_parser_register_anchor(parser, index,
                first_event->data.scalar.anchor)) return 0;

    return index;

error:
    yaml_free(tag);
    yaml_free(first_event->data.scalar.anchor);
    yaml_free(first_event->data.scalar.value);
    return 0;
}

/*
 * Compose a sequence node.
 */

static int
yaml_parser_load_sequence(yaml_parser_t *parser, yaml_event_t *first_event)
{
    yaml_event_t event;
    yaml_node_t node;
    struct {
        yaml_node_item_t *start;
        yaml_node_item_t *end;
        yaml_node_item_t *top;
    } items = { NULL, NULL, NULL };
    int index, item_index;
    yaml_char_t *tag = first_event->data.sequence_start.tag;

    if (!tag || strcmp((char *)tag, "!") == 0) {
        yaml_free(tag);
        tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_SEQUENCE_TAG);
        if (!tag) goto error;
    }

    if (!STACK_INIT(parser, items, INITIAL_STACK_SIZE)) goto error;

    SEQUENCE_NODE_INIT(node, tag, items.start, items.end,
            first_event->data.sequence_start.style,
            first_event->start_mark, first_event->end_mark);

    if (!PUSH(parser, parser->document->nodes, node)) goto error;

    index = parser->document->nodes.top - parser->document->nodes.start;

    if (!yaml_parser_register_anchor(parser, index,
                first_event->data.sequence_start.anchor)) return 0;

    if (!yaml_parser_parse(parser, &event)) return 0;

    while (event.type != YAML_SEQUENCE_END_EVENT) {
        item_index = yaml_parser_load_node(parser, &event);
        if (!item_index) return 0;
        if (!PUSH(parser,
                    parser->document->nodes.start[index-1].data.sequence.items,
                    item_index)) return 0;
        if (!yaml_parser_parse(parser, &event)) return 0;
    }

    parser->document->nodes.start[index-1].end_mark = event.end_mark;

    return index;

error:
    yaml_free(tag);
    yaml_free(first_event->data.sequence_start.anchor);
    return 0;
}

/*
 * Compose a mapping node.
 */

static int
yaml_parser_load_mapping(yaml_parser_t *parser, yaml_event_t *first_event)
{
    yaml_event_t event;
    yaml_node_t node;
    struct {
        yaml_node_pair_t *start;
        yaml_node_pair_t *end;
        yaml_node_pair_t *top;
    } pairs = { NULL, NULL, NULL };
    int index;
    yaml_node_pair_t pair;
    yaml_char_t *tag = first_event->data.mapping_start.tag;

    if (!tag || strcmp((char *)tag, "!") == 0) {
        yaml_free(tag);
        tag = yaml_strdup((yaml_char_t *)YAML_DEFAULT_MAPPING_TAG);
        if (!tag) goto error;
    }

    if (!STACK_INIT(parser, pairs, INITIAL_STACK_SIZE)) goto error;

    MAPPING_NODE_INIT(node, tag, pairs.start, pairs.end,
            first_event->data.mapping_start.style,
            first_event->start_mark, first_event->end_mark);

    if (!PUSH(parser, parser->document->nodes, node)) goto error;

    index = parser->document->nodes.top - parser->document->nodes.start;

    if (!yaml_parser_register_anchor(parser, index,
                first_event->data.mapping_start.anchor)) return 0;

    if (!yaml_parser_parse(parser, &event)) return 0;

    while (event.type != YAML_MAPPING_END_EVENT) {
        pair.key = yaml_parser_load_node(parser, &event);
        if (!pair.key) return 0;
        if (!yaml_parser_parse(parser, &event)) return 0;
        pair.value = yaml_parser_load_node(parser, &event);
        if (!pair.value) return 0;
        if (!PUSH(parser,
                    parser->document->nodes.start[index-1].data.mapping.pairs,
                    pair)) return 0;
        if (!yaml_parser_parse(parser, &event)) return 0;
    }

    parser->document->nodes.start[index-1].end_mark = event.end_mark;

    return index;

error:
    yaml_free(tag);
    yaml_free(first_event->data.mapping_start.anchor);
    return 0;
}

