diff --git a/cue/go.go b/cue/go.go
index a45fbc6..34755e4 100644
--- a/cue/go.go
+++ b/cue/go.go
@@ -15,27 +15,223 @@
 package cue
 
 import (
+	"encoding"
+	"encoding/json"
 	"fmt"
 	"math/big"
 	"reflect"
 	"sort"
 	"strings"
+	"sync"
 
-	"cuelang.org/go/cue/ast"
+	"cuelang.org/go/cue/parser"
 	"github.com/cockroachdb/apd"
 )
 
 // This file contains functionality for converting Go to CUE.
 
+func convertValue(inst *Instance, x interface{}) Value {
+	ctx := inst.index.newContext()
+	v := convert(ctx, baseValue{}, x)
+	return newValueRoot(ctx, v)
+}
+
+func convertType(inst *Instance, x interface{}) Value {
+	ctx := inst.index.newContext()
+	v := convertGoType(inst, reflect.TypeOf(x))
+	return newValueRoot(ctx, v)
+
+}
+
+// parseTag parses a CUE expression from a cue tag.
+func parseTag(ctx *context, obj *structLit, field label, tag string) value {
+	if p := strings.Index(tag, ","); p >= 0 {
+		tag = tag[:p]
+	}
+	if tag == "" {
+		return &top{}
+	}
+	expr, err := parser.ParseExpr(ctx.index.fset, "<field:>", tag)
+	if err != nil {
+		field := ctx.labelStr(field)
+		return ctx.mkErr(baseValue{}, "invalid tag %q for field %q: %v", tag, field, err)
+	}
+	v := newVisitor(ctx.index, nil, nil, obj)
+	return v.walk(expr)
+}
+
+// TODO: should we allow mapping names in cue tags? This only seems like a good
+// idea if we ever want to allow mapping CUE to a different name than JSON.
+var tagsWithNames = []string{"json", "yaml", "protobuf"}
+
+func getName(f *reflect.StructField) string {
+	name := f.Name
+	for _, s := range tagsWithNames {
+		if tag, ok := f.Tag.Lookup(s); ok {
+			if p := strings.Index(tag, ","); p >= 0 {
+				tag = tag[:p]
+			}
+			if tag != "" {
+				name = tag
+				break
+			}
+		}
+	}
+	return name
+}
+
+// isOptional indicates whether a field should be marked as optional.
+func isOptional(f *reflect.StructField) bool {
+	isOptional := false
+	switch f.Type.Kind() {
+	case reflect.Ptr, reflect.Map, reflect.Chan, reflect.Interface, reflect.Slice:
+		// Note: it may be confusing to distinguish between an empty slice and
+		// a nil slice. However, it is also surprizing to not be able to specify
+		// a default value for a slice. So for now we will allow it.
+		isOptional = true
+	}
+	if tag, ok := f.Tag.Lookup("cue"); ok {
+		// TODO: only if first field is not empty.
+		isOptional = false
+		for _, f := range strings.Split(tag, ",")[1:] {
+			switch f {
+			case "opt":
+				isOptional = true
+			case "req":
+				return false
+			}
+		}
+	} else if tag, ok = f.Tag.Lookup("json"); ok {
+		isOptional = false
+		for _, f := range strings.Split(tag, ",")[1:] {
+			if f == "omitempty" {
+				return true
+			}
+		}
+	}
+	return isOptional
+}
+
+// isOmitEmpty means that the zero value is interpreted as undefined.
+func isOmitEmpty(f *reflect.StructField) bool {
+	isOmitEmpty := false
+	switch f.Type.Kind() {
+	case reflect.Ptr, reflect.Map, reflect.Chan, reflect.Interface, reflect.Slice:
+		// Note: it may be confusing to distinguish between an empty slice and
+		// a nil slice. However, it is also surprizing to not be able to specify
+		// a default value for a slice. So for now we will allow it.
+		isOmitEmpty = true
+
+	default:
+		// TODO: we can also infer omit empty if a type cannot be nil if there
+		// is a constraint that unconditionally disallows the zero value.
+	}
+	tag, ok := f.Tag.Lookup("json")
+	if ok {
+		isOmitEmpty = false
+		for _, f := range strings.Split(tag, ",")[1:] {
+			if f == "omitempty" {
+				return true
+			}
+		}
+	}
+	return isOmitEmpty
+}
+
+// parseJSON parses JSON into a CUE value. b must be valid JSON.
+func parseJSON(ctx *context, b []byte) evaluated {
+	expr, err := parser.ParseExpr(ctx.index.fset, "json", b)
+	if err != nil {
+		panic(err) // cannot happen
+	}
+	v := newVisitor(ctx.index, nil, nil, nil)
+	return v.walk(expr).evalPartial(ctx)
+}
+
+func isZero(v reflect.Value) bool {
+	x := v.Interface()
+	if x == nil {
+		return true
+	}
+	switch k := v.Kind(); k {
+	case reflect.Struct, reflect.Array:
+		// we never allow optional values for these types.
+		return false
+
+	case reflect.Chan, reflect.Func, reflect.Interface, reflect.Map,
+		reflect.Slice:
+		// Note that for maps we preserve the distinction between a nil map and
+		// an empty map.
+		return v.IsNil()
+
+	case reflect.String:
+		return v.Len() == 0
+
+	default:
+		return x == reflect.Zero(v.Type()).Interface()
+	}
+}
+
 func convert(ctx *context, src source, x interface{}) evaluated {
 	switch v := x.(type) {
-	case evaluated:
-		return v
 	case nil:
-		return &nullLit{src.base()}
-	case ast.Expr:
-		x := newVisitorCtx(ctx, nil, nil, nil)
-		return ctx.manifest(x.walk(v))
+		// Interpret a nil pointer as an undefined value that is only
+		// null by default, but may still be set: *null | _.
+		return &disjunction{values: []dValue{
+			{val: &nullLit{src.base()}, marked: true},
+			{val: &top{src.base()}}},
+		}
+
+	case *big.Int:
+		n := newNum(src, intKind)
+		n.v.Coeff.Set(v)
+		if v.Sign() < 0 {
+			n.v.Coeff.Neg(&n.v.Coeff)
+			n.v.Negative = true
+		}
+		return n
+
+	case *big.Rat:
+		// should we represent this as a binary operation?
+		n := newNum(src, numKind)
+		ctx.Quo(&n.v, apd.NewWithBigInt(v.Num(), 0), apd.NewWithBigInt(v.Denom(), 0))
+		if !v.IsInt() {
+			n.k = floatKind
+		}
+		return n
+
+	case *big.Float:
+		n := newNum(src, floatKind)
+		n.v.SetString(v.String())
+		return n
+
+	case *apd.Decimal:
+		n := newNum(src, floatKind|intKind)
+		n.v.Set(v)
+		if !n.isInt(ctx) {
+			n.k = floatKind
+		}
+		return n
+
+	case json.Marshaler:
+		b, err := v.MarshalJSON()
+		if err != nil {
+			return ctx.mkErr(src, err)
+		}
+
+		return parseJSON(ctx, b)
+
+	case encoding.TextMarshaler:
+		b, err := v.MarshalText()
+		if err != nil {
+			return ctx.mkErr(src, err)
+		}
+		b, err = json.Marshal(string(b))
+		if err != nil {
+			return ctx.mkErr(src, err)
+		}
+		return parseJSON(ctx, b)
+
 	case error:
 		return ctx.mkErr(src, v.Error())
 	case bool:
@@ -68,32 +264,7 @@
 		r := newNum(src, floatKind)
 		r.v.SetString(fmt.Sprintf("%g", v))
 		return r
-	case *big.Int:
-		n := newNum(src, intKind)
-		n.v.Coeff.Set(v)
-		if v.Sign() < 0 {
-			n.v.Coeff.Neg(&n.v.Coeff)
-			n.v.Negative = true
-		}
-		return n
-	case *big.Rat:
-		n := newNum(src, numKind)
-		ctx.Quo(&n.v, apd.NewWithBigInt(v.Num(), 0), apd.NewWithBigInt(v.Denom(), 0))
-		if !v.IsInt() {
-			n.k = floatKind
-		}
-		return n
-	case *big.Float:
-		n := newNum(src, floatKind)
-		n.v.SetString(v.String())
-		return n
-	case *apd.Decimal:
-		n := newNum(src, floatKind|intKind)
-		n.v.Set(v)
-		if !n.isInt(ctx) {
-			n.k = floatKind
-		}
-		return n
+
 	case reflect.Value:
 		if v.CanInterface() {
 			return convert(ctx, src, v.Interface())
@@ -104,9 +275,15 @@
 		switch value.Kind() {
 		case reflect.Ptr:
 			if value.IsNil() {
-				return &nullLit{src.base()}
+				// Interpret a nil pointer as an undefined value that is only
+				// null by default, but may still be set: *null | _.
+				return &disjunction{values: []dValue{
+					{val: &nullLit{src.base()}, marked: true},
+					{val: &top{src.base()}}},
+				}
 			}
 			return convert(ctx, src, value.Elem().Interface())
+
 		case reflect.Struct:
 			obj := newStruct(src)
 			t := value.Type()
@@ -115,20 +292,16 @@
 				if t.PkgPath != "" {
 					continue
 				}
-				sub := convert(ctx, src, value.Field(i).Interface())
+				val := value.Field(i)
+				if isOmitEmpty(&t) && isZero(val) {
+					continue
+				}
+				sub := convert(ctx, src, val.Interface())
 				// leave errors like we do during normal evaluation or do we
 				// want to return the error?
-				name := t.Name
-				for _, s := range []string{"cue", "json", "protobuf"} {
-					if tag, ok := t.Tag.Lookup(s); ok {
-						if p := strings.Index(tag, ","); p >= 0 {
-							tag = tag[:p]
-						}
-						if tag != "" {
-							name = tag
-							break
-						}
-					}
+				name := getName(&t)
+				if name == "-" {
+					continue
 				}
 				f := ctx.strLabel(name)
 				obj.arcs = append(obj.arcs, arc{feature: f, v: sub})
@@ -187,3 +360,191 @@
 	n.v.Coeff.SetUint64(x)
 	return n
 }
+
+var (
+	typeCache sync.Map // map[reflect.Type]evaluated
+	mutex     sync.Mutex
+)
+
+func convertGoType(inst *Instance, t reflect.Type) value {
+	ctx := inst.newContext()
+	// TODO: this can be much more efficient.
+	mutex.Lock()
+	defer mutex.Unlock()
+	return goTypeToValue(ctx, t)
+}
+
+var (
+	jsonMarshaler = reflect.TypeOf(new(json.Marshaler)).Elem()
+	textMarshaler = reflect.TypeOf(new(encoding.TextMarshaler)).Elem()
+	topSentinel   = &top{}
+)
+
+// goTypeToValue converts a Go Type to a value.
+//
+// TODO: if this value will always be unified with a concrete type in Go, then
+// many of the fields may be omitted.
+func goTypeToValue(ctx *context, t reflect.Type) (e value) {
+	if e, ok := typeCache.Load(t); ok {
+		return e.(value)
+	}
+
+	// Even if this is for types that we know cast to a certain type, it can't
+	// hurt to return top, as in these cases the concrete values will be
+	// strict instances and there cannot be any tags that further constrain
+	// the values.
+	if t.Implements(jsonMarshaler) || t.Implements(textMarshaler) {
+		return topSentinel
+	}
+
+	switch k := t.Kind(); k {
+	case reflect.Ptr:
+		elem := t.Elem()
+		for elem.Kind() == reflect.Ptr {
+			elem = elem.Elem()
+		}
+		e = wrapOrNull(goTypeToValue(ctx, elem))
+
+	case reflect.Interface:
+		switch t.Name() {
+		case "error":
+			// This is really null | _|_. There is no error if the error is null.
+			e = &nullLit{} // null
+		default:
+			e = topSentinel // `_`
+		}
+
+	case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64,
+		reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
+		e = predefinedRanges[t.Kind().String()]
+
+	case reflect.Uint, reflect.Uintptr:
+		e = predefinedRanges["uint64"]
+
+	case reflect.Int:
+		e = predefinedRanges["int64"]
+
+	case reflect.String:
+		e = &basicType{k: stringKind}
+
+	case reflect.Bool:
+		e = &basicType{k: boolKind}
+
+	case reflect.Float32, reflect.Float64:
+		e = &basicType{k: floatKind}
+
+	case reflect.Struct:
+		// Some of these values have MarshalJSON methods, but that may not be
+		// the case for older Go versions.
+		name := fmt.Sprint(t)
+		switch name {
+		case "big.Int":
+			e = &basicType{k: intKind}
+			goto store
+		case "big.Rat", "big.Float", "apd.Decimal":
+			e = &basicType{k: floatKind}
+			goto store
+		case "time.Time":
+			// We let the concrete value decide.
+			e = topSentinel
+			goto store
+		}
+
+		// First iterate to create struct, then iterate another time to
+		// resolve field tags to allow field tags to refer to the struct fields.
+		tags := map[label]string{}
+		obj := newStruct(baseValue{})
+		typeCache.Store(t, obj)
+
+		for i := 0; i < t.NumField(); i++ {
+			f := t.Field(i)
+			if f.PkgPath != "" {
+				continue
+			}
+			elem := goTypeToValue(ctx, f.Type)
+
+			// leave errors like we do during normal evaluation or do we
+			// want to return the error?
+			name := getName(&f)
+			if name == "-" {
+				continue
+			}
+			l := ctx.strLabel(name)
+			obj.arcs = append(obj.arcs, arc{
+				feature: l,
+				// The GO JSON decoder always allows a value to be undefined.
+				optional: isOptional(&f),
+				v:        elem,
+			})
+
+			if tag, ok := f.Tag.Lookup("cue"); ok {
+				tags[l] = tag
+			}
+		}
+		sort.Sort(obj)
+
+		for label, tag := range tags {
+			v := parseTag(ctx, obj, label, tag)
+			for i, a := range obj.arcs {
+				if a.feature == label {
+					// Instead of unifying with the existing type, we substitute
+					// with the constraints from the tags. The type constraints
+					// will be implied when unified with a concrete value.
+					obj.arcs[i].v = mkBin(ctx, 0, opUnify, a.v, v)
+					// obj.arcs[i].v = v
+				}
+			}
+		}
+
+		return obj
+
+	case reflect.Array, reflect.Slice:
+		if t.Elem().Kind() == reflect.Uint8 {
+			e = &basicType{k: bytesKind}
+		} else {
+			elem := goTypeToValue(ctx, t.Elem())
+
+			var ln value = &top{}
+			if t.Kind() == reflect.Array {
+				ln = toInt(ctx, baseValue{}, int64(t.Len()))
+			}
+			e = &list{typ: elem, len: ln}
+		}
+		if k == reflect.Slice {
+			e = wrapOrNull(e)
+		}
+
+	case reflect.Map:
+		if key := t.Key(); key.Kind() != reflect.String {
+			// What does the JSON library do here?
+			e = ctx.mkErr(baseValue{}, "type %v not supported as key type", key)
+			break
+		}
+
+		obj := newStruct(baseValue{})
+		sig := &params{}
+		sig.add(ctx.label("_", true), &basicType{k: stringKind})
+		v := goTypeToValue(ctx, t.Elem())
+		obj.template = &lambdaExpr{params: sig, value: v}
+
+		e = wrapOrNull(obj)
+	}
+
+store:
+	// TODO: store error if not nil?
+	if e != nil {
+		typeCache.Store(t, e)
+	}
+	return e
+}
+
+func wrapOrNull(e value) value {
+	if e.kind().isAnyOf(nullKind) {
+		return e
+	}
+	e = &disjunction{values: []dValue{
+		{val: &nullLit{}, marked: true},
+		{val: e}},
+	}
+	return e
+}
diff --git a/cue/go_test.go b/cue/go_test.go
index 88895c3..a2f1d92 100644
--- a/cue/go_test.go
+++ b/cue/go_test.go
@@ -15,24 +15,25 @@
 package cue
 
 import (
-	"go/ast"
 	"math/big"
 	"reflect"
 	"testing"
 	"time"
 
+	"cuelang.org/go/cue/ast"
 	"cuelang.org/go/cue/errors"
 )
 
 func TestConvert(t *testing.T) {
 	i34 := big.NewInt(34)
 	d34 := mkBigInt(34)
+	n34 := mkBigInt(-34)
 	f34 := big.NewFloat(34.0000)
 	testCases := []struct {
 		goVal interface{}
 		want  string
 	}{{
-		nil, "null",
+		nil, "(*null | _)",
 	}, {
 		true, "true",
 	}, {
@@ -70,6 +71,8 @@
 	}, {
 		&d34, "34",
 	}, {
+		&n34, "-34",
+	}, {
 		[]int{1, 2, 3, 4}, "[1,2,3,4]",
 	}, {
 		[]interface{}{}, "[]",
@@ -109,7 +112,7 @@
 	}, {
 		&struct{ A int }{3}, "<0>{A: 3}",
 	}, {
-		(*struct{ A int })(nil), "null",
+		(*struct{ A int })(nil), "(*null | _)",
 	}, {
 		reflect.ValueOf(3), "3",
 	}, {
@@ -128,3 +131,78 @@
 		})
 	}
 }
+
+func TestConvertType(t *testing.T) {
+	testCases := []struct {
+		goTyp interface{}
+		want  string
+	}{{
+		struct {
+			A int      `cue:">=0&<100"`
+			B *big.Int `cue:">=0"`
+			C *big.Int
+			D big.Int
+			F *big.Float
+		}{},
+		// TODO: indicate that B is explicitly an int only.
+		`<0>{A: ((>=-9223372036854775808 & <=9223372036854775807) & (>=0 & <100)), ` +
+			`B: >=0, ` +
+			`C?: _, ` +
+			`D: int, ` +
+			`F?: _}`,
+	}, {
+		&struct {
+			A int16 `cue:">=0&<100"`
+			B error `json:"b"`
+			C string
+			D bool
+			F float64
+			L []byte
+			T time.Time
+		}{},
+		`(*null | <0>{A: ((>=-32768 & <=32767) & (>=0 & <100)), ` +
+			`C: string, ` +
+			`D: bool, ` +
+			`F: float, ` +
+			`b: null, ` +
+			`L?: (*null | bytes), ` +
+			`T: _})`,
+	}, {
+		struct {
+			A int8 `cue:"C-B"`
+			B int8 `cue:"C-A,opt"`
+			C int8 `cue:"A+B"`
+		}{},
+		// TODO: should B be marked as optional?
+		`<0>{A: ((>=-128 & <=127) & (<0>.C - <0>.B)), ` +
+			`B?: ((>=-128 & <=127) & (<0>.C - <0>.A)), ` +
+			`C: ((>=-128 & <=127) & (<0>.A + <0>.B))}`,
+	}, {
+		[]string{},
+		`(*null | [, ...string])`,
+	}, {
+		[4]string{},
+		`4*[string]`,
+	}, {
+		map[string]struct{ A map[string]uint }{},
+		`(*null | ` +
+			`<0>{<>: <1>(_: string)-><2>{` +
+			`A?: (*null | ` +
+			`<3>{<>: <4>(_: string)->(>=0 & <=18446744073709551615), })}, })`,
+	}, {
+		map[float32]int{},
+		`_|_(type float32 not supported as key type)`,
+	}}
+	inst := getInstance(t, "foo")
+
+	for _, tc := range testCases {
+		ctx := inst.newContext()
+		t.Run("", func(t *testing.T) {
+			v := goTypeToValue(ctx, reflect.TypeOf(tc.goTyp))
+			got := debugStr(ctx, v)
+			if got != tc.want {
+				t.Errorf("\n got %q;\nwant %q", got, tc.want)
+			}
+		})
+	}
+}
