cuelang.org/go@v0.13.0/encoding/jsonschema/constraints.go (about) 1 // Copyright 2019 CUE Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package jsonschema 16 17 import ( 18 "fmt" 19 20 "cuelang.org/go/cue" 21 ) 22 23 type constraint struct { 24 key string 25 26 // phase indicates on which pass c constraint should be added. This ensures 27 // that constraints are applied in the correct order. For instance, the 28 // "required" constraint validates that a listed field is contained in 29 // "properties". For this to work, "properties" must be processed before 30 // "required" and thus must have a lower phase number than the latter. 31 phase int 32 33 // versions holds the versions for which this constraint is defined. 34 versions versionSet 35 fn constraintFunc 36 } 37 38 // A constraintFunc converts a given JSON Schema constraint (specified in n) 39 // to a CUE constraint recorded in state. 40 type constraintFunc func(key string, n cue.Value, s *state) 41 42 var constraintMap = map[string]*constraint{} 43 44 func init() { 45 for _, c := range constraints { 46 if _, ok := constraintMap[c.key]; ok { 47 panic(fmt.Errorf("duplicate constraint entry for %q", c.key)) 48 } 49 constraintMap[c.key] = c 50 } 51 } 52 53 // Note: the following table is ordered lexically by keyword name. 54 // The various implementations are grouped by kind in the constraint-*.go files. 55 56 const numPhases = 5 57 58 // Note: OpenAPI is excluded from version sets by default, as it does not fit in 59 // the linear progression of the rest of the JSON Schema versions. 60 61 var constraints = []*constraint{ 62 px("$anchor", constraintTODO, vfrom(VersionDraft2019_09)), 63 p2("$comment", constraintComment, vfrom(VersionDraft7)), 64 p2("$defs", constraintAddDefinitions, allVersions), 65 px("$dynamicAnchor", constraintTODO, vfrom(VersionDraft2020_12)), 66 px("$dynamicRef", constraintTODO, vfrom(VersionDraft2020_12)), 67 p1("$id", constraintID, vfrom(VersionDraft6)), 68 px("$recursiveAnchor", constraintTODO, vbetween(VersionDraft2019_09, VersionDraft2020_12)), 69 px("$recursiveRef", constraintTODO, vbetween(VersionDraft2019_09, VersionDraft2020_12)), 70 p2("$ref", constraintRef, allVersions|openAPI|k8sAPI), 71 p0("$schema", constraintSchema, allVersions), 72 px("$vocabulary", constraintTODO, vfrom(VersionDraft2019_09)), 73 p4("additionalItems", constraintAdditionalItems, vto(VersionDraft2019_09)), 74 p4("additionalProperties", constraintAdditionalProperties, allVersions|openAPILike), 75 p3("allOf", constraintAllOf, allVersions|openAPILike), 76 p3("anyOf", constraintAnyOf, allVersions|openAPILike), 77 p2("const", constraintConst, vfrom(VersionDraft6)), 78 p2("contains", constraintContains, vfrom(VersionDraft6)), 79 p2("contentEncoding", constraintContentEncoding, vfrom(VersionDraft7)), 80 p2("contentMediaType", constraintContentMediaType, vfrom(VersionDraft7)), 81 px("contentSchema", constraintTODO, vfrom(VersionDraft2019_09)), 82 p2("default", constraintDefault, allVersions|openAPILike), 83 p2("definitions", constraintAddDefinitions, allVersions), 84 p2("dependencies", constraintDependencies, allVersions), 85 px("dependentRequired", constraintTODO, vfrom(VersionDraft2019_09)), 86 px("dependentSchemas", constraintTODO, vfrom(VersionDraft2019_09)), 87 p2("deprecated", constraintDeprecated, vfrom(VersionDraft2019_09)|openAPI), 88 p2("description", constraintDescription, allVersions|openAPILike), 89 px("discriminator", constraintTODO, openAPI), 90 p1("else", constraintElse, vfrom(VersionDraft7)), 91 p2("enum", constraintEnum, allVersions|openAPILike), 92 px("example", constraintTODO, openAPILike), 93 p2("examples", constraintExamples, vfrom(VersionDraft6)), 94 p2("exclusiveMaximum", constraintExclusiveMaximum, allVersions|openAPILike), 95 p2("exclusiveMinimum", constraintExclusiveMinimum, allVersions|openAPILike), 96 px("externalDocs", constraintTODO, openAPILike), 97 p1("format", constraintFormat, allVersions|openAPILike), 98 p1("id", constraintID, vto(VersionDraft4)), 99 p1("if", constraintIf, vfrom(VersionDraft7)), 100 p2("items", constraintItems, allVersions|openAPILike), 101 p1("maxContains", constraintMaxContains, vfrom(VersionDraft2019_09)), 102 p2("maxItems", constraintMaxItems, allVersions|openAPILike), 103 p2("maxLength", constraintMaxLength, allVersions|openAPILike), 104 p2("maxProperties", constraintMaxProperties, allVersions|openAPILike), 105 p3("maximum", constraintMaximum, allVersions|openAPILike), 106 p1("minContains", constraintMinContains, vfrom(VersionDraft2019_09)), 107 p2("minItems", constraintMinItems, allVersions|openAPILike), 108 p2("minLength", constraintMinLength, allVersions|openAPILike), 109 p1("minProperties", constraintMinProperties, allVersions|openAPILike), 110 p3("minimum", constraintMinimum, allVersions|openAPILike), 111 p2("multipleOf", constraintMultipleOf, allVersions|openAPILike), 112 p3("not", constraintNot, allVersions|openAPILike), 113 p2("nullable", constraintNullable, openAPILike), 114 p3("oneOf", constraintOneOf, allVersions|openAPILike), 115 p2("pattern", constraintPattern, allVersions|openAPILike), 116 p3("patternProperties", constraintPatternProperties, allVersions), 117 p2("prefixItems", constraintPrefixItems, vfrom(VersionDraft2020_12)), 118 p2("properties", constraintProperties, allVersions|openAPILike), 119 p2("propertyNames", constraintPropertyNames, vfrom(VersionDraft6)), 120 px("readOnly", constraintTODO, vfrom(VersionDraft7)|openAPI), 121 p3("required", constraintRequired, allVersions|openAPILike), 122 p1("then", constraintThen, vfrom(VersionDraft7)), 123 p2("title", constraintTitle, allVersions|openAPILike), 124 p2("type", constraintType, allVersions|openAPILike), 125 px("unevaluatedItems", constraintTODO, vfrom(VersionDraft2019_09)), 126 px("unevaluatedProperties", constraintTODO, vfrom(VersionDraft2019_09)), 127 p2("uniqueItems", constraintUniqueItems, allVersions|openAPILike), 128 px("writeOnly", constraintTODO, vfrom(VersionDraft7)|openAPI), 129 px("xml", constraintTODO, openAPI), 130 p1("x-kubernetes-embedded-resource", constraintEmbeddedResource, k8s), 131 p1("x-kubernetes-group-version-kind", constraintGroupVersionKind, k8sAPI), 132 p2("x-kubernetes-int-or-string", constraintIntOrString, k8s), 133 px("x-kubernetes-list-map-keys", constraintIgnore, k8s), 134 px("x-kubernetes-list-type", constraintIgnore, k8s), 135 px("x-kubernetes-map-type", constraintIgnore, k8s), 136 px("x-kubernetes-patch-merge-key", constraintIgnore, k8s), 137 px("x-kubernetes-patch-strategy", constraintIgnore, k8s), 138 p2("x-kubernetes-preserve-unknown-fields", constraintPreserveUnknownFields, k8s), 139 px("x-kubernetes-validations", constraintTODO, k8s), 140 } 141 142 // px represents a TODO constraint that we haven't decided on a phase for yet. 143 func px(name string, f constraintFunc, versions versionSet) *constraint { 144 return p1(name, f, versions) 145 } 146 147 func p0(name string, f constraintFunc, versions versionSet) *constraint { 148 return &constraint{key: name, phase: 0, versions: versions, fn: f} 149 } 150 151 func p1(name string, f constraintFunc, versions versionSet) *constraint { 152 return &constraint{key: name, phase: 1, versions: versions, fn: f} 153 } 154 155 func p2(name string, f constraintFunc, versions versionSet) *constraint { 156 return &constraint{key: name, phase: 2, versions: versions, fn: f} 157 } 158 159 func p3(name string, f constraintFunc, versions versionSet) *constraint { 160 return &constraint{key: name, phase: 3, versions: versions, fn: f} 161 } 162 163 func p4(name string, f constraintFunc, versions versionSet) *constraint { 164 return &constraint{key: name, phase: 4, versions: versions, fn: f} 165 }