blob: 35e208ce11f97e2df9c5e744721e1a51bb9c0a6c [file] [log] [blame]
Marcel van Lohuizen22abdad2021-04-09 13:44:05 +02001// 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 value contains functions for converting values to internal types
16// and various other Value-related utilities.
17package value
18
19import (
Marcel van Lohuizen1f78a8d2021-04-16 08:50:05 +020020 "strings"
21
Marcel van Lohuizen22abdad2021-04-09 13:44:05 +020022 "cuelang.org/go/cue"
Marcel van Lohuizen1f78a8d2021-04-16 08:50:05 +020023 "cuelang.org/go/cue/ast"
24 "cuelang.org/go/cue/errors"
Marcel van Lohuizen22abdad2021-04-09 13:44:05 +020025 "cuelang.org/go/internal/core/adt"
Marcel van Lohuizen1f78a8d2021-04-16 08:50:05 +020026 "cuelang.org/go/internal/core/compile"
27 "cuelang.org/go/internal/core/convert"
28 "cuelang.org/go/internal/core/eval"
Marcel van Lohuizen22abdad2021-04-09 13:44:05 +020029 "cuelang.org/go/internal/core/runtime"
30 "cuelang.org/go/internal/types"
31)
32
Marcel van Lohuizen421ead32021-04-16 08:31:32 +020033func ConvertToRuntime(c *cue.Context) *cue.Runtime {
34 return (*cue.Runtime)(c)
35}
36
37func ConvertToContext(r *cue.Runtime) *cue.Context {
38 (*runtime.Runtime)(r).Init()
39 return (*cue.Context)(r)
40}
41
Marcel van Lohuizen22abdad2021-04-09 13:44:05 +020042func ToInternal(v cue.Value) (*runtime.Runtime, *adt.Vertex) {
43 var t types.Value
44 v.Core(&t)
45 return t.R, t.V
46}
47
Marcel van Lohuizend76e2cc2021-04-16 08:47:50 +020048// Make wraps cue.MakeValue.
49func Make(ctx *adt.OpContext, v adt.Value) cue.Value {
50 return (*cue.Context)(ctx.Impl().(*runtime.Runtime)).Encode(v)
51}
52
Marcel van Lohuizen1f78a8d2021-04-16 08:50:05 +020053func MakeError(r *runtime.Runtime, err errors.Error) cue.Value {
54 b := &adt.Bottom{Err: err}
55 node := &adt.Vertex{BaseValue: b}
56 node.UpdateStatus(adt.Finalized)
57 node.AddConjunct(adt.MakeRootConjunct(nil, b))
58 return (*cue.Context)(r).Encode(node)
59}
Marcel van Lohuizen22abdad2021-04-09 13:44:05 +020060
Marcel van Lohuizen1f78a8d2021-04-16 08:50:05 +020061// UnifyBuiltin returns the given Value unified with the given builtin template.
62func UnifyBuiltin(v cue.Value, kind string) cue.Value {
63 p := strings.Split(kind, ".")
64 pkg, name := p[0], p[1]
65 s, _ := runtime.SharedRuntime.LoadImport(pkg)
66 if s == nil {
67 return v
68 }
69
70 ctx := v.Context()
71 a := s.Lookup((*runtime.Runtime)(ctx).Label(name, false))
72 if a == nil {
73 return v
74 }
75
76 return v.Unify(ctx.Encode(a))
77}
78
79func FromGoValue(r *cue.Context, x interface{}, nilIsTop bool) cue.Value {
80 rt := (*runtime.Runtime)(r)
81 rt.Init()
82 ctx := eval.NewContext(rt, nil)
83 v := convert.GoValueToValue(ctx, x, nilIsTop)
84 n := adt.ToVertex(v)
85 return r.Encode(n)
86}
87
88func FromGoType(r *cue.Context, x interface{}) cue.Value {
89 rt := (*runtime.Runtime)(r)
90 rt.Init()
91 ctx := eval.NewContext(rt, nil)
92 expr, err := convert.GoTypeToExpr(ctx, x)
93 if err != nil {
94 expr = &adt.Bottom{Err: err}
95 }
96 n := &adt.Vertex{}
97 n.AddConjunct(adt.MakeRootConjunct(nil, expr))
98 return r.Encode(n)
99}
100
101// EvalExpr evaluates an expression within an existing struct value.
102// Identifiers only resolve to values defined within the struct.
103//
104// Expressions may refer to builtin packages if they can be uniquely identified
105func EvalExpr(value cue.Value, expr ast.Expr) cue.Value {
106 r, scope := ToInternal(value)
107 ctx := eval.NewContext(r, nil)
108
109 cfg := &compile.Config{
110 Scope: scope,
111 Imports: func(x *ast.Ident) (pkgPath string) {
112 if !isBuiltin(x.Name) {
113 return ""
114 }
115 return x.Name
116 },
117 }
118
119 c, err := compile.Expr(cfg, ctx, pkgID(), expr)
120 if err != nil {
121 return MakeError(r, err)
122 }
123 v := adt.Resolve(ctx, c)
124
125 return (*cue.Context)(r).Encode(v)
126}
127
128func isBuiltin(s string) bool {
129 return runtime.SharedRuntime.IsBuiltinPackage(s)
130}
131
132// pkgID reports a package path that can never resolve to a valid package.
133func pkgID() string {
134 return "_"
135}