cuelang.org/go@v0.13.0/cue/build/context.go (about) 1 // Copyright 2018 The 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 build defines data types and utilities for defining CUE configuration 16 // instances. 17 // 18 // This package enforces the rules regarding packages and instances as defined 19 // in the spec, but it leaves any other details, as well as handling of modules, 20 // up to the implementation. 21 // 22 // A full implementation of instance loading can be found in the loader package. 23 // 24 // WARNING: this packages may change. It is fine to use load and cue, who both 25 // use this package. 26 package build 27 28 import ( 29 "cuelang.org/go/cue/ast" 30 ) 31 32 // A Context keeps track of state of building instances and caches work. 33 type Context struct { 34 loader LoadFunc 35 parseFunc func(str string, src interface{}) (*ast.File, error) 36 37 initialized bool 38 39 imports map[string]*Instance 40 } 41 42 // NewInstance creates an instance for this Context. If the [LoadFunc] 43 // is nil, then the LoadFunc in the [Context] is used. 44 func (c *Context) NewInstance(dir string, f LoadFunc) *Instance { 45 if c == nil { 46 c = &Context{} 47 } 48 if f == nil { 49 f = c.loader 50 } 51 return &Instance{ 52 ctxt: c, 53 loadFunc: f, 54 Dir: dir, 55 } 56 } 57 58 // Complete finishes the initialization of an instance. All files must have 59 // been added with AddFile before this call. 60 func (inst *Instance) Complete() error { 61 if inst.done { 62 return inst.Err 63 } 64 inst.done = true 65 66 err := inst.complete() 67 if err != nil { 68 inst.ReportError(err) 69 } 70 if inst.Err != nil { 71 inst.Incomplete = true 72 return inst.Err 73 } 74 return nil 75 } 76 77 func (c *Context) init() { 78 if !c.initialized { 79 c.initialized = true 80 c.imports = map[string]*Instance{} 81 } 82 } 83 84 // Options: 85 // - certain parse modes 86 // - parallelism 87 // - error handler (allows cancelling the context) 88 // - file set. 89 90 // NewContext creates a new build context. 91 // 92 // All instances must be created with a context. 93 func NewContext(opts ...Option) *Context { 94 c := &Context{} 95 for _, o := range opts { 96 o(c) 97 } 98 c.init() 99 return c 100 } 101 102 // Option define build options. 103 type Option func(c *Context) 104 105 // Loader sets parsing options. 106 func Loader(f LoadFunc) Option { 107 return func(c *Context) { c.loader = f } 108 } 109 110 // ParseFile is called to read and parse each file 111 // when building syntax tree. 112 // It must be safe to call ParseFile simultaneously from multiple goroutines. 113 // If f is nil, the loader will use [cuelang.org/go/cue/parser.ParseFile]. 114 // 115 // ParseFile should parse the source from src and use filename only for 116 // recording position information. 117 // 118 // An application may supply a custom implementation of ParseFile 119 // to change the effective file contents or the behavior of the parser, 120 // or to modify the syntax tree. For example, changing the backwards 121 // compatibility. 122 func ParseFile(f func(filename string, src interface{}) (*ast.File, error)) Option { 123 return func(c *Context) { c.parseFunc = f } 124 }