Skip to content

Initial description of annotation collection #610

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 8, 2018
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
187 changes: 186 additions & 1 deletion jsonschema-core.xml
Original file line number Diff line number Diff line change
Expand Up @@ -1140,6 +1140,191 @@
</t>
</section>

<section title="Collecting Annotations">
<t>
<cref>
The exact structure and format of the information collected is TBD,
but will be defined before the next draft. Some details of this
section may change as a result, but the overall process is expected
to remain the same. See GitHub issue #396 to track progress.
</cref>
</t>
<t>
Annotations are collected by keywords that explicitly define
annotation-collecting behavior. Note that boolean schemas cannot
produce annotations as they do not make use of keywords.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this not obvious enough?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Eh, to you and me, yes, but I can see someone asking about the boolean schemas contributing to an annotation that indicates that a boolean schema was used. Or something. I think it's harmless to state explicitly, but let me know if you think it is confusing.

</t>
<t>
A collected annotation MUST include the following information:
<list>
<t>
The name of the keyword that produces the annotation
</t>
<t>
The instance location to which it is attached, as a JSON Pointer
</t>
<t>
The absolute schema location of the attaching keyword, as a URI
</t>
<t>
The schema location path, indicating how reference keywords
such as "$ref" were followed to reach the absolute schema location
<cref>The exact format of this path is TBD, again see issue #396</cref>
</t>
<t>
The attached value(s)
</t>
</list>
</t>
<t>
If the same keyword attaches values from multiple schema locations
to the same instance location, and the annotation defines a process
for combining such values, then the combined value MUST also be associated
with the instance location.
</t>
<section title="Distinguishing Among Multiple Values">
<t>
Applications MAY make decisions on which of multiple annotation values
to use based on the schema location that contributed the value.
This is intended to allow flexible usage. Collecting the schema location
facilitates such usage.
</t>
<t>
For example, consider this schema, which uses annotations and assertions from
the <xref target="json-schema-validation">Validation specification</xref>:
</t>
<figure>
<preamble>
Note that some lines are wrapped for clarity.
</preamble>
<artwork>
<![CDATA[
{
"title": "Feature list",
"type": "array",
"items": [
{
"title": "Feature A",
"properties": {
"enabled": {
"$ref": "#/$defs/enabledToggle",
"default": true
}
}
},
{
"title": "Feature B",
"properties": {
"enabled": {
"description": "If set to null, Feature B
inherits the enabled
value from Feature A",
"$ref": "#/$defs/enabledToggle"
}
}
}
]
},
"$defs": {
"enabledToggle": {
"title": "Enabled",
"description": "Whether the feature is enabled (true),
disabled (false), or under
automatic control (null)",
"type": ["boolean", "null"],
"default": null
}
}
}
]]>
</artwork>
</figure>
<t>
In this example, both Feature A and Feature B make use of the re-usable
"enabledToggle" schema. That schema uses the "title", "description",
and "default" annotations, none of which define special behavior for
handling multiple values. Therefore the application has to decide how
to handle the additional "default" value for Feature A, and the additional
"description" value for Feature B.
</t>
<t>
The application programmer and the schema author need to agree on the
usage. For this example, let's assume that they agree that the most
specific "default" value will be used, and any additional, more generic
"default" values will be silently ignored. Let's also assume that they
agree that all "description" text is to be used, starting with the most
generic, and ending with the most specific. This requires the schema
author to write descriptions that work when combined in this way.
</t>
<t>
The application can use the schema location path to determine which
values are which. The values in the feature's immediate "enabled"
property schema are more specific, while the values under the re-usable
schema that is referred to with "$ref" are more generic. The schema
location path will show whether each value was found by crossing a
"$ref" or not.
</t>
<t>
Feature A will therefore use a default value of true, while Feature B
will use the generic default value of null. Feature A will only
have the generic description from the "enabledToggle" schema, while
Feature B will use that description, and also append its locally
defined description that explains how to interpret a null value.
</t>
<t>
Note that there are other reasonable approaches that a different application
might take. For example, an application may consider the presence of
two different values for "default" to be an error, regardless of their
schema locations.
</t>
</section>
<section title="Annotations and Assertions">
<t>
Schema objects that produce a false assertion result MUST NOT
produce any annotation results, whether from their own keywords
or from keywords in subschemas.
</t>
<t>
Note that the overall schema results may still include annotations
collected from other schema locations. Given this schema:
</t>
<figure>
<artwork>
<![CDATA[
{
"oneOf": [
{
"title": "Integer Value",
"type": "integer"
},
{
"title": "String Value",
"type": "string"
}
]
}
]]>
</artwork>
</figure>
<t>
And the instance <spanx style="verb">"This is a string"</spanx>, the
title annotation "Integer Value" is discarded because the type assertion
in that schema object fails. The title annotation "String Value"
is kept, as the instance passes the string type assertions.
</t>
</section>
<section title="Annotations and Applicators">
<t>
In addition to possibly defining annotation results of their own,
applicator keywords aggregate the annotations collected in their
subschema(s) or referenced schema(s). The rules for aggregating
annotation values are defined by each annotation keyword, and are
not directly affected by the logic used for combining assertion
results.
</t>
</section>
</section>

<section title="A Vocabulary for Applying Subschemas">
<t>
This section defines a vocabulary of applicator keywords that
Expand Down Expand Up @@ -1213,7 +1398,7 @@
</t>
</section>

<section title="not">
<section title="not" anchor="not">
<t>
This keyword's value MUST be a valid JSON Schema.
</t>
Expand Down