-
Notifications
You must be signed in to change notification settings - Fork 467
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
Constrain types so that only valid inputs match the schema #508
Comments
As far as it is easily possibe to trace back history, |
Hm, I tried this in yet another validator (the Line 4 (the XOR works?): it considers the mixed-schema invalid as I would expect Somehow the "oneOf" doesn't like the fact that "channel" is required... I'm going to experiment a bit more and check the docs for "required" again to try to make sense of this. |
Oh I see what's the problem in my case,
I'm wondering if it would help to split out an |
Okay this works. I'm using Combined schema for use with https://www.jsonschemavalidator.net/ (the three schemas in the (Note, I didn't include the {
"$schema": "https://json-schema.org/draft/2020-09/schema",
"properties": {
"featureIds": {
"type": "array",
"items": {
"oneOf": [
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "featureIdAttribute.schema.json",
"title": "Feature ID Attribute",
"type": "object",
"description": "Feature IDs to be used as indices to property arrays in the property table.",
"properties": {
"attribute": {
"type": "integer",
"minimum": 0
},
"extensions": {},
"extras": {}
},
"required": ["attribute"],
"additionalProperties": false
},
{
"$id": "implicitFeatureIdAttribute.schema.json",
"title": "Implicit Feature ID Attribute",
"type": "object",
"properties": {
"offset": {
"type": "integer",
"minimum": 0,
"default": 0
},
"repeat": {
"type": "integer",
"minimum": 1
},
"extensions": {},
"extras": {}
},
"additionalProperties": false
},
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "featureIdTexture.schema.json",
"title": "Feature ID Texture",
"type": "object",
"properties": {
"index": {},
"texCoord": {},
"channel": {
"type": "integer",
"minimum": 0
},
"extensions": {},
"extras": {}
},
"required": [
"channel"
],
"additionalProperties": false
}
]
}
}
}
} Test JSON to validate (first 3 objects are valid feature IDs, the last two are invalid) {
"featureIds": [
{
"offset": 0,
"repeat": 1
},
{
"attribute": 3
},
{
"index": 0,
"texCoord": 0,
"channel": 0
},
{
"index": 0,
"propertyTable": 0,
"channel": 0,
"offset": 0,
"repeat": 1
},
{
"attribute": 3,
"offset": 4
}
]
}
@javagl @donmccurdy any thoughts on this approach? |
There are a few technicalities to go through, but I think that |
I'm not sure I understand the details related to |
We talked about this on a call, the However, I also have another idea to fix this. If we change the implicit feature ID schema from:
to:
I'll experiment with this a bit and see what works. |
I tried that, but to ensure no mixed cases, you need to list all the fields across all three types of feature ID. I don't like this approach:
Another thought I had, what if it's like
|
I don't think we need to guarantee that all mixed cases fail validation — adding more indirection to the spec to make the schema validation easier doesn't feel like the right solution to me, unless it's necessary for things like code generation from the schema. There are lots of disallowed combinations of JSON properties that can't be caught by validating against the schema alone, such as: "primitives": [{
"mode": 0, // POINTS
"indices": 0, // disallowed for POINTS
"attributes": { ... }
}] If your earlier suggestion is enough to be sure that no valid files will fail validation, let's go with that? "anyOf": [
{"required": ["offset"]},
{"required": ["repeat"]}
], |
@donmccurdy okay, I'll trim down the schema a bit then I'll put in a PR |
That said – putting something like |
@donmccurdy you mention solving the validation issues, by that do you mean the schema just describes "type" as required and the other fields as optional? Then it's up to the application to determine which fields are required. Which I've certainly seen done before, but it feels perhaps messy here? Also how would you handle the difference between feature IDs on a primitive and feature IDs on a node for instancing? (which don't use the textures) Disallow the |
(I haven't caught up with this one yet, but just stumbled over the point that the
but as I said during the call: Some things will only be caught by a validator. Iff the attempt to squeeze "to much knowledge" into the schema causes the schema to become overly complicated, then this may be something to be covered in a different way...) |
@ptrgags in your first example from #508 (comment), suppose we omitted {
"$schema": "https://json-schema.org/draft/2020-09/schema",
"properties": {
"featureIds": {
"type": "array",
"items": {
"oneOf": [
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "featureIdAttribute.schema.json",
"title": "Feature ID Attribute",
"type": "object",
"description": "Feature IDs to be used as indices to property arrays in the property table.",
"properties": {
"type": {"const": "attribute"}, // ⚠️
"attribute": {
"type": "integer",
"minimum": 0
},
"extensions": {},
"extras": {}
},
"required": ["type", "attribute"]
},
{
"$id": "implicitFeatureIdAttribute.schema.json",
"title": "Implicit Feature ID Attribute",
"type": "object",
"properties": {
"type": {"const": "implicit"}, // ⚠️
"offset": {
"type": "integer",
"minimum": 0,
"default": 0
},
"repeat": {
"type": "integer",
"minimum": 1
},
"extensions": {},
"extras": {}
},
"required": ["type"]
},
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "featureIdTexture.schema.json",
"title": "Feature ID Texture",
"type": "object",
"properties": {
"type": {"const": "texture"}, // ⚠️
"index": {},
"texCoord": {},
"channel": {
"type": "integer",
"minimum": 0
},
"extensions": {},
"extras": {}
},
"required": ["type", "channel"]
}
]
}
}
}
} But as @javagl says, some issues can only be caught by a validator, and that's OK. Unless we think a |
I believe this is OBE after the recent schema updates in CesiumGS/glTF#56 |
Note: For now, this refers to a specific case in the
EXT_mesh_features
extension, but I think it is appropriate to bring it up here in the 3D Tiles repo, as all this is part of 3D Tiles Next, and we also might want to review other schemas for similar patterns. I noticed this recently during another schema cleanup PR. it might not be crucially important, and the question of whether it will be tackled depends on whether it could be solved with reasonable effort, but ... this issue is just to keep track of it:The
primitive.EXT_mesh_features.schema.json
defines an array of feature IDs, which may beoneOf
featureIdAttribute
orfeatureIdTexture
. Thes types already constrain the matching objects, so that only valid objects validate against the schema. For example,featureIdAttribute
already makes sure that the object either contains anattribute
, or aoffset/repeat
, but not both (via this clause)But there are further constraints when these types are combined in the
oneOf
. Currently, an object likevalidates against the relevant part of the schema, even though it is both, a
featureIdAttribute
and afeatureIdTexture
.(The tl;dr version is:
oneOf
means "any one of", and not "exactly one of"....)It might be possible to solve this, by defining a valid feature ID as something like
but that looks a bit clumsy...
(If someone wants to do first, quick tests: I assembled the relevant parts of the schema in CesiumGS/glTF#28 (comment) so that it can be copied+pasted into https://www.jsonschemavalidator.net/ )
The text was updated successfully, but these errors were encountered: