| < draft-newton-json-content-rules-08.txt | draft-newton-json-content-rules-09.txt > | |||
|---|---|---|---|---|
| Network Working Group A. Newton | Network Working Group A. Newton | |||
| Internet-Draft ARIN | Internet-Draft ARIN | |||
| Intended status: Standards Track P. Cordell | Intended status: Standards Track P. Cordell | |||
| Expires: September 29, 2017 Codalogic | Expires: April 1, 2018 Codalogic | |||
| March 28, 2017 | September 28, 2017 | |||
| A Language for Rules Describing JSON Content | A Language for Rules Describing JSON Content | |||
| draft-newton-json-content-rules-08 | draft-newton-json-content-rules-09 | |||
| Abstract | Abstract | |||
| This document describes a language for specifying and testing the | This document describes a language for specifying and testing the | |||
| expected content of JSON structures found in JSON-using protocols, | expected content of JSON structures found in JSON-using protocols, | |||
| software, and processes. | software, and processes. | |||
| Status of This Memo | Status of This Memo | |||
| This Internet-Draft is submitted in full conformance with the | This Internet-Draft is submitted in full conformance with the | |||
| provisions of BCP 78 and BCP 79. | provisions of BCP 78 and BCP 79. | |||
| 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 http://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 September 29, 2017. | This Internet-Draft will expire on April 1, 2018. | |||
| Copyright Notice | Copyright Notice | |||
| Copyright (c) 2017 IETF Trust and the persons identified as the | Copyright (c) 2017 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 | |||
| (http://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 | |||
| carefully, as they describe your rights and restrictions with respect | carefully, as they describe your rights and restrictions with respect | |||
| to this document. Code Components extracted from this document must | to this document. Code Components extracted from this document must | |||
| include Simplified BSD License text as described in Section 4.e of | include Simplified BSD License text as described in Section 4.e of | |||
| the Trust Legal Provisions and are provided without warranty as | the Trust Legal Provisions and are provided without warranty as | |||
| described in the Simplified BSD License. | described in the Simplified BSD License. | |||
| Table of Contents | Table of Contents | |||
| 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 | 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 | |||
| skipping to change at page 2, line 43 ¶ | skipping to change at page 2, line 43 ¶ | |||
| 5.2. ruleset-id . . . . . . . . . . . . . . . . . . . . . . . 27 | 5.2. ruleset-id . . . . . . . . . . . . . . . . . . . . . . . 27 | |||
| 5.3. import . . . . . . . . . . . . . . . . . . . . . . . . . 27 | 5.3. import . . . . . . . . . . . . . . . . . . . . . . . . . 27 | |||
| 6. Tips and Tricks . . . . . . . . . . . . . . . . . . . . . . . 28 | 6. Tips and Tricks . . . . . . . . . . . . . . . . . . . . . . . 28 | |||
| 6.1. Any Member with Any Value . . . . . . . . . . . . . . . . 28 | 6.1. Any Member with Any Value . . . . . . . . . . . . . . . . 28 | |||
| 6.2. Lists of Values . . . . . . . . . . . . . . . . . . . . . 29 | 6.2. Lists of Values . . . . . . . . . . . . . . . . . . . . . 29 | |||
| 6.3. Groups in Arrays . . . . . . . . . . . . . . . . . . . . 29 | 6.3. Groups in Arrays . . . . . . . . . . . . . . . . . . . . 29 | |||
| 6.4. Groups in Objects . . . . . . . . . . . . . . . . . . . . 30 | 6.4. Groups in Objects . . . . . . . . . . . . . . . . . . . . 30 | |||
| 6.5. Group Rules as Macros . . . . . . . . . . . . . . . . . . 31 | 6.5. Group Rules as Macros . . . . . . . . . . . . . . . . . . 31 | |||
| 6.6. Object Mixins . . . . . . . . . . . . . . . . . . . . . . 31 | 6.6. Object Mixins . . . . . . . . . . . . . . . . . . . . . . 31 | |||
| 6.7. Subordinate Dependencies . . . . . . . . . . . . . . . . 31 | 6.7. Subordinate Dependencies . . . . . . . . . . . . . . . . 31 | |||
| 7. ABNF Syntax . . . . . . . . . . . . . . . . . . . . . . . . . 32 | 7. Implementation Status . . . . . . . . . . . . . . . . . . . . 32 | |||
| 8. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 38 | 7.1. JCR Validator . . . . . . . . . . . . . . . . . . . . . . 32 | |||
| 9. References . . . . . . . . . . . . . . . . . . . . . . . . . 38 | 7.2. Codalogic JCR Parser . . . . . . . . . . . . . . . . . . 33 | |||
| 9.1. Normative References . . . . . . . . . . . . . . . . . . 38 | 7.3. JCR Java . . . . . . . . . . . . . . . . . . . . . . . . 33 | |||
| 9.2. Infomative References . . . . . . . . . . . . . . . . . . 38 | 8. ABNF Syntax . . . . . . . . . . . . . . . . . . . . . . . . . 33 | |||
| Appendix A. Co-Constraints . . . . . . . . . . . . . . . . . . . 39 | 9. Acknowledgements . . . . . . . . . . . . . . . . . . . . . . 39 | |||
| Appendix B. Testing Against JSON Content Rules . . . . . . . . . 39 | 10. References . . . . . . . . . . . . . . . . . . . . . . . . . 39 | |||
| B.1. Locally Overriding Rules . . . . . . . . . . . . . . . . 39 | 10.1. Normative References . . . . . . . . . . . . . . . . . . 39 | |||
| B.2. Rule Callbacks . . . . . . . . . . . . . . . . . . . . . 40 | 10.2. Infomative References . . . . . . . . . . . . . . . . . 40 | |||
| Appendix C. JCR Implementations . . . . . . . . . . . . . . . . 40 | 10.3. URIs . . . . . . . . . . . . . . . . . . . . . . . . . . 40 | |||
| Appendix D. Syntax Changes from -06 and -07 . . . . . . . . . . 41 | ||||
| Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 41 | Appendix A. Co-Constraints . . . . . . . . . . . . . . . . . . . 40 | |||
| Appendix B. Testing Against JSON Content Rules . . . . . . . . . 41 | ||||
| B.1. Locally Overriding Rules . . . . . . . . . . . . . . . . 41 | ||||
| B.2. Rule Callbacks . . . . . . . . . . . . . . . . . . . . . 42 | ||||
| Appendix C. Changes from -07 and -08 . . . . . . . . . . . . . . 42 | ||||
| Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 42 | ||||
| 1. Introduction | 1. Introduction | |||
| This document describes JSON Content Rules (JCR), a language for | This document describes JSON Content Rules (JCR), a language for | |||
| specifying and testing the interchange of data in JSON [RFC7159] | specifying and testing the interchange of data in JSON [RFC7159] | |||
| format used by computer protocols and processes. The syntax of JCR | format used by computer protocols and processes. The syntax of JCR | |||
| is not JSON but is "JSON-like", possessing the conciseness and | is not JSON but is "JSON-like", possessing the conciseness and | |||
| utility that has made JSON popular. | utility that has made JSON popular. | |||
| 1.1. A First Example: Specifying Content | 1.1. A First Example: Specifying Content | |||
| skipping to change at page 5, line 9 ¶ | skipping to change at page 5, line 9 ¶ | |||
| $fn = "file-name" : "rfc4627.txt" | $fn = "file-name" : "rfc4627.txt" | |||
| $lc = "line-count" : 2102 | $lc = "line-count" : 2102 | |||
| $wc = "word-count" : 16714 | $wc = "word-count" : 16714 | |||
| Figure 7 | Figure 7 | |||
| In this example, the protocol specification describes the JSON object | In this example, the protocol specification describes the JSON object | |||
| in general and an implementation overrides the rules for testing | in general and an implementation overrides the rules for testing | |||
| specific cases. | specific cases. | |||
| All figures used in this specification are available here [1]. | ||||
| 2. Overview of the Language | 2. Overview of the Language | |||
| JCR is composed of rules (as the name suggests). A collection of | JCR is composed of rules (as the name suggests). A collection of | |||
| rules that is processed together is a ruleset. Rulesets may also | rules that is processed together is a ruleset. Rulesets may also | |||
| contain comments, blank lines, and directives that apply to the | contain comments, blank lines, and directives that apply to the | |||
| processing of a ruleset. | processing of a ruleset. | |||
| Rules are composed of two parts, an optional rule name and a rule | Rules are composed of two parts, an optional rule name and a rule | |||
| specification. A rule specification can be either a type | specification. A rule specification can be either a type | |||
| specification or a member specification. A member specification | specification or a member specification. A member specification | |||
| skipping to change at page 32, line 19 ¶ | skipping to change at page 32, line 19 ¶ | |||
| ; $referrer_uri can only be present if | ; $referrer_uri can only be present if | |||
| ; $location_uri is present | ; $location_uri is present | |||
| { ( $location_uri, $referrer_uri? )? } | { ( $location_uri, $referrer_uri? )? } | |||
| $location_uri = "locationURI" : uri | $location_uri = "locationURI" : uri | |||
| $referrer_uri = "referrerURI" : uri | $referrer_uri = "referrerURI" : uri | |||
| Figure 69 | Figure 69 | |||
| 7. ABNF Syntax | 7. Implementation Status | |||
| This section records the status of known implementations of the | ||||
| protocol defined by this specification at the time of posting of this | ||||
| Internet-Draft, and is based on a proposal described in [RFC7492] . | ||||
| The description of implementations in this section is intended to | ||||
| assist the IETF in its decision processes in progressing drafts to | ||||
| RFCs. Please note that the listing of any individual implementation | ||||
| here does not imply endorsement by the IETF. Furthermore, no effort | ||||
| has been spent to verify the information presented here that was | ||||
| supplied by IETF contributors. This is not intended as, and must not | ||||
| be construed to be, a catalog of available implementations or their | ||||
| features. Readers are advised to note that other implementations may | ||||
| exist. | ||||
| According to [RFC7492] , "this will allow reviewers and working | ||||
| groups to assign due consideration to documents that have the benefit | ||||
| of running code, which may serve as evidence of valuable | ||||
| experimentation and feedback that have made the implemented protocols | ||||
| more mature. It is up to the individual working groups to use this | ||||
| information as they see fit". | ||||
| 7.1. JCR Validator | ||||
| The JCR Validator, written in Ruby, currently implements all portions | ||||
| of this specification, and has been used extensively to prototype | ||||
| various aspects of JCR under consideration. It's development has | ||||
| gone hand-in-hand with this specification. | ||||
| This software is primarily produced by the American Registry for | ||||
| Internet Numbers (ARIN) and freely distributable under the ISC | ||||
| license. | ||||
| Source code for this software is available on GitHub at | ||||
| <https://github.com/arineng/jcrvalidator>. This software is also | ||||
| easily obtained as a Ruby Gem through the Ruby Gem system. | ||||
| 7.2. Codalogic JCR Parser | ||||
| The Codalogic JCR Parser is a C++ implementation of a JCR parsing | ||||
| engine, and is a work in progress. It is targeted for the Windows | ||||
| platform. | ||||
| This software is produced by Codalogic Ltd and freely distributable | ||||
| under the Gnu LGPL v3 license. | ||||
| Source code is availabe on GitHub at <https://github.com/codalogic/ | ||||
| cl-jcr-parser>. | ||||
| 7.3. JCR Java | ||||
| JCR Java is a work in progress and currently only implements the | ||||
| parsing of JCR rulesets according to the ABNF using a custom parsing | ||||
| framework. | ||||
| This software is produced by the American Registry for Internet | ||||
| Numbers (ARIN) and freely distributable under the MIT license. | ||||
| Source code is available on BitBucket at | ||||
| <https://bitbucket.org/anewton_1998/jcr_java>. | ||||
| 8. ABNF Syntax | ||||
| The following ABNF describes the syntax for JSON Content Rules. A | The following ABNF describes the syntax for JSON Content Rules. A | |||
| text file containing these ABNF rules can be downloaded from | text file containing these ABNF rules can be downloaded from | |||
| [JCR_ABNF]. | [JCR_ABNF]. | |||
| jcr = *( sp-cmt / directive / root-rule / rule ) | jcr = *( sp-cmt / directive / root-rule / rule ) | |||
| sp-cmt = spaces / comment | ||||
| spaces = 1*( WSP / CR / LF ) | ||||
| DSPs = ; Directive spaces | ||||
| 1*WSP / ; When in one-line directive | ||||
| 1*sp-cmt ; When in muti-line directive | ||||
| comment = ";" *comment-char comment-end-char | ||||
| comment-char = HTAB / %x20-10FFFF | ||||
| ; Any char other than CR / LF | ||||
| comment-end-char = CR / LF | ||||
| directive = "#" (one-line-directive / multi-line-directive) | ||||
| one-line-directive = [ DSPs ] | ||||
| (directive-def / one-line-tbd-directive-d) | ||||
| *WSP eol | ||||
| multi-line-directive = "{" *sp-cmt | ||||
| ( directive-def / | ||||
| multi-line-tbd-directive-d ) | ||||
| *sp-cmt "}" | ||||
| directive-def = jcr-version-d / ruleset-id-d / import-d | ||||
| jcr-version-d = jcr-version-kw DSPs major-version | ||||
| "." minor-version | ||||
| *( DSPs "+" [ DSPs ] extension-id ) | ||||
| major-version = non-neg-integer | ||||
| minor-version = non-neg-integer | ||||
| extension-id = ALPHA *not-space | ||||
| ruleset-id-d = ruleset-id-kw DSPs ruleset-id | ||||
| import-d = import-kw DSPs ruleset-id | ||||
| [ DSPs as-kw DSPs ruleset-id-alias ] | ||||
| ruleset-id = ALPHA *not-space | ||||
| not-space = %x21-10FFFF | ||||
| ruleset-id-alias = name | ||||
| one-line-tbd-directive-d = directive-name | ||||
| [ WSP one-line-directive-parameters ] | ||||
| directive-name = name | ||||
| one-line-directive-parameters = *not-eol | ||||
| not-eol = HTAB / %x20-10FFFF | ||||
| eol = CR / LF | ||||
| multi-line-tbd-directive-d = directive-name | ||||
| [ 1*sp-cmt multi-line-directive-parameters ] | ||||
| multi-line-directive-parameters = multi-line-parameters | ||||
| multi-line-parameters = *(comment / q-string / regex / | ||||
| not-multi-line-special) | ||||
| not-multi-line-special = spaces / %x21 / %x23-2E / %x30-3A / | ||||
| %x3C-7C / %x7E-10FFFF ; not ", /, ; or } | ||||
| root-rule = value-rule / group-rule | sp-cmt = spaces / comment | |||
| spaces = 1*( WSP / CR / LF ) | ||||
| DSPs = ; Directive spaces | ||||
| 1*WSP / ; When in one-line directive | ||||
| 1*sp-cmt ; When in muti-line directive | ||||
| comment = ";" *comment-char comment-end-char | ||||
| comment-char = HTAB / %x20-10FFFF | ||||
| ; Any char other than CR / LF | ||||
| comment-end-char = CR / LF | ||||
| rule = annotations "$" rule-name *sp-cmt | directive = "#" (one-line-directive / multi-line-directive) | |||
| "=" *sp-cmt rule-def | one-line-directive = [ DSPs ] | |||
| (directive-def / one-line-tbd-directive-d) | ||||
| *WSP eol | ||||
| multi-line-directive = "{" *sp-cmt | ||||
| ( directive-def / | ||||
| multi-line-tbd-directive-d ) | ||||
| *sp-cmt "}" | ||||
| directive-def = jcr-version-d / ruleset-id-d / import-d | ||||
| jcr-version-d = jcr-version-kw DSPs major-version | ||||
| "." minor-version | ||||
| *( DSPs "+" [ DSPs ] extension-id ) | ||||
| major-version = non-neg-integer | ||||
| minor-version = non-neg-integer | ||||
| extension-id = ALPHA *not-space | ||||
| ruleset-id-d = ruleset-id-kw DSPs ruleset-id | ||||
| import-d = import-kw DSPs ruleset-id | ||||
| [ DSPs as-kw DSPs ruleset-id-alias ] | ||||
| ruleset-id = ALPHA *not-space | ||||
| not-space = %x21-10FFFF | ||||
| ruleset-id-alias = name | ||||
| one-line-tbd-directive-d = directive-name | ||||
| [ WSP one-line-directive-parameters ] | ||||
| directive-name = name | ||||
| one-line-directive-parameters = *not-eol | ||||
| not-eol = HTAB / %x20-10FFFF | ||||
| eol = CR / LF | ||||
| multi-line-tbd-directive-d = directive-name | ||||
| [ 1*sp-cmt multi-line-directive-parameters ] | ||||
| multi-line-directive-parameters = multi-line-parameters | ||||
| multi-line-parameters = *(comment / q-string / regex / | ||||
| not-multi-line-special) | ||||
| not-multi-line-special = spaces / %x21 / %x23-2E / %x30-3A / | ||||
| %x3C-7C / %x7E-10FFFF ; not ", /, ; or } | ||||
| rule-name = name | root-rule = value-rule / group-rule | |||
| target-rule-name = annotations "$" | ||||
| [ ruleset-id-alias "." ] | ||||
| rule-name | ||||
| name = ALPHA *( ALPHA / DIGIT / "-" / "-" ) | ||||
| rule-def = member-rule / type-designator rule-def-type-rule / | rule = annotations "$" rule-name *sp-cmt | |||
| array-rule / object-rule / group-rule / | "=" *sp-cmt rule-def | |||
| target-rule-name | ||||
| type-designator = type-kw 1*sp-cmt / ":" *sp-cmt | ||||
| rule-def-type-rule = value-rule / type-choice | ||||
| value-rule = primitive-rule / array-rule / object-rule | ||||
| member-rule = annotations | ||||
| member-name-spec *sp-cmt ":" *sp-cmt type-rule | ||||
| member-name-spec = regex / q-string | ||||
| type-rule = value-rule / type-choice / target-rule-name | ||||
| type-choice = annotations "(" type-choice-items | ||||
| *( choice-combiner type-choice-items ) ")" | ||||
| explicit-type-choice = type-designator type-choice | ||||
| type-choice-items = *sp-cmt ( type-choice / type-rule ) *sp-cmt | ||||
| annotations = *( "@{" *sp-cmt annotation-set *sp-cmt "}" | rule-name = name | |||
| *sp-cmt ) | target-rule-name = annotations "$" | |||
| [ ruleset-id-alias "." ] | ||||
| rule-name | ||||
| name = ALPHA *( ALPHA / DIGIT / "-" / "-" ) | ||||
| annotation-set = not-annotation / unordered-annotation / | rule-def = member-rule / type-designator rule-def-type-rule / | |||
| root-annotation / tbd-annotation | array-rule / object-rule / group-rule / | |||
| not-annotation = not-kw | target-rule-name | |||
| unordered-annotation = unordered-kw | type-designator = type-kw 1*sp-cmt / ":" *sp-cmt | |||
| root-annotation = root-kw | rule-def-type-rule = value-rule / type-choice | |||
| tbd-annotation = annotation-name [ spaces annotation-parameters ] | value-rule = primitive-rule / array-rule / object-rule | |||
| annotation-name = name | member-rule = annotations | |||
| annotation-parameters = multi-line-parameters | member-name-spec *sp-cmt ":" *sp-cmt type-rule | |||
| member-name-spec = regex / q-string | ||||
| type-rule = value-rule / type-choice / target-rule-name | ||||
| type-choice = annotations "(" type-choice-items | ||||
| *( choice-combiner type-choice-items ) ")" | ||||
| explicit-type-choice = type-designator type-choice | ||||
| type-choice-items = *sp-cmt ( type-choice / type-rule ) *sp-cmt | ||||
| primitive-rule = annotations primitive-def | annotations = *( "@{" *sp-cmt annotation-set *sp-cmt "}" | |||
| primitive-def = string-type / string-range / string-value / | *sp-cmt ) | |||
| null-type / boolean-type / true-value / | annotation-set = not-annotation / unordered-annotation / | |||
| false-value / double-type / float-type / | root-annotation / tbd-annotation | |||
| float-range / float-value / | not-annotation = not-kw | |||
| integer-type / integer-range / integer-value / | unordered-annotation = unordered-kw | |||
| sized-int-type / sized-uint-type / ipv4-type / | root-annotation = root-kw | |||
| ipv6-type / ipaddr-type / fqdn-type / idn-type / | tbd-annotation = annotation-name [ spaces annotation-parameters ] | |||
| uri-type / phone-type / email-type / | annotation-name = name | |||
| datetime-type / date-type / time-type / | annotation-parameters = multi-line-parameters | |||
| hex-type / base32hex-type / base32-type / | ||||
| base64url-type / base64-type / any | ||||
| null-type = null-kw | ||||
| boolean-type = boolean-kw | ||||
| true-value = true-kw | ||||
| false-value = false-kw | ||||
| string-type = string-kw | ||||
| string-value = q-string | ||||
| string-range = regex | ||||
| double-type = double-kw | ||||
| float-type = float-kw | ||||
| float-range = float-min ".." [ float-max ] / ".." float-max | ||||
| float-min = float | ||||
| float-max = float | ||||
| float-value = float | ||||
| integer-type = integer-kw | ||||
| integer-range = integer-min ".." [ integer-max ] / | ||||
| ".." integer-max | ||||
| integer-min = integer | ||||
| integer-max = integer | ||||
| integer-value = integer | ||||
| sized-int-type = int-kw pos-integer | ||||
| sized-uint-type = uint-kw pos-integer | ||||
| ipv4-type = ipv4-kw | ||||
| ipv6-type = ipv6-kw | ||||
| ipaddr-type = ipaddr-kw | ||||
| fqdn-type = fqdn-kw | ||||
| idn-type = idn-kw | ||||
| uri-type = uri-kw [ ".." uri-scheme ] | ||||
| phone-type = phone-kw | ||||
| email-type = email-kw | ||||
| datetime-type = datetime-kw | ||||
| date-type = date-kw | ||||
| time-type = time-kw | ||||
| hex-type = hex-kw | ||||
| base32hex-type = base32hex-kw | ||||
| base32-type = base32-kw | ||||
| base64url-type = base64url-kw | ||||
| base64-type = base64-kw | ||||
| any = any-kw | ||||
| object-rule = annotations "{" *sp-cmt | primitive-rule = annotations primitive-def | |||
| [ object-items *sp-cmt ] "}" | primitive-def = string-type / string-range / string-value / | |||
| object-items = object-item (*( sequence-combiner object-item ) / | null-type / boolean-type / true-value / | |||
| *( choice-combiner object-item ) ) | false-value / double-type / float-type / | |||
| object-item = object-item-types *sp-cmt [ repetition ] | float-range / float-value / | |||
| object-item-types = object-group / member-rule / target-rule-name | integer-type / integer-range / integer-value / | |||
| object-group = "(" *sp-cmt [ object-items *sp-cmt ] ")" | sized-int-type / sized-uint-type / ipv4-type / | |||
| ipv6-type / ipaddr-type / fqdn-type / idn-type / | ||||
| uri-type / phone-type / email-type / | ||||
| datetime-type / date-type / time-type / | ||||
| hex-type / base32hex-type / base32-type / | ||||
| base64url-type / base64-type / any | ||||
| null-type = null-kw | ||||
| boolean-type = boolean-kw | ||||
| true-value = true-kw | ||||
| false-value = false-kw | ||||
| string-type = string-kw | ||||
| string-value = q-string | ||||
| string-range = regex | ||||
| double-type = double-kw | ||||
| float-type = float-kw | ||||
| float-range = float-min ".." [ float-max ] / ".." float-max | ||||
| float-min = float | ||||
| float-max = float | ||||
| float-value = float | ||||
| integer-type = integer-kw | ||||
| integer-range = integer-min ".." [ integer-max ] / | ||||
| ".." integer-max | ||||
| integer-min = integer | ||||
| integer-max = integer | ||||
| integer-value = integer | ||||
| sized-int-type = int-kw pos-integer | ||||
| sized-uint-type = uint-kw pos-integer | ||||
| ipv4-type = ipv4-kw | ||||
| ipv6-type = ipv6-kw | ||||
| ipaddr-type = ipaddr-kw | ||||
| fqdn-type = fqdn-kw | ||||
| idn-type = idn-kw | ||||
| uri-type = uri-kw [ ".." uri-scheme ] | ||||
| phone-type = phone-kw | ||||
| email-type = email-kw | ||||
| datetime-type = datetime-kw | ||||
| date-type = date-kw | ||||
| time-type = time-kw | ||||
| hex-type = hex-kw | ||||
| base32hex-type = base32hex-kw | ||||
| base32-type = base32-kw | ||||
| base64url-type = base64url-kw | ||||
| base64-type = base64-kw | ||||
| any = any-kw | ||||
| array-rule = annotations "[" *sp-cmt [ array-items *sp-cmt ] "]" | object-rule = annotations "{" *sp-cmt | |||
| array-items = array-item (*( sequence-combiner array-item ) / | [ object-items *sp-cmt ] "}" | |||
| *( choice-combiner array-item ) ) | object-items = object-item [ 1*( sequence-combiner object-item ) / | |||
| array-item = array-item-types *sp-cmt [ repetition ] | 1*( choice-combiner object-item ) ] | |||
| array-item-types = array-group / type-rule / explicit-type-choice | object-item = object-item-types *sp-cmt [ repetition *sp-cmt ] | |||
| array-group = "(" *sp-cmt [ array-items *sp-cmt ] ")" | object-item-types = object-group / member-rule / target-rule-name | |||
| object-group = annotations "(" *sp-cmt [ object-items *sp-cmt ] ")" | ||||
| group-rule = annotations "(" *sp-cmt [ group-items *sp-cmt ] ")" | array-rule = annotations "[" *sp-cmt [ array-items *sp-cmt ] "]" | |||
| group-items = group-item (*( sequence-combiner group-item ) / | array-items = array-item [ 1*( sequence-combiner array-item ) / | |||
| *( choice-combiner group-item ) ) | 1*( choice-combiner array-item ) ] | |||
| group-item = group-item-types *sp-cmt [ repetition ] | array-item = array-item-types *sp-cmt [ repetition *sp-cmt ] | |||
| group-item-types = group-group / member-rule / | array-item-types = array-group / type-rule / explicit-type-choice | |||
| type-rule / explicit-type-choice | array-group = annotations "(" *sp-cmt [ array-items *sp-cmt ] ")" | |||
| group-group = group-rule | ||||
| sequence-combiner = *sp-cmt "," *sp-cmt | group-rule = annotations "(" *sp-cmt [ group-items *sp-cmt ] ")" | |||
| choice-combiner = *sp-cmt "|" *sp-cmt | group-items = group-item [ 1*( sequence-combiner group-item ) / | |||
| 1*( choice-combiner group-item ) ] | ||||
| group-item = group-item-types *sp-cmt [ repetition *sp-cmt ] | ||||
| group-item-types = group-group / member-rule / | ||||
| type-rule / explicit-type-choice | ||||
| group-group = group-rule | ||||
| sequence-combiner = "," *sp-cmt | ||||
| choice-combiner = "|" *sp-cmt | ||||
| repetition = optional / one-or-more / | repetition = optional / one-or-more / | |||
| repetition-range / zero-or-more | repetition-range / zero-or-more | |||
| optional = "?" | optional = "?" | |||
| one-or-more = "+" [ repetition-step ] | one-or-more = "+" [ repetition-step ] | |||
| zero-or-more = "*" [ repetition-step ] | zero-or-more = "*" [ repetition-step ] | |||
| repetition-range = "*" *sp-cmt ( | repetition-range = "*" *sp-cmt ( | |||
| min-max-repetition / min-repetition / | min-max-repetition / min-repetition / | |||
| max-repetition / specific-repetition ) | max-repetition / specific-repetition ) | |||
| min-max-repetition = min-repeat ".." max-repeat | min-max-repetition = min-repeat ".." max-repeat | |||
| [ repetition-step ] | [ repetition-step ] | |||
| min-repetition = min-repeat ".." [ repetition-step ] | ||||
| max-repetition = ".." max-repeat [ repetition-step ] | ||||
| min-repeat = non-neg-integer | ||||
| max-repeat = non-neg-integer | ||||
| specific-repetition = non-neg-integer | ||||
| repetition-step = "%" step-size | ||||
| step-size = non-neg-integer | ||||
| min-repetition = min-repeat ".." [ repetition-step ] | integer = "0" / ["-"] pos-integer | |||
| max-repetition = ".." max-repeat [ repetition-step ] | non-neg-integer = "0" / pos-integer | |||
| min-repeat = non-neg-integer | pos-integer = digit1-9 *DIGIT | |||
| max-repeat = non-neg-integer | ||||
| specific-repetition = non-neg-integer | ||||
| repetition-step = "%" step-size | ||||
| step-size = non-neg-integer | ||||
| integer = "0" / ["-"] pos-integer | float = [ minus ] int frac [ exp ] | |||
| non-neg-integer = "0" / pos-integer | ; From RFC 7159 except 'frac' required | |||
| pos-integer = digit1-9 *DIGIT | minus = %x2D ; - | |||
| plus = %x2B ; + | ||||
| int = zero / ( digit1-9 *DIGIT ) | ||||
| digit1-9 = %x31-39 ; 1-9 | ||||
| frac = decimal-point 1*DIGIT | ||||
| decimal-point = %x2E ; . | ||||
| exp = e [ minus / plus ] 1*DIGIT | ||||
| e = %x65 / %x45 ; e E | ||||
| zero = %x30 ; 0 | ||||
| float = [ minus ] int frac [ exp ] | q-string = quotation-mark *char quotation-mark | |||
| ; From RFC 7159 except 'frac' required | ; From RFC 7159 | |||
| minus = %x2D ; - | char = unescaped / | |||
| plus = %x2B ; + | escape ( | |||
| int = zero / ( digit1-9 *DIGIT ) | %x22 / ; " quotation mark U+0022 | |||
| digit1-9 = %x31-39 ; 1-9 | %x5C / ; \ reverse solidus U+005C | |||
| frac = decimal-point 1*DIGIT | %x2F / ; / solidus U+002F | |||
| decimal-point = %x2E ; . | %x62 / ; b backspace U+0008 | |||
| exp = e [ minus / plus ] 1*DIGIT | %x66 / ; f form feed U+000C | |||
| e = %x65 / %x45 ; e E | %x6E / ; n line feed U+000A | |||
| zero = %x30 ; 0 | %x72 / ; r carriage return U+000D | |||
| %x74 / ; t tab U+0009 | ||||
| %x75 4HEXDIG ) ; uXXXX U+XXXX | ||||
| escape = %x5C ; \ | ||||
| quotation-mark = %x22 ; " | ||||
| unescaped = %x20-21 / %x23-5B / %x5D-10FFFF | ||||
| q-string = quotation-mark *char quotation-mark | regex = "/" *( escape "/" / not-slash ) "/" | |||
| ; From RFC 7159 | [ regex-modifiers ] | |||
| char = unescaped / | not-slash = HTAB / CR / LF / %x20-2E / %x30-10FFFF | |||
| escape ( | ; Any char except "/" | |||
| %x22 / ; " quotation mark U+0022 | regex-modifiers = *( "i" / "s" / "x" ) | |||
| %x5C / ; \ reverse solidus U+005C | ||||
| %x2F / ; / solidus U+002F | ||||
| %x62 / ; b backspace U+0008 | ||||
| %x66 / ; f form feed U+000C | ||||
| %x6E / ; n line feed U+000A | ||||
| %x72 / ; r carriage return U+000D | ||||
| %x74 / ; t tab U+0009 | ||||
| %x75 4HEXDIG ) ; uXXXX U+XXXX | ||||
| escape = %x5C ; \ | ||||
| quotation-mark = %x22 ; " | ||||
| unescaped = %x20-21 / %x23-5B / %x5D-10FFFF | ||||
| regex = "/" *( escape "/" / not-slash ) "/" | uri-scheme = 1*ALPHA | |||
| [ regex-modifiers ] | ||||
| not-slash = HTAB / CR / LF / %x20-2E / %x30-10FFFF | ||||
| ; Any char except "/" | ||||
| regex-modifiers = *( "i" / "s" / "x" ) | ||||
| uri-scheme = 1*ALPHA | ;; Keywords | |||
| ;; Keywords | any-kw = %x61.6E.79 ; "any" | |||
| any-kw = %x61.6E.79 ; "any" | as-kw = %x61.73 ; "as" | |||
| as-kw = %x61.73 ; "as" | base32-kw = %x62.61.73.65.33.32 ; "base32" | |||
| base32-kw = %x62.61.73.65.33.32 ; "base32" | base32hex-kw = %x62.61.73.65.33.32.68.65.78 ; "base32hex" | |||
| base32hex-kw = %x62.61.73.65.33.32.68.65.78 ; "base32hex" | base64-kw = %x62.61.73.65.36.34 ; "base64" | |||
| base64-kw = %x62.61.73.65.36.34 ; "base64" | base64url-kw = %x62.61.73.65.36.34.75.72.6C ; "base64url" | |||
| base64url-kw = %x62.61.73.65.36.34.75.72.6C ; "base64url" | boolean-kw = %x62.6F.6F.6C.65.61.6E ; "boolean" | |||
| boolean-kw = %x62.6F.6F.6C.65.61.6E ; "boolean" | date-kw = %x64.61.74.65 ; "date" | |||
| date-kw = %x64.61.74.65 ; "date" | datetime-kw = %x64.61.74.65.74.69.6D.65 ; "datetime" | |||
| datetime-kw = %x64.61.74.65.74.69.6D.65 ; "datetime" | double-kw = %x64.6F.75.62.6C.65 ; "double" | |||
| double-kw = %x64.6F.75.62.6C.65 ; "double" | email-kw = %x65.6D.61.69.6C ; "email" | |||
| email-kw = %x65.6D.61.69.6C ; "email" | false-kw = %x66.61.6C.73.65 ; "false" | |||
| false-kw = %x66.61.6C.73.65 ; "false" | float-kw = %x66.6C.6F.61.74 ; "float" | |||
| float-kw = %x66.6C.6F.61.74 ; "float" | fqdn-kw = %x66.71.64.6E ; "fqdn" | |||
| fqdn-kw = %x66.71.64.6E ; "fqdn" | hex-kw = %x68.65.78 ; "hex" | |||
| hex-kw = %x68.65.78 ; "hex" | idn-kw = %x69.64.6E ; "idn" | |||
| idn-kw = %x69.64.6E ; "idn" | import-kw = %x69.6D.70.6F.72.74 ; "import" | |||
| import-kw = %x69.6D.70.6F.72.74 ; "import" | int-kw = %x69.6E.74 ; "int" | |||
| int-kw = %x69.6E.74 ; "int" | integer-kw = %x69.6E.74.65.67.65.72 ; "integer" | |||
| integer-kw = %x69.6E.74.65.67.65.72 ; "integer" | ipaddr-kw = %x69.70.61.64.64.72 ; "ipaddr" | |||
| ipaddr-kw = %x69.70.61.64.64.72 ; "ipaddr" | ipv4-kw = %x69.70.76.34 ; "ipv4" | |||
| ipv4-kw = %x69.70.76.34 ; "ipv4" | ipv6-kw = %x69.70.76.36 ; "ipv6" | |||
| ipv6-kw = %x69.70.76.36 ; "ipv6" | jcr-version-kw = %x6A.63.72.2D.76.65.72.73.69.6F.6E ; "jcr-version" | |||
| jcr-version-kw = %x6A.63.72.2D.76.65.72.73.69.6F.6E ; "jcr-version" | not-kw = %x6E.6F.74 ; "not" | |||
| not-kw = %x6E.6F.74 ; "not" | null-kw = %x6E.75.6C.6C ; "null" | |||
| null-kw = %x6E.75.6C.6C ; "null" | phone-kw = %x70.68.6F.6E.65 ; "phone" | |||
| phone-kw = %x70.68.6F.6E.65 ; "phone" | root-kw = %x72.6F.6F.74 ; "root" | |||
| root-kw = %x72.6F.6F.74 ; "root" | ruleset-id-kw = %x72.75.6C.65.73.65.74.2D.69.64 ; "ruleset-id" | |||
| ruleset-id-kw = %x72.75.6C.65.73.65.74.2D.69.64 ; "ruleset-id" | string-kw = %x73.74.72.69.6E.67 ; "string" | |||
| string-kw = %x73.74.72.69.6E.67 ; "string" | time-kw = %x74.69.6D.65 ; "time" | |||
| time-kw = %x74.69.6D.65 ; "time" | true-kw = %x74.72.75.65 ; "true" | |||
| true-kw = %x74.72.75.65 ; "true" | type-kw = %x74.79.70.65 ; "type" | |||
| type-kw = %x74.79.70.65 ; "type" | uint-kw = %x75.69.6E.74 ; "uint" | |||
| uint-kw = %x75.69.6E.74 ; "uint" | unordered-kw = %x75.6E.6F.72.64.65.72.65.64 ; "unordered" | |||
| unordered-kw = %x75.6E.6F.72.64.65.72.65.64 ; "unordered" | uri-kw = %x75.72.69 ; "uri" | |||
| uri-kw = %x75.72.69 ; "uri" | ||||
| ;; Referenced RFC 5234 Core Rules | ;; Referenced RFC 5234 Core Rules | |||
| ALPHA = %x41-5A / %x61-7A ; A-Z / a-z | ALPHA = %x41-5A / %x61-7A ; A-Z / a-z | |||
| CR = %x0D ; carriage return | CR = %x0D ; carriage return | |||
| DIGIT = %x30-39 ; 0-9 | DIGIT = %x30-39 ; 0-9 | |||
| HEXDIG = DIGIT / "A" / "B" / "C" / "D" / "E" / "F" | HEXDIG = DIGIT / "A" / "B" / "C" / "D" / "E" / "F" | |||
| HTAB = %x09 ; horizontal tab | HTAB = %x09 ; horizontal tab | |||
| LF = %x0A ; linefeed | LF = %x0A ; linefeed | |||
| SP = %x20 ; space | SP = %x20 ; space | |||
| WSP = SP / HTAB ; white space | WSP = SP / HTAB ; white space | |||
| Figure 70: ABNF for JSON Content Rules | Figure 70: ABNF for JSON Content Rules | |||
| 8. Acknowledgements | 9. Acknowledgements | |||
| John Cowan, Andrew Biggs, Paul Kyzivat and Paul Jones provided | John Cowan, Andrew Biggs, Paul Kyzivat and Paul Jones provided | |||
| feedback and suggestions which led to many changes in the syntax. | feedback and suggestions which led to many changes in the syntax. | |||
| 9. References | 10. References | |||
| 9.1. Normative References | 10.1. Normative References | |||
| [JCR_ABNF] | ||||
| Newton, A. and P. Cordell, "ABNF for JSON Content Rules", | ||||
| <https://raw.githubusercontent.com/arineng/jcr/master/ | ||||
| jcr-abnf.txt>. | ||||
| [RFC1166] Kirkpatrick, S., Stahl, M., and M. Recker, "Internet | [RFC1166] Kirkpatrick, S., Stahl, M., and M. Recker, "Internet | |||
| numbers", RFC 1166, July 1990. | numbers", RFC 1166, DOI 10.17487/RFC1166, July 1990, | |||
| <https://www.rfc-editor.org/info/rfc1166>. | ||||
| [RFC3339] Klyne, G., Ed. and C. Newman, "Date and Time on the | [RFC3339] Klyne, G. and C. Newman, "Date and Time on the Internet: | |||
| Internet: Timestamps", RFC 3339, July 2002. | Timestamps", RFC 3339, DOI 10.17487/RFC3339, July 2002, | |||
| <https://www.rfc-editor.org/info/rfc3339>. | ||||
| [RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform | [RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform | |||
| Resource Identifier (URI): Generic Syntax", STD 66, RFC | Resource Identifier (URI): Generic Syntax", STD 66, | |||
| 3986, January 2005. | RFC 3986, DOI 10.17487/RFC3986, January 2005, | |||
| <https://www.rfc-editor.org/info/rfc3986>. | ||||
| [RFC4234] Crocker, D., Ed. and P. Overell, "Augmented BNF for Syntax | [RFC4234] Crocker, D., Ed. and P. Overell, "Augmented BNF for Syntax | |||
| Specifications: ABNF", RFC 4234, October 2005. | Specifications: ABNF", RFC 4234, DOI 10.17487/RFC4234, | |||
| October 2005, <https://www.rfc-editor.org/info/rfc4234>. | ||||
| [RFC4648] Josefsson, S., "The Base16, Base32, and Base64 Data | [RFC4648] Josefsson, S., "The Base16, Base32, and Base64 Data | |||
| Encodings", RFC 4648, October 2006. | Encodings", RFC 4648, DOI 10.17487/RFC4648, October 2006, | |||
| <https://www.rfc-editor.org/info/rfc4648>. | ||||
| [RFC5322] Resnick, P., Ed., "Internet Message Format", RFC 5322, | [RFC5322] Resnick, P., Ed., "Internet Message Format", RFC 5322, | |||
| October 2008. | DOI 10.17487/RFC5322, October 2008, | |||
| <https://www.rfc-editor.org/info/rfc5322>. | ||||
| [RFC5952] Kawamura, S. and M. Kawashima, "A Recommendation for IPv6 | [RFC5952] Kawamura, S. and M. Kawashima, "A Recommendation for IPv6 | |||
| Address Text Representation", RFC 5952, August 2010. | Address Text Representation", RFC 5952, | |||
| DOI 10.17487/RFC5952, August 2010, | ||||
| [RFC7159] Bray, T., "The JavaScript Object Notation (JSON) Data | <https://www.rfc-editor.org/info/rfc5952>. | |||
| Interchange Format", RFC 7159, March 2014. | ||||
| [JCR_ABNF] | [RFC7159] Bray, T., Ed., "The JavaScript Object Notation (JSON) Data | |||
| Newton, A. and P. Cordell, "ABNF for JSON Content Rules", | Interchange Format", RFC 7159, DOI 10.17487/RFC7159, March | |||
| <https://raw.githubusercontent.com/arineng/jcr/08/jcr- | 2014, <https://www.rfc-editor.org/info/rfc7159>. | |||
| abnf.txt>. | ||||
| 9.2. Infomative References | 10.2. Infomative References | |||
| [I-D.cordell-jcr-co-constraints] | [I-D.cordell-jcr-co-constraints] | |||
| Cordell, P. and A. Newton, "Co-Constraints for JSON | Cordell, P. and A. Newton, "Co-Constraints for JSON | |||
| Content Rules", draft-cordell-jcr-co-constraints-00 (work | Content Rules", draft-cordell-jcr-co-constraints-00 (work | |||
| in progress), March 2016. | in progress), March 2016. | |||
| [JCR_SPECIFICATION_FIGURES] | [RFC7492] Bhatia, M., Zhang, D., and M. Jethanandani, "Analysis of | |||
| Newton, A. and P. Cordell, "Figures in the JCR | Bidirectional Forwarding Detection (BFD) Security | |||
| Specification", <https://github.com/arineng/jcr/tree/08/ | According to the Keying and Authentication for Routing | |||
| figs>. | Protocols (KARP) Design Guidelines", RFC 7492, | |||
| DOI 10.17487/RFC7492, March 2015, | ||||
| <https://www.rfc-editor.org/info/rfc7492>. | ||||
| [ARIN_JCR_VALIDATOR] | 10.3. URIs | |||
| American Registry for Internet Numbers, "JSON Content | ||||
| Rules Validator (Work In Progress)", | ||||
| <https://github.com/arineng/jcrvalidator>. | ||||
| [CODALOGIC_JCR_VALIDATOR] | [1] https://github.com/arineng/jcr/tree/master/figs | |||
| Codalogic, "cl-jcr-parser (Work In Progress)", | ||||
| <https://github.com/codalogic/cl-jcr-parser>. | ||||
| Appendix A. Co-Constraints | Appendix A. Co-Constraints | |||
| This specification defines a small set of annotations and directives | This specification defines a small set of annotations and directives | |||
| for JCR, yet the syntax is extensible allowing for other annotations | for JCR, yet the syntax is extensible allowing for other annotations | |||
| and directives. [I-D.cordell-jcr-co-constraints] ("Co-Constraints | and directives. [I-D.cordell-jcr-co-constraints] ("Co-Constraints | |||
| for JCR") defines further annotations and directives which define | for JCR") defines further annotations and directives which define | |||
| more detailed constraints on JSON messages, including co-constraints | more detailed constraints on JSON messages, including co-constraints | |||
| (constraining parts of JSON message based on another part of a JSON | (constraining parts of JSON message based on another part of a JSON | |||
| message). | message). | |||
| skipping to change at page 40, line 47 ¶ | skipping to change at page 42, line 22 ¶ | |||
| complex than that which can be expressed in JCR, sometimes involving | complex than that which can be expressed in JCR, sometimes involving | |||
| variables and interdependencies which can only be expressed in a | variables and interdependencies which can only be expressed in a | |||
| programming language. | programming language. | |||
| A JCR processor may provide a mechanism for the execution of local | A JCR processor may provide a mechanism for the execution of local | |||
| functions or methods based on the name of a rule being evaluated. | functions or methods based on the name of a rule being evaluated. | |||
| Such a mechanism could pass to the function the data to be evaluated, | Such a mechanism could pass to the function the data to be evaluated, | |||
| and that function could return to the processor the result of | and that function could return to the processor the result of | |||
| evaluating the data in the function. | evaluating the data in the function. | |||
| Appendix C. JCR Implementations | Appendix C. Changes from -07 and -08 | |||
| The following implementations, [ARIN_JCR_VALIDATOR] and | ||||
| [CODALOGIC_JCR_VALIDATOR] have influenced the development of this | ||||
| document. | ||||
| Appendix D. Syntax Changes from -06 and -07 | ||||
| The differences between this document and -07 are not significant, as | ||||
| this version of this draft is provided for the purposes of keeping | ||||
| the document active within the IETF archives. | ||||
| The syntax described in this document is changed significantly, and | ||||
| in a non-backwards compatible manner, from the syntax described in | ||||
| the -06 version of this specification. The vast majority of these | ||||
| changes have occurred to meet the goals of the syntax being a | ||||
| superset of JSON and easy to comprehend by a casual reader unfamiliar | ||||
| with JCR but familiar with JSON. | ||||
| The latter of those two goals is subjective, and therefore a series | ||||
| of focus group sessions were convened where participants, all | ||||
| professional software developers with familiarity with JSON but not | ||||
| JCR, were asked to read and interpret various rulesets and allowed to | ||||
| offer suggested improvements. Outcomes of these sessions resulted in | ||||
| many changes, such as the use of '$' characters to note rule names | ||||
| and the change of the repetition syntax. | ||||
| Other changes came from feedback given directly to the authors via | ||||
| email and on the IETF JSON Working Group mailing list. | ||||
| Most figures from this document can be found in file form at | This revision of the document makes no substantive changes to any | |||
| [JCR_SPECIFICATION_FIGURES]. | parts of the specification. Some of the ABNF has been updated to | |||
| more correctly allow group rules, and other small change have been | ||||
| made to the ABNF to make it simpler. | ||||
| Authors' Addresses | Authors' Addresses | |||
| Andrew Lee Newton | Andrew Lee Newton | |||
| American Registry for Internet Numbers | American Registry for Internet Numbers | |||
| PO Box 232290 | PO Box 232290 | |||
| Centreville, VA 20120 | Centreville, VA 20120 | |||
| US | US | |||
| Email: andy@arin.net | Email: andy@arin.net | |||
| End of changes. 45 change blocks. | ||||
| 329 lines changed or deleted | 375 lines changed or added | |||
This html diff was produced by rfcdiff 1.48. The latest version is available from http://tools.ietf.org/tools/rfcdiff/ | ||||