cuelang.org/go@v0.10.1/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 func (v Value) LookupPath(p Path) Value { 39 if v.v == nil { 40 return Value{} 41 } 42 n := v.v 43 parent := v.parent_ 44 ctx := v.ctx() 45 46 outer: 47 for _, sel := range p.path { 48 f := sel.sel.feature(v.idx) 49 for _, a := range n.Arcs { 50 if a.Label == f { 51 if a.IsConstraint() && !sel.sel.isConstraint() { 52 break 53 } 54 parent = linkParent(parent, n, a) 55 n = a 56 continue outer 57 } 58 } 59 if sel.sel.isConstraint() { 60 x := &adt.Vertex{ 61 Parent: n, 62 Label: sel.sel.feature(ctx), 63 } 64 n.MatchAndInsert(ctx, x) 65 if len(x.Conjuncts) > 0 { 66 x.Finalize(ctx) 67 parent = linkParent(parent, n, x) 68 n = x 69 continue 70 } 71 } 72 73 var x *adt.Bottom 74 if err, ok := sel.sel.(pathError); ok { 75 x = &adt.Bottom{Err: err.Error} 76 } else { 77 x = mkErr(v.idx, n, adt.EvalError, "field not found: %v", sel.sel) 78 if n.Accept(ctx, f) { 79 x.Code = adt.IncompleteError 80 } 81 x.NotExists = true 82 } 83 v := makeValue(v.idx, n, parent) 84 return newErrValue(v, x) 85 } 86 return makeValue(v.idx, n, parent) 87 }