cmd/cue/cmd: merge data files by default

This also harmonizes handling of schema versus data.

The distinction between data and schema is not always
clear. Yet the cue command makes a notable distinction
on how the two are handled and even varied behavior
based on whether the two were mixed or not.

Also, there was a difference in behavior based on CUE
vs JSON files: CUE files were merged in a single package,
whereas JSON files were printed one-by-one.

Advantages:
- less distinction between different formats
- merge JSON files on the command line
- merge schema and data on the command line

There are a few exceptions:
- cue vet still validates data files individually
- schema are separated when the -d flag is used.

The latter is kind of an eye sore and we probably need
a different approach selecting schema.

Change-Id: I4d61b363d4ad08f4d0cfb1fe4bdf4f15b106988e
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/5745
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
diff --git a/internal/encoding/encoding.go b/internal/encoding/encoding.go
index 379e378..03fc7ab 100644
--- a/internal/encoding/encoding.go
+++ b/internal/encoding/encoding.go
@@ -43,16 +43,17 @@
 )
 
 type Decoder struct {
-	cfg       *Config
-	closer    io.Closer
-	next      func() (ast.Expr, error)
-	interpret interpretFunc
-	expr      ast.Expr
-	file      *ast.File
-	filename  string // may change on iteration for some formats
-	id        string
-	index     int
-	err       error
+	cfg            *Config
+	closer         io.Closer
+	next           func() (ast.Expr, error)
+	interpretFunc  interpretFunc
+	interpretation build.Interpretation
+	expr           ast.Expr
+	file           *ast.File
+	filename       string // may change on iteration for some formats
+	id             string
+	index          int
+	err            error
 }
 
 type interpretFunc func(*cue.Instance) (file *ast.File, id string, err error)
@@ -62,10 +63,14 @@
 func (i *Decoder) ID() string {
 	return i.id
 }
-
 func (i *Decoder) Filename() string { return i.filename }
-func (i *Decoder) Index() int       { return i.index }
-func (i *Decoder) Done() bool       { return i.err != nil }
+
+// Interpretation returns the current interpretation detected by Detect.
+func (i *Decoder) Interpretation() build.Interpretation {
+	return i.interpretation
+}
+func (i *Decoder) Index() int { return i.index }
+func (i *Decoder) Done() bool { return i.err != nil }
 
 func (i *Decoder) Next() {
 	if i.err != nil {
@@ -83,7 +88,7 @@
 
 func (i *Decoder) doInterpret() {
 	// Interpretations
-	if i.interpret != nil {
+	if i.interpretFunc != nil {
 		var r cue.Runtime
 		i.file = i.File()
 		inst, err := r.CompileFile(i.file)
@@ -91,7 +96,7 @@
 			i.err = err
 			return
 		}
-		i.file, i.id, i.err = i.interpret(inst)
+		i.file, i.id, i.err = i.interpretFunc(inst)
 	}
 }
 
@@ -176,8 +181,8 @@
 	case build.Auto:
 		openAPI := openAPIFunc(cfg, f)
 		jsonSchema := jsonSchemaFunc(cfg, f)
-		i.interpret = func(inst *cue.Instance) (file *ast.File, id string, err error) {
-			switch Detect(inst.Value()) {
+		i.interpretFunc = func(inst *cue.Instance) (file *ast.File, id string, err error) {
+			switch i.interpretation = Detect(inst.Value()); i.interpretation {
 			case build.JSONSchema:
 				return jsonSchema(inst)
 			case build.OpenAPI:
@@ -186,9 +191,11 @@
 			return i.file, "", i.err
 		}
 	case build.OpenAPI:
-		i.interpret = openAPIFunc(cfg, f)
+		i.interpretation = build.OpenAPI
+		i.interpretFunc = openAPIFunc(cfg, f)
 	case build.JSONSchema:
-		i.interpret = jsonSchemaFunc(cfg, f)
+		i.interpretation = build.JSONSchema
+		i.interpretFunc = jsonSchemaFunc(cfg, f)
 	default:
 		i.err = fmt.Errorf("unsupported interpretation %q", f.Interpretation)
 	}