github.com/solo-io/cue@v0.4.7/internal/core/debug/compact.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 debug prints a given ADT node. 16 // 17 // Note that the result is not valid CUE, but instead prints the internals 18 // of an ADT node in human-readable form. It uses a simple indentation algorithm 19 // for improved readability and diffing. 20 // 21 package debug 22 23 import ( 24 "fmt" 25 26 "github.com/solo-io/cue/cue/literal" 27 "github.com/solo-io/cue/internal/core/adt" 28 ) 29 30 type compactPrinter struct { 31 printer 32 } 33 34 func (w *compactPrinter) node(n adt.Node) { 35 switch x := n.(type) { 36 case *adt.Vertex: 37 if x.BaseValue == nil || (w.cfg.Raw && !x.IsData()) { 38 for i, c := range x.Conjuncts { 39 if i > 0 { 40 w.string(" & ") 41 } 42 w.node(c.Expr()) 43 } 44 return 45 } 46 47 switch v := x.BaseValue.(type) { 48 case *adt.StructMarker: 49 w.string("{") 50 for i, a := range x.Arcs { 51 if i > 0 { 52 w.string(",") 53 } 54 w.label(a.Label) 55 w.string(":") 56 w.node(a) 57 } 58 w.string("}") 59 60 case *adt.ListMarker: 61 w.string("[") 62 for i, a := range x.Arcs { 63 if i > 0 { 64 w.string(",") 65 } 66 w.node(a) 67 } 68 w.string("]") 69 70 case adt.Value: 71 w.node(v) 72 } 73 74 case *adt.StructMarker: 75 w.string("struct") 76 77 case *adt.ListMarker: 78 w.string("list") 79 80 case *adt.StructLit: 81 w.string("{") 82 for i, d := range x.Decls { 83 if i > 0 { 84 w.string(",") 85 } 86 w.node(d) 87 } 88 w.string("}") 89 90 case *adt.ListLit: 91 w.string("[") 92 for i, d := range x.Elems { 93 if i > 0 { 94 w.string(",") 95 } 96 w.node(d) 97 } 98 w.string("]") 99 100 case *adt.Field: 101 s := w.labelString(x.Label) 102 w.string(s) 103 w.string(":") 104 w.node(x.Value) 105 106 case *adt.OptionalField: 107 s := w.labelString(x.Label) 108 w.string(s) 109 w.string("?:") 110 w.node(x.Value) 111 112 case *adt.BulkOptionalField: 113 w.string("[") 114 w.node(x.Filter) 115 w.string("]:") 116 w.node(x.Value) 117 118 case *adt.DynamicField: 119 w.node(x.Key) 120 if x.IsOptional() { 121 w.string("?") 122 } 123 w.string(":") 124 w.node(x.Value) 125 126 case *adt.Ellipsis: 127 w.string("...") 128 if x.Value != nil { 129 w.node(x.Value) 130 } 131 132 case *adt.Bottom: 133 w.string(`_|_`) 134 if x.Err != nil { 135 w.string("(") 136 w.string(x.Err.Error()) 137 w.string(")") 138 } 139 140 case *adt.Null: 141 w.string("null") 142 143 case *adt.Bool: 144 fmt.Fprint(w, x.B) 145 146 case *adt.Num: 147 fmt.Fprint(w, &x.X) 148 149 case *adt.String: 150 w.string(literal.String.Quote(x.Str)) 151 152 case *adt.Bytes: 153 w.string(literal.Bytes.Quote(string(x.B))) 154 155 case *adt.Top: 156 w.string("_") 157 158 case *adt.BasicType: 159 fmt.Fprint(w, x.K) 160 161 case *adt.BoundExpr: 162 fmt.Fprint(w, x.Op) 163 w.node(x.Expr) 164 165 case *adt.BoundValue: 166 fmt.Fprint(w, x.Op) 167 w.node(x.Value) 168 169 case *adt.NodeLink: 170 w.string(openTuple) 171 for i, f := range x.Node.Path() { 172 if i > 0 { 173 w.string(".") 174 } 175 w.label(f) 176 } 177 w.string(closeTuple) 178 179 case *adt.FieldReference: 180 w.label(x.Label) 181 182 case *adt.ValueReference: 183 w.label(x.Label) 184 185 case *adt.LabelReference: 186 if x.Src == nil { 187 w.string("LABEL") 188 } else { 189 w.string(x.Src.Name) 190 } 191 192 case *adt.DynamicReference: 193 w.node(x.Label) 194 195 case *adt.ImportReference: 196 w.label(x.ImportPath) 197 198 case *adt.LetReference: 199 w.ident(x.Label) 200 201 case *adt.SelectorExpr: 202 w.node(x.X) 203 w.string(".") 204 w.label(x.Sel) 205 206 case *adt.IndexExpr: 207 w.node(x.X) 208 w.string("[") 209 w.node(x.Index) 210 w.string("]") 211 212 case *adt.SliceExpr: 213 w.node(x.X) 214 w.string("[") 215 if x.Lo != nil { 216 w.node(x.Lo) 217 } 218 w.string(":") 219 if x.Hi != nil { 220 w.node(x.Hi) 221 } 222 if x.Stride != nil { 223 w.string(":") 224 w.node(x.Stride) 225 } 226 w.string("]") 227 228 case *adt.Interpolation: 229 w.interpolation(x) 230 231 case *adt.UnaryExpr: 232 fmt.Fprint(w, x.Op) 233 w.node(x.X) 234 235 case *adt.BinaryExpr: 236 w.string("(") 237 w.node(x.X) 238 fmt.Fprint(w, " ", x.Op, " ") 239 w.node(x.Y) 240 w.string(")") 241 242 case *adt.CallExpr: 243 w.node(x.Fun) 244 w.string("(") 245 for i, a := range x.Args { 246 if i > 0 { 247 w.string(", ") 248 } 249 w.node(a) 250 } 251 w.string(")") 252 253 case *adt.Builtin: 254 if x.Package != 0 { 255 w.label(x.Package) 256 w.string(".") 257 } 258 w.string(x.Name) 259 260 case *adt.BuiltinValidator: 261 w.node(x.Builtin) 262 w.string("(") 263 for i, a := range x.Args { 264 if i > 0 { 265 w.string(", ") 266 } 267 w.node(a) 268 } 269 w.string(")") 270 271 case *adt.DisjunctionExpr: 272 w.string("(") 273 for i, a := range x.Values { 274 if i > 0 { 275 w.string("|") 276 } 277 // Disjunct 278 if a.Default { 279 w.string("*") 280 } 281 w.node(a.Val) 282 } 283 w.string(")") 284 285 case *adt.Conjunction: 286 for i, c := range x.Values { 287 if i > 0 { 288 w.string(" & ") 289 } 290 w.node(c) 291 } 292 293 case *adt.Disjunction: 294 for i, c := range x.Values { 295 if i > 0 { 296 w.string(" | ") 297 } 298 if i < x.NumDefaults { 299 w.string("*") 300 } 301 w.node(c) 302 } 303 304 case *adt.ForClause: 305 w.string("for ") 306 w.ident(x.Key) 307 w.string(", ") 308 w.ident(x.Value) 309 w.string(" in ") 310 w.node(x.Src) 311 w.string(" ") 312 w.node(x.Dst) 313 314 case *adt.IfClause: 315 w.string("if ") 316 w.node(x.Condition) 317 w.string(" ") 318 w.node(x.Dst) 319 320 case *adt.LetClause: 321 w.string("let ") 322 w.ident(x.Label) 323 w.string(" = ") 324 w.node(x.Expr) 325 w.string(" ") 326 w.node(x.Dst) 327 328 case *adt.ValueClause: 329 w.node(x.StructLit) 330 331 default: 332 panic(fmt.Sprintf("unknown type %T", x)) 333 } 334 }