internal/value: implement interface type that is both value and instance

Change-Id: I2afe782eebb766a04aaaeaf1a43f02b25a99beb7
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/9441
Reviewed-by: CUE cueckoo <cueckoo@gmail.com>
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
diff --git a/cue/instance.go b/cue/instance.go
index c0b47f6..b45a315 100644
--- a/cue/instance.go
+++ b/cue/instance.go
@@ -26,6 +26,23 @@
 	"cuelang.org/go/internal/core/runtime"
 )
 
+// An InstanceOrValue is implemented by Value and *Instance.
+//
+// This is a placeholder type that is used to allow Instance-based APIs to
+// transition to Value-based APIs. The goals is to get rid of the Instance
+// type before v1.0.0.
+type InstanceOrValue interface {
+	Value() Value
+
+	internal()
+}
+
+func (Value) internal()     {}
+func (*Instance) internal() {}
+
+// Value implements value.Instance.
+func (v hiddenValue) Value() Value { return v }
+
 // An Instance defines a single configuration based on a collection of
 // underlying CUE files.
 type Instance struct {
diff --git a/encoding/jsonschema/jsonschema.go b/encoding/jsonschema/jsonschema.go
index 9e81b73..a0f6283 100644
--- a/encoding/jsonschema/jsonschema.go
+++ b/encoding/jsonschema/jsonschema.go
@@ -40,7 +40,7 @@
 //
 // The generated CUE schema is guaranteed to deem valid any value that is
 // a valid instance of the source JSON schema.
-func Extract(data *cue.Instance, cfg *Config) (f *ast.File, err error) {
+func Extract(data cue.InstanceOrValue, cfg *Config) (f *ast.File, err error) {
 	d := &decoder{cfg: cfg}
 
 	f = d.decode(data.Value())
diff --git a/tools/flow/flow.go b/tools/flow/flow.go
index 3669efa..17eabe4 100644
--- a/tools/flow/flow.go
+++ b/tools/flow/flow.go
@@ -194,7 +194,9 @@
 }
 
 // New creates a Controller for a given Instance and TaskFunc.
-func New(cfg *Config, inst *cue.Instance, f TaskFunc) *Controller {
+//
+// The instance value can either be a *cue.Instance or a cue.Value.
+func New(cfg *Config, inst cue.InstanceOrValue, f TaskFunc) *Controller {
 	v := inst.Value()
 	ctx := eval.NewContext(value.ToInternal(v))
 
diff --git a/tools/flow/flow_test.go b/tools/flow/flow_test.go
index c34d97c..eec577f 100644
--- a/tools/flow/flow_test.go
+++ b/tools/flow/flow_test.go
@@ -24,6 +24,7 @@
 	"testing"
 
 	"cuelang.org/go/cue"
+	"cuelang.org/go/cue/cuecontext"
 	"cuelang.org/go/cue/errors"
 	"cuelang.org/go/cue/format"
 	"cuelang.org/go/internal/cuetest"
@@ -43,10 +44,11 @@
 	test.Run(t, func(t *cuetxtar.Test) {
 		a := t.ValidInstances()
 
-		inst := cue.Build(a)[0]
-		if inst.Err != nil {
-			t.Fatal(inst.Err)
+		insts, err := cuecontext.New().BuildInstances(a)
+		if err != nil {
+			t.Fatal(err)
 		}
+		v := insts[0]
 
 		seqNum = 0
 
@@ -76,7 +78,7 @@
 			UpdateFunc:     updateFunc,
 		}
 
-		c := flow.New(cfg, inst, taskFunc)
+		c := flow.New(cfg, v, taskFunc)
 
 		w := t.Writer("errors")
 		if err := c.Run(context.Background()); err != nil {
diff --git a/tools/trim/trim.go b/tools/trim/trim.go
index d2dea39..cff7543 100644
--- a/tools/trim/trim.go
+++ b/tools/trim/trim.go
@@ -71,7 +71,7 @@
 // as can be derived from the evaluated values in inst.
 // Trimming is done on a best-effort basis and only when the removed field
 // is clearly implied by another field, rather than equal sibling fields.
-func Files(files []*ast.File, inst *cue.Instance, cfg *Config) error {
+func Files(files []*ast.File, inst cue.InstanceOrValue, cfg *Config) error {
 	r, v := value.ToInternal(inst.Value())
 
 	t := &trimmer{
diff --git a/tools/trim/trim_test.go b/tools/trim/trim_test.go
index e3ea234..9181f72 100644
--- a/tools/trim/trim_test.go
+++ b/tools/trim/trim_test.go
@@ -19,6 +19,7 @@
 
 	"cuelang.org/go/cue"
 	"cuelang.org/go/cue/ast"
+	"cuelang.org/go/cue/cuecontext"
 	"cuelang.org/go/cue/errors"
 	"cuelang.org/go/cue/format"
 	"cuelang.org/go/cue/parser"
@@ -255,12 +256,12 @@
 			if err != nil {
 				t.Fatal(err)
 			}
-			r := cue.Runtime{}
-			inst, err := r.CompileFile(f)
-			if err != nil {
+			r := cuecontext.New()
+			v := r.BuildFile(f)
+			if err := v.Err(); err != nil {
 				t.Fatal(err)
 			}
-			err = Files([]*ast.File{f}, inst, &Config{Trace: false})
+			err = Files([]*ast.File{f}, v, &Config{Trace: false})
 			if err != nil {
 				t.Fatal(err)
 			}