From 2c17ae0d102eaddb79bf1a4d17cb23a238b91043 Mon Sep 17 00:00:00 2001 From: Henry Andrews Date: Sat, 26 May 2018 23:28:44 -0700 Subject: [PATCH 1/4] Default behaviors; annotation-dependent results Describe how default behaviors work in more detail, covering all three major keyword categories. Allow keywords to depend on the presence or absence of adjacent keywords (this is already true with "additionalItems" and "items'). Allow keywords to depend on the annotation results of subschemas and adjacent keywords. This is the fundamental mechanism behind the forthcoming "unevaluatedProperties" and "unevaluatedItems" keywords. The behavior of "additionalProperties" and "additionalItems" can be described with this mechanism (along with the presence or absence mechanism) as well, which will serve as a proof of concept of the approach in a subsequent commit. --- jsonschema-core.xml | 41 ++++++++++++++++++++++++++++++++++++----- 1 file changed, 36 insertions(+), 5 deletions(-) diff --git a/jsonschema-core.xml b/jsonschema-core.xml index 937e5f7f..b450bcb8 100644 --- a/jsonschema-core.xml +++ b/jsonschema-core.xml @@ -126,8 +126,9 @@
JSON Schema keywords fall into several general behavior categories. - Assertions validate that an instance satisfies constraints. Annotations - attach information that applications may use in any way they see fit. + Assertions validate that an instance satisfies constraints, producing + a boolean result. Annotations attach information that applications + may use in any way they see fit. Applicators apply subschemas to parts of the instance and combine their results. @@ -145,6 +146,38 @@ subschemas have been evaluated, although in some circumstance evaluation may be short-circuited due to assertion results. + + Keyword behavior MAY be defined in terms of the annotation results + of subschemas and/or adjacent keywords. + 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. + + + A missing keyword MUST NOT produce a false assertion result, MUST + NOT produce annotation results, and MUST NOT cause any other schema + to be evaluated as part of its own behavioral definition. + However, given that missing keywords do not contribute annotations, + the lack of annotation results may indirectly change the behavior + of other keywords. + + + In some cases, the missing keyword assertion behavior of a keyword is + identical to that produced by a certain value, and keyword definitions + SHOULD note such values where known. However, even if the value which + 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 known to an implementation to have assertion or applicator behavior + that depend on annotation results MUST then be treated as errors, unless + an alternate implementation producing the same behavior is available. + Keywords of this sort SHOULD describe reasonable alternate approaches + when appropriate. + Extension keywords SHOULD stay within these categories, keeping in mind that annotations in particular are extremely flexible. Complex behavior @@ -190,9 +223,7 @@ An instance can only fail an assertion that is present in the schema. - In some cases, this no-op behavior is identical to a keyword that exists with - certain values, and keyword definitions SHOULD note such values where known. - These default behaviors MUST NOT result in assertion failures. +
From a771f510b42f02588cba735689aea85f7d8fca0d Mon Sep 17 00:00:00 2001 From: Henry Andrews Date: Sun, 27 May 2018 21:44:29 -0700 Subject: [PATCH 2/4] Remove outdated child validation language These paragraphs are no longer needed now that the keywords are clearly designated as Applicators. Both the general applicator section and the introduction to this vocabulary cover the behavior clearly. Note that the remaining phrasing is still too validation-centric. This will be addressed in the future. --- jsonschema-core.xml | 22 ---------------------- 1 file changed, 22 deletions(-) diff --git a/jsonschema-core.xml b/jsonschema-core.xml index b450bcb8..0af1974e 100644 --- a/jsonschema-core.xml +++ b/jsonschema-core.xml @@ -1245,10 +1245,6 @@ The value of "items" MUST be either a valid JSON Schema or an array of valid JSON Schemas. - - This keyword determines how child instances validate for arrays, - and does not directly validate the immediate instance itself. - If "items" is a schema, validation succeeds if all elements in the array successfully validate against that schema. @@ -1267,10 +1263,6 @@ The value of "additionalItems" MUST be a valid JSON Schema. - - This keyword determines how child instances validate for arrays, - and does not directly validate the immediate instance itself. - If "items" is an array of schemas, validation succeeds if every instance element at a position greater than the size @@ -1303,10 +1295,6 @@ The value of "properties" MUST be an object. Each value of this object MUST be a valid JSON Schema. - - This keyword determines how child instances validate for objects, - and does not directly validate the immediate instance itself. - Validation succeeds if, for each name that appears in both the instance and as a name within this keyword's value, the child @@ -1325,12 +1313,6 @@ ECMA 262 regular expression dialect. Each property value of this object MUST be a valid JSON Schema. - - This keyword determines how child instances validate for objects, - and does not directly validate the immediate instance itself. - Validation of the primitive instance type against this keyword - always succeeds. - Validation succeeds if, for each instance name that matches any regular expressions that appear as a property name in this keyword's value, @@ -1346,10 +1328,6 @@ The value of "additionalProperties" MUST be a valid JSON Schema. - - This keyword determines how child instances validate for objects, - and does not directly validate the immediate instance itself. - Validation with "additionalProperties" applies only to the child values of instance names that do not match any names in "properties", From b72cdd692122572b206c693a6b8f90d2bc915a26 Mon Sep 17 00:00:00 2001 From: Henry Andrews Date: Sun, 27 May 2018 23:47:14 -0700 Subject: [PATCH 3/4] Define additional* in terms of annotations This aligns the behavior of "additionalItems" and "additionalProperties" with the rules given for dependent keywords in the previous commit. Specifically, "additionalItems" depends on the presence or absence of "items", and its newly defined annotation results, while "additionalProperties" depends on the annotation results of "properties" and "patternProperties". The standard explicitly allows implementing these keywords in other ways (presumably the way implementations currently handle them) as either an optimization or to support the keywords in implementations that do not support annotations. This avoids requiring existing assertion-only validators to change their behavior. Note that the rationale for "additionalItems" being ignored when "items" is absent has been changed to align it with this new framework. Doing anything else would have required an absent keyword to produce annotation results as default behavior, which leads to very difficult problems as the set of keywords with such behavior grows. --- jsonschema-core.xml | 105 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 86 insertions(+), 19 deletions(-) diff --git a/jsonschema-core.xml b/jsonschema-core.xml index 0af1974e..69c5d3f8 100644 --- a/jsonschema-core.xml +++ b/jsonschema-core.xml @@ -176,7 +176,10 @@ that depend on annotation results MUST then be treated as errors, unless an alternate implementation producing the same behavior is available. Keywords of this sort SHOULD describe reasonable alternate approaches - when appropriate. + when appropriate. This approach is demonstrated by the + "" and + "" keywords in this + document. Extension keywords SHOULD stay within these categories, keeping in mind @@ -1242,8 +1245,8 @@
- The value of "items" MUST be either a valid JSON Schema or an array of valid - JSON Schemas. + The value of "items" MUST be either a valid JSON Schema or + an array of valid JSON Schemas. If "items" is a schema, validation succeeds if all elements @@ -1255,26 +1258,52 @@ same position, if any. - Omitting this keyword has the same behavior as an empty schema. + This keyword produces an annotation value which is the largest + index to which this keyword applied a subschema. The value + MAY be a boolean true if a subschema was applied to every + index of the instance, such as when "items" is a schema. + + + Annotation results from multiple "items" keyword are combined + by setting the combined result to true if any of the values + are true, and otherwise retaining the larges numerical value. + + + Omitting this keyword has the same assertion behavior as + an empty schema.
-
+
The value of "additionalItems" MUST be a valid JSON Schema. - If "items" is an array of schemas, validation succeeds - if every instance element at a position greater than the size - of "items" validates against "additionalItems". + The behavior of this keyword depends on the presence and + annotation result of "items" within the same schema object. + If "items" is present, and its annotation result is a number, + validation succeeds if every instance element at an index + greater than that number validates against "additionalItems". - Otherwise, "additionalItems" MUST be ignored, as the "items" - schema (possibly the default value of an empty schema) is - applied to all elements. + Otherwise, if "items" is absent or its annotation result + is the boolean true, "additionalItems" MUST be ignored. - Omitting this keyword has the same behavior as an empty schema. + If the "additionalItems" subschema is applied to any + positions within the instance array, it produces an + annotation result of boolean true, analogous to the + single schema behavior of "items". + + + Omitting this keyword has the same assertion behavior as + an empty schema. + + + Implementation MAY choose to implement or optimize this keyword + in another way that produces the same effect, such as by directly + checking for the presence and size of an "items" array. + Implementations that do not support annotation collection MUST do so.
@@ -1284,7 +1313,16 @@ An array instance is valid against "contains" if at least one of - its elements is valid against the given schema. + its elements is valid against the given schema. This keyword + does not produce annotation results. + + Should it produce a set of the indices for which the + array element is valid against the subschema? "contains" + does not affect "additionalItems" or any other current + or proposed keyword, but the information could be useful, + and implementation that collect annotations need to + apply "contains" to every element anyway. +
@@ -1302,7 +1340,14 @@ corresponding schema.
- Omitting this keyword has the same behavior as an empty object. + The annotation result of this keyword is the set of instance + property names matched by this keyword. Multiple annotation + results for "properties" are combined by taking the union + of the sets. + + + Omitting this keyword has the same assertion behavior as + an empty object.
@@ -1320,25 +1365,47 @@ schema that corresponds to a matching regular expression. - Omitting this keyword has the same behavior as an empty object. + The annotation result of this keyword is the set of instance + property names matched by this keyword. Multiple annotation + results for "patternProperties" are combined by taking the union + of the sets. + + + Omitting this keyword has the same assertion behavior as + an empty object.
-
+
The value of "additionalProperties" MUST be a valid JSON Schema. + The behavior of this keyword depends on the presence and + annotation results of "properties" and "patternProperties" + within the same schema object. Validation with "additionalProperties" applies only to the child - values of instance names that do not match any names in "properties", - and do not match any regular expression in "patternProperties". + values of instance names that do not appear in the annotation + results of either "properties" or "patternProperties". For all such properties, validation succeeds if the child instance validates against the "additionalProperties" schema. - Omitting this keyword has the same behavior as an empty schema. + The annotation result of this keyword is the set of instance + property names validated by this keyword's subschema. + + + Omitting this keyword has the same assertion behavior as + an empty schema. + + + Implementation MAY choose to implement or optimize this keyword + in another way that produces the same effect, such as by directly + checking the names in "properties" and the patterns in + "patternProperties" against the instance property set. + Implementations that do not support annotation collection MUST do so.
From bc2a04247aa0d3bf53e850b40f5829dbc06c981d Mon Sep 17 00:00:00 2001 From: Henry Andrews Date: Mon, 11 Jun 2018 22:18:07 -0700 Subject: [PATCH 4/4] Improved wording, fix typo. This tries to make the concept of having multiple annotation results for the same keyword more clear in the applicator vocabulary. --- jsonschema-core.xml | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/jsonschema-core.xml b/jsonschema-core.xml index 69c5d3f8..9f23a7a1 100644 --- a/jsonschema-core.xml +++ b/jsonschema-core.xml @@ -1264,9 +1264,10 @@ index of the instance, such as when "items" is a schema. - Annotation results from multiple "items" keyword are combined + Annotation results for "items" keywords from multiple + schemas applied to the same instance location are combined by setting the combined result to true if any of the values - are true, and otherwise retaining the larges numerical value. + are true, and otherwise retaining the largest numerical value. Omitting this keyword has the same assertion behavior as @@ -1293,14 +1294,17 @@ If the "additionalItems" subschema is applied to any positions within the instance array, it produces an annotation result of boolean true, analogous to the - single schema behavior of "items". + single schema behavior of "items". If any "additionalItems" + keyword from any subschema applied to the same instance + location produces an annotation value of true, then + the combined result from these keywords is also true. Omitting this keyword has the same assertion behavior as an empty schema. - Implementation MAY choose to implement or optimize this keyword + Implementations MAY choose to implement or optimize this keyword in another way that produces the same effect, such as by directly checking for the presence and size of an "items" array. Implementations that do not support annotation collection MUST do so. @@ -1341,8 +1345,9 @@ The annotation result of this keyword is the set of instance - property names matched by this keyword. Multiple annotation - results for "properties" are combined by taking the union + property names matched by this keyword. Annotation results + for "properties" keywords from multiple schemas applied to + the same instance location are combined by taking the union of the sets. @@ -1366,8 +1371,9 @@ The annotation result of this keyword is the set of instance - property names matched by this keyword. Multiple annotation - results for "patternProperties" are combined by taking the union + property names matched by this keyword. Annotation results + for "patternProperties" keywords from multiple schemas applied to + the same instance location are combined by taking the union of the sets. @@ -1395,6 +1401,9 @@ The annotation result of this keyword is the set of instance property names validated by this keyword's subschema. + Annotation results for "additionalProperties" keywords from + multiple schemas applied to the same instance location are combined + by taking the union of the sets. Omitting this keyword has the same assertion behavior as