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  }