daml/daml-lf/spec/value.rst
Gary Verhaegen d2e2c21684
update copyright headers (#12240)
New year, new copyright, new expected unknown issues with various files
that won't be covered by the script and/or will be but shouldn't change.

I'll do the details on Jan 1, but would appreciate this being
preapproved so I can actually get it merged by then.

CHANGELOG_BEGIN
CHANGELOG_END
2022-01-03 16:36:51 +00:00

603 lines
19 KiB
ReStructuredText

.. Copyright (c) 2022 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.
.. SPDX-License-Identifier: Apache-2.0
Daml-LF Value Specification
===========================
**version 14, 22 June 2021**
The Daml-LF language includes ways to define *data types*,
specifications of structure, and includes rules by which a restricted
subset of those data types are considered *serializable*.
This specification, in concert with the ``value.proto`` machine-readable
definition, defines a format by which *values* of *serializable Daml-LF
types* may be represented. Only such *serializable values* may be
stored on a ledger.
Values are typically consumed in tandem with related Daml-LF type
information, so many fields that may be inferred with this information
are optional. For example, `message RecordField`_ names are defined as
part of their respective LF datatypes, so there is no need to repeat
that information in the record value.
Do not read this without ``value.proto``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
``value.proto`` defines the baseline rules for values; that file must be
consulted in concert with this document for a full specification of
Daml-LF values. Except where required for clarity, we do not repeat
rules defined and enforced in that file within this document. When
consulting the section on each message type, you must also refer to the
same definition in ``value.proto`` for a full definition of the
requirements for that message.
This document is insufficiently detailed to construct a correct value;
you must refer to ``value.proto`` as well to have a full set of rules.
Do not read ``value.proto`` without this
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
In the same fashion, ``value.proto`` by itself cannot be consulted for a
full specification of the value format, because it is impossible to
define all the requirements for values in the ``.proto`` format. All
such rules are included in this document, instead.
If you are constructing a Daml-LF value, it is not sufficient to merely
conform to the structure defined in ``value.proto``; you must also
conform to the rules defined in this document. A value that happens to
conform to ``value.proto``, yet violates some rule of this document, is
not a valid Daml-LF value.
Backward compatibility
^^^^^^^^^^^^^^^^^^^^^^
Daml-LF values are accompanied by a version identifier; every change to
``value.proto`` entails a change to this specification, and every change
to this specification introduces a unique new version. `Version
history`_ defines a total ordering of all past versions; any version *y*
not listed there should be considered *y>k* for any known version *k*.
A value of version *n* may be interpreted by consulting any version of
this document *m≥n*. Likewise, any version *q* of the value
specification is sufficient to interpret values of any version *r≤q*.
In other words, later versions of this specification preserve the
semantics and parseability of earlier versions; there is no need to
consult or implement older versions in order to interpret any value, and
you may always simply consult the latest appropriate version.
By contrast, a value of version *s* must be rejected by a
consumer that implements this specification of version *t<s*. So if you
produce a value of version *s*, you may assume that its consumer either
implements some version *u≥s*, or will reject the message containing the
value. The ``.proto`` format may make parsing such values possible, but
that is irrelevant; semantics defined in later versions of this
specification may be vital for correctly interpreting values defined
under those later versions, and you must not suppose otherwise.
For example, suppose you have a value of version 3. You can expect it
to be interpreted the same by consumers implementing specification
version 3, 5, 5000, and so on. On the other hand, you can expect a
consumer of version 1 or 2 to reject the message containing that value,
because specification version 3 might define some semantics vital to
understanding your value.
"since version"
~~~~~~~~~~~~~~~
Every message type and field is accompanied by one or more *since
version x* annotations in this document, preceding some description of
semantics. This defines when that message, field, or semantic rule was
introduced in the value specification. Where there are multiple
overlapping definitions of semantics for the same field of the form
*since version x*, the correct interpretation for any value of version
*y* is that under the greatest *x* such that *x≤y*, failing that the
second-greatest such *x*, and so on.
For example, suppose you have received values of versions 4 and 5, and
this document defines overlapping semantics for *since version 2*, *4*,
and *6*. You should interpret both values according to the *since
version 4* section, also relying on *since version 2* where not in
conflict with *since version 4*; however, the *since version 6* section
must be ignored entirely.
Changing this specification
^^^^^^^^^^^^^^^^^^^^^^^^^^^
Future versions of this specification must conform to the `Daml-LF
Governance process`_ and preserve all invariants described above. Where
these are in conflict, the governance process takes priority.
If you introduce version *z*, your changes to this document should
almost certainly all occur under *since version z* annotations; a new
version without any such annotations in either this or the
`transaction`_ specification is probably not a new version at all.
Simply updating the semantic descriptions is tantamount to retroactively
editing the specification of older versions, and is a violation of
governance except where correction of the description of those older
versions is actually desirable.
Moreover, if those semantics conflict with prior version *y*, such as by
deleting a field, you should note that with an annotation *since version
z, conflicts with version y*.
For example, suppose in version 4, you are defining new semantics for a
field introduced in version 2. Simply describing those semantics under
the existing *since version 2* section is a governance violation; you
must add a *since version 4* section and describe the semantics there;
this section should be titled *since version 4, conflicts with version
2* if it does not merely extend, but instead replaces some part of the
*since version 2* description.
However, you may modify the *since version 2* section to explain how
*that version* differs from the newly-added version 4; that is because
this change doesn't modify the specified rules for version 2, it merely
clarifies those rules for the reader, who might otherwise miss an
important subtlety in the comparison.
Additionally, you should update the following `Version history`_.
.. _`Daml-LF Governance process`: ../governance.rst
.. _`transaction`: transaction.rst
Version history
^^^^^^^^^^^^^^^
This table lists every version of this specification in ascending order
(oldest first).
Support for value versions 1 to 5 was dropped on 2020-12-10.
This breaking change does not impact ledgers created with SDK 1.0.0 or
later.
+--------------------+-----------------+
| Version identifier | Date introduced |
+====================+=================+
+--------------------+-----------------+
| 10 | 2019-11-07 |
+--------------------+-----------------+
| 11 | 2021-01-19 |
+--------------------+-----------------+
| 12 | 2021-01-27 |
+--------------------+-----------------+
| 13 | 2021-04-06 |
+--------------------+-----------------+
| 14 | 2021-22-06 |
+--------------------+-----------------+
| dev | |
+--------------------+-----------------+
message VersionedValue
^^^^^^^^^^^^^^^^^^^^^^
The outermost entry point, a `message Value`_ with version annotation.
(*since version 10*)
In this version, these fields are included:
* ``string`` version
* `message Value`_ value
``version`` is required, and must be a version of this specification.
For backward compatibility reasons:
- the version `10` is encoded as the string "6";
- string "10" is reserved and will be never used to encoded any future version;
- versions 11 or latter will be encoded as string, for instance
version 11 of this specification, ``version`` must be ``"11"``.
Consumers can expect this field to be present and to have the
semantics defined here without knowing the version of this value in
advance.
Known versions are listed in ascending order in `Version history`_; any
``version`` not in this list should be considered newer than any version
in same list, and consumers must reject values with such unknown
versions.
``value`` is required.
``VersionedValue`` does not participate in the general recursion of
`message Value`_ itself, because every whole ``Value`` must be
interpreted only according to a single version of this specification.
message Value
^^^^^^^^^^^^^
An actual Daml-LF *serializable value*.
(*since version 10*)
As of version 10, may be any one of these:
* `message Record`_ record
* `message Variant`_ variant
* `message ContractId`_ contract_id_struct
* `message List`_ list
* ``sint64`` int64
* ``string`` `field numeric`_
* ``string`` text
* ``sfixed64`` `field timestamp`_
* ``string`` `field party`_
* ``bool`` bool
* ``Empty`` `field unit`_
* ``int32`` `field date`_
* `message Optional`_ optional
* `message Map`_ map
* `message Enum`_ enum
* `message Numeric`_ numeric
``Value`` is recursive by virtue of occurrences in some of the above
cases, e.g. ``list`` contains any number of ``Value``. The maximum
depth of a nested ``Value``, including the outermost, is 100; any more
yields an invalid value.
(*since version 11*)
As of version 11, may be any one of the above, or this:
* `message GenMap`_ gen_map
field contract_id
~~~~~~~~~~~~~~~~~
(*since version 10*)
Its text must be a valid contract ID.
field numeric
~~~~~~~~~~~~~
(*since version 10*)
Expresses a signed number that can be represented in base-10 without
loss of precision with at most 38 digits and with a scale between 0
and 37 (bounds inclusive). In other words, in base-10, a number with
at most 38 digits from which at most 37 appears on the right hand side
of the decimal point. A leading `-` sign may be optionally included
to indicate negative number. In regular expression terms::
-?([1-9][0-9]*|0)\.[0-9]*
with the additional constraint that the string must contain at most 38
digits.
Any value that does not conform, either by being outside the range or
having too many decimal digits or for any other reason, must be
rejected as an invalid message; consumers must not round, overflow, or
otherwise try to compensate for "bad" input when reading decimal
fields. As such, value producers should take care to properly format
these decimals.
field timestamp
~~~~~~~~~~~~~~~
(*since version 10*)
The number of microseconds since 1970-01-01T00:00:00Z, with that epoch
being 0. The allowed range is 0001-01-01T00:00:00Z to
9999-12-31T23:59:59.999999Z, inclusive; while ``sfixed64`` supports
numbers outside that range, such timestamps are not allowed and must be
rejected with error by conforming consumers.
field party
~~~~~~~~~~~
(*since version 10*)
A party identifier; unlike arbitrary text, this will be interpreted
with respect to the ledger under consideration by whatever command
contains this value. Party identifiers are restricted to be a
non-empty string of printable US-ASCII characters (characters ranging
from '\32' to '\127').
field unit
~~~~~~~~~~
(*since version 10*)
While ``Empty`` contains no information, conforming consumers are
permitted to expect this member of `message Value`_ to be chosen
correctly in appropriate contexts. So if the ``Value``'s Daml-LF type
is ``Unit``, a consumer *may* reject the message if the ``Value`` is not
the ``unit`` member of the sum, so value producers must take care to
select this member and not another value as a placeholder (e.g. 0,
false, empty text) in such cases.
field date
~~~~~~~~~~
(*since version 10*)
The number of days since 1970-01-01, with that epoch being 0. The
allowed range is 0001-01-01 to 9999-12-31, inclusive; while ``int32``
supports numbers outside that range, such dates are not allowed and must
be rejected with error by conforming consumers.
message Record
^^^^^^^^^^^^^^
(*since version 10*)
The core primitive for combining `message Value`_ of different type into
a single value.
As of version 10, these fields are included:
* `message Identifier`_ record_id
* repeated `message RecordField`_ fields
``record_id`` is required.
.. note: *this section is non-normative*
The fully-qualified `message Identifier`_ of the Daml-LF record
type.
The number and types of values in *fields* must match the Daml-LF
record type associated with the `message Record`_, whether that
record type is inferred from context or explicitly supplied as a
`field record_id`_.
Additionally, the *order* of fields must match the order in which
they are declared in Daml-LF for that record type. Neither
producers nor consumers are permitted to use ``label`` to reorder
the fields.
So, for example, it is unsafe to use a ``Map``, ``HashMap``, or
some such as a trivial intermediate representation of fields,
because enumerating it will likely output fields in the wrong
order; if such a structure is used, you must use the LF record type
information to output the fields in the correct order.
(*since version 12*)
As of version 12 the `field record_id`_ is not used anymore
message RecordField
^^^^^^^^^^^^^^^^^^^
(*since version 10*)
One of `field fields`_.
As of version 10, these fields are included:
* ``string`` label
* `message Value`_ value
``label`` may be an empty string and Value is required.
.. note: *this section is non-normative*
If ``label`` is non-empty it must match the name of the field in
this position in the Daml-LF record type under consideration. For
example, if the second field of an LF record type is named ``bar``,
then label of the second element of `field fields`_ may be
``"bar"``, or an empty string in circumstances mentioned above.
Any other label produces an invalid LF value.
The ``value`` field must conform to the type of this field of the
containing record, as declared by the LF record type. It must be
supplied in all cases.
(*since version 12*)
As of version 12, the field ``label`` is not used anymore.
message Identifier
^^^^^^^^^^^^^^^^^^
(*since version 10*)
A reference to a Daml-LF record or variant type.
As of version 10, these fields are included, all required to be
non-empty:
* ``string`` package_id
* repeated ``string`` module_name
* repeated ``string`` name
``package_id`` is a Daml-LF package ID, indicating the LF package in
which the type is defined. package ID are restricted to be a
non-empty string of printable US-ASCII characters (characters ranging
from '\32' to '\127').
``module_name`` lists the components of the name of the module within
that package.
``name`` lists the components of the name of the type declaration within
that module.
Each component of ``module_name`` and ``name`` must be non empty. Moreover,
we restrict each component as follows:
* The first character must be ``$``, ``_``, or an ASCII letter;
* Every other character must be ``$``, ``_``, an ASCII letter, or an
ASCII digit.
message Variant
^^^^^^^^^^^^^^^
(*since version 10*)
The core primitive for injecting `message Value`_ of different type into
a single type at runtime.
As of version 10, these fields are included:
* `message Identifier`_ variant_id
* ``string`` `field constructor`_
* `message Value`_ value
All the fields are required.
.. note: *this section is non-normative*
``value`` must conform to the LF type selected by the `field
constructor`_.
(*since version 12*)
As of version 12, the `field variant_id`_ is not used anymore.
field variant_id
~~~~~~~~~~~~~~~~
(*since version 10*)
The fully-qualified `message Identifier`_ of the Daml-LF variant type.
It may be omitted.
field constructor
~~~~~~~~~~~~~~~~~
The name of the variant alternative selected for this variant value.
Required.
For example, given the LF variant::
data E = L Text | R Text
A `message Variant`_ conforming to ``E`` may have in this field ``"L"``
or ``"R"``; any other ``constructor`` yields an invalid Value.
message ContractId
^^^^^^^^^^^^^^^^^^
(*since version 10*)
A reference to a contract, either absolute or relative.
As of version 10, this field is included:
* ``string`` contract_id
``contract_id`` must conform to the regular expression::
[A-Za-z0-9._:-]+
message List
^^^^^^^^^^^^
(*since version 10*)
A homogenous list of values.
As of version 10, these fields are included:
* repeated `message Value`_ elements
.. note: *this section is non-normative*
Every member of ``elements`` must conform to the same type.
message Optional
^^^^^^^^^^^^^^^^
(*since version 10*)
An optional value (equivalent to Scala's ``Option`` or Haskell's
``Maybe``).
In this version, these fields are included:
* `message Value`_ value
The ``value`` field is optional, embodying the semantics of the
``Optional`` type.
message Map.Entry
^^^^^^^^^^^^^^^^^
(*since version 10*)
A map entry (key-value pair) used to build `message Map`_.
As of version 10, these fields are included:
* string key
* `message Value`_ value
Both ``key`` and ``value`` are required.
message Map
^^^^^^^^^^^
(*since version 10*)
A homogeneous map where keys are strings.
In this version, these fields are included:
* repeated `message Map.Entry`_ entries
.. note: *this section is non-normative*
The ``value`` field of every member of ``entries`` must conform to
the same type. If two ore more entries have the same keys, the
last one overrides the former entry. Entries with different key may
occur in arbitrary order.
message Enum
^^^^^^^^^^^^
(*since version 10*)
An Enum value, a specialized form of variant without argument.
In this version, these fields are included:
* `message Identifier`_ enum_id
* ``string`` value
All fields are required.
(*since version 12*)
As of version 12, the `field enum_id`_ is not used anymore.
.. note: *this section is non-normative*
``value`` must to be one of the values of the enum type to which
this ``message Enum`` conforms.
message GenMap.Entry
^^^^^^^^^^^^^^^^^
(*since version 11*)
A map entry (key-value pair) used to build `message GenMap`_.
As of version 11, these fields are included:
* `message Value`_ key
* `message Value`_ value
Both ``key`` and ``value`` are required.
message GenMap
^^^^^^^^^^^
(*since version 11*)
A map where keys and values are homogeneous.
In this version, these fields are included:
* repeated `message GenMap.Entry`_ entries
.. note: *this section is non-normative*
The ``value`` field of every member of ``entries`` must conform to
the same type. The ``key`` field of every member of ``entries``
must conform to the same type. If two ore more entries have the
same keys, the last one overrides the former entry. Entries with
different key may occur in arbitrary order.