cuelang.org/go@v0.13.0/internal/core/runtime/runtime.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 runtime
    16  
    17  import (
    18  	"cuelang.org/go/cue/build"
    19  	"cuelang.org/go/internal"
    20  	"cuelang.org/go/internal/core/adt"
    21  	"cuelang.org/go/internal/cuedebug"
    22  	"cuelang.org/go/internal/cueexperiment"
    23  )
    24  
    25  // A Runtime maintains data structures for indexing and reuse for evaluation.
    26  type Runtime struct {
    27  	index *index
    28  
    29  	loaded map[*build.Instance]interface{}
    30  
    31  	// interpreters implement extern functionality. The map key corresponds to
    32  	// the kind in a file-level @extern(kind) attribute.
    33  	interpreters map[string]Interpreter
    34  
    35  	version  internal.EvaluatorVersion
    36  	topoSort bool
    37  
    38  	flags cuedebug.Config
    39  }
    40  
    41  func (r *Runtime) Settings() (internal.EvaluatorVersion, cuedebug.Config) {
    42  	return r.version, r.flags
    43  }
    44  
    45  func (r *Runtime) ConfigureOpCtx(ctx *adt.OpContext) {
    46  	ctx.Version = r.version
    47  	ctx.TopoSort = r.topoSort
    48  	ctx.Config = r.flags
    49  }
    50  
    51  func (r *Runtime) SetBuildData(b *build.Instance, x interface{}) {
    52  	r.loaded[b] = x
    53  }
    54  
    55  func (r *Runtime) BuildData(b *build.Instance) (x interface{}, ok bool) {
    56  	x, ok = r.loaded[b]
    57  	return x, ok
    58  }
    59  
    60  // New creates a new Runtime obeying the CUE_EXPERIMENT and CUE_DEBUG flags set
    61  // via environment variables.
    62  func New() *Runtime {
    63  	r := &Runtime{}
    64  	r.Init()
    65  	return r
    66  }
    67  
    68  // NewWithSettings creates a new Runtime using the given runtime version and
    69  // debug flags. The builtins registered with RegisterBuiltin are available for
    70  // evaluation.
    71  func NewWithSettings(v internal.EvaluatorVersion, flags cuedebug.Config) *Runtime {
    72  	r := New()
    73  	// Override the evaluator version and debug flags derived from env vars
    74  	// with the explicit arguments given to us here.
    75  	r.version = v
    76  	r.SetDebugOptions(&flags)
    77  	return r
    78  }
    79  
    80  // SetVersion sets the version to use for the Runtime. This should only be set
    81  // before first use.
    82  func (r *Runtime) SetVersion(v internal.EvaluatorVersion) {
    83  	switch v {
    84  	case internal.EvalV2, internal.EvalV3:
    85  		r.version = v
    86  	case internal.EvalVersionUnset, internal.DefaultVersion:
    87  		cueexperiment.Init()
    88  		if cueexperiment.Flags.EvalV3 {
    89  			r.version = internal.EvalV3
    90  		} else {
    91  			r.version = internal.EvalV2
    92  		}
    93  	}
    94  }
    95  
    96  // SetTopologicalSort sets whether or not to use topological sorting
    97  // for the Runtime.
    98  func (r *Runtime) SetTopologicalSort(b bool) {
    99  	r.topoSort = b
   100  }
   101  
   102  // SetDebugOptions sets the debug flags to use for the Runtime. This should only
   103  // be set before first use.
   104  func (r *Runtime) SetDebugOptions(flags *cuedebug.Config) {
   105  	r.flags = *flags
   106  	r.topoSort = r.topoSort || r.flags.SortFields
   107  }
   108  
   109  // IsInitialized reports whether the runtime has been initialized.
   110  func (r *Runtime) IsInitialized() bool {
   111  	return r.index != nil
   112  }
   113  
   114  func (r *Runtime) Init() {
   115  	if r.index != nil {
   116  		return
   117  	}
   118  	r.index = newIndex()
   119  
   120  	// TODO: the builtin-specific instances will ultimately also not be
   121  	// shared by indexes.
   122  	r.index.builtinPaths = sharedIndex.builtinPaths
   123  	r.index.builtinShort = sharedIndex.builtinShort
   124  
   125  	r.loaded = map[*build.Instance]interface{}{}
   126  
   127  	r.SetVersion(internal.DefaultVersion)
   128  	r.topoSort = cueexperiment.Flags.TopoSort
   129  
   130  	// By default we follow the environment's CUE_DEBUG settings,
   131  	// which can be overriden via [Runtime.SetDebugOptions],
   132  	// such as with the API option [cuelang.org/go/cue/cuecontext.CUE_DEBUG].
   133  	cuedebug.Init()
   134  	r.SetDebugOptions(&cuedebug.Flags)
   135  }