def _add_id_or_name(flat_path, element_pb, empty_allowed):
    """Add the ID or name from an element to a list.

    :type flat_path: list
    :param flat_path: List of accumulated path parts.

    :type element_pb: :class:`._app_engine_key_pb2.Path.Element`
    :param element_pb: The element containing ID or name.

    :type empty_allowed: bool
    :param empty_allowed: Indicates if neither ID or name need be set. If
                          :data:`False`, then **exactly** one of them must be.

    :raises: :exc:`ValueError` if 0 or 2 of ID/name are set (unless
             ``empty_allowed=True`` and 0 are set).
    """
    id_ = element_pb.id
    name = element_pb.name
    # NOTE: Below 0 and the empty string are the "null" values for their
    #       respective types, indicating that the value is unset.
    if id_ == 0:
        if name == u"":
            if not empty_allowed:
                raise ValueError(_EMPTY_ELEMENT)
        else:
            flat_path.append(name)
    else:
        if name == u"":
            flat_path.append(id_)
        else:
            msg = _BAD_ELEMENT_TEMPLATE.format(id_, name)
            raise ValueError(msg)
Add the ID or name from an element to a list.

    :type flat_path: list
    :param flat_path: List of accumulated path parts.

    :type element_pb: :class:`._app_engine_key_pb2.Path.Element`
    :param element_pb: The element containing ID or name.

    :type empty_allowed: bool
    :param empty_allowed: Indicates if neither ID or name need be set. If
                          :data:`False`, then **exactly** one of them must be.

    :raises: :exc:`ValueError` if 0 or 2 of ID/name are set (unless
             ``empty_allowed=True`` and 0 are set).