diff --git a/jsonschema-core.xml b/jsonschema-core.xml
index 93638219..f81a3e14 100644
--- a/jsonschema-core.xml
+++ b/jsonschema-core.xml
@@ -687,14 +687,74 @@
- Keyword behavior MAY be defined in terms of the annotation results
- of subschemas and/or adjacent keywords
- (keywords within the same schema object) and their subschemas.
+ Keyword behavior MAY be defined in terms of the annotation or
+ validation results of adjacent keywords (keywords within the same
+ schema object) and their subschemas.
Such keywords MUST NOT result in a circular dependency.
Keywords MAY modify their behavior based on the presence or absence
of another keyword in the same
schema object.
+
+ Keywords MAY specify dependencies on keywords in other vocabularies.
+ However, dependencies are purely in terms of keyword/annotation name.
+ While a keyword's description SHOULD indicate the vocabulary that is
+ expected to provide the dependency, this is not an enforceable dependency.
+ As with overlapping keyword names in general, the behavior of using
+ vocabularies with incompatible semantics is undefined.
+
+
+ In addition to depending on specific adjacent keywords, a keyword MAY
+ depend on specific annotations collected through any and all in-place applicators,
+ without needing to list individual in-place applicator keywords. This allows
+ for continued correct behavior when some other vocabulary adds previously unknown
+ in-place applicators. An annotation that has been collected through in-place
+ applicators will have the same instance location as that which is currently
+ being processed.
+
+ At this time, the only class of keywords that can be depended upon like this
+ are in-place applicators. To date, no use cases have been found for other
+ keyword class dependencies. This could change in the future.
+
+
+
+ Keywords defining interactions through these mechanisms SHOULD be supported by any
+ vocabulary plugin architecture; interactions of this sort involving adjacent
+ keywords and in-place applicators are expressed in machine-readable form in the
+ vocabulary file.
+
+
+ Vocabulary authors MUST NOT assume that vocabulary plug-in architectures
+ will allow any other form of interaction. Save for explicit agreement,
+ schema authors SHALL NOT expect these keywords depending on additional
+ interactions to be supported by peer implementations.
+
+
+
+ While keyword interactions MUST be defined as described above in order
+ to be implementable in any conforming plugin architecture, implementations
+ MAY choose other ways to implement specific keyword dependencies for
+ reasons of performance or simplicity.
+
+
+ Because annotation collection can add significant cost in terms of both
+ computation and memory, implementations MAY opt out of this feature.
+ Keywords that are specified in terms of collected annotations SHOULD
+ describe reasonable alternate approaches when appropriate.
+ This approach is demonstrated by the
+ "" and
+ "" keywords in this
+ document. However, ""
+ and "" do not
+ specify alternate approaches, as the complexity of those keywords
+ is not conducive to simple alternatives.
+
+
+ Note that when no such alternate approach is possible for a keyword,
+ implementations that do not support annotation collection will not
+ be able to support those keywords or vocabularies that contain them.
+
+
@@ -712,21 +772,6 @@
produces the default behavior would produce annotation results if
present, the default behavior still MUST NOT result in annotations.
-
- Because annotation collection can add significant cost in terms of both
- computation and memory, implementations MAY opt out of this feature.
- Keywords that are specified in terms of collected annotations SHOULD
- describe reasonable alternate approaches when appropriate.
- This approach is demonstrated by the
- "" and
- "" keywords in this
- document.
-
-
- Note that when no such alternate approach is possible for a keyword,
- implementations that do not support annotation collections will not
- be able to support those keywords or vocabularies that contain them.
-
@@ -1111,7 +1156,7 @@
The current URI for the Core vocabulary is:
- <https://json-schema.org/draft/2019-09/vocab/core>.
+ .
The current URI for the corresponding meta-schema is:
@@ -1292,6 +1337,122 @@
+
+
+ The vocabulary file is a machine-readable specification of
+ essential information that a vocabulary plugin system would
+ need to know to support keyword interactions. It allows
+ the implementation to evaluate keywords in the correct order
+ across all vocabularies.
+
+
+ This draft introduces a minimal format based on preliminary feedback.
+ Its format may change substantially in the next draft as more
+ feedback comes in. However, the capabilities it is currently able
+ to describe are expected ot remain, even if the syntax changes.
+
+
+ The vocabulary file MUST be a JSON document consisting
+ of a single object with two properties:
+
+
+ The value of this keyword MUST be an absolute-URI,
+ which MUST be the URI expected to be used in the
+ "$vocabulary" keyword in a meta-schema; as noted
+ in the "$vocabulary" description, this URI is an
+ identifier rather than a locator
+
+
+ An object whose keys MUST be the complete set
+ of keywords defined by this vocabulary, and whose
+ values MUST be objects as defined below
+
+
+ The per-keyword object MAY be empty, or MAY have any of the following
+ properties:
+
+
+ The value of this property MUST be a boolean; if true, the
+ keyword is an in-place applicator; if false (the default)
+ it is some other unspecified classification
+
+
+ The value of this property MUST be an array of strings;
+ the strings MUST be names of the annotations (which are the
+ same as the keywords that produce them) on which this keyword's
+ behavior depends; the annotations/keywords need not be defined
+ in this same vocabulary; the default is an empty array
+
+
+ The value of this property MUST be a boolean; if true,
+ the keyword depends on the annotations listed in "dependsOn"
+ both from adjacent keywords, and from annotations attached to
+ the current instance location that are collected through
+ adjacent in-place applicator keywords; if false (the default),
+ only annotations collected directly from adjacent keywords are used
+
+
+ The value of this property MUST be an object; the property
+ names MUST be names of keywords, and the property values MUST
+ be booleans, such that this keyword MUST be evaluated only if
+ the keywords in this object are present as adjacent keywords,
+ and produce an assertion result equal to the property value
+
+
+
+
+ Note that when using "throughInPlaceApplicators", a keyword may depend
+ on itself, as it may appear in in-place applicator subschemas.
+ When examining adjacent keywords, implementations MUST detect such
+ a self-dependency and avoid deadlocking.
+
+
+
+
+ The following example set of keywords, taken from other vocabularies
+ in this specification, demonstrate all of the above possibilities:
+
+
+
+
+
+
+
@@ -2086,7 +2247,7 @@
The current URI for this vocabulary, known as the Applicator vocabulary, is:
- <https://json-schema.org/draft/2019-09/vocab/applicator>.
+ .
The current URI for the corresponding meta-schema is:
@@ -2099,34 +2260,6 @@
before the next to indicate the same syntax and semantics
as those listed here.
-
-
- Schema keywords typically operate independently, without
- affecting each other's outcomes.
-
-
- For schema author convenience, there are some exceptions among the
- keywords in this vocabulary:
-
-
- "additionalProperties", whose behavior is defined in terms of
- "properties" and "patternProperties"
-
-
- "unevaluatedProperties", whose behavior is defined in terms of
- annotations from "properties", "patternProperties",
- "additionalProperties" and itself
-
-
- "items", whose behavior is defined in terms of "prefixItems"
-
-
- "unevaluatedItems", whose behavior is defined in terms of annotations
- from "prefixItems", "items", "contains", and itself
-
-
-
-
diff --git a/vocab/applicator.json b/vocab/applicator.json
new file mode 100644
index 00000000..3aff8265
--- /dev/null
+++ b/vocab/applicator.json
@@ -0,0 +1,42 @@
+{
+ "vocabulary": "https://json-schema.org/draft/next/vocab/applicator",
+ "keywords": {
+ "allOf": {
+ "inPlaceApplicator": true
+ },
+ "anyOf": {
+ "inPlaceApplicator": true
+ },
+ "oneOf": {
+ "inPlaceApplicator": true
+ },
+ "not": {
+ "inPlaceApplicator": true
+ },
+ "if": {
+ "inPlaceApplicator": true
+ },
+ "then": {
+ "inPlaceApplicator": true,
+ "dependsOnValidity": {"if": true}
+ },
+ "else": {
+ "inPlaceApplicator": true,
+ "dependsOnValidity": {"if": false}
+ },
+ "dependentSchemas": {
+ "inPlaceApplicator": true
+ },
+ "prefixItems": {},
+ "items": {
+ "dependsOn": ["prefixItems"]
+ },
+ "contains": {},
+ "properties": {},
+ "patternProperties": {},
+ "additionalProperties": {
+ "dependsOn": ["properties", "patternProperties"]
+ },
+ "propertyNames": {}
+ }
+}
diff --git a/vocab/core.json b/vocab/core.json
new file mode 100644
index 00000000..7fe2b7b7
--- /dev/null
+++ b/vocab/core.json
@@ -0,0 +1,18 @@
+{
+ "vocabulary": "https://json-schema.org/draft/next/vocab/core",
+ "keywords": {
+ "$schema": {},
+ "$vocabulary": {},
+ "$id": {},
+ "$anchor": {},
+ "$ref": {
+ "inPlaceApplicator": true
+ },
+ "$dynamicAnchor": {},
+ "$dynamicRef": {
+ "inPlaceApplicator": true
+ },
+ "$defs": {},
+ "$comment": {}
+ }
+}
diff --git a/vocab/unevaluated.json b/vocab/unevaluated.json
new file mode 100644
index 00000000..d59baa1f
--- /dev/null
+++ b/vocab/unevaluated.json
@@ -0,0 +1,23 @@
+{
+ "vocabulary": "https://json-schema.org/draft/next/vocab/unevaluated",
+ "keywords": {
+ "unevaluatedItems": {
+ "dependsOn": [
+ "prefixItems",
+ "items",
+ "contains",
+ "unevaluatedItems"
+ ],
+ "throughInPlaceApplicators": true
+ },
+ "unevaluatedProperties": {
+ "dependsOn": [
+ "properties",
+ "patternProperties",
+ "additionalProperties",
+ "unevaluatedProperties"
+ ],
+ "throughInPlaceApplicators": true
+ }
+ }
+}