encoding/jsonschema: expose API of JSON Schema decoder

Change-Id: I191d7bc2394486fa63050fca6721f65aa0589b22
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/4760
Reviewed-by: Antoine Pelisse <apelisse@google.com>
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
diff --git a/encoding/jsonschema/decode.go b/encoding/jsonschema/decode.go
index 84d7ed8..c644ff0 100644
--- a/encoding/jsonschema/decode.go
+++ b/encoding/jsonschema/decode.go
@@ -34,19 +34,10 @@
 
 const rootDefs = "def"
 
-func decode(filename string, inst *cue.Instance) (*ast.File, errors.Error) {
-	d := &decoder{
-		imports: map[string]*ast.Ident{},
-	}
-	e := d.decode(filename, inst)
-	if d.errs != nil {
-		return nil, d.errs
-	}
-	return e, nil
-}
-
 // A decoder converts JSON schema to CUE.
 type decoder struct {
+	cfg *Config
+
 	errs    errors.Error
 	imports map[string]*ast.Ident
 
@@ -63,12 +54,13 @@
 	return ident
 }
 
-func (d *decoder) decode(filename string, inst *cue.Instance) *ast.File {
+func (d *decoder) decode(inst *cue.Instance) *ast.File {
 	root := state{decoder: d}
 	expr, state := root.schemaState(inst.Value())
 
 	var a []ast.Decl
 
+	filename := d.cfg.ID
 	name := filepath.ToSlash(filename)
 	if state.id != "" {
 		name = strings.Trim(name, "#")
diff --git a/encoding/jsonschema/decode_test.go b/encoding/jsonschema/decode_test.go
index da64a24..dddb127 100644
--- a/encoding/jsonschema/decode_test.go
+++ b/encoding/jsonschema/decode_test.go
@@ -75,8 +75,7 @@
 				t.Fatal(err)
 			}
 
-			// TODO: use actual API.
-			expr, err := decode(fullpath, in)
+			expr, err := Extract(in, &Config{ID: fullpath})
 			if err != nil && errout == nil {
 				t.Fatal(errors.Details(err, nil))
 			}
diff --git a/encoding/jsonschema/jsonschema.go b/encoding/jsonschema/jsonschema.go
new file mode 100644
index 0000000..8c496e6
--- /dev/null
+++ b/encoding/jsonschema/jsonschema.go
@@ -0,0 +1,64 @@
+// Copyright 2020 CUE Authors
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+// Package jsonschema implements the JSON schema standard.
+//
+// Mapping and Linking
+//
+// JSON Schema are often defined in a single file. CUE, on the other hand
+// idomatically defines schema as a definition.
+//
+// CUE:
+//    $schema: which schema is used for validation.
+//    $id: which validation does this schema provide.
+//
+//    Foo: _ @jsonschema(sc)
+//    @source(https://...) // What schema is used to validate.
+//
+// NOTE: JSON Schema is a draft standard and may undergo backwards incompatible
+// changes.
+package jsonschema
+
+import (
+	"cuelang.org/go/cue"
+	"cuelang.org/go/cue/ast"
+)
+
+// Extract converts JSON Schema data into an equivalent CUE representation.
+//
+// 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) (*ast.File, error) {
+	d := &decoder{
+		cfg:     cfg,
+		imports: map[string]*ast.Ident{},
+	}
+	e := d.decode(data)
+	if d.errs != nil {
+		return nil, d.errs
+	}
+	return e, nil
+}
+
+// A Config configures a JSON Schema encoding or decoding.
+type Config struct {
+	ID string // URL of the original source, corresponding to the $id field.
+
+	// TODO: configurability to make it compatible with OpenAPI, such as
+	// - locations of definitions: #/components/schemas, for instance.
+	// - selection and definition of formats
+	// - documentation hooks.
+
+	_ struct{} // prohibit casting from different type.
+}