#
#  Copyright (C) 2018 Codethink Limited
#  Copyright (C) 2019 Bloomberg LLP
#
#  This program is free software; you can redistribute it and/or
#  modify it under the terms of the GNU Lesser General Public
#  License as published by the Free Software Foundation; either
#  version 2 of the License, or (at your option) any later version.
#
#  This library 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
#  Lesser General Public License for more details.
#
#  You should have received a copy of the GNU Lesser General Public
#  License along with this library. If not, see <http://www.gnu.org/licenses/>.
#
#  Authors:
#        Tristan Van Berkom <tristan.vanberkom@codethink.co.uk>
#        Daniel Silverstone <daniel.silverstone@codethink.co.uk>
#        James Ennis <james.ennis@codethink.co.uk>
#        Benjamin Schubert <bschubert@bloomberg.net>

"""
Node - Parsed YAML configuration
================================

This module contains the building blocks for handling YAML configuration.

Everything that is loaded from YAML is encapsulated in such nodes, which
provide helper methods to validate configuration on access.

Using node methods when reading configuration will ensure that errors
are always coherently notified to the user.

.. note:: Plugins are not expected to handle exceptions thrown by node
          methods for the above reason; They are private. There should
          always be a way to acquire information without resorting to
          exception handling.

Node types
----------

The most important classes defined here are:

* :class:`.MappingNode`: represents a YAML Mapping (dictionary)
* :class:`.ScalarNode`: represents a YAML Scalar (string, boolean, integer)
* :class:`.SequenceNode`: represents a YAML Sequence (list)


Class Reference
---------------
"""

import string

from ._exceptions import LoadError
from .exceptions import LoadErrorReason


# A sentinel to be used as a default argument for functions that need
# to distinguish between a kwarg set to None and an unset kwarg.
_sentinel = object()


cdef class Node:
    """This is the base class for YAML document nodes.

    YAML Nodes contain information to describe the provenance of the YAML
    which resulted in the Node, allowing mapping back from a Node to the place
    in the file it came from.

    .. note:: You should never need to create a :class:`.Node` manually.
              If you do, you can create :class:`.Node` from dictionaries with
              :func:`Node.from_dict() <buildstream.node.Node.from_dict>`.
              If something else is needed, please open an issue.
    """

    def __init__(self):
        raise NotImplementedError("Please do not construct nodes like this. Use Node.from_dict(dict) instead.")

    def __cinit__(self, int file_index, int line, int column, *args):
        self.file_index = file_index
        self.line = line
        self.column = column

    # This is in order to ensure we never add a `Node` to a cache key
    # as ujson will try to convert objects if they have a `__json__`
    # attribute.
    def __json__(self):
        raise ValueError("Nodes should not be allowed when jsonify-ing data", self)

    def __str__(self):
        return "{}: {}".format(self.get_provenance(), self.strip_node_info())

    #############################################################
    #                  Abstract Public Methods                  #
    #############################################################

    cpdef Node clone(self):
        """Clone the node and return the copy.

        Returns:
            :class:`.Node`: a clone of the current node
        """
        raise NotImplementedError()

    cpdef object strip_node_info(self):
        """ Remove all the node information (provenance) and return the underlying data as plain python objects

        Returns:
            (list, dict, str, None): the underlying data that was held in the node structure.
        """
        raise NotImplementedError()

    #############################################################
    #                       Public Methods                      #
    #############################################################

    @classmethod
    def from_dict(cls, dict value):
        """from_dict(value)

        Create a new node from the given dictionary.

        This is a recursive operation, and will transform every value in the
        dictionary to a :class:`.Node` instance

        Valid values for keys are `str`
        Valid values for values are `list`, `dict`, `str`, `int`, `bool` or None.
        `list` and `dict` can also only contain such types.

        Args:
            value (dict): dictionary from which to create a node.

        Raises:
            :class:`TypeError`: when the value cannot be converted to a :class:`Node`

        Returns:
            :class:`.MappingNode`: a new mapping containing the value
        """
        if value:
            return __new_node_from_dict(value, MappingNode.__new__(
                MappingNode, _SYNTHETIC_FILE_INDEX, 0, __next_synthetic_counter(), {}))
        else:
            # We got an empty dict, we can shortcut
            return MappingNode.__new__(MappingNode, _SYNTHETIC_FILE_INDEX, 0, __next_synthetic_counter(), {})

    cpdef ProvenanceInformation get_provenance(self):
        """A convenience accessor to obtain the node's :class:`.ProvenanceInformation`

        The provenance information allows you to inform the user of where
        a node came. Transforming the information to a string will show the file, line and column
        in the file where the node is.

        An example usage would be:

        .. code-block:: python

            # With `config` being your node
            max_jobs_node = config.get_node('max-jobs')
            max_jobs = max_jobs_node.as_int()

            if max_jobs < 1:  # We can't get a negative number of jobs
                raise LoadError("Error at {}: Max jobs needs to be >= 1".format(
                    max_jobs_node.get_provenance()
                )

            # Will print something like:
            # element.bst [line 4, col 7]: Max jobs needs to be >= 1

        Returns:
            :class:`.ProvenanceInformation`: the provenance information for the node.
        """
        return ProvenanceInformation(self)

    #############################################################
    #        Abstract Private Methods used in BuildStream       #
    #############################################################

    # _assert_fully_composited()
    #
    # This must be called on a fully loaded and composited node,
    # after all composition has completed.
    #
    # This checks that no more composition directives are present
    # in the data.
    #
    # Raises:
    #    (LoadError): If any assertions fail
    #
    cpdef void _assert_fully_composited(self) except *:
        raise NotImplementedError()

    #############################################################
    #                Abstract Protected Methods                 #
    #############################################################

    # _compose_on(key, target, path)
    #
    # Compose the current node on the given target.
    #
    # Args:
    #   key (str): key on the target on which to compose the current value
    #   target (.Node): target node on which to compose
    #   path (list): path from the root of the target when composing recursively
    #         in order to give accurate error reporting.
    #
    # Raises:
    #   (_CompositeError): if an error is encountered during composition
    #
    cdef void _compose_on(self, str key, MappingNode target, list path) except *:
        raise NotImplementedError()

    # _is_composite_list
    #
    # Checks if the node is a Mapping with list composition
    # directives.
    #
    # Returns:
    #    (bool): True if node was a Mapping containing only
    #            list composition directives
    #
    # Raises:
    #    (LoadError): If node was a mapping and contained a mix of
    #                 list composition directives and other keys
    #
    cdef bint _is_composite_list(self) except *:
        raise NotImplementedError()

    # _walk_find(target, path)
    #
    # Walk the node to search for `target`.
    #
    # When this returns `True`, the `path` argument will contain the full path
    # to the target from the root node.
    #
    # Args:
    #   target (.Node): target to find in the node tree
    #   path (list): current path from the root
    #
    # Returns:
    #   (bool): whether the target was found in the tree or not
    #
    cdef bint _walk_find(self, Node target, list path) except *:
        raise NotImplementedError()

    #############################################################
    #                     Protected Methods                     #
    #############################################################

    # _shares_position_with(target)
    #
    # Check whether the current node is at the same position in its tree as the target.
    #
    # This is useful when we want to know if two nodes are 'identical', that is they
    # are at the exact same position in each respective tree, but do not necessarily
    # have the same content.
    #
    # Args:
    #   target (.Node): the target to compare with the current node.
    #
    # Returns:
    #   (bool): whether the two nodes share the same position
    #
    cdef bint _shares_position_with(self, Node target):
        return (self.file_index == target.file_index and
                self.line == target.line and
                self.column == target.column)


cdef class ScalarNode(Node):
    """This class represents a Scalar (int, str, bool, None) in a YAML document.

    .. note:: If you need to store another type of scalars, please open an issue
              on the project.

    .. note:: You should never have to create a :class:`.ScalarNode` directly
    """

    def __cinit__(self, int file_index, int line, int column, object value):
        cdef value_type = type(value)

        if value_type is str:
            value = value.strip()
        elif value_type is bool:
            if value:
                value = "True"
            else:
                value = "False"
        elif value_type is int:
            value = str(value)
        elif value is None:
            pass
        else:
            raise ValueError("ScalarNode can only hold str, int, bool or None objects")

        self.value = value

    def __reduce__(self):
        return (
            ScalarNode.__new__,
            (ScalarNode, self.file_index, self.line, self.column, self.value),
        )

    #############################################################
    #                       Public Methods                      #
    #############################################################

    cpdef bint as_bool(self) except *:
        """Get the value of the node as a boolean.

        .. note:: BuildStream treats the values 'True' and 'true' as True,
                  and the values 'False' and 'false' as False.  Any other
                  string values (such as the valid YAML 'TRUE' or 'FALSE'
                  will be considered as an error)

        Raises:
            :class:`buildstream._exceptions.LoadError`: if the value cannot be coerced to
                                                        a bool correctly.

        Returns:
            :class:`bool`: the value contained in the node, as a boolean
        """
        if type(self.value) is bool:
            return self.value

        # Don't coerce strings to booleans, this makes "False" strings evaluate to True
        if self.value in ('True', 'true'):
            return True
        elif self.value in ('False', 'false'):
            return False
        else:
            provenance = self.get_provenance()
            path = provenance._toplevel._find(self)[-1]
            raise LoadError("{}: Value of '{}' is not of the expected type '{}'"
                            .format(provenance, path, bool.__name__, self.value),
                            LoadErrorReason.INVALID_DATA)

    cpdef object as_enum(self, object constraint):
        """Get the value of the node as an enum member from `constraint`

        The constraint must be a :class:`buildstream.types.FastEnum` or a plain python Enum.

        For example you could do:

        .. code-block:: python

            from buildstream.types import FastEnum

            class SupportedCompressions(FastEnum):
              NONE = "none"
              GZIP = "gzip"
              XZ = "xz"


            x = config.get_scalar('compress').as_enum(SupportedCompressions)

            if x == SupportedCompressions.GZIP:
                print("Using GZIP")

        Args:
            constraint (:class:`buildstream.types.FastEnum` or :class:`Enum`): an enum from which to extract the value
                                                                               for the current node.

        Returns:
            :class:`FastEnum` or :class:`Enum`: the value contained in the node, as a member of `constraint`
        """
        try:
            return constraint(self.value)
        except ValueError:
            provenance = self.get_provenance()
            path = provenance._toplevel._find(self)[-1]
            valid_values = [str(v.value) for v in constraint]
            raise LoadError("{}: Value of '{}' should be one of '{}'".format(
                                provenance, path, ", ".join(valid_values)),
                            LoadErrorReason.INVALID_DATA)

    cpdef int as_int(self) except *:
        """Get the value of the node as an integer.

        Raises:
            :class:`buildstream._exceptions.LoadError`: if the value cannot be coerced to
                                                        an integer correctly.

        Returns:
            :class:`int`: the value contained in the node, as a integer
        """
        try:
            return int(self.value)
        except ValueError:
            provenance = self.get_provenance()
            path = provenance._toplevel._find(self)[-1]
            raise LoadError("{}: Value of '{}' is not of the expected type '{}'"
                            .format(provenance, path, int.__name__),
                            LoadErrorReason.INVALID_DATA)

    cpdef str as_str(self):
        """Get the value of the node as a string.

        Returns:
            :class:`str`: the value contained in the node, as a string, or `None` if the content
                          is `None`.
        """
        # We keep 'None' as 'None' to simplify the API's usage and allow chaining for users
        if self.value is None:
            return None
        return str(self.value)

    cpdef bint is_none(self):
        """Determine whether the current scalar is `None`.

        Returns:
            :class:`bool`: `True` if the value of the scalar is `None`, else `False`
        """
        return self.value is None

    #############################################################
    #               Public Methods implementations              #
    #############################################################

    cpdef ScalarNode clone(self):
        return ScalarNode.__new__(
            ScalarNode, self.file_index, self.line, self.column, self.value
        )

    cpdef object strip_node_info(self):
        return self.value

    #############################################################
    #              Private Methods implementations              #
    #############################################################

    cpdef void _assert_fully_composited(self) except *:
        pass

    #############################################################
    #                     Protected Methods                     #
    #############################################################

    cdef void _compose_on(self, str key, MappingNode target, list path) except *:
        cdef Node target_value = target.value.get(key)

        if target_value is not None and type(target_value) is not ScalarNode:
            raise __CompositeError(path,
                                   "{}: Cannot compose scalar on non-scalar at {}".format(
                                       self.get_provenance(),
                                       target_value.get_provenance()))

        target.value[key] = self

    cdef bint _is_composite_list(self) except *:
        return False

    cdef bint _walk_find(self, Node target, list path) except *:
        return self._shares_position_with(target)


cdef class MappingNode(Node):
    """This class represents a Mapping (dict) in a YAML document.

    It behaves mostly like a :class:`dict`, but doesn't allow untyped value access
    (Nothing of the form :code:`my_dict[my_value]`.

    It also doesn't allow anything else than :class:`str` as keys, to align with YAML.

    You can however use common dict operations in it:

    .. code-block:: python

        # Assign a new value to a key
        my_mapping[key] = my_value

        # Delete an entry
        del my_mapping[key]

    When assigning a key/value pair, the key must be a string,
    and the value can be any of:

    * a :class:`Node`, in which case the node is just assigned like normally
    * a :class:`list`, :class:`dict`, :class:`int`, :class:`str`, :class:`bool` or :class:`None`.
      In which case, the value will be converted to a :class:`Node` for you.

    Therefore, all values in a :class:`.MappingNode` will be :class:`Node`.

    .. note:: You should never create an instance directly. Use :func:`Node.from_dict() <buildstream.node.Node.from_dict>`
              instead, which will ensure your node is correctly formatted.
    """

    def __cinit__(self, int file_index, int line, int column, dict value):
        self.value = value

    def __reduce__(self):
        return (
            MappingNode.__new__,
            (MappingNode, self.file_index, self.line, self.column, self.value),
        )

    def __contains__(self, what):
        return what in self.value

    def __delitem__(self, str key):
        del self.value[key]

    def __setitem__(self, str key, object value):
        cdef Node old_value

        if type(value) in [MappingNode, ScalarNode, SequenceNode]:
            self.value[key] = value
        else:
            node = __create_node_recursive(value, self)

            # FIXME: Do we really want to override provenance?
            #
            # Related to https://gitlab.com/BuildStream/buildstream/issues/1058
            #
            # There are only two cases were nodes are set in the code (hence without provenance):
            #   - When automatic variables are set by the core (e-g: max-jobs)
            #   - when plugins call Element.set_public_data
            #
            # The first case should never throw errors, so it is of limited interests.
            #
            # The second is more important. What should probably be done here is to have 'set_public_data'
            # able of creating a fake provenance with the name of the plugin, the project and probably the
            # element name.
            #
            # We would therefore have much better error messages, and would be able to get rid of most synthetic
            # nodes.
            old_value = self.value.get(key)
            if old_value:
                node.file_index = old_value.file_index
                node.line = old_value.line
                node.column = old_value.column

            self.value[key] = node

    #############################################################
    #                       Public Methods                      #
    #############################################################

    cpdef bint get_bool(self, str key, object default=_sentinel) except *:
        """get_bool(key, default=sentinel)

        Get the value of the node for `key` as a boolean.

        This is equivalent to: :code:`mapping.get_scalar(my_key, my_default).as_bool()`.

        Args:
            key (str): key for which to get the value
            default (bool): default value to return if `key` is not in the mapping

        Raises:
           :class:`buildstream._exceptions.LoadError`: if the value at `key` is not a
                                                       :class:`.ScalarNode` or isn't a
                                                       valid `boolean`

        Returns:
            :class:`bool`: the value at `key` or the default
        """
        cdef ScalarNode scalar = self.get_scalar(key, default)
        return scalar.as_bool()

    cpdef object get_enum(self, str key, object constraint, object default=_sentinel):
        """Get the value of the node as an enum member from `constraint`

        Args:
            key (str): key for which to get the value
            constraint (:class:`buildstream.types.FastEnum` or :class:`Enum`): an enum from which to extract the value
                                                                               for the current node.
            default (object): default value to return if `key` is not in the mapping

        Raises:
            :class:`buildstream._exceptions.LoadError`: if the value is not is not found or not part of the
                                                        provided enum.

        Returns:
            :class:`buildstream.types.Enum` or :class:`Enum`: the value contained in the node, as a member of
                                                              `constraint`
        """
        cdef object value = self.value.get(key, _sentinel)

        if value is _sentinel:
            if default is _sentinel:
                provenance = self.get_provenance()
                raise LoadError("{}: Dictionary did not contain expected key '{}'".format(provenance, key),
                                LoadErrorReason.INVALID_DATA)

            if default is None:
                return None
            else:
                return constraint(default)

        if type(value) is not ScalarNode:
            provenance = value.get_provenance()
            raise LoadError("{}: Value of '{}' is not of the expected type 'scalar'"
                                .format(provenance, key),
                            LoadErrorReason.INVALID_DATA)

        return (<ScalarNode> value).as_enum(constraint)

    cpdef object get_int(self, str key, object default=_sentinel):
        """get_int(key, default=sentinel)

        Get the value of the node for `key` as an integer.

        This is equivalent to: :code:`mapping.get_scalar(my_key, my_default).as_int()`.

        Args:
            key (str): key for which to get the value
            default (int, None): default value to return if `key` is not in the mapping

        Raises:
           :class:`buildstream._exceptions.LoadError`: if the value at `key` is not a
                                                       :class:`.ScalarNode` or isn't a
                                                       valid `integer`

        Returns:
            :class:`int` or :class:`None`: the value at `key` or the default
        """
        cdef ScalarNode scalar = self.get_scalar(key, default)
        if default is None and scalar.is_none():
            return None
        return scalar.as_int()

    cpdef MappingNode get_mapping(self, str key, object default=_sentinel):
        """get_mapping(key, default=sentinel)

        Get the value of the node for `key` as a :class:`.MappingNode`.

        Args:
            key (str): key for which to get the value
            default (dict): default value to return if `key` is not in the mapping. It will be converted
                            to a :class:`.MappingNode` before being returned

        Raises:
           :class:`buildstream._exceptions.LoadError`: if the value at `key` is not a
                                                       :class:`.MappingNode`

        Returns:
            :class:`.MappingNode`: the value at `key` or the default
        """
        value = self._get(key, default, MappingNode)

        if type(value) is not MappingNode and value is not None:
            provenance = value.get_provenance()
            raise LoadError("{}: Value of '{}' is not of the expected type 'dict'"
                            .format(provenance, key), LoadErrorReason.INVALID_DATA)

        return value

    cpdef Node get_node(self, str key, list allowed_types = None, bint allow_none = False):
        """get_node(key, allowed_types=None, allow_none=False)

        Get the value of the node for `key` as a :class:`.Node`.

        This is useful if you have configuration that can be either a :class:`.ScalarNode` or
        a :class:`.MappingNode` for example.

        This method will validate that the value is indeed exactly one of those types (not a subclass)
        and raise an exception accordingly.

        Args:
            key (str): key for which to get the value
            allowed_types (list): list of valid subtypes of :class:`.Node` that are valid return values.
                                  If this is `None`, no checks are done on the return value.
            allow_none (bool): whether to allow the return value to be `None` or not

        Raises:
           :class:`buildstream._exceptions.LoadError`: if the value at `key` is not one
                                                       of the expected types or if it doesn't
                                                       exist.

        Returns:
            :class:`.Node`: the value at `key` or `None`
        """
        cdef value = self.value.get(key, _sentinel)

        if value is _sentinel:
            if allow_none:
                return None

            provenance = self.get_provenance()
            raise LoadError("{}: Dictionary did not contain expected key '{}'".format(provenance, key),
                            LoadErrorReason.INVALID_DATA)

        __validate_node_type(value, allowed_types, key)

        return value

    cpdef ScalarNode get_scalar(self, str key, object default=_sentinel):
        """get_scalar(key, default=sentinel)

        Get the value of the node for `key` as a :class:`.ScalarNode`.

        Args:
            key (str): key for which to get the value
            default (str, int, bool, None): default value to return if `key` is not in the mapping.
                                            It will be converted to a :class:`.ScalarNode` before being
                                            returned.

        Raises:
           :class:`buildstream._exceptions.LoadError`: if the value at `key` is not a
                                                       :class:`.MappingNode`

        Returns:
            :class:`.ScalarNode`: the value at `key` or the default
        """
        value = self._get(key, default, ScalarNode)

        if type(value) is not ScalarNode:
            if value is None:
                value = ScalarNode.__new__(ScalarNode, self.file_index, 0, __next_synthetic_counter(), None)
            else:
                provenance = value.get_provenance()
                raise LoadError("{}: Value of '{}' is not of the expected type 'scalar'"
                                .format(provenance, key), LoadErrorReason.INVALID_DATA)

        return value

    cpdef SequenceNode get_sequence(self, str key, object default=_sentinel, list allowed_types = None):
        """get_sequence(key, default=sentinel)

        Get the value of the node for `key` as a :class:`.SequenceNode`.

        Args:
            key (str): key for which to get the value
            default (list): default value to return if `key` is not in the mapping. It will be converted
                            to a :class:`.SequenceNode` before being returned
            allowed_types (list): list of valid subtypes of :class:`.Node` that are valid for nodes in the sequence.

        Raises:
           :class:`buildstream._exceptions.LoadError`: if the value at `key` is not a
                                                       :class:`.SequenceNode`

        Returns:
            :class:`.SequenceNode`: the value at `key` or the default
        """
        cdef Node value = self._get(key, default, SequenceNode)
        cdef Node node

        if type(value) is not SequenceNode and value is not None:
            provenance = value.get_provenance()
            raise LoadError("{}: Value of '{}' is not of the expected type 'list'"
                            .format(provenance, key), LoadErrorReason.INVALID_DATA)

        if allowed_types:
            for node in value:
                __validate_node_type(node, allowed_types)

        return <SequenceNode> value

    cpdef str get_str(self, str key, object default=_sentinel):
        """get_str(key, default=sentinel)

        Get the value of the node for `key` as an string.

        This is equivalent to: :code:`mapping.get_scalar(my_key, my_default).as_str()`.

        Args:
            key (str): key for which to get the value
            default (str): default value to return if `key` is not in the mapping

        Raises:
           :class:`buildstream._exceptions.LoadError`: if the value at `key` is not a
                                                       :class:`.ScalarNode` or isn't a
                                                       valid `str`

        Returns:
            :class:`str`: the value at `key` or the default
        """
        cdef ScalarNode scalar = self.get_scalar(key, default)
        return scalar.as_str()

    cpdef list get_str_list(self, str key, object default=_sentinel):
        """get_str_list(key, default=sentinel)

        Get the value of the node for `key` as a list of strings.

        This is equivalent to: :code:`mapping.get_sequence(my_key, my_default).as_str_list()`.

        Args:
            key (str): key for which to get the value
            default (str): default value to return if `key` is not in the mapping

        Raises:
           :class:`buildstream._exceptions.LoadError`: if the value at `key` is not a
                                                       :class:`.SequenceNode` or if any
                                                       of its internal values is not a ScalarNode.

        Returns:
            :class:`list`: the value at `key` or the default
        """
        cdef SequenceNode sequence = self.get_sequence(key, default)
        if sequence is not None:
            return sequence.as_str_list()
        return None

    cpdef object items(self):
        """Get a new view of the mapping items ((key, value) pairs).

        This is equivalent to running :code:`my_dict.item()` on a `dict`.

        Returns:
             :class:`dict_items`: a view on the underlying dictionary
        """
        return self.value.items()

    cpdef list keys(self):
        """Get the list of all keys in the mapping.

        This is equivalent to running :code:`my_dict.keys()` on a `dict`.

        Returns:
             :class:`list`: a list of all keys in the mapping
        """
        return list(self.value.keys())

    cpdef void safe_del(self, str key):
        """safe_del(key)

        Remove the entry at `key` in the dictionary if it exists.

        This method is a safe equivalent to :code:`del mapping[key]`, that doesn't
        throw anything if the key doesn't exist.

        Args:
            key (str): key to remove from the mapping
        """
        self.value.pop(key, None)

    cpdef void validate_keys(self, list valid_keys) except *:
        """validate_keys(valid_keys)

        Validate that the node doesn't contain extra keys

        This validates the node so as to ensure the user has not specified
        any keys which are unrecognized by BuildStream (usually this
        means a typo which would otherwise not trigger an error).

        Args:
           valid_keys (list): A list of valid keys for the specified node

        Raises:
            :class:`buildstream._exceptions.LoadError`: In the case that the specified node contained
                                                        one or more invalid keys
        """

        # Probably the fastest way to do this: https://stackoverflow.com/a/23062482
        cdef set valid_keys_set = set(valid_keys)
        cdef str key

        for key in self.value:
            if key not in valid_keys_set:
                provenance = self.get_node(key).get_provenance()
                raise LoadError("{}: Unexpected key: {}".format(provenance, key),
                                LoadErrorReason.INVALID_DATA)

    cpdef object values(self):
        """Get the values in the mapping.

        This is equivalent to running :code:`my_dict.values()` on a `dict`.

        Returns:
             :class:`dict_values`: a list of all values in the mapping
        """
        return self.value.values()

    #############################################################
    #               Public Methods implementations              #
    #############################################################

    cpdef MappingNode clone(self):
        cdef dict copy = {}
        cdef str key
        cdef Node value

        for key, value in self.value.items():
            copy[key] = value.clone()

        return MappingNode.__new__(MappingNode, self.file_index, self.line, self.column, copy)

    cpdef object strip_node_info(self):
        cdef str key
        cdef Node value

        return {key: value.strip_node_info() for key, value in self.value.items()}

    #############################################################
    #            Private Methods used in BuildStream            #
    #############################################################

    # _composite()
    #
    # Compose one mapping node onto another
    #
    # Args:
    #    target (Node): The target to compose into
    #
    # Raises: LoadError
    #
    cpdef void _composite(self, MappingNode target) except *:
        try:
            self.__composite(target, [])
        except __CompositeError as e:
            source_provenance = self.get_provenance()
            error_prefix = ""
            if source_provenance:
                error_prefix = "{}: ".format(source_provenance)
            raise LoadError("{}Failure composing {}: {}"
                            .format(error_prefix,
                                    e.path,
                                    e.message),
                            LoadErrorReason.ILLEGAL_COMPOSITE) from e

    # Like self._composite(target), but where values in the target don't get overridden by values in self.
    #
    cpdef void _composite_under(self, MappingNode target) except *:
        target._composite(self)

        cdef str key
        cdef Node value
        cdef list to_delete = [key for key in target.value.keys() if key not in self.value]

        for key, value in self.value.items():
            target.value[key] = value
        for key in to_delete:
            del target.value[key]

    # _find()
    #
    # Searches the given node tree for the given target node.
    #
    # This is typically used when trying to walk a path to a given node
    # for the purpose of then modifying a similar tree of objects elsewhere
    #
    # Args:
    #    target (Node): The node you are looking for in that tree
    #
    # Returns:
    #    (list): A path from `node` to `target` or None if `target` is not in the subtree
    cpdef list _find(self, Node target):
        cdef list path = []
        if self._walk_find(target, path):
            return path
        return None

    #############################################################
    #              Private Methods implementations              #
    #############################################################

    cpdef void _assert_fully_composited(self) except *:
        cdef str key
        cdef Node value

        for key, value in self.value.items():
            # Assert that list composition directives dont remain, this
            # indicates that the user intended to override a list which
            # never existed in the underlying data
            #
            if key in ('(>)', '(<)', '(=)'):
                provenance = value.get_provenance()
                raise LoadError("{}: Attempt to override non-existing list".format(provenance),
                                LoadErrorReason.TRAILING_LIST_DIRECTIVE)

            value._assert_fully_composited()

    #############################################################
    #                     Protected Methods                     #
    #############################################################

    cdef void _compose_on(self, str key, MappingNode target, list path) except *:
        cdef Node target_value

        if self._is_composite_list():
            if key not in target.value:
                # Composite list clobbers empty space
                target.value[key] = self
            else:
                target_value = target.value[key]

                if type(target_value) is SequenceNode:
                    # Composite list composes into a list
                    self._compose_on_list(target_value)
                elif target_value._is_composite_list():
                    # Composite list merges into composite list
                    self._compose_on_composite_dict(target_value)
                else:
                    # Else composing on top of normal dict or a scalar, so raise...
                    raise __CompositeError(path,
                                           "{}: Cannot compose lists onto {}".format(
                                                self.get_provenance(),
                                                target_value.get_provenance()))
        else:
            # We're composing a dict into target now
            if key not in target.value:
                # Target lacks a dict at that point, make a fresh one with
                # the same provenance as the incoming dict
                target.value[key] = MappingNode.__new__(MappingNode, self.file_index, self.line, self.column, {})

            self.__composite(target.value[key], path)

    # _compose_on_list(target)
    #
    # Compose the current node on the given sequence.
    #
    # Args:
    #   target (.SequenceNode): sequence on which to compose the current composite dict
    #
    cdef void _compose_on_list(self, SequenceNode target):
        cdef SequenceNode clobber = self.value.get("(=)")
        cdef SequenceNode prefix = self.value.get("(<)")
        cdef SequenceNode suffix = self.value.get("(>)")

        if clobber is not None:
            target.value.clear()
            target.value.extend(clobber.value)
        if prefix is not None:
            for v in reversed(prefix.value):
                target.value.insert(0, v)
        if suffix is not None:
            target.value.extend(suffix.value)

    # _compose_on_composite_dict(target)
    #
    # Compose the current node on the given composite dict.
    #
    # A composite dict is a dict that contains composition directives.
    #
    # Args:
    #   target (.MappingNode): sequence on which to compose the current composite dict
    #
    cdef void _compose_on_composite_dict(self, MappingNode target):
        cdef SequenceNode clobber = self.value.get("(=)")
        cdef SequenceNode prefix = self.value.get("(<)")
        cdef SequenceNode suffix = self.value.get("(>)")

        if clobber is not None:
            # We want to clobber the target list
            # which basically means replacing the target list
            # with ourselves
            target.value["(=)"] = clobber
            if prefix is not None:
                target.value["(<)"] = prefix
            elif "(<)" in target.value:
                (<SequenceNode> target.value["(<)"]).value.clear()
            if suffix is not None:
                target.value["(>)"] = suffix
            elif "(>)" in target.value:
                (<SequenceNode> target.value["(>)"]).value.clear()
        else:
            # Not clobbering, so prefix the prefix and suffix the suffix
            if prefix is not None:
                if "(<)" in target.value:
                    for v in reversed(prefix.value):
                        (<SequenceNode> target.value["(<)"]).value.insert(0, v)
                else:
                    target.value["(<)"] = prefix
            if suffix is not None:
                if "(>)" in target.value:
                    (<SequenceNode> target.value["(>)"]).value.extend(suffix.value)
                else:
                    target.value["(>)"] = suffix

    cdef bint _is_composite_list(self) except *:
        cdef bint has_directives = False
        cdef bint has_keys = False
        cdef str key

        for key in self.value.keys():
            if key in ["(>)", "(<)", "(=)"]:
                has_directives = True
            else:
                has_keys = True

        if has_keys and has_directives:
            provenance = self.get_provenance()
            raise LoadError("{}: Dictionary contains list composition directives and arbitrary keys"
                            .format(provenance), LoadErrorReason.INVALID_DATA)

        return has_directives

    cdef bint _walk_find(self, Node target, list path) except *:
        cdef str k
        cdef Node v

        if self._shares_position_with(target):
            return True

        for k, v in self.value.items():
            path.append(k)
            if v._walk_find(target, path):
                return True
            del path[-1]

        return False

    #############################################################
    #                      Private Methods                      #
    #############################################################

    # __composite(target, path)
    #
    # Helper method to compose the current node on another.
    #
    # Args:
    #   target (.MappingNode): target on which to compose the current node
    #   path (list): path from the root of the target when composing recursively
    #                in order to give accurate error reporting.
    #
    cdef void __composite(self, MappingNode target, list path) except *:
        cdef str key
        cdef Node value

        for key, value in self.value.items():
            path.append(key)
            value._compose_on(key, target, path)
            path.pop()

        # Clobber the provenance of the target mapping node if we're not
        # synthetic.
        if self.file_index != _SYNTHETIC_FILE_INDEX:
            target.file_index = self.file_index
            target.line = self.line
            target.column = self.column

    # _get(key, default, default_constructor)
    #
    # Internal helper method to get an entry from the underlying dictionary.
    #
    # Args:
    #   key (str): the key for which to retrieve the entry
    #   default (object): default value if the entry is not present
    #   default_constructor (object): method to transform the `default` into a Node
    #                                 if the entry is not present
    #
    # Raises:
    #   (LoadError): if the key is not present and no default has been given.
    #
    cdef Node _get(self, str key, object default, object default_constructor):
        value = self.value.get(key, _sentinel)

        if value is _sentinel:
            if default is _sentinel:
                provenance = self.get_provenance()
                raise LoadError("{}: Dictionary did not contain expected key '{}'".format(provenance, key),
                                LoadErrorReason.INVALID_DATA)

            if default is None:
                value = None
            else:
                value = default_constructor.__new__(
                    default_constructor, _SYNTHETIC_FILE_INDEX, 0, __next_synthetic_counter(), default)

        return value


cdef class SequenceNode(Node):
    """This class represents a Sequence (list) in a YAML document.

    It behaves mostly like a :class:`list`, but doesn't allow untyped value access
    (Nothing of the form :code:`my_list[my_value]`).

    You can however perform common list operations on it:

    .. code-block:: python

        # Assign a value
        my_sequence[key] = value

        # Get the length
        len(my_sequence)

        # Reverse it
        reversed(my_sequence)

        # And iter over it
        for value in my_sequence:
            print(value)

    All values in a :class:`SequenceNode` will be :class:`Node`.
    """

    def __cinit__(self, int file_index, int line, int column, list value):
        self.value = value

    def __reduce__(self):
        return (
            SequenceNode.__new__,
            (SequenceNode, self.file_index, self.line, self.column, self.value),
        )

    def __iter__(self):
        return iter(self.value)

    def __len__(self):
        return len(self.value)

    def __reversed__(self):
        return reversed(self.value)

    def __setitem__(self, int key, object value):
        cdef Node old_value

        if type(value) in [MappingNode, ScalarNode, SequenceNode]:
            self.value[key] = value
        else:
            node = __create_node_recursive(value, self)

            # FIXME: Do we really want to override provenance?
            # See __setitem__ on 'MappingNode' for more context
            old_value = self.value[key]
            if old_value:
                node.file_index = old_value.file_index
                node.line = old_value.line
                node.column = old_value.column

            self.value[key] = node

    #############################################################
    #                       Public Methods                      #
    #############################################################

    cpdef void append(self, object value):
        """append(value)

        Append the given object to the sequence.

        Args:
            value (object): the value to append to the list. This can either be:

                                - a :class:`Node`
                                - a :class:`int`, :class:`bool`, :class:`str`, :class:`None`,
                                  :class:`dict` or :class:`list`. In which case, this will be
                                  converted into a :class:`Node` beforehand

        Raises:
            :class:`TypeError`: when the value cannot be converted to a :class:`Node`
        """
        if type(value) in [MappingNode, ScalarNode, SequenceNode]:
            self.value.append(value)
        else:
            node = __create_node_recursive(value, self)
            self.value.append(node)

    cpdef list as_str_list(self):
        """Get the values of the sequence as a list of strings.

        Raises:
            :class:`buildstream._exceptions.LoadError`: if the sequence contains more than
                                                        :class:`ScalarNode`

        Returns:
            :class:`list`: the content of the sequence as a list of strings
        """
        cdef list str_list = []
        cdef Node node
        for node in self.value:
            if type(node) is not ScalarNode:
                provenance = node.get_provenance()
                raise LoadError("{}: List item is not of the expected type 'scalar'"
                                .format(provenance), LoadErrorReason.INVALID_DATA)
            str_list.append(node.as_str())

        return str_list

    cpdef MappingNode mapping_at(self, int index):
        """mapping_at(index)

        Retrieve the entry at `index` as a :class:`.MappingNode`.

        Args:
            index (int): index for which to get the value

        Raises:
           :class:`buildstream._exceptions.LoadError`: if the value at `key` is not a
                                                       :class:`.MappingNode`
           :class:`IndexError`: if no value exists at this index

        Returns:
            :class:`.MappingNode`: the value at `index`
        """
        value = self.value[index]

        if type(value) is not MappingNode:
            provenance = self.get_provenance()
            path = ["[{}]".format(p) for p in provenance._toplevel._find(self)] + ["[{}]".format(index)]
            raise LoadError("{}: Value of '{}' is not of the expected type '{}'"
                            .format(provenance, path, MappingNode.__name__),
                            LoadErrorReason.INVALID_DATA)
        return value

    cpdef Node node_at(self, int index, list allowed_types = None):
        """node_at(index, allowed_types=None)

        Retrieve the entry at `index` as a :class:`.Node`.

        This is useful if you have configuration that can be either a :class:`.ScalarNode` or
        a :class:`.MappingNode` for example.

        This method will validate that the value is indeed exactly one of those types (not a subclass)
        and raise an exception accordingly.

        Args:
            index (int): index for which to get the value
            allowed_types (list): list of valid subtypes of :class:`.Node` that are valid return values.
                                  If this is `None`, no checks are done on the return value.

        Raises:
           :class:`buildstream._exceptions.LoadError`: if the value at `index` is not of one of the
                                                       expected types
           :class:`IndexError`: if no value exists at this index

        Returns:
            :class:`.Node`: the value at `index`
        """
        cdef value = self.value[index]
        __validate_node_type(value, allowed_types, str(index))
        return value

    cpdef ScalarNode scalar_at(self, int index):
        """scalar_at(index)

        Retrieve the entry at `index` as a :class:`.ScalarNode`.

        Args:
            index (int): index for which to get the value

        Raises:
           :class:`buildstream._exceptions.LoadError`: if the value at `key` is not a
                                                       :class:`.ScalarNode`
           :class:`IndexError`: if no value exists at this index

        Returns:
            :class:`.ScalarNode`: the value at `index`
        """
        value = self.value[index]

        if type(value) is not ScalarNode:
            provenance = self.get_provenance()
            path = ["[{}]".format(p) for p in provenance._toplevel._find(self)] + ["[{}]".format(index)]
            raise LoadError("{}: Value of '{}' is not of the expected type '{}'"
                            .format(provenance, path, ScalarNode.__name__),
                            LoadErrorReason.INVALID_DATA)
        return value

    cpdef SequenceNode sequence_at(self, int index):
        """sequence_at(index)

        Retrieve the entry at `index` as a :class:`.SequenceNode`.

        Args:
            index (int): index for which to get the value

        Raises:
           :class:`buildstream._exceptions.LoadError`: if the value at `key` is not a
                                                       :class:`.SequenceNode`
           :class:`IndexError`: if no value exists at this index

        Returns:
            :class:`.SequenceNode`: the value at `index`
        """
        value = self.value[index]

        if type(value) is not SequenceNode:
            provenance = self.get_provenance()
            path = ["[{}]".format(p) for p in provenance.toplevel._find(self)] + ["[{}]".format(index)]
            raise LoadError("{}: Value of '{}' is not of the expected type '{}'"
                            .format(provenance, path, SequenceNode.__name__),
                            LoadErrorReason.INVALID_DATA)

        return value

    #############################################################
    #               Public Methods implementations              #
    #############################################################

    cpdef SequenceNode clone(self):
        cdef list copy = []
        cdef Node entry

        for entry in self.value:
            copy.append(entry.clone())

        return SequenceNode.__new__(SequenceNode, self.file_index, self.line, self.column, copy)

    cpdef object strip_node_info(self):
        cdef Node value
        return [value.strip_node_info() for value in self.value]

    #############################################################
    #              Private Methods implementations              #
    #############################################################

    cpdef void _assert_fully_composited(self) except *:
        cdef Node value
        for value in self.value:
            value._assert_fully_composited()

    #############################################################
    #                     Protected Methods                     #
    #############################################################

    cdef void _compose_on(self, str key, MappingNode target, list path) except *:
        # List clobbers anything list-like
        cdef Node target_value = target.value.get(key)

        if not (target_value is None or
                type(target_value) is SequenceNode or
                target_value._is_composite_list()):
            raise __CompositeError(path,
                                  "{}: List cannot overwrite {} at: {}"
                                  .format(self.get_provenance(),
                                          key,
                                          target_value.get_provenance()))

        # If the target is a list of conditional statements, then we are
        # also conditional statements, and we need to append ourselves
        # to that list instead of overwriting it in order to preserve the
        # conditional for later evaluation.
        if type(target_value) is SequenceNode and key == "(?)":
            (<SequenceNode> target.value[key]).value.extend(self.value)
        else:
            # Looks good, clobber it
            target.value[key] = self

    cdef bint _is_composite_list(self) except *:
        return False

    cdef bint _walk_find(self, Node target, list path) except *:
        cdef int i
        cdef Node v

        if self._shares_position_with(target):
            return True

        for i, v in enumerate(self.value):
            path.append(i)
            if v._walk_find(target, path):
                return True
            del path[-1]

        return False


# Returned from Node.get_provenance
cdef class ProvenanceInformation:
    """Represents the location of a YAML node in a file.

    This can effectively be used as a pretty print to display those information in
    errors consistently.

    You can retrieve this information for a :class:`Node` with
    :func:`Node.get_provenance() <buildstream.node.Node.get_provenance()>`
    """

    def __init__(self, Node nodeish):
        cdef __FileInfo fileinfo

        self._node = nodeish
        if (nodeish is None) or (nodeish.file_index == _SYNTHETIC_FILE_INDEX):
            self._filename = ""
            self._shortname = ""
            self._displayname = ""
            self._line = 1
            self._col = 0
            self._toplevel = None
            self._project = None
        else:
            fileinfo = <__FileInfo> __FILE_LIST[nodeish.file_index]
            self._filename = fileinfo.filename
            self._shortname = fileinfo.shortname
            self._displayname = fileinfo.displayname
            # We add 1 here to convert from computerish to humanish
            self._line = nodeish.line + 1
            self._col = nodeish.column
            self._toplevel = fileinfo.toplevel
            self._project = fileinfo.project
        self._is_synthetic = (self._filename == '') or (self._col < 0)

    # Convert a Provenance to a string for error reporting
    def __str__(self):
        if self._is_synthetic:
            return "{} [synthetic node]".format(self._displayname)
        else:
            return "{} [line {:d} column {:d}]".format(self._displayname, self._line, self._col)


#############################################################
#                BuildStream Private methods                #
#############################################################

# Purely synthetic nodes will have _SYNTHETIC_FILE_INDEX for the file number, have line number
# zero, and a negative column number which comes from inverting the next value
# out of this counter.  Synthetic nodes created with a reference node will
# have a file number from the reference node, some unknown line number, and
# a negative column number from this counter.
cdef int _SYNTHETIC_FILE_INDEX = -1

# _assert_symbol_name()
#
# A helper function to check if a loaded string is a valid symbol
# name and to raise a consistent LoadError if not. For strings which
# are required to be symbols.
#
# Args:
#    symbol_name (str): The loaded symbol name
#    purpose (str): The purpose of the string, for an error message
#    ref_node (Node): The node of the loaded symbol, or None
#    allow_dashes (bool): Whether dashes are allowed for this symbol
#
# Raises:
#    LoadError: If the symbol_name is invalid
#
# Note that dashes are generally preferred for variable names and
# usage in YAML, but things such as option names which will be
# evaluated with jinja2 cannot use dashes.
def _assert_symbol_name(str symbol_name, str purpose, *, Node ref_node=None, bint allow_dashes=True):
    cdef str valid_chars = string.digits + string.ascii_letters + '_'
    if allow_dashes:
        valid_chars += '-'

    cdef bint valid = True
    if not symbol_name:
        valid = False
    elif any(x not in valid_chars for x in symbol_name):
        valid = False
    elif symbol_name[0] in string.digits:
        valid = False

    if not valid:
        detail = "Symbol names must contain only alphanumeric characters, " + \
                 "may not start with a digit, and may contain underscores"
        if allow_dashes:
            detail += " or dashes"

        message = "Invalid symbol name for {}: '{}'".format(purpose, symbol_name)
        if ref_node:
            provenance = ref_node.get_provenance()
            if provenance is not None:
                message = "{}: {}".format(provenance, message)

        raise LoadError(message, LoadErrorReason.INVALID_SYMBOL_NAME, detail=detail)


# _create_new_file(filename, shortname, displayname, toplevel, project)
#
# Create a new synthetic file and return it's index in the `._FILE_LIST`.
#
# Args:
#   filename (str): the name to give to the file
#   shortname (str): a shorter name used when showing information on the screen
#   displayname (str): the name to give when reporting errors
#   project (object): project with which to associate the current file (when dealing with junctions)
#
# Returns:
#   (int): the index in the `._FILE_LIST` that identifies the new file
#
cdef Py_ssize_t _create_new_file(str filename, str shortname, str displayname, object project):
    cdef Py_ssize_t file_number = len(__FILE_LIST)
    __FILE_LIST.append(__FileInfo(filename, shortname, displayname, None, project))

    return file_number


# _set_root_node_for_file(file_index, contents)
#
# Set the root node for the given file
#
# Args:
#   file_index (int): the index in the `._FILE_LIST` for the file for which to set the root
#   contents (.MappingNode): node that should be the root for the file
#
cdef void _set_root_node_for_file(Py_ssize_t file_index, MappingNode contents) except *:
    cdef __FileInfo f_info

    if file_index != _SYNTHETIC_FILE_INDEX:
        f_info = <__FileInfo> __FILE_LIST[file_index]
        f_info.toplevel = contents


# _new_synthetic_file()
#
# Create a new synthetic mapping node, with an associated file entry
# (in _FILE_LIST) such that later tracking can correctly determine which
# file needs writing to in order to persist the changes.
#
# Args:
#    filename (str): The name of the synthetic file to create
#    project (Project): The optional project to associate this synthetic file with
#
# Returns:
#    (Node): An empty YAML mapping node, whose provenance is to this new
#            synthetic file
#
def _new_synthetic_file(str filename, object project=None):
    cdef Py_ssize_t file_index = len(__FILE_LIST)
    cdef Node node = MappingNode.__new__(MappingNode, file_index, 0, 0, {})

    __FILE_LIST.append(__FileInfo(filename,
                                  filename,
                                  "<synthetic {}>".format(filename),
                                  node,
                                  project))
    return node


# _reset_global_state()
#
# This resets the global variables __FILE_LIST and __counter to their initial
# state. This is used by the test suite to improve isolation between tests
# running in the same process.
#
def _reset_global_state():
    global __FILE_LIST, __counter
    __FILE_LIST = []
    __counter = 0


#############################################################
#                 Module local helper Methods               #
#############################################################

# File name handling
cdef list __FILE_LIST = []

# synthetic counter for synthetic nodes
cdef int __counter = 0


class __CompositeError(Exception):
    def __init__(self, path, message):
        super().__init__(message)
        self.path = path
        self.message = message


# Metadata container for a yaml toplevel node.
#
# This class contains metadata around a yaml node in order to be able
# to trace back the provenance of a node to the file.
#
cdef class __FileInfo:

    cdef str filename, shortname, displayname
    cdef MappingNode toplevel,
    cdef object project

    def __init__(self, str filename, str shortname, str displayname, MappingNode toplevel, object project):
        self.filename = filename
        self.shortname = shortname
        self.displayname = displayname
        self.toplevel = toplevel
        self.project = project


cdef int __next_synthetic_counter():
    global __counter
    __counter -= 1
    return __counter


cdef Node __create_node_recursive(object value, Node ref_node):
    cdef value_type = type(value)

    if value_type is list:
        node = __new_node_from_list(value, ref_node)
    elif value_type in [int, str, bool]:
        node = ScalarNode.__new__(ScalarNode, ref_node.file_index, ref_node.line, __next_synthetic_counter(), value)
    elif value_type is dict:
        node = __new_node_from_dict(value, ref_node)
    else:
        raise TypeError(
            "Unable to assign a value of type {} to a Node.".format(value_type))

    return node


# _new_node_from_dict()
#
# Args:
#   indict (dict): The input dictionary
#   ref_node (Node): The dictionary to take as reference for position
#
# Returns:
#   (Node): A new synthetic YAML tree which represents this dictionary
#
cdef Node __new_node_from_dict(dict indict, Node ref_node):
    cdef MappingNode ret = MappingNode.__new__(
        MappingNode, ref_node.file_index, ref_node.line, __next_synthetic_counter(), {})
    cdef str k

    for k, v in indict.items():
        ret.value[k] = __create_node_recursive(v, ref_node)

    return ret


# Internal function to help new_node_from_dict() to handle lists
cdef Node __new_node_from_list(list inlist, Node ref_node):
    cdef SequenceNode ret = SequenceNode.__new__(
        SequenceNode, ref_node.file_index, ref_node.line, __next_synthetic_counter(), [])

    for v in inlist:
        ret.value.append(__create_node_recursive(v, ref_node))

    return ret


# __validate_node_type(node, allowed_types, key)
#
# Validates that this node is of the expected node type,
# and raises a user facing LoadError if not.
#
# Args:
#   allowed_types (list): list of valid subtypes of Node, or None
#   key (str): A key, in case the validated node is a value for a key
#
# Raises:
#    (LoadError): If this node is not of the expected type
#
cdef void __validate_node_type(Node node, list allowed_types = None, str key = None) except *:
    cdef ProvenanceInformation provenance
    cdef list human_types
    cdef str message

    if allowed_types and type(node) not in allowed_types:
        provenance = node.get_provenance()
        human_types = []
        if MappingNode in allowed_types:
            human_types.append("dict")
        if SequenceNode in allowed_types:
            human_types.append('list')
        if ScalarNode in allowed_types:
            human_types.append('scalar')

        message = "{}: Value ".format(provenance)
        if key:
            message += "of '{}' ".format(key)
        message += "is not one of the following: {}.".format(", ".join(human_types))
        raise LoadError(message, LoadErrorReason.INVALID_DATA)
