-
-
Notifications
You must be signed in to change notification settings - Fork 3
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
Implement a better abstraction layer for efficiently handling annotations #1065
Comments
@michaelmior I just added a real example based on
On evaluation path, you might start evaluating |
In the current evaluator implementation, we directly keep the instance location and evaluation paths as pointers that we push to and pop from when executing every individual instruction: jsontoolkit/src/jsonschema/compile_evaluate.cc Lines 251 to 252 in ddc6917
|
Perfect! That clarifies things. Is it true that the actual value of annotations never need to be returned in the current implementation? |
Correct. You never need to "retrieve" the annotation values, just check containment given the adjacent and non-adjacent algorithms. That said, we do pass references to the value at the time of emission to the evaluation callback to the user for them to hook on them if needed (for whatever they are doing or for reporting reasons). But internally, the evaluator doesn't need them. |
hey @jviotti :) I gave a first look at this document. Here are my questions mark:
|
They are not related to each other. Each represent an orthogonal path that might change on its own. For example, consider this schema and instance based on the one I showed above: // Schema
{
"properties": {
"foo": { "type": "string" }
},
"additionalProperties": {
"type": "integer"
}
}
// Instance
{ "foo": "bar", "one": 1, "two": 2 } The evaluation with regards to those pointers goes like this :
As you see, each moves pretty much independently and you cannot consider one as an extension of the other. I suggested a map above as a theoretical representation, but if we can do a tree, that sounds good too. Whatever satisfies those requirements.
It is an OR. I'll clarify! |
@tony-go @michaelmior One thing that could help with allocations is the observation that for the evaluation path, its JSON Pointer tokens almost always correspond to JSON Schema keywords (i.e. One interesting thing we could do is have a variant of the i.e. imagine you can construct the pointer with a second argument that is the pool or something like that |
I think that makes sense. I suspect that you'll have a lot of repetition even among tokens that aren't keywords, so the pool approach makes sense to me even without pre-populating the pool. |
Yeah, way more clear now! Also I wonder if we could not rename them to:
I think it would be less confusing if it was like that. WDYT?
❤️ |
We shouldn't be inventing our own names. |
Actually, I'm realising there is one case where we do need this: |
In JSON Schema, annotations are JSON values associated to a given instance location (a JSON Pointer) and evaluation path (a JSON Pointer). A container to hold annotations, in theory could be something like this:
Note that there can be multiple JSON values associated with a given instance location and evaluation path, but duplicates are not taken into account.
Write Operations
Insertion: You need to be able to insert a JSON document into a given instance location and evaluation path. The challenge here is to avoid copying the given pointers and the JSON value.
Removal: You need to be able to remove all annotations produced at a given evaluation path or its children, independently of its instance location. For example, if you want to remove annotations at evaluate path
/properties/not
, you also remove any annotation produced at evaluate path/properties/not/foo
and/properties/not/foo/bar/baz
.Read Operations
Adjacent containment: You need to be able to check if a given set of keywords (OR) emitted the given annotation value for a given instance location, sibling to the given evaluation path.
For example, you might be looking for the annotation value
"foo"
at instance location/myObject
, from keywordsbar
orbaz
, sibling to evaluation path/one/two/three
. That means the following combinations are valid:/myObject
//one/two/bar
/"foo"
/myObject
//one/two/baz
/"foo"
General containment: You need to be able to check if a given set of keywords (OR) emitted the given annotation value for a given instance location, sibling to the given evaluation path or on any of its children
For example, you might be looking for the annotation value
"foo"
at instance location/myObject
, from keywordsbar
orbaz
, sibling to evaluation path/one/two/three
. That means all the following combinations are valid:/myObject
//one/two/bar
/"foo"
/myObject
//one/two/baz
/"foo"
/myObject
//one/two/whatever/a/b/c/bar
/"foo"
Real Example
Consider the following schema. If the instance is an object, if it defines the property
foo
, the latter must be a string. If it defines any other property that is notfoo
, that property must be an integer.Now consider the following instance:
Relying on annotations, the evaluation goes as follows:
properties
. Thefoo
property is defined and it validates against the given subschema""
(instance location, the root of the document) /"/properties"
(evaluation path) /"foo"
(value)additionalProperties
""
(instance location) /"/properties"
OR""
(instance location) /"/patternProperties"
The text was updated successfully, but these errors were encountered: