draft-ietf-cbor-cddl-04.txt   draft-ietf-cbor-cddl-05.txt 
Network Working Group H. Birkholz CBOR H. Birkholz
Internet-Draft Fraunhofer SIT Internet-Draft Fraunhofer SIT
Intended status: Standards Track C. Vigano Intended status: Standards Track C. Vigano
Expires: February 11, 2019 Universitaet Bremen Expires: February 24, 2019 Universitaet Bremen
C. Bormann C. Bormann
Universitaet Bremen TZI Universitaet Bremen TZI
August 10, 2018 August 23, 2018
Concise data definition language (CDDL): a notational convention to Concise data definition language (CDDL): a notational convention to
express CBOR and JSON data structures express CBOR and JSON data structures
draft-ietf-cbor-cddl-04 draft-ietf-cbor-cddl-05
Abstract Abstract
This document proposes a notational convention to express CBOR data This document proposes a notational convention to express CBOR data
structures (RFC 7049). Its main goal is to provide an easy and structures (RFC 7049). Its main goal is to provide an easy and
unambiguous way to express structures for protocol messages and data unambiguous way to express structures for protocol messages and data
formats that use CBOR or JSON. formats that use CBOR or JSON.
Status of This Memo Status of This Memo
skipping to change at page 1, line 37 skipping to change at page 1, line 37
Internet-Drafts are working documents of the Internet Engineering Internet-Drafts are working documents of the Internet Engineering
Task Force (IETF). Note that other groups may also distribute Task Force (IETF). Note that other groups may also distribute
working documents as Internet-Drafts. The list of current Internet- working documents as Internet-Drafts. The list of current Internet-
Drafts is at https://datatracker.ietf.org/drafts/current/. Drafts is at https://datatracker.ietf.org/drafts/current/.
Internet-Drafts are draft documents valid for a maximum of six months Internet-Drafts are draft documents valid for a maximum of six months
and may be updated, replaced, or obsoleted by other documents at any and may be updated, replaced, or obsoleted by other documents at any
time. It is inappropriate to use Internet-Drafts as reference time. It is inappropriate to use Internet-Drafts as reference
material or to cite them other than as "work in progress." material or to cite them other than as "work in progress."
This Internet-Draft will expire on February 11, 2019. This Internet-Draft will expire on February 24, 2019.
Copyright Notice Copyright Notice
Copyright (c) 2018 IETF Trust and the persons identified as the Copyright (c) 2018 IETF Trust and the persons identified as the
document authors. All rights reserved. document authors. All rights reserved.
This document is subject to BCP 78 and the IETF Trust's Legal This document is subject to BCP 78 and the IETF Trust's Legal
Provisions Relating to IETF Documents Provisions Relating to IETF Documents
(https://trustee.ietf.org/license-info) in effect on the date of (https://trustee.ietf.org/license-info) in effect on the date of
publication of this document. Please review these documents publication of this document. Please review these documents
skipping to change at page 2, line 25 skipping to change at page 2, line 25
2.1.1. Usage . . . . . . . . . . . . . . . . . . . . . . . . 8 2.1.1. Usage . . . . . . . . . . . . . . . . . . . . . . . . 8
2.1.2. Syntax . . . . . . . . . . . . . . . . . . . . . . . 9 2.1.2. Syntax . . . . . . . . . . . . . . . . . . . . . . . 9
2.2. Types . . . . . . . . . . . . . . . . . . . . . . . . . . 9 2.2. Types . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2.2.1. Values . . . . . . . . . . . . . . . . . . . . . . . 9 2.2.1. Values . . . . . . . . . . . . . . . . . . . . . . . 9
2.2.2. Choices . . . . . . . . . . . . . . . . . . . . . . . 10 2.2.2. Choices . . . . . . . . . . . . . . . . . . . . . . . 10
2.2.3. Representation Types . . . . . . . . . . . . . . . . 12 2.2.3. Representation Types . . . . . . . . . . . . . . . . 12
2.2.4. Root type . . . . . . . . . . . . . . . . . . . . . . 13 2.2.4. Root type . . . . . . . . . . . . . . . . . . . . . . 13
3. Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 3. Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
3.1. General conventions . . . . . . . . . . . . . . . . . . . 13 3.1. General conventions . . . . . . . . . . . . . . . . . . . 13
3.2. Occurrence . . . . . . . . . . . . . . . . . . . . . . . 15 3.2. Occurrence . . . . . . . . . . . . . . . . . . . . . . . 15
3.3. Predefined names for types . . . . . . . . . . . . . . . 15 3.3. Predefined names for types . . . . . . . . . . . . . . . 16
3.4. Arrays . . . . . . . . . . . . . . . . . . . . . . . . . 16 3.4. Arrays . . . . . . . . . . . . . . . . . . . . . . . . . 16
3.5. Maps . . . . . . . . . . . . . . . . . . . . . . . . . . 17 3.5. Maps . . . . . . . . . . . . . . . . . . . . . . . . . . 17
3.5.1. Structs . . . . . . . . . . . . . . . . . . . . . . . 17 3.5.1. Structs . . . . . . . . . . . . . . . . . . . . . . . 17
3.5.2. Tables . . . . . . . . . . . . . . . . . . . . . . . 20 3.5.2. Tables . . . . . . . . . . . . . . . . . . . . . . . 20
3.5.3. Cuts in Maps . . . . . . . . . . . . . . . . . . . . 21 3.5.3. Non-deterministic order . . . . . . . . . . . . . . . 21
3.6. Tags . . . . . . . . . . . . . . . . . . . . . . . . . . 22 3.5.4. Cuts in Maps . . . . . . . . . . . . . . . . . . . . 22
3.7. Unwrapping . . . . . . . . . . . . . . . . . . . . . . . 22 3.6. Tags . . . . . . . . . . . . . . . . . . . . . . . . . . 23
3.8. Controls . . . . . . . . . . . . . . . . . . . . . . . . 23 3.7. Unwrapping . . . . . . . . . . . . . . . . . . . . . . . 23
3.8.1. Control operator .size . . . . . . . . . . . . . . . 24 3.8. Controls . . . . . . . . . . . . . . . . . . . . . . . . 24
3.8.2. Control operator .bits . . . . . . . . . . . . . . . 24 3.8.1. Control operator .size . . . . . . . . . . . . . . . 25
3.8.3. Control operator .regexp . . . . . . . . . . . . . . 25 3.8.2. Control operator .bits . . . . . . . . . . . . . . . 25
3.8.4. Control operators .cbor and .cborseq . . . . . . . . 27 3.8.3. Control operator .regexp . . . . . . . . . . . . . . 26
3.8.5. Control operators .within and .and . . . . . . . . . 27 3.8.4. Control operators .cbor and .cborseq . . . . . . . . 28
3.8.5. Control operators .within and .and . . . . . . . . . 28
3.8.6. Control operators .lt, .le, .gt, .ge, .eq, .ne, and 3.8.6. Control operators .lt, .le, .gt, .ge, .eq, .ne, and
.default . . . . . . . . . . . . . . . . . . . . . . 28 .default . . . . . . . . . . . . . . . . . . . . . . 29
3.9. Socket/Plug . . . . . . . . . . . . . . . . . . . . . . . 29 3.9. Socket/Plug . . . . . . . . . . . . . . . . . . . . . . . 30
3.10. Generics . . . . . . . . . . . . . . . . . . . . . . . . 30 3.10. Generics . . . . . . . . . . . . . . . . . . . . . . . . 31
3.11. Operator Precedence . . . . . . . . . . . . . . . . . . . 31 3.11. Operator Precedence . . . . . . . . . . . . . . . . . . . 32
4. Making Use of CDDL . . . . . . . . . . . . . . . . . . . . . 32 4. Making Use of CDDL . . . . . . . . . . . . . . . . . . . . . 33
4.1. As a guide to a human user . . . . . . . . . . . . . . . 32 4.1. As a guide to a human user . . . . . . . . . . . . . . . 33
4.2. For automated checking of CBOR data structure . . . . . . 33 4.2. For automated checking of CBOR data structure . . . . . . 34
4.3. For data analysis tools . . . . . . . . . . . . . . . . . 33 4.3. For data analysis tools . . . . . . . . . . . . . . . . . 34
5. Security considerations . . . . . . . . . . . . . . . . . . . 33 5. Security considerations . . . . . . . . . . . . . . . . . . . 34
6. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 34 6. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 35
6.1. CDDL control operator registry . . . . . . . . . . . . . 34 6.1. CDDL control operator registry . . . . . . . . . . . . . 35
7. References . . . . . . . . . . . . . . . . . . . . . . . . . 35
7.1. Normative References . . . . . . . . . . . . . . . . . . 35 7. References . . . . . . . . . . . . . . . . . . . . . . . . . 36
7.2. Informative References . . . . . . . . . . . . . . . . . 36 7.1. Normative References . . . . . . . . . . . . . . . . . . 36
Appendix A. (Not used.) . . . . . . . . . . . . . . . . . . . . 37 7.2. Informative References . . . . . . . . . . . . . . . . . 37
Appendix B. ABNF grammar . . . . . . . . . . . . . . . . . . . . 37 Appendix A. Examples . . . . . . . . . . . . . . . . . . . . . . 39
Appendix C. Matching rules . . . . . . . . . . . . . . . . . . . 40 A.1. RFC 7071 . . . . . . . . . . . . . . . . . . . . . . . . 39
Appendix D. Standard Prelude . . . . . . . . . . . . . . . . . . 44 A.2. Examples from JSON Content Rules . . . . . . . . . . . . 43
Appendix E. Use with JSON . . . . . . . . . . . . . . . . . . . 46 Appendix B. ABNF grammar . . . . . . . . . . . . . . . . . . . . 45
Appendix F. The CDDL tool . . . . . . . . . . . . . . . . . . . 48 Appendix C. Matching rules . . . . . . . . . . . . . . . . . . . 47
Appendix G. Extended Diagnostic Notation . . . . . . . . . . . . 48 Appendix D. Standard Prelude . . . . . . . . . . . . . . . . . . 51
G.1. White space in byte string notation . . . . . . . . . . . 49 Appendix E. Use with JSON . . . . . . . . . . . . . . . . . . . 53
G.2. Text in byte string notation . . . . . . . . . . . . . . 49 Appendix F. The CDDL tool . . . . . . . . . . . . . . . . . . . 55
G.3. Embedded CBOR and CBOR sequences in byte strings . . . . 49 Appendix G. Extended Diagnostic Notation . . . . . . . . . . . . 55
G.4. Concatenated Strings . . . . . . . . . . . . . . . . . . 50 G.1. White space in byte string notation . . . . . . . . . . . 56
G.5. Hexadecimal, octal, and binary numbers . . . . . . . . . 50 G.2. Text in byte string notation . . . . . . . . . . . . . . 56
G.6. Comments . . . . . . . . . . . . . . . . . . . . . . . . 51 G.3. Embedded CBOR and CBOR sequences in byte strings . . . . 56
Appendix H. Examples . . . . . . . . . . . . . . . . . . . . . . 51 G.4. Concatenated Strings . . . . . . . . . . . . . . . . . . 57
H.1. RFC 7071 . . . . . . . . . . . . . . . . . . . . . . . . 52 G.5. Hexadecimal, octal, and binary numbers . . . . . . . . . 57
H.1.1. Examples from JSON Content Rules . . . . . . . . . . 56 G.6. Comments . . . . . . . . . . . . . . . . . . . . . . . . 58
Contributors . . . . . . . . . . . . . . . . . . . . . . . . . . 58 Contributors . . . . . . . . . . . . . . . . . . . . . . . . . . 58
Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . 58 Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . 59
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 58 Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 59
1. Introduction 1. Introduction
In this document, a notational convention to express CBOR [RFC7049] In this document, a notational convention to express CBOR [RFC7049]
data structures is defined. data structures is defined.
The main goal for the convention is to provide a unified notation The main goal for the convention is to provide a unified notation
that can be used when defining protocols that use CBOR. We term the that can be used when defining protocols that use CBOR. We term the
convention "Concise data definition language", or CDDL. convention "Concise data definition language", or CDDL.
The CBOR notational convention has the following goals: The CBOR notational convention has the following goals:
(G1) Provide an unambiguous description of the overall structure of (G1) Provide an unambiguous description of the overall structure of
a CBOR data structure. a CBOR data item.
(G2) Flexibility to express the freedoms of choice in the CBOR data (G2) Be flexible in expressing the multiple ways in which data can
format. be represented in the CBOR data format.
(G3) Able to express common CBOR datatypes and structures. (G3) Able to express common CBOR datatypes and structures.
(G4) Human and machine readable and processable. (G4) Provide a single format that is both readable and editable for
humans and processable by machine.
(G5) Automatic checking of data format compliance. (G5) Enable automatic checking of CBOR data items for data format
compliance.
(G6) Extraction of specific elements from CBOR data for further (G6) Enable extraction of specific elements from CBOR data for
processing. further processing.
Not an original goal per se, but a convenient side effect of the JSON Not an original goal per se, but a convenient side effect of the JSON
generic data model being a subset of the CBOR generic data model, is generic data model being a subset of the CBOR generic data model, is
the fact that CDDL can also be used for describing JSON data the fact that CDDL can also be used for describing JSON data
structures (see Appendix E). structures (see Appendix E).
This document has the following structure: This document has the following structure:
The syntax of CDDL is defined in Section 3. Examples of CDDL and The syntax of CDDL is defined in Section 3. Examples of CDDL and
related CBOR data items ("instances") are defined in Appendix H. related CBOR data items ("instances", which all happen to be in JSON
Section 4 discusses usage of CDDL. Examples are provided early in form) are given in Appendix A. Section 4 discusses usage of CDDL.
the text to better illustrate concept definitions. A formal Examples are provided early in the text to better illustrate concept
definition of CDDL using ABNF grammar is provided in Appendix B. definitions. A formal definition of CDDL using ABNF grammar is
Finally, a _prelude_ of standard CDDL definitions that is provided in Appendix B. Finally, a _prelude_ of standard CDDL
automatically prepended to and thus available in every CBOR definitions that is automatically prepended to and thus available in
specification is listed in Appendix D. every CBOR specification is listed in Appendix D.
1.1. Requirements notation 1.1. Requirements notation
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and
"OPTIONAL" in this document are to be interpreted as described in RFC "OPTIONAL" in this document are to be interpreted as described in
2119, BCP 14 [RFC2119]. BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all
capitals, as shown here.
1.2. Terminology 1.2. Terminology
New terms are introduced in _cursive_. CDDL text in the running text New terms are introduced in _cursive_. CDDL text in the running text
is in "typewriter". is in "typewriter".
In this specification, the term "byte" is used in its now customary In this specification, the term "byte" is used in its now customary
sense as a synonym for "octet". sense as a synonym for "octet".
2. The Style of Data Structure Specification 2. The Style of Data Structure Specification
skipping to change at page 6, line 12 skipping to change at page 6, line 16
e.g., an "int" is either a "uint" or a "nint" (negative integer). e.g., an "int" is either a "uint" or a "nint" (negative integer).
Finally, a type can be built as an array or a map from a group. Finally, a type can be built as an array or a map from a group.
The rest of this section introduces a number of basic concepts of The rest of this section introduces a number of basic concepts of
CDDL, and section Section 3 defines additional syntax. Appendix C CDDL, and section Section 3 defines additional syntax. Appendix C
gives a concise summary of the semantics of CDDL. gives a concise summary of the semantics of CDDL.
2.1. Groups and Composition in CDDL 2.1. Groups and Composition in CDDL
CDDL Groups are lists of group _entries_, each of which can be a CDDL Groups are lists of group _entries_, each of which can be a
name/value pair or a more complex group expression composed of name/ name/value pair or a more complex group expression (which then in
value pairs. A CDDL group is a production in a grammar that can turn stands for a sequence of name/value pairs). A CDDL group is a
produce certain sequences of name/value pairs but not others. production in a grammar that matches certain sequences of name/value
pairs but not others. The grammar is based on the concepts of
Parsing Expression Grammars [PEG].
In an array context, only the value of the name/value pair is In an array context, only the value of the name/value pair is
represented; the name is annotation only (and can be left off from represented; the name is annotation only (and can be left off from
the group specification if not needed). In a map context, the names the group specification if not needed). In a map context, the names
become the map keys ("member keys"). become the map keys ("member keys").
In an array context, the sequence of elements in the group is In an array context, the actual sequence of elements in the group is
important, as it is the information that allows associating actual important, as that sequence is the information that allows
array elements with entries in the group. In a map context, the associating actual array elements with entries in the group. In a
sequence of entries in a group is not relevant (but there is still a map context, the sequence of entries in a group is not relevant (but
need to write down group entries in a sequence). there is still a need to write down group entries in a sequence).
An array matches a specification given as a group when the group can An array matches a specification given as a group when the group
produce a sequence of name/value pairs the value parts of which matches a sequence of name/value pairs the value parts of which
exactly match the elements of the array in order. exactly match the elements of the array in order.
A map matches a specification given as a group when the group can A map matches a specification given as a group when the group matches
produce a sequence of name/value pairs such that all of these name/ a sequence of name/value pairs such that all of these name/value
value pairs are present in the map and the map has no name/value pair pairs are present in the map and the map has no name/value pair that
that is not covered by the group. is not covered by the group.
A simple example of using a group right in a map definition is: A simple example of using a group directly in a map definition is:
person = { person = {
age: int, age: int,
name: tstr, name: tstr,
employer: tstr, employer: tstr,
} }
Figure 1: Using a group directly in a map Figure 1: Using a group directly in a map
The three entries of the group are written between the curly braces The three entries of the group are written between the curly braces
skipping to change at page 9, line 9 skipping to change at page 9, line 9
With this, one is allowed to define all small parts of their data With this, one is allowed to define all small parts of their data
structures and compose bigger protocol units with those or to have structures and compose bigger protocol units with those or to have
only one big protocol data unit that has all definitions ad hoc where only one big protocol data unit that has all definitions ad hoc where
needed. needed.
2.1.2. Syntax 2.1.2. Syntax
The composition syntax intends to be concise and easy to read: The composition syntax intends to be concise and easy to read:
o The start of a group can be marked by '(' o The start and end of a group can be marked by '(' and ')'
o The end of a group can be marked by ')'
o Definitions of entries inside of a group are noted as follows: o Definitions of entries inside of a group are noted as follows:
_keytype => valuetype,_ (read "keytype maps to valuetype"). The _keytype => valuetype,_ (read "keytype maps to valuetype"). The
comma is actually optional (not just in the final entry), but it comma is actually optional (not just in the final entry), but it
is considered good style to set it. The double arrow can be is considered good style to set it. The double arrow can be
replaced by a colon in the common case of directly using a text replaced by a colon in the common case of directly using a text
string or integer literal as a key (see Section 3.5.1). string or integer literal as a key (see Section 3.5.1; this is
also the common way of naming elements of an array just for
documentation, see Section 3.4).
A basic entry consists of a _keytype_ and a _valuetype_, both of A basic entry consists of a _keytype_ and a _valuetype_, both of
which are types (Section 2.2); this entry can produce any name-value which are types (Section 2.2); this entry matches any name-value pair
pair the name of which is in the keytype and the value of which is in the name of which is in the keytype and the value of which is in the
the valuetype. valuetype.
A group defined as a sequence of group entries can produce any A group defined as a sequence of group entries matches any sequence
sequence of name-value pairs that is composed by concatenation in of name-value pairs that is composed by concatenation in order of
order of what the entries can produce. what the entries match.
A group definition can also contain choices between groups, see A group definition can also contain choices between groups, see
Section 2.2.2. Section 2.2.2.
2.2. Types 2.2. Types
2.2.1. Values 2.2.1. Values
Values such as numbers and strings can be used in place of a type. Values such as numbers and strings can be used in place of a type.
(For instance, this is a very common thing to do for a keytype, (For instance, this is a very common thing to do for a keytype,
common enough that CDDL provides additional convenience syntax for common enough that CDDL provides additional convenience syntax for
this.) this.)
The value notation is based on the C language, but does not offer all The value notation is based on the C language, but does not offer all
the syntactic variations Appendix B. The value notation for numbers the syntactic variations (see Appendix B for details). The value
inherits from C the distinction between integer values (no fractional notation for numbers inherits from C the distinction between integer
part or exponent given -- NR1 [ISO6093]) and floating point values values (no fractional part or exponent given -- NR1 [ISO6093]) and
(where a fractional part and/or an exponent is present -- NR2 or floating point values (where a fractional part and/or an exponent is
NR3), so the type "1" does not include any floating point numbers present -- NR2 or NR3), so the type "1" does not include any floating
while the types "1e3" and "1.5" are both floating point numbers and point numbers while the types "1e3" and "1.5" are both floating point
do not include any integer numbers. numbers and do not include any integer numbers.
2.2.2. Choices 2.2.2. Choices
Many places that allow a type also allow a choice between types, Many places that allow a type also allow a choice between types,
delimited by a "/" (slash). The entire choice construct can be put delimited by a "/" (slash). The entire choice construct can be put
into parentheses if this is required to make the construction into parentheses if this is required to make the construction
unambiguous (please see Appendix B for the details). unambiguous (please see Appendix B for the details).
Choices of values can be used to express enumerations: Choices of values can be used to express enumerations:
skipping to change at page 10, line 34 skipping to change at page 10, line 34
delivery = ( delivery = (
street: tstr, ? number: uint, city // street: tstr, ? number: uint, city //
po-box: uint, city // po-box: uint, city //
per-pickup: true ) per-pickup: true )
city = ( city = (
name: tstr, zip-code: uint name: tstr, zip-code: uint
) )
A group choice can produce the union of the sets of name-value pair A group choice matches the union of the sets of name-value pair
sequences that the alternatives in the choice can. sequences that the alternatives in the choice can.
Both for type choices and for group choices, additional alternatives Both for type choices and for group choices, additional alternatives
can be added to a rule later in separate rules by using "/=" and can be added to a rule later in separate rules by using "/=" and
"//=", respectively, instead of "=": "//=", respectively, instead of "=":
attire /= "swimwear" attire /= "swimwear"
delivery //= ( delivery //= (
lat: float, long: float, drone-type: tstr lat: float, long: float, drone-type: tstr
skipping to change at page 11, line 35 skipping to change at page 11, line 35
float-range = 0.0..10.0 ; only floats match float-range = 0.0..10.0 ; only floats match
BAD-range1 = 0..10.0 ; NOT DEFINED BAD-range1 = 0..10.0 ; NOT DEFINED
BAD-range2 = 0.0..10 ; NOT DEFINED BAD-range2 = 0.0..10 ; NOT DEFINED
numeric-range = int-range / float-range numeric-range = int-range / float-range
(See also the control operators .lt/.ge and .le/.gt in (See also the control operators .lt/.ge and .le/.gt in
Section 3.8.6.) Section 3.8.6.)
Note that the dot is a valid name continuation character in CDDL, so Note that the dot is a valid name continuation character in CDDL, so
"min..max" is not a range expression but a single name. When using a "min..max" is not a range expression but a single name. When using a
name as the left hand side, use spacing as in "min .. max" to name as the left hand side of a range operator, use spacing as in
separate off the range operator. "min .. max" to separate off the range operator.
2.2.2.2. Turning a group into a choice 2.2.2.2. Turning a group into a choice
Some choices are built out of large numbers of values, often Some choices are built out of large numbers of values, often
integers, each of which is best given a semantic name in the integers, each of which is best given a semantic name in the
specification. Instead of naming each of these integers and then specification. Instead of naming each of these integers and then
accumulating these into a choice, CDDL allows building a choice from accumulating these into a choice, CDDL allows building a choice from
a group by prefixing it with a "&" character: a group by prefixing it with a "&" character:
terminal-color = &basecolors terminal-color = &basecolors
basecolors = ( basecolors = (
black: 0, red: 1, green: 2, yellow: 3, black: 0, red: 1, green: 2, yellow: 3,
blue: 4, magenta: 5, cyan: 6, white: 7, blue: 4, magenta: 5, cyan: 6, white: 7,
) )
extended-color = &( extended-color = &(
basecolors, basecolors,
orange: 8, pink: 9, purple: 10, brown: 11, orange: 8, pink: 9, purple: 10, brown: 11,
) )
As with the use of groups in arrays (Section 3.4), the membernames As with the use of groups in arrays (Section 3.4), the member names
have only documentary value (in particular, they might be used by a have only documentary value (in particular, they might be used by a
tool when displaying integers that are taken from that choice). tool when displaying integers that are taken from that choice).
2.2.3. Representation Types 2.2.3. Representation Types
CDDL allows the specification of a data item type by referring to the CDDL allows the specification of a data item type by referring to the
CBOR representation (major and minor numbers). How this is used CBOR representation (major and minor numbers). How this is used
should be evident from the prelude (Appendix D): a hash mark ("#") should be evident from the prelude (Appendix D): a hash mark ("#")
optionally followed by a major type, which can be followed by optionally followed by a number from 0 to 7 identifying the major
additional information, specifies the set of values that can be type, which then can be followed by a dot and a number specifying the
serialized in CBOR (i.e., "any"), by the given major type if one is additional information. This construction specifies the set of
given, or by the given major type with the additional information if values that can be serialized in CBOR (i.e., "any"), by the given
both are given. Note that although this notation is based on the major type if one is given, or by the given major type with the
CBOR serialization, it is about a set of values at the data model additional information if both are given. Where a major type of 6
level, e.g. "#7.25" specifies the set of values that can be (Tag) is used, the type of the tagged item can be specified by
represented as half-precision floats; it does not mandate that these appending it in parentheses.
values also do have to be serialized as half-precision floats: CDDL
does not provide any language means to restrict the choice of Note that although this notation is based on the CBOR serialization,
serialization variants. This also enables the use of CDDL with JSON, it is about a set of values at the data model level, e.g. "#7.25"
which uses a fundamentally different way of serializing (some of) the specifies the set of values that can be represented as half-precision
same values. floats; it does not mandate that these values also do have to be
serialized as half-precision floats: CDDL does not provide any
language means to restrict the choice of serialization variants.
This also enables the use of CDDL with JSON, which uses a
fundamentally different way of serializing (some of) the same values.
It may be necessary to make use of representation types outside the It may be necessary to make use of representation types outside the
prelude, e.g., a specification could start by making use of an prelude, e.g., a specification could start by making use of an
existing tag in a more specific way, or define a new tag not defined existing tag in a more specific way, or define a new tag not defined
in the prelude: in the prelude:
my_breakfast = #6.55799(breakfast) ; cbor-any is too general! my_breakfast = #6.55799(breakfast) ; cbor-any is too general!
breakfast = cereal / porridge breakfast = cereal / porridge
cereal = #6.998(tstr) cereal = #6.998(tstr)
porridge = #6.999([liquid, solid]) porridge = #6.999([liquid, solid])
skipping to change at page 14, line 34 skipping to change at page 14, line 42
They follow the conventions for strings as defined in section 7 of They follow the conventions for strings as defined in section 7 of
[RFC8259]. (ABNF users may want to note that there is no support [RFC8259]. (ABNF users may want to note that there is no support
in CDDL for the concept of case insensitivity in text strings; if in CDDL for the concept of case insensitivity in text strings; if
necessary, regular expressions can be used (Section 3.8.3).) necessary, regular expressions can be used (Section 3.8.3).)
o Byte strings are enclosed by single quotation "'" characters and o Byte strings are enclosed by single quotation "'" characters and
may be prefixed by "h" or "b64". If unprefixed, the string is may be prefixed by "h" or "b64". If unprefixed, the string is
interpreted as with a text string, except that single quotes must interpreted as with a text string, except that single quotes must
be escaped and that the UTF-8 bytes resulting are marked as a byte be escaped and that the UTF-8 bytes resulting are marked as a byte
string (major type 2). If prefixed as "h" or "b64", the string is string (major type 2). If prefixed as "h" or "b64", the string is
interpreted as a sequence of hex digits or a base64(url) string, interpreted as a sequence of pairs of hex digits (base16) or a
respectively (as with the diagnostic notation in section 6 of base64(url) string, respectively (as with the diagnostic notation
[RFC7049]; cf. Appendix G.2); any white space present within the in section 6 of [RFC7049]; cf. Appendix G.2); any white space
string (including comments) is ignored in the prefixed case. present within the string (including comments) is ignored in the
prefixed case.
o CDDL uses UTF-8 [RFC3629] for its encoding. o CDDL uses UTF-8 [RFC3629] for its encoding.
Example: Example:
; This is a comment ; This is a comment
person = { g } person = { g }
g = ( g = (
"name": tstr, "name": tstr,
skipping to change at page 15, line 15 skipping to change at page 15, line 23
3.2. Occurrence 3.2. Occurrence
An optional _occurrence_ indicator can be given in front of a group An optional _occurrence_ indicator can be given in front of a group
entry. It is either one of the characters '?' (optional), '*' (zero entry. It is either one of the characters '?' (optional), '*' (zero
or more), or '+' (one or more), or is of the form n*m, where n and m or more), or '+' (one or more), or is of the form n*m, where n and m
are optional unsigned integers and n is the lower limit (default 0) are optional unsigned integers and n is the lower limit (default 0)
and m is the upper limit (default no limit) of occurrences. and m is the upper limit (default no limit) of occurrences.
If no occurrence indicator is specified, the group entry is to occur If no occurrence indicator is specified, the group entry is to occur
exactly once (as if 1*1 were specified). A group entry with an exactly once (as if 1*1 were specified). A group entry with an
occurrence indicator can produce sequences of name-value pairs that occurrence indicator matches sequences of name-value pairs that are
are composed by concatenating a number of sequences that the basic composed by concatenating a number of sequences that the basic group
group entry can produce, where the number needs to be allowed by the entry matches, where the number needs to be allowed by the occurrence
occurrence indicator. indicator.
Note that CDDL, outside any directives/annotations that could Note that CDDL, outside any directives/annotations that could
possibly be defined, does not make any prescription as to whether possibly be defined, does not make any prescription as to whether
arrays or maps use the definite length or indefinite length encoding. arrays or maps use the definite length or indefinite length encoding.
I.e., there is no correlation between leaving the size of an array I.e., there is no correlation between leaving the size of an array
"open" in the spec and the fact that it is then interchanged with "open" in the spec and the fact that it is then interchanged with
definite or indefinite length. definite or indefinite length.
Please also note that CDDL can describe flexibility that the data Please also note that CDDL can describe flexibility that the data
model of the target representation does not have. This is rather model of the target representation does not have. This is rather
skipping to change at page 18, line 35 skipping to change at page 18, line 37
sample-point: int, sample-point: int,
samples: [+ float], samples: [+ float],
} }
where "located-samples" is the datatype to be used when referring to where "located-samples" is the datatype to be used when referring to
the struct, and "sample-point" and "samples" are the keys to be used. the struct, and "sample-point" and "samples" are the keys to be used.
This is actually a complete example: an identifier that is followed This is actually a complete example: an identifier that is followed
by a colon can be directly used as the text string for a member key by a colon can be directly used as the text string for a member key
(we speak of a "bareword" member key), as can a double-quoted string (we speak of a "bareword" member key), as can a double-quoted string
or a number. (When other types, in particular multi-valued ones, are or a number. (When other types, in particular multi-valued ones, are
used as keytypes, they are followed by a double arrow, see below.) used as the types of keys, they are followed by a double arrow, see
below.)
If a text string key does not match the syntax for an identifier (or If a text string key does not match the syntax for an identifier (or
if the specifier just happens to prefer using double quotes), the if the specifier just happens to prefer using double quotes), the
text string syntax can also be used in the member key position, text string syntax can also be used in the member key position,
followed by a colon. The above example could therefore have been followed by a colon. The above example could therefore have been
written with quoted strings in the member key positions. More written with quoted strings in the member key positions. More
generally, all the types defined can be used in a keytype position by generally, all the types defined can be used in a keytype position by
following them with a double arrow -- in particular, the double arrow following them with a double arrow -- in particular, the double arrow
is necessary if a type is named by an identifier (which would be is necessary if a type is named by an identifier (which would be
interpreted as a string before a colon). A string also is a (single- interpreted as a string before a colon). A string also is a (single-
valued) type, so another form for this example is: valued) type, so another form for this example is:
located-samples = { located-samples = {
"sample-point" => int, "sample-point" => int,
"samples" => [+ float], "samples" => [+ float],
} }
See Section 3.5.3 below for how the colon shortcut described here See Section 3.5.4 below for how the colon shortcut described here
also adds some implied semantics. also adds some implied semantics.
A better way to demonstrate the double-arrow use may be: A better way to demonstrate the double-arrow use may be:
located-samples = { located-samples = {
sample-point: int, sample-point: int,
samples: [+ float], samples: [+ float],
* equipment-type => equipment-tolerances, * equipment-type => equipment-tolerances,
} }
equipment-type = [name: tstr, manufacturer: tstr] equipment-type = [name: tstr, manufacturer: tstr]
equipment-tolerances = [+ [float, float]] equipment-tolerances = [+ [float, float]]
The example below defines a struct with optional entries: display The example below defines a struct with optional entries: display
name (as a text string), the name components first name and family name (as a text string), the name components first name and family
name (as a map of text strings), and age information (as an unsigned name (as text strings), and age information (as an unsigned integer).
integer).
PersonalData = { PersonalData = {
? displayName: tstr, ? displayName: tstr,
NameComponents, NameComponents,
? age: uint, ? age: uint,
} }
NameComponents = ( NameComponents = (
? firstName: tstr, ? firstName: tstr,
? familyName: tstr, ? familyName: tstr,
skipping to change at page 21, line 5 skipping to change at page 21, line 5
If the specification does not need to restrict one of x or y (i.e., If the specification does not need to restrict one of x or y (i.e.,
the application is free to choose per entry), it can be replaced by the application is free to choose per entry), it can be replaced by
the predefined name "any". the predefined name "any".
As another example, the following could be used as a conversion table As another example, the following could be used as a conversion table
converting from an integer or float to a string: converting from an integer or float to a string:
tostring = {* mynumber => tstr} tostring = {* mynumber => tstr}
mynumber = int / float mynumber = int / float
3.5.3. Cuts in Maps 3.5.3. Non-deterministic order
While the way arrays are matched is fully determined by the Parsing
Expression Grammar (PEG) algorithm, matching is more complicated for
maps, as maps do not have an inherent order. For each candidate
name/value pair that the PEG algorithm would try, a matching member
is picked out of the entire map. For certain group expressions, more
than one member in the map may match. Most often, this is
inconsequential, as the group expression tends to consume all
matches:
labeled-values = {
? fritz: number,
* label => value
}
label = text
value = number
Here, if any member with the key "fritz" is present, this will be
picked by the first entry of the group; all remaining text/number
member will be picked by the second entry (and if anything remains
unpicked, the map does not match).
However, it is possible to construct group expressions where what is
actually picked is indeterminate, and does matter:
do-not-do-this = {
int => int,
int => 6,
}
When this expression is matched against "{3: 5, 4: 6}", the first
group entry might pick off the "3: 5", leaving "4: 6" for matching
the second one. Or it might pick off "4: 6", leaving nothing for the
second entry. This pathological non-determinism is caused by
specifying more general before more specific, and by having a general
rule that only consumes a subset of the map key/value pairs that it
is able to match -- both tend not to occur in real-world
specifications of maps. At the time of writing, CDDL tools cannot
detect such cases automatically, and for the present version of the
CDDL specification, the specification writer is simply urged to not
write pathologically non-deterministic specifications.
(The astute reader will be reminded of what was called "ambiguous
content models" in SGML and "non-deterministic content models" in
XML. That problem is related to the one described here, but the
problem here is specifically caused by the lack of order in maps,
something that the XML schema languages do not have to contend with.
Note that Relax-NG's "interleave" pattern handles lack of order
explicitly on the specification side, while the instances in XML
always have determinate order.)
3.5.4. Cuts in Maps
The extensibility idiom discussed above for structs has one problem: The extensibility idiom discussed above for structs has one problem:
extensible-map-example = { extensible-map-example = {
? "optional-key" => int, ? "optional-key" => int,
* tstr => any * tstr => any
} }
In this example, there is one optional key "optional-key", which, In this example, there is one optional key "optional-key", which,
when present, maps to an integer. There is also a wild card for any when present, maps to an integer. There is also a wild card for any
skipping to change at page 21, line 35 skipping to change at page 22, line 39
extend the type of "optional-key"), but in many cases isn't. extend the type of "optional-key"), but in many cases isn't.
In anticipation of a more general potential feature called "cuts", In anticipation of a more general potential feature called "cuts",
CDDL allows inserting a cut "^" into the definition of the map entry: CDDL allows inserting a cut "^" into the definition of the map entry:
extensible-map-example = { extensible-map-example = {
? "optional-key" ^ => int, ? "optional-key" ^ => int,
* tstr => any * tstr => any
} }
A cut in this position means that once the map key matches the name A cut in this position means that once the member key matches the
part of an entry that can be produced and carries a cut, other name part of an entry that carries a cut, other potential matches for
potential matches for the key that occur in later entries in the the key of the member that occur in later entries in the group of the
group of the map are no longer allowed. (This rule applies map are no longer allowed. In other words, when a group entry would
independent of whether the value matches, too.) So the example above pick a key/value pair based on just a matching key, it "locks in" the
no longer matches the version modified with a cut. pick -- this rule applies independent of whether the value matches as
well, so when it does not, the entire map fails to match. In
summary, the example above no longer matches the specification as
modified with the cut.
Since the desire for this kind of exclusive matching is so frequent, Since the desire for this kind of exclusive matching is so frequent,
the ":" shortcut is actually defined to include the cut semantics. the ":" shortcut is actually defined to include the cut semantics.
So the preceding example (including the cut) can be written more So the preceding example (including the cut) can be written more
simply as: simply as:
extensible-map-example = { extensible-map-example = {
? "optional-key": int, ? "optional-key": int,
* tstr => any * tstr => any
} }
skipping to change at page 23, line 50 skipping to change at page 25, line 4
3.8. Controls 3.8. Controls
A _control_ allows to relate a _target_ type with a _controller_ type A _control_ allows to relate a _target_ type with a _controller_ type
via a _control operator_. via a _control operator_.
The syntax for a control type is "target .control-operator The syntax for a control type is "target .control-operator
controller", where control operators are special identifiers prefixed controller", where control operators are special identifiers prefixed
by a dot. (Note that _target_ or _controller_ might need to be by a dot. (Note that _target_ or _controller_ might need to be
parenthesized.) parenthesized.)
A number of control operators are defined at this point. Further
A number of control operators are defined at his point. Note that control operators may be defined by new versions of this
the CDDL tool does not currently support combining multiple controls specification or by registering them according to the procedures in
on a single target. Further control operators may be defined by new Section 6.1.
versions of this specification or by registering them according to
the procedures in Section 6.1.
3.8.1. Control operator .size 3.8.1. Control operator .size
A ".size" control controls the size of the target in bytes by the A ".size" control controls the size of the target in bytes by the
control type. The control is defined for text and byte strings, control type. The control is defined for text and byte strings,
where it directly controls the number of bytes in the string. It is where it directly controls the number of bytes in the string. It is
also defined for unsigned integers (see below). Figure 8 shows also defined for unsigned integers (see below). Figure 8 shows
example usage for byte strings. example usage for byte strings.
full-address = [[+ label], ip4, ip6] full-address = [[+ label], ip4, ip6]
skipping to change at page 28, line 12 skipping to change at page 29, line 12
$message /= [3, dough: text, topping: [* text]] $message /= [3, dough: text, topping: [* text]]
$message /= [4, noodles: text, sauce: text, parmesan: bool] $message /= [4, noodles: text, sauce: text, parmesan: bool]
For ".within", a tool might flag an error if type1 allows data items For ".within", a tool might flag an error if type1 allows data items
that are not allowed by type2. In contrast, for ".and", there is no that are not allowed by type2. In contrast, for ".and", there is no
expectation that type1 already is a subset of type2. expectation that type1 already is a subset of type2.
3.8.6. Control operators .lt, .le, .gt, .ge, .eq, .ne, and .default 3.8.6. Control operators .lt, .le, .gt, .ge, .eq, .ne, and .default
The controls .lt, .le, .gt, .ge, .eq, .ne specify a constraint on the The controls .lt, .le, .gt, .ge, .eq, .ne specify a constraint on the
left hand side type to be a value less than, less than or equal, left hand side type to be a value less than, less than or equal,
equal to, not equal to, greater than, or greater than or equal to a greater than, greater than or equal, equal, or not equal, to a value
value given as a (single-valued) right hand side type. In the given as a (single-valued) right hand side type. In the present
present specification, the first four controls (.lt, .le, .gt, .ge) specification, the first four controls (.lt, .le, .gt, .ge) are
are defined only for numeric types, as these have a natural ordering defined only for numeric types, as these have a natural ordering
relationship. relationship.
speed = number .ge 0 ; unit: m/s speed = number .ge 0 ; unit: m/s
.ne and .eq are defined both for numeric values and values of other .ne and .eq are defined both for numeric values and values of other
types. If one of the values is not of a numeric type, equality is types. If one of the values is not of a numeric type, equality is
determined as follows: Text strings are equal (satisfy .eq/do not determined as follows: Text strings are equal (satisfy .eq/do not
satisfy .ne) if they are bytewise identical; the same applies for satisfy .ne) if they are byte-wise identical; the same applies for
byte strings. Arrays are equal if they have the same number of byte strings. Arrays are equal if they have the same number of
elements, all of which are equal pairwise in order between the elements, all of which are equal pairwise in order between the
arrays. Maps are equal if they have the same number of key/value arrays. Maps are equal if they have the same number of key/value
pairs, and there is pairwise equality between the key/value pairs pairs, and there is pairwise equality between the key/value pairs
between the two maps. Tagged values are equal if they both have the between the two maps. Tagged values are equal if they both have the
same tag and the values are equal. Values of simple types match if same tag and the values are equal. Values of simple types match if
they are the same values. Numeric types that occur within arrays, they are the same values. Numeric types that occur within arrays,
maps, or tagged values are equal if their numeric value is equal and maps, or tagged values are equal if their numeric value is equal and
they are both integers or both floating point values. All other they are both integers or both floating point values. All other
cases are not equal (e.g., comparing a text string with a byte cases are not equal (e.g., comparing a text string with a byte
skipping to change at page 29, line 37 skipping to change at page 30, line 37
$$tcp-option //= ( $$tcp-option //= (
sack-permitted: true sack-permitted: true
) )
Names that start with a single "$" are "type sockets", names with a Names that start with a single "$" are "type sockets", names with a
double "$$" are "group sockets". It is not an error if there is no double "$$" are "group sockets". It is not an error if there is no
definition for a socket at all; this then means there is no way to definition for a socket at all; this then means there is no way to
satisfy the rule (i.e., the choice is empty). satisfy the rule (i.e., the choice is empty).
All definitions (plugs) for socket names must be augmentations, i.e., As a convention, all definitions (plugs) for socket names must be
they must be using "/=" and "//=", respectively. augmentations, i.e., they must be using "/=" and "//=", respectively.
To pick up the example illustrated in Figure 7, the socket/plug To pick up the example illustrated in Figure 7, the socket/plug
mechanism could be used as shown in Figure 12: mechanism could be used as shown in Figure 12:
PersonalData = { PersonalData = {
? displayName: tstr, ? displayName: tstr,
NameComponents, NameComponents,
? age: uint, ? age: uint,
* $$personaldata-extensions * $$personaldata-extensions
} }
skipping to change at page 32, line 35 skipping to change at page 33, line 35
| , | 2 | group, group | 3 | | , | 2 | group, group | 3 |
| * | 1 | * group | 4 | | * | 1 | * group | 4 |
| N*M | 1 | N*M group | 4 | | N*M | 1 | N*M group | 4 |
| + | 1 | + group | 4 | | + | 1 | + group | 4 |
| ? | 1 | ? group | 4 | | ? | 1 | ? group | 4 |
| => | 2 | type => type | 5 | | => | 2 | type => type | 5 |
| : | 2 | name: type | 5 | | : | 2 | name: type | 5 |
| / | 2 | type / type | 6 | | / | 2 | type / type | 6 |
| .. | 2 | type..type | 7 | | .. | 2 | type..type | 7 |
| ... | 2 | type...type | 7 | | ... | 2 | type...type | 7 |
| .anno | 2 | type .anno type | 7 | | .ctrl | 2 | type .ctrl type | 7 |
| & | 1 | &group | 8 | | & | 1 | &group | 8 |
| ~ | 1 | ~type | 8 | | ~ | 1 | ~type | 8 |
+----------+----+---------------------------+------+ +----------+----+---------------------------+------+
Table 1: Summary of operator precedences Table 1: Summary of operator precedences
4. Making Use of CDDL 4. Making Use of CDDL
In this section, we discuss several potential ways to employ CDDL. In this section, we discuss several potential ways to employ CDDL.
skipping to change at page 34, line 16 skipping to change at page 35, line 16
that uses CDDL to define CBOR structures include the following: that uses CDDL to define CBOR structures include the following:
o Where could the language maybe cause confusion in a way that will o Where could the language maybe cause confusion in a way that will
enable security issues? enable security issues?
o Where a CDDL matcher is part of the implementation of a system, o Where a CDDL matcher is part of the implementation of a system,
the security of the system ought not depend on the correctness of the security of the system ought not depend on the correctness of
the CDDL specification or CDDL implementation without any further the CDDL specification or CDDL implementation without any further
defenses in place. defenses in place.
o Where the CDDL includes extension points, the impact of extensions
on the security of the system needs to be carefully considered.
Writers of CDDL specifications are strongly encouraged to value Writers of CDDL specifications are strongly encouraged to value
simplicity and transparency of the specification over its elegance. simplicity and transparency of the specification over its elegance.
Keep it as simple as possible while still expressing the needed data Keep it as simple as possible while still expressing the needed data
model. model.
A related observation about formal description techniques in general A related observation about formal description techniques in general
that is strongly recommended to be kept in mind by writers of CDDL that is strongly recommended to be kept in mind by writers of CDDL
specifications: Just because CDDL makes it easier to handle specifications: Just because CDDL makes it easier to handle
complexity in a specification, that does not make that complexity complexity in a specification, that does not make that complexity
somehow less bad (except maybe on the level of the humans having to somehow less bad (except maybe on the level of the humans having to
skipping to change at page 36, line 23 skipping to change at page 37, line 23
[RFC7493] Bray, T., Ed., "The I-JSON Message Format", RFC 7493, [RFC7493] Bray, T., Ed., "The I-JSON Message Format", RFC 7493,
DOI 10.17487/RFC7493, March 2015, DOI 10.17487/RFC7493, March 2015,
<https://www.rfc-editor.org/info/rfc7493>. <https://www.rfc-editor.org/info/rfc7493>.
[RFC8126] Cotton, M., Leiba, B., and T. Narten, "Guidelines for [RFC8126] Cotton, M., Leiba, B., and T. Narten, "Guidelines for
Writing an IANA Considerations Section in RFCs", BCP 26, Writing an IANA Considerations Section in RFCs", BCP 26,
RFC 8126, DOI 10.17487/RFC8126, June 2017, RFC 8126, DOI 10.17487/RFC8126, June 2017,
<https://www.rfc-editor.org/info/rfc8126>. <https://www.rfc-editor.org/info/rfc8126>.
[RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC
2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174,
May 2017, <https://www.rfc-editor.org/info/rfc8174>.
[RFC8259] Bray, T., Ed., "The JavaScript Object Notation (JSON) Data [RFC8259] Bray, T., Ed., "The JavaScript Object Notation (JSON) Data
Interchange Format", STD 90, RFC 8259, Interchange Format", STD 90, RFC 8259,
DOI 10.17487/RFC8259, December 2017, DOI 10.17487/RFC8259, December 2017,
<https://www.rfc-editor.org/info/rfc8259>. <https://www.rfc-editor.org/info/rfc8259>.
[W3C.REC-xmlschema-2-20041028] [W3C.REC-xmlschema-2-20041028]
Biron, P. and A. Malhotra, "XML Schema Part 2: Datatypes Biron, P. and A. Malhotra, "XML Schema Part 2: Datatypes
Second Edition", World Wide Web Consortium Recommendation Second Edition", World Wide Web Consortium Recommendation
REC-xmlschema-2-20041028, October 2004, REC-xmlschema-2-20041028, October 2004,
<http://www.w3.org/TR/2004/REC-xmlschema-2-20041028>. <http://www.w3.org/TR/2004/REC-xmlschema-2-20041028>.
skipping to change at page 37, line 45 skipping to change at page 39, line 5
<https://www.rfc-editor.org/info/rfc8007>. <https://www.rfc-editor.org/info/rfc8007>.
[RFC8152] Schaad, J., "CBOR Object Signing and Encryption (COSE)", [RFC8152] Schaad, J., "CBOR Object Signing and Encryption (COSE)",
RFC 8152, DOI 10.17487/RFC8152, July 2017, RFC 8152, DOI 10.17487/RFC8152, July 2017,
<https://www.rfc-editor.org/info/rfc8152>. <https://www.rfc-editor.org/info/rfc8152>.
7.3. URIs 7.3. URIs
[1] https://github.com/cabo/cbor-diag [1] https://github.com/cabo/cbor-diag
Appendix A. (Not used.) Appendix A. Examples
This section contains a few examples of structures defined using
CDDL.
The theme for the first example is taken from [RFC7071], which
defines certain JSON structures in English. For a similar example,
it may also be of interest to examine Appendix A of [RFC8007], which
contains a CDDL definition for a JSON structure defined in the main
body of the RFC.
The second subsection in this appendix translates examples from
[I-D.newton-json-content-rules] into CDDL.
These examples all happen to describe data that is interchanged in
JSON. Examples for CDDL definitions of data that is interchanged in
CBOR can be found in [RFC8152], [I-D.ietf-anima-grasp], or
[I-D.ietf-core-senml].
A.1. RFC 7071
[RFC7071] defines the Reputon structure for JSON using somewhat
formalized English text. Here is a (somewhat verbose) equivalent
definition using the same terms, but notated in CDDL:
reputation-object = {
reputation-context,
reputon-list
}
reputation-context = (
application: text
)
reputon-list = (
reputons: reputon-array
)
reputon-array = [* reputon]
reputon = {
rater-value,
assertion-value,
rated-value,
rating-value,
? conf-value,
? normal-value,
? sample-value,
? gen-value,
? expire-value,
* ext-value,
}
rater-value = ( rater: text )
assertion-value = ( assertion: text )
rated-value = ( rated: text )
rating-value = ( rating: float16 )
conf-value = ( confidence: float16 )
normal-value = ( normal-rating: float16 )
sample-value = ( sample-size: uint )
gen-value = ( generated: uint )
expire-value = ( expires: uint )
ext-value = ( text => any )
An equivalent, more compact form of this example would be:
reputation-object = {
application: text
reputons: [* reputon]
}
reputon = {
rater: text
assertion: text
rated: text
rating: float16
? confidence: float16
? normal-rating: float16
? sample-size: uint
? generated: uint
? expires: uint
* text => any
}
Note how this rather clearly delineates the structure somewhat
shrouded by so many words in section 6.2.2. of [RFC7071]. Also, this
definition makes it clear that several ext-values are allowed (by
definition with different member names); RFC 7071 could be read to
forbid the repetition of ext-value ("A specific reputon-element MUST
NOT appear more than once" is ambiguous.)
The CDDL tool (which hasn't quite been trained for polite
conversation) says:
{
"application": "tridentiferous",
"reputons": [
{
"rater": "loamily",
"assertion": "Dasyprocta",
"rated": "uncommensurableness",
"rating": 0.05055809746548934,
"confidence": 0.7484706448605812,
"normal-rating": 0.8677887734049299,
"sample-size": 4059,
"expires": 3969,
"bearer": "nitty",
"faucal": "postulnar",
"naturalism": "sarcotic"
},
{
"rater": "precreed",
"assertion": "xanthosis",
"rated": "balsamy",
"rating": 0.36091333590593955,
"confidence": 0.3700759808403371,
"sample-size": 3904
},
{
"rater": "urinosexual",
"assertion": "malacostracous",
"rated": "arenariae",
"rating": 0.9210673488013762,
"normal-rating": 0.4778762617112776,
"sample-size": 4428,
"generated": 3294,
"backfurrow": "enterable",
"fruitgrower": "flannelflower"
},
{
"rater": "pedologistically",
"assertion": "unmetaphysical",
"rated": "elocutionist",
"rating": 0.42073613384304287,
"misimagine": "retinaculum",
"snobbish": "contradict",
"Bosporanic": "periostotomy",
"dayworker": "intragyral"
}
]
}
A.2. Examples from JSON Content Rules
Although JSON Content Rules [I-D.newton-json-content-rules] seems to
address a more general problem than CDDL, it is still a worthwhile
resource to explore for examples (beyond all the inspiration the
format itself has had for CDDL).
Figure 2 of the JCR I-D looks very similar, if slightly less noisy,
in CDDL:
root = [2*2 {
precision: text,
Latitude: float,
Longitude: float,
Address: text,
City: text,
State: text,
Zip: text,
Country: text
}]
Figure 13: JCR, Figure 2, in CDDL
Apart from the lack of a need to quote the member names, text strings
are called "text" or "tstr" in CDDL ("string" would be ambiguous as
CBOR also provides byte strings).
The CDDL tool creates the below example instance for this:
[{"precision": "pyrosphere", "Latitude": 0.5399712314350172,
"Longitude": 0.5157523963028087, "Address": "resow",
"City": "problemwise", "State": "martyrlike", "Zip": "preprove",
"Country": "Pace"},
{"precision": "unrigging", "Latitude": 0.10422704368372193,
"Longitude": 0.6279808663725834, "Address": "picturedom",
"City": "decipherability", "State": "autometry", "Zip": "pout",
"Country": "wimple"}]
Figure 4 of the JCR I-D in CDDL:
root = { image }
image = (
Image: {
size,
Title: text,
thumbnail,
IDs: [* int]
}
)
size = (
Width: 0..1280
Height: 0..1024
)
thumbnail = (
Thumbnail: {
size,
Url: ~uri
}
)
This shows how the group concept can be used to keep related elements
(here: width, height) together, and to emulate the JCR style of
specification. (It also shows referencing a type by unwrapping a tag
from the prelude, "uri" - this could be done differently.) The more
compact form of Figure 5 of the JCR I-D could be emulated like this:
root = {
Image: {
size, Title: text,
Thumbnail: { size, Url: ~uri },
IDs: [* int]
}
}
size = (
Width: 0..1280,
Height: 0..1024,
)
The CDDL tool creates the below example instance for this:
{"Image": {"Width": 566, "Height": 516, "Title": "leisterer",
"Thumbnail": {"Width": 1111, "Height": 176, "Url": 32("scrog")},
"IDs": []}}
Appendix B. ABNF grammar Appendix B. ABNF grammar
The following is a formal definition of the CDDL syntax in Augmented The following is a formal definition of the CDDL syntax in Augmented
Backus-Naur Form (ABNF, [RFC5234]). Backus-Naur Form (ABNF, [RFC5234]).
cddl = S 1*(rule S) cddl = S 1*(rule S)
rule = typename [genericparm] S assign S type rule = typename [genericparm] S assignt S type
/ groupname [genericparm] S assign S grpent / groupname [genericparm] S assigng S grpent
typename = id typename = id
groupname = id groupname = id
assign = "=" / "/=" / "//=" assignt = "=" / "/="
assigng = "=" / "//="
genericparm = "<" S id S *("," S id S ) ">" genericparm = "<" S id S *("," S id S ) ">"
genericarg = "<" S type1 S *("," S type1 S ) ">" genericarg = "<" S type1 S *("," S type1 S ) ">"
type = type1 *(S "/" S type1) type = type1 *(S "/" S type1)
type1 = type2 [S (rangeop / ctlop) S type2] type1 = type2 [S (rangeop / ctlop) S type2]
type2 = value type2 = value
/ typename [genericarg] / typename [genericarg]
skipping to change at page 39, line 48 skipping to change at page 47, line 7
BINDIG = %x30-31 BINDIG = %x30-31
S = *WS S = *WS
WS = SP / NL WS = SP / NL
SP = %x20 SP = %x20
NL = COMMENT / CRLF NL = COMMENT / CRLF
COMMENT = ";" *PCHAR CRLF COMMENT = ";" *PCHAR CRLF
PCHAR = %x20-10FFFD PCHAR = %x20-10FFFD
CRLF = %x0A / %x0D.0A CRLF = %x0A / %x0D.0A
Figure 13: CDDL ABNF Figure 14: CDDL ABNF
Note that this ABNF does not attempt to reflect the detailed rules of Note that this ABNF does not attempt to reflect the detailed rules of
what can be in a prefixed byte string. what can be in a prefixed byte string.
Appendix C. Matching rules Appendix C. Matching rules
In this appendix, we go through the ABNF syntax rules defined in In this appendix, we go through the ABNF syntax rules defined in
Appendix B and briefly describe the matching semantics of each Appendix B and briefly describe the matching semantics of each
syntactic feature. In this context, an instance (data item) syntactic feature. In this context, an instance (data item)
"matches" a CDDL specification if it is allowed by the CDDL "matches" a CDDL specification if it is allowed by the CDDL
specification; this is then broken down to parts of specifications specification; this is then broken down to parts of specifications
(type and group expressions) and parts of instances (data items). (type and group expressions) and parts of instances (data items).
cddl = S 1*rule cddl = S 1*rule
A CDDL specification is a sequence of one or more rules. Each rule A CDDL specification is a sequence of one or more rules. Each rule
gives a name to a right hand side expression, either a CDDL type or a gives a name to a right hand side expression, either a CDDL type or a
CDDL group. Rule names can be used in the rule itself and/or other CDDL group. Rule names can be used in the rule itself and/or other
rules (and tools can output warnings if that is not the case). The rules (and tools can output warnings if that is not the case). The
order of the rules is significant only in two cases, including the order of the rules is significant only in two cases:
following: The first rule defines the semantics of the entire
specification; hence, its name may be descriptive only (or may be
used in itself or other rules as with the other rule names).
rule = typename [genericparm] S assign S type S 1. The first rule defines the semantics of the entire specification;
/ groupname [genericparm] S assign S grpent S hence, there is no need to give that root rule a special name or
special syntax in the language (as, e.g., with "start" in Relax-
NG); its name can be therefore chosen to be descriptive. (As
with all other rule names, the name of the initial rule may be
used in itself or in other rules).
2. Where a rule contributes to a type or group choice (using "/=" or
"//="), that choice is populated in the order the rules are
given; see below.
rule = typename [genericparm] S assignt S type S
/ groupname [genericparm] S assigng S grpent S
typename = id typename = id
groupname = id groupname = id
A rule defines a name for a type expression (production "type") or A rule defines a name for a type expression (production "type") or
for a group expression (production "grpent"), with the intention that for a group expression (production "grpent"), with the intention that
the semantics does not change when the name is replaced by its the semantics does not change when the name is replaced by its
(parenthesized if needed) definition. (parenthesized if needed) definition. Note that whether the name
defined by a rule stands for a type or a group isn't always
determined by syntax alone: e.g., "a = b" can make "a" a type if "b"
is one, or a group if "b" is one. More subtly, in "a = (b)", "a" may
be used as a type if "b" is a type, or as a group both when "b" is a
group and when "b" is a type (a good convention to make the latter
case stand out to the human reader is to write "a = (b,)"). (Note
that the same dual meaning of parentheses applies within an
expression, but often can be resolved by the context of the
parenthesized expression. On the more general point, it may not be
clear immediately either whether "b" stands for a group or a type --
this semantic processing may need to span several levels of rule
definitions before a determination can be made.)
assign = "=" / "/=" / "//=" assignt = "=" / "/="
assigng = "=" / "//="
A plain equals sign defines the rule name as the equivalent of the A plain equals sign defines the rule name as the equivalent of the
expression to the right. A "/=" or "//=" extends a named type or a expression to the right. A "/=" or "//=" extends a named type or a
group by additional choices; a number of these could be replaced by group by additional choices; a number of these could be replaced by
collecting all the right hand sides and creating a single rule with a collecting all the right hand sides and creating a single rule with a
type choice or a group choice built from the right hand sides in the type choice or a group choice built from the right hand sides in the
order of the rules given. (It is not an error to extend a rule name order of the rules given. (It is not an error to extend a rule name
that has not yet been defined; this makes the right hand side the that has not yet been defined; this makes the right hand side the
first entry in the choice being created.) The creation of the type first entry in the choice being created.)
choices and group choices from the right hand sides of rules is the
other case where rule order can be significant.
genericparm = "<" S id S *("," S id S ) ">" genericparm = "<" S id S *("," S id S ) ">"
genericarg = "<" S type1 S *("," S type1 S ) ">" genericarg = "<" S type1 S *("," S type1 S ) ">"
Rule names can have generic parameters, which cause temporary Rule names can have generic parameters, which cause temporary
assignments within the right hand sides to the parameter names from assignments within the right hand sides to the parameter names from
the arguments given when citing the rule name. the arguments given when citing the rule name.
type = type1 S *("/" S type1 S) type = type1 S *("/" S type1 S)
A type can be given as a choice between one or more types. The A type can be given as a choice between one or more types. The
choice matches a data item if the data item matches any one of the choice matches a data item if the data item matches any one of the
types given in the choice. The choice uses Parsing Expression types given in the choice. The choice uses Parsing Expression
Grammar [PEG] semantics: The first choice that matches wins. (As a Grammar [PEG] semantics: The first choice that matches wins. (As a
skipping to change at page 41, line 23 skipping to change at page 49, line 4
Grammar [PEG] semantics: The first choice that matches wins. (As a Grammar [PEG] semantics: The first choice that matches wins. (As a
result, the order of rules that contribute to a single rule name can result, the order of rules that contribute to a single rule name can
very well matter.) very well matter.)
type1 = type2 [S (rangeop / ctlop) S type2] type1 = type2 [S (rangeop / ctlop) S type2]
Two types can be combined with a range operator (which see below) or Two types can be combined with a range operator (which see below) or
a control operator (see Section 3.8). a control operator (see Section 3.8).
type2 = value type2 = value
A type can be just a single value (such as 1 or "icecream" or A type can be just a single value (such as 1 or "icecream" or
h'0815'), which matches only a data item with that specific value (no h'0815'), which matches only a data item with that specific value (no
conversions defined), conversions defined),
/ typename [genericarg] / typename [genericarg]
or be defined by a rule giving a meaning to a name (possibly after or be defined by a rule giving a meaning to a name (possibly after
supplying generic args as required by the generic parameters), supplying generic arguments as required by the generic parameters),
/ "(" type ")" / "(" S type S ")"
or be defined in a parenthesized type expression (parentheses may be or be defined in a parenthesized type expression (parentheses may be
necessary to override some operator precendence), or necessary to override some operator precedence), or
/ "~" S typename [genericarg]
an "unwrapped" group (see Section 3.7), which matches the group
inside a type defined as a map or an array by wrapping the group, or
/ "#" "6" ["." uint] "(" S type S ")" ; note no space!
a tagged data item, tagged with the "uint" given and containing the
type given as the tagged value, or
/ "#" DIGIT ["." uint] ; major/ai
a data item of a major type (given by the DIGIT), optionally
constrained to the additional information given by the uint, or
/ "#" ; any
any data item, or
/ "{" S group S "}" / "{" S group S "}"
a map expression, which matches a valid CBOR map the key/value pairs a map expression, which matches a valid CBOR map the key/value pairs
of which can be ordered in such a way that the resulting sequence of which can be ordered in such a way that the resulting sequence
matches the group expression, or matches the group expression, or
/ "[" S group S "]" / "[" S group S "]"
an array expression, which matches a CBOR array the elements of an array expression, which matches a CBOR array the elements of
which, when taken as values and complemented by a wildcard (matches which, when taken as values and complemented by a wildcard (matches
anything) key each, match the group, or anything) key each, match the group, or
/ "~" S typename [genericarg]
an "unwrapped" group (see Section 3.7), which matches the group
inside a type defined as a map or an array by wrapping the group, or
/ "&" S "(" S group S ")" / "&" S "(" S group S ")"
/ "&" S groupname [genericarg] / "&" S groupname [genericarg]
an enumeration expression, which matches any a value that is within an enumeration expression, which matches any a value that is within
the set of values that the values of the group given can take. the set of values that the values of the group given can take, or
/ "#" "6" ["." uint] "(" S type S ")" ; note no space!
a tagged data item, tagged with the "uint" given and containing the
type given as the tagged value, or
/ "#" DIGIT ["." uint] ; major/ai
a data item of a major type (given by the DIGIT), optionally
constrained to the additional information given by the uint, or
/ "#" ; any
any data item.
rangeop = "..." / ".." rangeop = "..." / ".."
A range operator can be used to join two type expressions that stand A range operator can be used to join two type expressions that stand
for either two integer values or two floating point values; it for either two integer values or two floating point values; it
matches any value that is between the two values, where the first matches any value that is between the two values, where the first
value is always included in the matching set and the second value is value is always included in the matching set and the second value is
included for ".." and excluded for "...". included for ".." and excluded for "...".
ctlop = "." id ctlop = "." id
skipping to change at page 43, line 32 skipping to change at page 51, line 14
memberkey = type1 S ["^" S] "=>" memberkey = type1 S ["^" S] "=>"
/ bareword S ":" / bareword S ":"
/ value S ":" / value S ":"
Key types can be given by a type expression, a bareword (which stands Key types can be given by a type expression, a bareword (which stands
for a type that just contains a string value created from this for a type that just contains a string value created from this
bareword), or a value (which stands for a type that just contains bareword), or a value (which stands for a type that just contains
this value). A key value matches its key type if the key value is a this value). A key value matches its key type if the key value is a
member of the key type, unless a cut preceding it in the group member of the key type, unless a cut preceding it in the group
applies (see Section 3.5.3 how map matching is infuenced by the applies (see Section 3.5.4 how map matching is influenced by the
presence of the cuts denoted by "^" or ":" in previous entries). presence of the cuts denoted by "^" or ":" in previous entries).
bareword = id bareword = id
A bareword is an alternative way to write a type with a single text A bareword is an alternative way to write a type with a single text
string value; it can only be used in the syntactic context given string value; it can only be used in the syntactic context given
above. above.
optcom = S ["," S] optcom = S ["," S]
skipping to change at page 45, line 50 skipping to change at page 52, line 50
float32-64 = float32 / float64 float32-64 = float32 / float64
float = float16-32 / float64 float = float16-32 / float64
false = #7.20 false = #7.20
true = #7.21 true = #7.21
bool = false / true bool = false / true
nil = #7.22 nil = #7.22
null = nil null = nil
undefined = #7.23 undefined = #7.23
Figure 14: CDDL Prelude Figure 15: CDDL Prelude
Note that the prelude is deemed to be fixed. This means, for Note that the prelude is deemed to be fixed. This means, for
instance, that additional tags beyond [RFC7049], as registered, need instance, that additional tags beyond [RFC7049], as registered, need
to be defined in each CDDL file that is using them. to be defined in each CDDL file that is using them.
A common stumbling point is that the prelude does not define a type A common stumbling point is that the prelude does not define a type
"string". CBOR has byte strings ("bytes" in the prelude) and text "string". CBOR has byte strings ("bytes" in the prelude) and text
strings ("text"), so a type that is simply called "string" would be strings ("text"), so a type that is simply called "string" would be
ambiguous. ambiguous.
skipping to change at page 46, line 47 skipping to change at page 53, line 47
float16-32 = float16 / float32 float16-32 = float16 / float32
float32-64 = float32 / float64 float32-64 = float32 / float64
float = float16-32 / float64 float = float16-32 / float64
false = #7.20 false = #7.20
true = #7.21 true = #7.21
bool = false / true bool = false / true
nil = #7.22 nil = #7.22
null = nil null = nil
Figure 15: JSON compatible subset of CDDL Prelude Figure 16: JSON compatible subset of CDDL Prelude
(The major types given here do not have a direct meaning in JSON, but (The major types given here do not have a direct meaning in JSON, but
they can be interpreted as CBOR major types translated through they can be interpreted as CBOR major types translated through
Section 4 of [RFC7049].) Section 4 of [RFC7049].)
There are a few fine points in using CDDL with JSON. First, JSON There are a few fine points in using CDDL with JSON. First, JSON
does not distinguish between integers and floating point numbers; does not distinguish between integers and floating point numbers;
there is only one kind of number (which may happen to be integral). there is only one kind of number (which may happen to be integral).
In this context, specifying a type as "uint", "nint" or "int" then In this context, specifying a type as "uint", "nint" or "int" then
becomes a predicate that the number be integral. As an example, this becomes a predicate that the number be integral. As an example, this
means that the following JSON numbers are all matching "uint": means that the following JSON numbers are all matching "uint":
skipping to change at page 47, line 36 skipping to change at page 54, line 36
numbers and decimal fractions and does not have limits to its numbers and decimal fractions and does not have limits to its
precision or range. In practice, JSON numbers are often parsed into precision or range. In practice, JSON numbers are often parsed into
a number type that is called float64 here, creating a number of a number type that is called float64 here, creating a number of
limitations to the generic data model [RFC7493]. In particular, this limitations to the generic data model [RFC7493]. In particular, this
means that integers can only be expressed with interoperable means that integers can only be expressed with interoperable
exactness when they lie in the range [-(2**53)+1, (2**53)-1] -- a exactness when they lie in the range [-(2**53)+1, (2**53)-1] -- a
smaller range than that covered by CDDL "int". smaller range than that covered by CDDL "int".
JSON applications that want to stay compatible with I-JSON therefore JSON applications that want to stay compatible with I-JSON therefore
may want to define integer types with more limited ranges, such as in may want to define integer types with more limited ranges, such as in
Figure 16. Note that the types given here are not part of the Figure 17. Note that the types given here are not part of the
prelude; they need to be copied into the CDDL specification if prelude; they need to be copied into the CDDL specification if
needed. needed.
ij-uint = 0..9007199254740991 ij-uint = 0..9007199254740991
ij-nint = -9007199254740991..-1 ij-nint = -9007199254740991..-1
ij-int = -9007199254740991..9007199254740991 ij-int = -9007199254740991..9007199254740991
Figure 16: I-JSON types for CDDL (not part of prelude) Figure 17: I-JSON types for CDDL (not part of prelude)
JSON applications that do not need to stay compatible with I-JSON and JSON applications that do not need to stay compatible with I-JSON and
that actually may need to go beyond the 64-bit unsigned and negative that actually may need to go beyond the 64-bit unsigned and negative
integers supported by "int" (= "uint"/"nint") may want to use the integers supported by "int" (= "uint"/"nint") may want to use the
following additional types from the standard prelude, which are following additional types from the standard prelude, which are
expressed in terms of tags but can straightforwardly be mapped into expressed in terms of tags but can straightforwardly be mapped into
JSON (but not I-JSON) numbers: JSON (but not I-JSON) numbers:
biguint = #6.2(bstr) biguint = #6.2(bstr)
bignint = #6.3(bstr) bignint = #6.3(bstr)
skipping to change at page 48, line 33 skipping to change at page 55, line 33
check the syntax, generate one or more instances (expressed in CBOR check the syntax, generate one or more instances (expressed in CBOR
diagnostic notation or in pretty-printed JSON), and validate an diagnostic notation or in pretty-printed JSON), and validate an
existing instance against the specification: existing instance against the specification:
Usage: Usage:
cddl spec.cddl generate [n] cddl spec.cddl generate [n]
cddl spec.cddl json-generate [n] cddl spec.cddl json-generate [n]
cddl spec.cddl validate instance.cbor cddl spec.cddl validate instance.cbor
cddl spec.cddl validate instance.json cddl spec.cddl validate instance.json
Figure 17: CDDL tool usage Figure 18: CDDL tool usage
Install on a system with a modern Ruby via: Install on a system with a modern Ruby via:
gem install cddl gem install cddl
Figure 18: CDDL tool installation Figure 19: CDDL tool installation
The accompanying CBOR diagnostic tools (which are automatically The accompanying CBOR diagnostic tools (which are automatically
installed by the above) are described in https://github.com/cabo/ installed by the above) are described in https://github.com/cabo/
cbor-diag [1]; they can be used to convert between binary CBOR, a cbor-diag [1]; they can be used to convert between binary CBOR, a
pretty-printed form of that, CBOR diagnostic notation, JSON, and pretty-printed form of that, CBOR diagnostic notation, JSON, and
YAML. YAML.
Appendix G. Extended Diagnostic Notation Appendix G. Extended Diagnostic Notation
Section 6 of [RFC7049] defines a "diagnostic notation" in order to be Section 6 of [RFC7049] defines a "diagnostic notation" in order to be
skipping to change at page 51, line 44 skipping to change at page 58, line 44
This can be used to annotate a CBOR structure as in: This can be used to annotate a CBOR structure as in:
/grasp-message/ [/M_DISCOVERY/ 1, /session-id/ 10584416, /grasp-message/ [/M_DISCOVERY/ 1, /session-id/ 10584416,
/objective/ [/objective-name/ "opsonize", /objective/ [/objective-name/ "opsonize",
/D, N, S/ 7, /loop-count/ 105]] /D, N, S/ 7, /loop-count/ 105]]
(There are currently no end-of-line comments. If we want to add (There are currently no end-of-line comments. If we want to add
them, "//" sounds like a reasonable delimiter given that we already them, "//" sounds like a reasonable delimiter given that we already
use slashes for comments, but we also could go e.g. for "#".) use slashes for comments, but we also could go e.g. for "#".)
Appendix H. Examples
This section contains various examples of structures defined using
CDDL.
The theme for the first example is taken from [RFC7071], which
defines certain JSON structures in English. For a similar example,
it may also be of interest to examine Appendix A of [RFC8007], which
contains a CDDL definition for a JSON structure defined in the main
body of the RFC.
The second subsection in this appendix translates examples from
[I-D.newton-json-content-rules] into CDDL.
These examples all happen to describe data that is interchanged in
JSON. Examples for CDDL definitions of data that is interchanged in
CBOR can be found in [RFC8152], [I-D.ietf-anima-grasp], or
[I-D.ietf-core-senml].
H.1. RFC 7071
[RFC7071] defines the Reputon structure for JSON using somewhat
formalized English text. Here is a (somewhat verbose) equivalent
definition using the same terms, but notated in CDDL:
reputation-object = {
reputation-context,
reputon-list
}
reputation-context = (
application: text
)
reputon-list = (
reputons: reputon-array
)
reputon-array = [* reputon]
reputon = {
rater-value,
assertion-value,
rated-value,
rating-value,
? conf-value,
? normal-value,
? sample-value,
? gen-value,
? expire-value,
* ext-value,
}
rater-value = ( rater: text )
assertion-value = ( assertion: text )
rated-value = ( rated: text )
rating-value = ( rating: float16 )
conf-value = ( confidence: float16 )
normal-value = ( normal-rating: float16 )
sample-value = ( sample-size: uint )
gen-value = ( generated: uint )
expire-value = ( expires: uint )
ext-value = ( text => any )
An equivalent, more compact form of this example would be:
reputation-object = {
application: text
reputons: [* reputon]
}
reputon = {
rater: text
assertion: text
rated: text
rating: float16
? confidence: float16
? normal-rating: float16
? sample-size: uint
? generated: uint
? expires: uint
* text => any
}
Note how this rather clearly delineates the structure somewhat
shrouded by so many words in section 6.2.2. of [RFC7071]. Also, this
definition makes it clear that several ext-values are allowed (by
definition with different member names); RFC 7071 could be read to
forbid the repetition of ext-value ("A specific reputon-element MUST
NOT appear more than once" is ambiguous.)
The CDDL tool (which hasn't quite been trained for polite
conversation) says:
{
"application": "tridentiferous",
"reputons": [
{
"rater": "loamily",
"assertion": "Dasyprocta",
"rated": "uncommensurableness",
"rating": 0.05055809746548934,
"confidence": 0.7484706448605812,
"normal-rating": 0.8677887734049299,
"sample-size": 4059,
"expires": 3969,
"bearer": "nitty",
"faucal": "postulnar",
"naturalism": "sarcotic"
},
{
"rater": "precreed",
"assertion": "xanthosis",
"rated": "balsamy",
"rating": 0.36091333590593955,
"confidence": 0.3700759808403371,
"sample-size": 3904
},
{
"rater": "urinosexual",
"assertion": "malacostracous",
"rated": "arenariae",
"rating": 0.9210673488013762,
"normal-rating": 0.4778762617112776,
"sample-size": 4428,
"generated": 3294,
"backfurrow": "enterable",
"fruitgrower": "flannelflower"
},
{
"rater": "pedologistically",
"assertion": "unmetaphysical",
"rated": "elocutionist",
"rating": 0.42073613384304287,
"misimagine": "retinaculum",
"snobbish": "contradict",
"Bosporanic": "periostotomy",
"dayworker": "intragyral"
}
]
}
H.1.1. Examples from JSON Content Rules
Although JSON Content Rules [I-D.newton-json-content-rules] seems to
address a more general problem than CDDL, it is still a worthwhile
resource to explore for examples (beyond all the inspiration the
format itself has had for CDDL).
Figure 2 of the JCR I-D looks very similar, if slightly less noisy,
in CDDL:
root = [2*2 {
precision: text,
Latitude: float,
Longitude: float,
Address: text,
City: text,
State: text,
Zip: text,
Country: text
}]
Figure 19: JCR, Figure 2, in CDDL
Apart from the lack of a need to quote the member names, text strings
are called "text" or "tstr" in CDDL ("string" would be ambiguous as
CBOR also provides byte strings).
The CDDL tool creates the below example instance for this:
[{"precision": "pyrosphere", "Latitude": 0.5399712314350172,
"Longitude": 0.5157523963028087, "Address": "resow",
"City": "problemwise", "State": "martyrlike", "Zip": "preprove",
"Country": "Pace"},
{"precision": "unrigging", "Latitude": 0.10422704368372193,
"Longitude": 0.6279808663725834, "Address": "picturedom",
"City": "decipherability", "State": "autometry", "Zip": "pout",
"Country": "wimple"}]
Figure 4 of the JCR I-D in CDDL:
root = { image }
image = (
Image: {
size,
Title: text,
thumbnail,
IDs: [* int]
}
)
size = (
Width: 0..1280
Height: 0..1024
)
thumbnail = (
Thumbnail: {
size,
Url: ~uri
}
)
This shows how the group concept can be used to keep related elements
(here: width, height) together, and to emulate the JCR style of
specification. (It also shows referencing a type by unwrapping a tag
from the prelude, "uri" - this could be done differently.) The more
compact form of Figure 5 of the JCR I-D could be emulated like this:
root = {
Image: {
size, Title: text,
Thumbnail: { size, Url: ~uri },
IDs: [* int]
}
}
size = (
Width: 0..1280,
Height: 0..1024,
)
The CDDL tool creates the below example instance for this:
{"Image": {"Width": 566, "Height": 516, "Title": "leisterer",
"Thumbnail": {"Width": 1111, "Height": 176, "Url": 32("scrog")},
"IDs": []}}
Contributors Contributors
CDDL was originally conceived by Bert Greevenbosch, who also wrote CDDL was originally conceived by Bert Greevenbosch, who also wrote
the original five versions of this document. the original five versions of this document.
Acknowledgements Acknowledgements
Inspiration was taken from the C and Pascal languages, MPEG's Inspiration was taken from the C and Pascal languages, MPEG's
conventions for describing structures in the ISO base media file conventions for describing structures in the ISO base media file
format, Relax-NG and its compact syntax [RELAXNG], and in particular format, Relax-NG and its compact syntax [RELAXNG], and in particular
from Andrew Lee Newton's "JSON Content Rules" from Andrew Lee Newton's "JSON Content Rules"
[I-D.newton-json-content-rules]. [I-D.newton-json-content-rules].
Lots of highly useful feedback came from members of the IETF CBOR WG, Lots of highly useful feedback came from members of the IETF CBOR WG,
in particular Brian Carpenter, Burt Harris, Jeffrey Yasskin, Jim in particular Ari Keraenen, Brian Carpenter, Burt Harris, Jeffrey
Hague, Jim Schaad, Joe Hildebrand, Max Pritikin, Michael Richardson, Yasskin, Jim Hague, Jim Schaad, Joe Hildebrand, Max Pritikin, Michael
Pete Cordell, Sean Leonard, and Yaron Sheffer. Also, Francesca Richardson, Pete Cordell, Sean Leonard, and Yaron Sheffer. Also,
Palombini and Joe volunteered to chair the WG when it was created, Francesca Palombini and Joe volunteered to chair the WG when it was
providing the framework for generating and processing this feedback; created, providing the framework for generating and processing this
with Barry Leiba having taken over from Joe since. feedback; with Barry Leiba having taken over from Joe since.
The CDDL tool was written by Carsten Bormann, building on previous The CDDL tool was written by Carsten Bormann, building on previous
work by Troy Heninger and Tom Lord. work by Troy Heninger and Tom Lord.
Authors' Addresses Authors' Addresses
Henk Birkholz Henk Birkholz
Fraunhofer SIT Fraunhofer SIT
Rheinstrasse 75 Rheinstrasse 75
Darmstadt 64295 Darmstadt 64295
 End of changes. 69 change blocks. 
427 lines changed or deleted 518 lines changed or added

This html diff was produced by rfcdiff 1.47. The latest version is available from http://tools.ietf.org/tools/rfcdiff/