github.com/solo-io/cue@v0.4.7/internal/core/adt/default.go (about) 1 // Copyright 2020 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 adt 16 17 // Default returns the default value or itself if there is no default. 18 func Default(v Value) Value { 19 switch x := v.(type) { 20 case *Vertex: 21 return x.Default() 22 case *Disjunction: 23 return x.Default() 24 default: 25 return v 26 } 27 } 28 29 func (d *Disjunction) Default() Value { 30 switch d.NumDefaults { 31 case 0: 32 return d 33 case 1: 34 return d.Values[0] 35 default: 36 return &Disjunction{ 37 Src: d.Src, 38 Values: d.Values[:d.NumDefaults], 39 NumDefaults: 0, 40 } 41 } 42 } 43 44 // Default returns the default value or itself if there is no default. 45 // 46 // It also closes a list, representing its default value. 47 func (v *Vertex) Default() *Vertex { 48 switch d := v.BaseValue.(type) { 49 default: 50 return v 51 52 case *Disjunction: 53 var w *Vertex 54 55 switch d.NumDefaults { 56 case 0: 57 if d.HasDefaults { 58 v = &Vertex{ 59 Parent: v.Parent, 60 status: Finalized, 61 BaseValue: &Bottom{}, 62 } 63 } 64 return v 65 case 1: 66 w = d.Values[0] 67 default: 68 x := *v 69 x.state = nil 70 x.BaseValue = &Disjunction{ 71 Src: d.Src, 72 Values: d.Values[:d.NumDefaults], 73 NumDefaults: 0, 74 } 75 w = &x 76 } 77 78 w.Conjuncts = nil 79 for _, c := range v.Conjuncts { 80 // TODO: preserve field information. 81 expr, _ := stripNonDefaults(c.Expr()) 82 w.Conjuncts = append(w.Conjuncts, MakeRootConjunct(c.Env, expr)) 83 } 84 return w 85 86 case *ListMarker: 87 m := *d 88 m.IsOpen = false 89 90 w := *v 91 w.BaseValue = &m 92 w.state = nil 93 return &w 94 } 95 } 96 97 // TODO: this should go: record preexpanded disjunctions in Vertex. 98 func stripNonDefaults(expr Expr) (r Expr, stripped bool) { 99 switch x := expr.(type) { 100 case *DisjunctionExpr: 101 if !x.HasDefaults { 102 return x, false 103 } 104 d := *x 105 d.Values = []Disjunct{} 106 for _, v := range x.Values { 107 if v.Default { 108 d.Values = append(d.Values, v) 109 } 110 } 111 if len(d.Values) == 1 { 112 return d.Values[0].Val, true 113 } 114 return &d, true 115 116 case *BinaryExpr: 117 if x.Op != AndOp { 118 return x, false 119 } 120 a, sa := stripNonDefaults(x.X) 121 b, sb := stripNonDefaults(x.Y) 122 if sa || sb { 123 bin := *x 124 bin.X = a 125 bin.Y = b 126 return &bin, true 127 } 128 return x, false 129 130 default: 131 return x, false 132 } 133 }