cuelang.org/go@v0.13.0/cue/query.go (about) 1 // Copyright 2021 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 cue 16 17 import ( 18 "cuelang.org/go/internal/core/adt" 19 ) 20 21 // This file contains query-related code. 22 23 // getScopePrefix finds the Vertex that exists in v for the longest prefix of p. 24 // 25 // It is used to make the parent scopes visible when resolving expressions. 26 func getScopePrefix(v Value, p Path) Value { 27 for _, sel := range p.Selectors() { 28 w := v.LookupPath(MakePath(sel)) 29 if !w.Exists() { 30 break 31 } 32 v = w 33 } 34 return v 35 } 36 37 // LookupPath reports the value for path p relative to v. 38 // 39 // Use [AnyString] and [AnyIndex] to find the value of undefined element types 40 // for structs and lists respectively, for example for the patterns in 41 // `{[string]: int}` and `[...string]`. 42 func (v Value) LookupPath(p Path) Value { 43 if v.v == nil { 44 return Value{} 45 } 46 n := v.v 47 parent := v.parent_ 48 ctx := v.ctx() 49 50 outer: 51 for _, sel := range p.path { 52 f := sel.sel.feature(v.idx) 53 deref := n.DerefValue() 54 for _, a := range deref.Arcs { 55 if a.Label == f { 56 if a.IsConstraint() && !sel.sel.isConstraint() { 57 break 58 } 59 parent = linkParent(parent, n, a) 60 n = a 61 continue outer 62 } 63 } 64 if sel.sel.isConstraint() { 65 x := &adt.Vertex{ 66 Parent: n, 67 Label: sel.sel.feature(ctx), 68 } 69 deref.MatchAndInsert(ctx, x) 70 if x.HasConjuncts() { 71 x.Finalize(ctx) 72 parent = linkParent(parent, n, x) 73 n = x 74 continue 75 } 76 } 77 78 var x *adt.Bottom 79 if err, ok := sel.sel.(pathError); ok { 80 x = &adt.Bottom{Err: err.Error} 81 } else { 82 x = mkErr(n, adt.EvalError, "field not found: %v", sel.sel) 83 if n.Accept(ctx, f) { 84 x.Code = adt.IncompleteError 85 } 86 x.NotExists = true 87 } 88 v := makeValue(v.idx, n, parent) 89 return newErrValue(v, x) 90 } 91 return makeValue(v.idx, n, parent) 92 }