# Generated by the protocol buffer compiler.  DO NOT EDIT!
# sources: v1alpha1/graph.proto
# plugin: python-betterproto
# This file has been @generated
import builtins
from dataclasses import dataclass
from typing import (
    Dict,
    List,
    Optional,
)

import betterproto


@dataclass(eq=False, repr=False)
class Location(betterproto.Message):
    """Structured name identifying a path from a root to a Runtime"""

    location: List[str] = betterproto.string_field(1)
    """
    Atoms in the name, each identifying a Runtime that is a child
     of the previous Runtime
    """


@dataclass(eq=False, repr=False)
class StructValue(betterproto.Message):
    """A `Value::struct` of unordered fields named by distinct strings"""

    map: Dict[str, "Value"] = betterproto.map_field(
        1, betterproto.TYPE_STRING, betterproto.TYPE_MESSAGE
    )
    """Fields keyed by name"""


@dataclass(eq=False, repr=False)
class PairValue(betterproto.Message):
    """
    Contents of a `Value::pair` or one entry in a `MapValue`, i.e. two values
    """

    first: "Value" = betterproto.message_field(1)
    """First element of the `Value::pair` or key of the map entry"""

    second: "Value" = betterproto.message_field(2)
    """Second element of the `Value::pair` or value/RHS of the map entry"""


@dataclass(eq=False, repr=False)
class MapValue(betterproto.Message):
    """Contents of a `Value::map`: a collection of (key, value) pairs"""

    pairs: List["PairValue"] = betterproto.message_field(1)
    """
    List of mappings.
     (Note: keys of a protobuf `map` cannot be message types like `Value`.)
    """


@dataclass(eq=False, repr=False)
class VecValue(betterproto.Message):
    """Contents of a `Value::vec`: a list of values"""

    vec: List["Value"] = betterproto.message_field(2)
    """Elements of the list"""


@dataclass(eq=False, repr=False)
class VariantValue(betterproto.Message):
    """
    A `Value` tagged with a string to make a disjoint union of component types
    """

    tag: str = betterproto.string_field(1)
    """
    Label, selects the appropriate handler of a `Node::match`
     destructuring the variant
    """

    value: "Value" = betterproto.message_field(2)
    """Contents"""


@dataclass(eq=False, repr=False)
class Value(betterproto.Message):
    """A value that can be passed around a Tierkreis graph."""

    graph: "Graph" = betterproto.message_field(1, group="value")
    """A Tierkreis Graph (i.e., a higher-order function value)"""

    integer: int = betterproto.int64_field(2, group="value")
    """Signed 64-bit integer value"""

    boolean: bool = betterproto.bool_field(3, group="value")
    """Boolean value"""

    str: builtins.str = betterproto.string_field(9, group="value")
    """String value"""

    flt: float = betterproto.double_field(10, group="value")
    """Double-precision (64-bit) floating-point value"""

    pair: "PairValue" = betterproto.message_field(4, group="value")
    """A pair of two other values"""

    vec: "VecValue" = betterproto.message_field(5, group="value")
    """An arbitrary-length list of values"""

    map: "MapValue" = betterproto.message_field(7, group="value")
    """
    A map from keys (values) to values. Keys must be hashable, i.e. must not
     be or contain `graph`s, `map`s, `struct`s or `float`s
    """

    struct: "StructValue" = betterproto.message_field(8, group="value")
    """
    A structure (aka record) value with string-named fields (each storing a `Value`)
    """

    variant: "VariantValue" = betterproto.message_field(12, group="value")
    """
    A value tagged with a string to make a value of sum type (see `Type::Variant`)
    """


@dataclass(eq=False, repr=False)
class Output(betterproto.Message):
    """
    A value was placed onto an edge - used for visualization by the Python runtime.
    """

    edge: "Edge" = betterproto.message_field(1)
    """The edge (of the outermost graph) onto which the value was placed"""

    value: "Value" = betterproto.message_field(2)
    """The value, i.e. an intermediate during graph execution"""


@dataclass(eq=False, repr=False)
class OutputStream(betterproto.Message):
    """
    A list of all the `Output`s, used for visualization by the Python runtime.
    """

    stream: List["Output"] = betterproto.message_field(1)
    """All the `Output`s so far."""


@dataclass(eq=False, repr=False)
class Type(betterproto.Message):
    """
    / A type of values (generally of `Kind::Star`) that can be passed around a Tierkreis graph
     (except `Row`, of `Kind::Row`, describing a row of values which is not a value itself).
    """

    var: str = betterproto.string_field(1, group="type")
    """
    Type variable, used inside polymorphic `TypeScheme`s only.
     Can be of [Kind::Row] or [Kind::Star].
    """

    int: "Empty" = betterproto.message_field(2, group="type")
    """Type of signed integers (values must be `Value::int`)"""

    bool: "Empty" = betterproto.message_field(3, group="type")
    """Type of booleans (values must be `Value::bool`)"""

    graph: "GraphType" = betterproto.message_field(4, group="type")
    """Type of `Value::graph`s, with a specified row of inputs and outputs"""

    pair: "PairType" = betterproto.message_field(5, group="type")
    """Type of `Value::pair`s, with types for the two elements"""

    vec: "Type" = betterproto.message_field(6, group="type")
    """
    Type of arbitrary-length homogeneous lists, with the type for all elements.
     Values must be `Value::vec`.
    """

    row: "RowType" = betterproto.message_field(7, group="type")
    """
    An unordered row of named types. Unlike the other variants (except possibly
     `Type::Var`), this is a `Kind::Row`, not a type of values (`Kind::Star`), so
     cannot be used as a member of any other Type (e.g. `Type::Vec`). However,
     this can appear in a `LacksConstraint` or `PartitionConstraint`, or in a
     `tierkreis.v1alpha.signature.UnifyError`.
    """

    map: "PairType" = betterproto.message_field(9, group="type")
    """
    Type of maps, containing two types - one for all the keys and one for the values.
     We do nothing to rule out key types that are not hashable, only the actual
     `Value`s used as keys.
    """

    struct: "StructType" = betterproto.message_field(10, group="type")
    """
    Type of `Value::struct`s with a specified row of field names and types.
     Optionally, the struct type itself may have a name.
    """

    str: "Empty" = betterproto.message_field(11, group="type")
    """Type of strings (values must be `Value::str`)"""

    flt: "Empty" = betterproto.message_field(12, group="type")
    """Type of double-precision floats ()"""

    variant: "RowType" = betterproto.message_field(14, group="type")
    """
    A disjoint (tagged) union of other types, given as a row.
     May be open, for the output of a `Tag` operation, or closed,
     for the input to match (where the handlers are known).
    """


@dataclass(eq=False, repr=False)
class GraphType(betterproto.Message):
    """
    Describes the type of a graph by specifying the input and output rows
    """

    inputs: "RowType" = betterproto.message_field(1)
    """The inputs to the graph (known and/or variable)"""

    outputs: "RowType" = betterproto.message_field(2)
    """The outputs to the graph (known and/or variable)"""


@dataclass(eq=False, repr=False)
class PairType(betterproto.Message):
    """Used to describe the type of a pair, or of a map (key + value)"""

    first: "Type" = betterproto.message_field(1)
    """Type of the first element of the pair, or the keys in the map"""

    second: "Type" = betterproto.message_field(2)
    """Type of the second element of the pair, or the values in the map"""


@dataclass(eq=False, repr=False)
class RowType(betterproto.Message):
    """
    An unordered set of names (strings), each with a type; possibly
     plus a variable (of `Kind::Row`) to stand for an unknown portion.
    """

    content: Dict[str, "Type"] = betterproto.map_field(
        1, betterproto.TYPE_STRING, betterproto.TYPE_MESSAGE
    )
    """
    Known labels, and types for each (of course these may contain variables)
    """

    rest: str = betterproto.string_field(2)
    """
    May contain the name of a variable (of `Kind::Row`), in which case the `RowType`
     is an "open row" and also includes any number of other fields stood for by that
     variable (with names disjoint from those in `content`).
     Otherwise, a "closed row" i.e. exactly/only the fields in `content`
    """


@dataclass(eq=False, repr=False)
class StructType(betterproto.Message):
    """
    Describes a `Type::Struct`: the row of fields, optionally with a name for the type.
    """

    shape: "RowType" = betterproto.message_field(1)
    """The fields in the struct"""

    name: str = betterproto.string_field(2, group="name_opt")
    """Optional name of the struct type. (TODO how is this used?)"""


@dataclass(eq=False, repr=False)
class FunctionName(betterproto.Message):
    """Qualified name of a function"""

    namespaces: List[str] = betterproto.string_field(1)
    """
    Identifies a `tierkreis.v1alpha1.signature.Namespace` (perhaps a subspace)
     by traversing downwards from the root
    """

    name: str = betterproto.string_field(2)
    """Name of the function within that subspace"""


@dataclass(eq=False, repr=False)
class FunctionNode(betterproto.Message):
    """
    Describes a `Node::function`, identifying the function to call,
     and optionally a time after which execution should be retried
    """

    name: "FunctionName" = betterproto.message_field(1)
    """Qualified name of the function"""

    retry_secs: Optional[int] = betterproto.uint32_field(2, optional=True)
    """
    Time after which execution of the function may be assumed to have
     failed and should be retried (in due course)
    """


@dataclass(eq=False, repr=False)
class BoxNode(betterproto.Message):
    """Describes a `Node::box`: a location at which to run a graph"""

    loc: "Location" = betterproto.message_field(1)
    """On which runtime to run the subgraph"""

    graph: "Graph" = betterproto.message_field(2)
    """Definition of the graph to run"""


@dataclass(eq=False, repr=False)
class Node(betterproto.Message):
    """A node in a `Graph`"""

    input: "Empty" = betterproto.message_field(1, group="node")
    """The node that emits a graph's input values."""

    output: "Empty" = betterproto.message_field(2, group="node")
    """The node that receives a graph's output values."""

    const: "Value" = betterproto.message_field(3, group="node")
    """A node that emits a constant value (contained within)."""

    box: "BoxNode" = betterproto.message_field(4, group="node")
    """
    A subgraph embedded as a single node. The ports of the node are the ports
     of the embedded graph. Box nodes can be used to conveniently compose common
     subgraphs. The box also specifies a location at which to run the graph.
    """

    function: "FunctionNode" = betterproto.message_field(5, group="node")
    """
    A node that executes a function with a specified name. The type and runtime
     behavior of a function node depend on the functions provided by the environment
     in which the graph is interpreted.
    """

    match: "Empty" = betterproto.message_field(6, group="node")
    """
    Perform pattern matching on a variant value, with handlers according to the
     input `Type::variant`
    """

    tag: str = betterproto.string_field(7, group="node")
    """Create a variant. Tag(tag) :: forall T. T -> Variant(tag:T | ...)"""


@dataclass(eq=False, repr=False)
class Edge(betterproto.Message):
    """An edge in a `Graph`"""

    port_from: str = betterproto.string_field(1)
    """Source (out-)port of `node_from`"""

    port_to: str = betterproto.string_field(2)
    """Target/destination (in-)port of `node_to`"""

    node_from: int = betterproto.uint32_field(3)
    """Source node"""

    node_to: int = betterproto.uint32_field(4)
    """Source port"""

    edge_type: "Type" = betterproto.message_field(5)
    """
    Explicit annotation of the type of the edge. Client may (optionally)
     provide; typechecking will (always) fill in.
    """


@dataclass(eq=False, repr=False)
class Graph(betterproto.Message):
    """
    A computation graph is a directed acyclic port graph in which data flows along
     the edges and as it is processed by the nodes.  Nodes in the graph are densely numbered
     starting from 0. The inputs of the graph are emitted by a `Node::input` at index 0,
     and the outputs are received by a `Node::output` at index 1.
     Each node has labelled input and output ports, encoded implicitly as the endpoints of the
     graph's edges. The port labels are unique among a node's input and output ports individually,
     but input and output ports with the same label are considered different. Any port in the graph
     has exactly one edge connected to it.
    """

    nodes: List["Node"] = betterproto.message_field(1)
    """
    The nodes in the graph. The first two must be a `Node::input` and a `Node::output`,
     and there must not be any other such nodes at any other index.
    """

    edges: List["Edge"] = betterproto.message_field(2)
    """
    The edges in the graph. Each can optionally be annotated with a type.
    """

    name: str = betterproto.string_field(3)
    """
    User-provided name of the graph. Used for debug/display, does not affect execution.
    """

    input_order: List[str] = betterproto.string_field(4)
    """
    Optional ordering of input ports used by graph builders if available.
     Listed ports will be reported and wired up in the order given
     and before ports that are not listed
    """

    output_order: List[str] = betterproto.string_field(5)
    """Like `input_order` but for the output ports."""


@dataclass(eq=False, repr=False)
class Empty(betterproto.Message):
    """
    This is supposed to be `google.protobuf.Empty` but unfortunately there is no
     support for this in `betterproto` yet.
    """

    pass


@dataclass(eq=False, repr=False)
class TypeScheme(betterproto.Message):
    """
    A polymorphic type scheme. Usually (but not necessarily) for a function.
    """

    variables: List["TypeSchemeVar"] = betterproto.message_field(1)
    """
    Variables over which the scheme is polymorphic, each with its `Kind`.
     A concrete type (usable for a port or edge) can be obtained by giving
     a type or row (according to the `Kind`) for each.
    """

    constraints: List["Constraint"] = betterproto.message_field(2)
    """
    Constraints restricting the legal instantiations of the [Self::variables]
    """

    body: "Type" = betterproto.message_field(3)
    """
    The body of the type scheme, i.e. potentially containing occurrences of the
     `variables`, into which values (`Type`s or `RowTypes`) for the variables
     are substituted in order to instantiate the scheme into a concrete type.
    """


@dataclass(eq=False, repr=False)
class TypeSchemeVar(betterproto.Message):
    """Describes a variable bound by a `TypeScheme`"""

    name: str = betterproto.string_field(1)
    """Name of the variable"""

    kind: "Kind" = betterproto.message_field(2)
    """Whether the variable is a `Type` of `Value`s or a `RowType`"""


@dataclass(eq=False, repr=False)
class Constraint(betterproto.Message):
    """
    Specifies a restriction on possible instantiations of type variables in a [TypeScheme]
    """

    lacks: "LacksConstraint" = betterproto.message_field(1, group="constraint")
    """A type variable of `Kind::Row` does *not* have a specified label"""

    partition: "PartitionConstraint" = betterproto.message_field(2, group="constraint")
    """
    A row is the union of two other rows (we expect at least two of the three
     rows to contain variables)
    """


@dataclass(eq=False, repr=False)
class PartitionConstraint(betterproto.Message):
    """
    `Constraint` that a row is the union of two other rows (which for any label in common,
     must have `Type`s that can be made the same)
    """

    left: "Type" = betterproto.message_field(1)
    """
    One input to the union - a `Type::Row` or a `Type::Var` of `Kind::Row`
    """

    right: "Type" = betterproto.message_field(2)
    """
    The other input to the union - a `Type::Row` or a `Type::Var` of `Kind::Row`
    """

    union: "Type" = betterproto.message_field(3)
    """
    The result, i.e. `left` and `right` merged together.
     Could be a `Type::Row` or a `Type::Var` of `Kind::Row`
    """


@dataclass(eq=False, repr=False)
class LacksConstraint(betterproto.Message):
    """
    `Constraint` that a row does not contain an element with the specified name
    """

    row: "Type" = betterproto.message_field(1)
    """A `Type::row` or a `Type::var` of `Kind::row`"""

    label: str = betterproto.string_field(2)
    """Field name that must not be present in `row`"""


@dataclass(eq=False, repr=False)
class Kind(betterproto.Message):
    """
    The kind of a type variable - i.e. whether the "type" variable stands for
     a single type, or (some part of) a row.
    """

    star: "Empty" = betterproto.message_field(1, group="kind")
    """Kind of types (describing sets of values)"""

    row: "Empty" = betterproto.message_field(2, group="kind")
    """Kind of rows (unordered names each with a type)"""
