cue: remove FileSet from API

Change-Id: Idc52c4a07cc2ddfaaa217b30050a14e14584655d
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/2123
Reviewed-by: Marcel van Lohuizen <mpvl@google.com>
diff --git a/cmd/cue/cmd/add.go b/cmd/cue/cmd/add.go
index 5e18eed..430ecc8 100644
--- a/cmd/cue/cmd/add.go
+++ b/cmd/cue/cmd/add.go
@@ -30,7 +30,6 @@
 	"cuelang.org/go/cue/format"
 	"cuelang.org/go/cue/load"
 	"cuelang.org/go/cue/parser"
-	"cuelang.org/go/cue/token"
 	"github.com/spf13/cobra"
 )
 
@@ -251,7 +250,7 @@
 			return nil, fmt.Errorf("cannot append to directory %s", file)
 		}
 
-		f, err := parser.ParseFile(token.NewFileSet(), file, nil)
+		f, err := parser.ParseFile(file, nil)
 		if err != nil {
 			return nil, err
 		}
diff --git a/cmd/cue/cmd/eval.go b/cmd/cue/cmd/eval.go
index 99bf30b..7590bf8 100644
--- a/cmd/cue/cmd/eval.go
+++ b/cmd/cue/cmd/eval.go
@@ -21,7 +21,6 @@
 	"cuelang.org/go/cue/ast"
 	"cuelang.org/go/cue/format"
 	"cuelang.org/go/cue/parser"
-	"cuelang.org/go/cue/token"
 	"github.com/spf13/cobra"
 )
 
@@ -51,7 +50,7 @@
 
 		var exprs []ast.Expr
 		for _, e := range *expressions {
-			expr, err := parser.ParseExpr(token.NewFileSet(), "<expression flag>", e)
+			expr, err := parser.ParseExpr("<expression flag>", e)
 			if err != nil {
 				return err
 			}
diff --git a/cmd/cue/cmd/get_go.go b/cmd/cue/cmd/get_go.go
index 0ab6262..60f24a1 100644
--- a/cmd/cue/cmd/get_go.go
+++ b/cmd/cue/cmd/get_go.go
@@ -33,7 +33,6 @@
 
 	"cuelang.org/go/cue/format"
 	"cuelang.org/go/cue/parser"
-	cuetoken "cuelang.org/go/cue/token"
 	"github.com/spf13/cobra"
 	"golang.org/x/tools/go/packages"
 )
@@ -501,7 +500,7 @@
 			if filepath.Ext(path) != ".cue" {
 				return nil
 			}
-			f, err := parser.ParseFile(cuetoken.NewFileSet(), path, nil)
+			f, err := parser.ParseFile(path, nil)
 			if err != nil {
 				return err
 			}
diff --git a/cmd/cue/cmd/import.go b/cmd/cue/cmd/import.go
index 4b8422b..4023d1e 100644
--- a/cmd/cue/cmd/import.go
+++ b/cmd/cue/cmd/import.go
@@ -428,7 +428,7 @@
 
 		switch {
 		case *node != "":
-			inst, err := cue.FromExpr(nil, expr)
+			inst, err := cue.FromExpr(expr)
 			if err != nil {
 				return err
 			}
@@ -570,8 +570,7 @@
 }
 
 func parsePath(exprs string) (p []ast.Label, err error) {
-	fset := token.NewFileSet()
-	f, err := parser.ParseFile(fset, "<path flag>", exprs+": _")
+	f, err := parser.ParseFile("<path flag>", exprs+": _")
 	if err != nil {
 		return nil, fmt.Errorf("parser error in path %q: %v", exprs, err)
 	}
@@ -614,8 +613,6 @@
 	return filename
 }
 
-var fset = token.NewFileSet()
-
 func handleJSON(path string, r io.Reader) (objects []ast.Expr, err error) {
 	d := json.NewDecoder(r)
 
@@ -628,7 +625,7 @@
 		if err != nil {
 			return nil, fmt.Errorf("could not parse JSON: %v", err)
 		}
-		expr, err := parser.ParseExpr(fset, path, []byte(raw))
+		expr, err := parser.ParseExpr(path, []byte(raw))
 		if err != nil {
 			return nil, fmt.Errorf("invalid input: %v %q", err, raw)
 		}
@@ -638,7 +635,7 @@
 }
 
 func handleYAML(path string, r io.Reader) (objects []ast.Expr, err error) {
-	d, err := yaml.NewDecoder(fset, path, r)
+	d, err := yaml.NewDecoder(path, r)
 	if err != nil {
 		return nil, err
 	}
@@ -748,9 +745,8 @@
 
 func tryParse(str string) (s ast.Expr, format *encodingInfo) {
 	b := []byte(str)
-	fset := token.NewFileSet()
 	if json.Valid(b) {
-		expr, err := parser.ParseExpr(fset, "", b)
+		expr, err := parser.ParseExpr("", b)
 		if err != nil {
 			// TODO: report error
 			return nil, nil
@@ -763,7 +759,7 @@
 		return expr, jsonEnc
 	}
 
-	if expr, err := yaml.Unmarshal(fset, "", b); err == nil {
+	if expr, err := yaml.Unmarshal("", b); err == nil {
 		switch expr.(type) {
 		case *ast.StructLit, *ast.ListLit:
 		default:
diff --git a/cmd/cue/cmd/trim.go b/cmd/cue/cmd/trim.go
index ae64826..e6ff1ad 100644
--- a/cmd/cue/cmd/trim.go
+++ b/cmd/cue/cmd/trim.go
@@ -113,7 +113,6 @@
 	log.SetOutput(cmd.OutOrStderr())
 
 	ctxt := build.NewContext(build.ParseOptions(parser.ParseComments))
-	fset := ctxt.FileSet()
 	binst := load.Instances(args, &load.Config{Context: ctxt})
 
 	instances := cue.Build(binst)
@@ -134,7 +133,7 @@
 
 	for i, inst := range binst {
 
-		gen := newTrimSet(fset)
+		gen := newTrimSet()
 		for _, f := range inst.Files {
 			gen.markNodes(f)
 		}
@@ -182,16 +181,14 @@
 }
 
 type trimSet struct {
-	fset      *token.FileSet
 	stack     []string
 	exclude   map[ast.Node]bool // don't remove fields marked here
 	alwaysGen map[ast.Node]bool // node is always from a generated source
 	fromComp  map[ast.Node]bool // node originated from a comprehension
 }
 
-func newTrimSet(fset *token.FileSet) *trimSet {
+func newTrimSet() *trimSet {
 	return &trimSet{
-		fset:      fset,
 		exclude:   map[ast.Node]bool{},
 		alwaysGen: map[ast.Node]bool{},
 		fromComp:  map[ast.Node]bool{},
diff --git a/cmd/cue/cmd/vet.go b/cmd/cue/cmd/vet.go
index 27cbeaa..81987da 100644
--- a/cmd/cue/cmd/vet.go
+++ b/cmd/cue/cmd/vet.go
@@ -18,7 +18,6 @@
 	"cuelang.org/go/cue"
 	"cuelang.org/go/cue/ast"
 	"cuelang.org/go/cue/parser"
-	"cuelang.org/go/cue/token"
 	"github.com/spf13/cobra"
 )
 
@@ -45,7 +44,7 @@
 
 	var exprs []ast.Expr
 	for _, e := range *expressions {
-		expr, err := parser.ParseExpr(token.NewFileSet(), "<expression flag>", e)
+		expr, err := parser.ParseExpr("<expression flag>", e)
 		if err != nil {
 			return err
 		}
diff --git a/cue/ast_test.go b/cue/ast_test.go
index 91ec603..c46f4e7 100644
--- a/cue/ast_test.go
+++ b/cue/ast_test.go
@@ -20,7 +20,6 @@
 
 	"cuelang.org/go/cue/errors"
 	"cuelang.org/go/cue/parser"
-	"cuelang.org/go/cue/token"
 )
 
 func TestCompile(t *testing.T) {
@@ -360,7 +359,7 @@
 			if errs != nil {
 				t.Fatal(errs)
 			}
-			expr, err := parser.ParseExpr(token.NewFileSet(), "<test>", tc.expr)
+			expr, err := parser.ParseExpr("<test>", tc.expr)
 			if err != nil {
 				t.Fatal(err)
 			}
diff --git a/cue/build.go b/cue/build.go
index 24a5f07..2e7402b 100644
--- a/cue/build.go
+++ b/cue/build.go
@@ -33,7 +33,7 @@
 	if len(instances) == 0 {
 		panic("cue: list of instances must not be empty")
 	}
-	index := newIndex(instances[0].Context().FileSet())
+	index := newIndex()
 
 	loaded := []*Instance{}
 
@@ -48,8 +48,8 @@
 
 // FromExpr creates an instance from an expression.
 // Any references must be resolved beforehand.
-func FromExpr(fset *token.FileSet, expr ast.Expr) (*Instance, error) {
-	i := newIndex(fset).NewInstance(nil)
+func FromExpr(expr ast.Expr) (*Instance, error) {
+	i := newIndex().NewInstance(nil)
 	err := i.insertFile(&ast.File{
 		Decls: []ast.Decl{&ast.EmitDecl{Expr: expr}},
 	})
@@ -63,8 +63,6 @@
 //
 // All instances belonging to the same package should share this index.
 type index struct {
-	fset *token.FileSet
-
 	labelMap map[string]label
 	labels   []string
 
@@ -79,16 +77,15 @@
 
 // sharedIndex is used for indexing builtins and any other labels common to
 // all instances.
-var sharedIndex = newSharedIndex(token.NewFileSet())
+var sharedIndex = newSharedIndex()
 
-func newSharedIndex(f *token.FileSet) *index {
+func newSharedIndex() *index {
 	// TODO: nasty hack to indicate FileSet of shared index. Remove the whole
 	// FileSet idea from the API. Just take the hit of the extra pointers for
 	// positions in the ast, and then optimize the storage in an abstract
 	// machine implementation for storing graphs.
 	token.NewFile("dummy", sharedOffset, 0)
 	i := &index{
-		fset:     f,
 		labelMap: map[string]label{"": 0},
 		labels:   []string{""},
 	}
@@ -96,10 +93,9 @@
 }
 
 // newIndex creates a new index.
-func newIndex(f *token.FileSet) *index {
+func newIndex() *index {
 	parent := sharedIndex
 	i := &index{
-		fset:     f,
 		labelMap: map[string]label{},
 		loaded:   map[*build.Instance]*Instance{},
 		offset:   label(len(parent.labels)) + parent.offset,
diff --git a/cue/build/context.go b/cue/build/context.go
index c1b3649..2065c96 100644
--- a/cue/build/context.go
+++ b/cue/build/context.go
@@ -29,13 +29,11 @@
 	"context"
 
 	"cuelang.org/go/cue/parser"
-	"cuelang.org/go/cue/token"
 )
 
 // A Context keeps track of state of building instances and caches work.
 type Context struct {
 	ctxt context.Context
-	fset *token.FileSet
 
 	loader       LoadFunc
 	parseOptions []parser.Option
@@ -79,7 +77,6 @@
 		c.ctxt = context.Background()
 		c.initialized = true
 		c.imports = map[string]*Instance{}
-		c.fset = token.NewFileSet()
 	}
 }
 
@@ -101,12 +98,6 @@
 	return c
 }
 
-// FileSet reports the file set used for parsing files.
-func (c *Context) FileSet() *token.FileSet {
-	c.init()
-	return c.fset
-}
-
 // PurgeCache purges the instance cache.
 func (c *Context) PurgeCache() {
 	for name := range c.imports {
diff --git a/cue/build/instance.go b/cue/build/instance.go
index ec6eaf7..da3eb24 100644
--- a/cue/build/instance.go
+++ b/cue/build/instance.go
@@ -179,7 +179,7 @@
 // match the package name of the instance.
 func (inst *Instance) AddFile(filename string, src interface{}) error {
 	c := inst.ctxt
-	file, err := parser.ParseFile(c.FileSet(), filename, src, c.parseOptions...)
+	file, err := parser.ParseFile(filename, src, c.parseOptions...)
 	if err == nil {
 		err = inst.addSyntax(file)
 	}
diff --git a/cue/build_test.go b/cue/build_test.go
index fb58eb7..f06adad 100644
--- a/cue/build_test.go
+++ b/cue/build_test.go
@@ -41,7 +41,7 @@
 	}}
 	for _, tc := range testCases {
 		t.Run("", func(t *testing.T) {
-			inst, err := FromExpr(nil, tc.expr)
+			inst, err := FromExpr(tc.expr)
 			if err != nil {
 				t.Fatal(err)
 			}
diff --git a/cue/builtin.go b/cue/builtin.go
index b0df1ef..13708a4 100644
--- a/cue/builtin.go
+++ b/cue/builtin.go
@@ -78,7 +78,7 @@
 
 	// Parse builtin CUE
 	if p.cue != "" {
-		expr, err := parser.ParseExpr(ctx.index.fset, name, p.cue)
+		expr, err := parser.ParseExpr(name, p.cue)
 		if err != nil {
 			fmt.Println(p.cue)
 			panic(err)
@@ -97,7 +97,7 @@
 // newConstBuiltin parses and creates any CUE expression that does not have
 // fields.
 func mustParseConstBuiltin(ctx *context, name, val string) evaluated {
-	expr, err := parser.ParseExpr(ctx.index.fset, "<builtin:"+name+">", val)
+	expr, err := parser.ParseExpr("<builtin:"+name+">", val)
 	if err != nil {
 		panic(err)
 	}
diff --git a/cue/builtins.go b/cue/builtins.go
index fb621c3..c03ef81 100644
--- a/cue/builtins.go
+++ b/cue/builtins.go
@@ -27,7 +27,6 @@
 
 	"cuelang.org/go/cue/literal"
 	"cuelang.org/go/cue/parser"
-	"cuelang.org/go/cue/token"
 	"cuelang.org/go/internal/third_party/yaml"
 	goyaml "github.com/ghodss/yaml"
 )
@@ -381,8 +380,7 @@
 					if !json.Valid(b) {
 						return nil, fmt.Errorf("json: invalid JSON")
 					}
-					fset := token.NewFileSet()
-					expr, err := parser.ParseExpr(fset, "json", b)
+					expr, err := parser.ParseExpr("json", b)
 					if err != nil {
 
 						return nil, fmt.Errorf("json: could not parse JSON: %v", err)
@@ -437,8 +435,7 @@
 			Func: func(c *callCtxt) {
 				data := c.bytes(0)
 				c.ret, c.err = func() (interface{}, error) {
-					fset := token.NewFileSet()
-					return yaml.Unmarshal(fset, "", data)
+					return yaml.Unmarshal("", data)
 				}()
 			},
 		}},
diff --git a/cue/errors.go b/cue/errors.go
index 4247fb5..62aa4e7 100644
--- a/cue/errors.go
+++ b/cue/errors.go
@@ -82,23 +82,20 @@
 func (x *bottom) kind() kind { return bottomKind }
 
 func (x *bottom) Position() []token.Pos {
-	if x.index != nil && x.index.fset != nil {
-		return appendPositions(nil, x.index.fset, x.pos)
+	if x.index != nil {
+		return appendPositions(nil, x.pos)
 	}
 	return nil
 }
 
-func appendPositions(pos []token.Pos, fset *token.FileSet, src source) []token.Pos {
+func appendPositions(pos []token.Pos, src source) []token.Pos {
 	if src != nil {
 		if p := src.Pos(); p != token.NoPos {
-			if p.Offset() >= sharedOffset {
-				fset = sharedIndex.fset
-			}
 			return append(pos, src.Pos())
 		}
 		if c := src.computed(); c != nil {
-			pos = appendPositions(pos, fset, c.x)
-			pos = appendPositions(pos, fset, c.y)
+			pos = appendPositions(pos, c.x)
+			pos = appendPositions(pos, c.y)
 		}
 	}
 	return pos
@@ -108,8 +105,8 @@
 
 func (x *bottom) FormatError(p errors.Printer) error {
 	p.Print(x.msg)
-	if p.Detail() && x.index != nil && x.index.fset != nil {
-		locs := appendLocations(nil, x.index.fset, x.pos)
+	if p.Detail() && x.index != nil {
+		locs := appendLocations(nil, x.pos)
 		sort.Strings(locs)
 		for _, l := range locs {
 			p.Printf("%s\n", l)
@@ -121,17 +118,14 @@
 	return nil
 }
 
-func appendLocations(locs []string, fset *token.FileSet, src source) []string {
+func appendLocations(locs []string, src source) []string {
 	if src != nil {
 		if p := src.Pos(); p != token.NoPos {
-			if p.Offset() >= sharedOffset {
-				fset = sharedIndex.fset
-			}
 			return append(locs, src.Pos().String())
 		}
 		if c := src.computed(); c != nil {
-			locs = appendLocations(locs, fset, c.x)
-			locs = appendLocations(locs, fset, c.y)
+			locs = appendLocations(locs, c.x)
+			locs = appendLocations(locs, c.y)
 		}
 	}
 	return locs
diff --git a/cue/format/format.go b/cue/format/format.go
index 5b72b23..89f0438 100644
--- a/cue/format/format.go
+++ b/cue/format/format.go
@@ -30,12 +30,6 @@
 // An Option sets behavior of the formatter.
 type Option func(c *config)
 
-// FileSet sets the file set that was used for creating a node. The formatter
-// generally formats fine without it.
-func FileSet(fset *token.FileSet) Option {
-	return func(c *config) { c.fset = fset }
-}
-
 // Simplify allows the formatter to simplify output, such as removing
 // unnecessary quotes.
 func Simplify() Option {
@@ -96,11 +90,8 @@
 //
 func Source(b []byte, opt ...Option) ([]byte, error) {
 	cfg := newConfig(opt)
-	if cfg.fset == nil {
-		cfg.fset = token.NewFileSet()
-	}
 
-	f, err := parser.ParseFile(cfg.fset, "", b, parser.ParseComments)
+	f, err := parser.ParseFile("", b, parser.ParseComments)
 	if err != nil {
 		return nil, fmt.Errorf("parse: %s", err)
 	}
@@ -114,8 +105,6 @@
 }
 
 type config struct {
-	fset *token.FileSet
-
 	UseSpaces bool
 	TabIndent bool
 	Tabwidth  int // default: 8
@@ -264,7 +253,7 @@
 func (f *formatter) onOneLine(node ast.Node) bool {
 	a := node.Pos()
 	b := node.End()
-	if f.fset != nil && a.IsValid() && b.IsValid() {
+	if a.IsValid() && b.IsValid() {
 		return f.lineFor(a) == f.lineFor(b)
 	}
 	// TODO: walk and look at relative positions to determine the same?
@@ -277,7 +266,8 @@
 	f.current.parentSep = f.current.nodeSep
 
 	if node != nil {
-		if f.current.nodeSep != blank && f.onOneLine(node) {
+		s, ok := node.(*ast.StructLit)
+		if ok && len(s.Elts) <= 1 && f.current.nodeSep != blank && f.onOneLine(node) {
 			f.current.nodeSep = blank
 		}
 		f.current.cg = node.Comments()
diff --git a/cue/format/format_test.go b/cue/format/format_test.go
index 8510209..c6e49ae 100644
--- a/cue/format/format_test.go
+++ b/cue/format/format_test.go
@@ -33,7 +33,7 @@
 )
 
 var (
-	defaultConfig = newConfig([]Option{FileSet(fset)})
+	defaultConfig = newConfig([]Option{})
 	Fprint        = defaultConfig.fprint
 )
 
@@ -44,8 +44,6 @@
 
 var update = flag.Bool("update", false, "update golden files")
 
-var fset = token.NewFileSet()
-
 type checkMode uint
 
 const (
@@ -71,7 +69,7 @@
 	}
 
 	// make sure formatted output is syntactically correct
-	if _, err := parser.ParseFile(fset, "", res, parser.AllErrors); err != nil {
+	if _, err := parser.ParseFile("", res, parser.AllErrors); err != nil {
 		return nil, fmt.Errorf("re-parse: %s\n%s", err, res)
 	}
 
@@ -227,7 +225,7 @@
 func TestBadNodes(t *testing.T) {
 	const src = "package p\n("
 	const res = "package p\n\n(BadExpr)\n"
-	f, err := parser.ParseFile(fset, "", src, parser.ParseComments)
+	f, err := parser.ParseFile("", src, parser.ParseComments)
 	if err == nil {
 		t.Error("expected illegal program") // error in test
 	}
@@ -313,7 +311,7 @@
 `
 
 	// parse original
-	f1, err := parser.ParseFile(fset, "src", src, parser.ParseComments)
+	f1, err := parser.ParseFile("src", src, parser.ParseComments)
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -327,7 +325,7 @@
 
 	// parse pretty printed original
 	// (//line comments must be interpreted even w/o syntax.ParseComments set)
-	f2, err := parser.ParseFile(fset, "", buf.Bytes(),
+	f2, err := parser.ParseFile("", buf.Bytes(),
 		parser.AllErrors, parser.ParseComments)
 	if err != nil {
 		t.Fatalf("%s\n%s", err, buf.Bytes())
@@ -377,7 +375,7 @@
 
 func TestDeclLists(t *testing.T) {
 	for _, src := range decls {
-		file, err := parser.ParseFile(fset, "", "package p\n"+src, parser.ParseComments)
+		file, err := parser.ParseFile("", "package p\n"+src, parser.ParseComments)
 		if err != nil {
 			panic(err) // error in test
 		}
diff --git a/cue/format/node.go b/cue/format/node.go
index d054270..6054e31 100644
--- a/cue/format/node.go
+++ b/cue/format/node.go
@@ -276,9 +276,8 @@
 		if f.cfg.simplify && n.Kind == token.STRING && len(n.Value) > 2 {
 			s := n.Value
 			unquoted, err := strconv.Unquote(s)
-			fset := token.NewFileSet()
 			if err == nil {
-				e, _ := parser.ParseExpr(fset, "check", unquoted)
+				e, _ := parser.ParseExpr("check", unquoted)
 				if _, ok := e.(*ast.Ident); ok {
 					f.print(n.ValuePos, unquoted)
 					break
diff --git a/cue/format/printer.go b/cue/format/printer.go
index 96518a0..fbbc4ee 100644
--- a/cue/format/printer.go
+++ b/cue/format/printer.go
@@ -29,8 +29,7 @@
 type printer struct {
 	w tabwriter.Writer
 
-	fset *token.FileSet
-	cfg  *config
+	cfg *config
 
 	allowed     whiteSpace
 	requested   whiteSpace
@@ -62,9 +61,6 @@
 }
 
 func (p *printer) lineFor(pos token.Pos) int {
-	if p.fset == nil {
-		return 0
-	}
 	return pos.Line()
 }
 
diff --git a/cue/gen.go b/cue/gen.go
index a255876..145ed1e 100644
--- a/cue/gen.go
+++ b/cue/gen.go
@@ -40,7 +40,6 @@
 	"cuelang.org/go/cue"
 	cueformat "cuelang.org/go/cue/format"
 	"cuelang.org/go/cue/load"
-	cuetoken "cuelang.org/go/cue/token"
 )
 
 const prefix = "../pkg/"
@@ -68,7 +67,6 @@
 		w:     &bytes.Buffer{},
 		decls: &bytes.Buffer{},
 		fset:  token.NewFileSet(),
-		cfset: cuetoken.NewFileSet(),
 	}
 
 	fmt.Fprintln(g.w, "var builtinPackages = map[string]*builtinPkg{")
@@ -137,7 +135,6 @@
 	w          *bytes.Buffer
 	decls      *bytes.Buffer
 	fset       *token.FileSet
-	cfset      *cuetoken.FileSet
 	defaultPkg string
 	first      bool
 	iota       int
diff --git a/cue/go.go b/cue/go.go
index aad63bb..a577772 100644
--- a/cue/go.go
+++ b/cue/go.go
@@ -66,7 +66,7 @@
 	if tag == "" {
 		return &top{}
 	}
-	expr, err := parser.ParseExpr(ctx.index.fset, "<field:>", tag)
+	expr, err := parser.ParseExpr("<field:>", tag)
 	if err != nil {
 		field := ctx.labelStr(field)
 		return ctx.mkErr(baseValue{}, "invalid tag %q for field %q: %v", tag, field, err)
@@ -155,7 +155,7 @@
 
 // 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)
+	expr, err := parser.ParseExpr("json", b)
 	if err != nil {
 		panic(err) // cannot happen
 	}
diff --git a/cue/load/import.go b/cue/load/import.go
index e066951..9585e33 100644
--- a/cue/load/import.go
+++ b/cue/load/import.go
@@ -316,7 +316,6 @@
 	name := filepath.Base(fullPath)
 	dir := filepath.Dir(fullPath)
 
-	fset := token.NewFileSet()
 	ext := nameExt(name)
 	p := fp.pkg
 
@@ -341,7 +340,7 @@
 		return false // don't mark as added
 	}
 
-	pf, err := parser.ParseFile(fset, filename, data, parser.ImportsOnly, parser.ParseComments)
+	pf, err := parser.ParseFile(filename, data, parser.ImportsOnly, parser.ParseComments)
 	if err != nil {
 		return badFile(err)
 	}
diff --git a/cue/parser/error_test.go b/cue/parser/error_test.go
index e20df24..eb0cb1f 100644
--- a/cue/parser/error_test.go
+++ b/cue/parser/error_test.go
@@ -154,7 +154,7 @@
 		return
 	}
 
-	f, err := ParseFile(token.NewFileSet(), filename, src, DeclarationErrors, AllErrors)
+	f, err := ParseFile(filename, src, DeclarationErrors, AllErrors)
 	file := f.Pos().File()
 	found, ok := err.(errors.List)
 	if err != nil && !ok {
diff --git a/cue/parser/example_test.go b/cue/parser/example_test.go
index 195da10..33657fd 100644
--- a/cue/parser/example_test.go
+++ b/cue/parser/example_test.go
@@ -18,15 +18,12 @@
 	"fmt"
 
 	"cuelang.org/go/cue/parser"
-	"cuelang.org/go/cue/token"
 )
 
 func ExampleParseFile() {
-	fset := token.NewFileSet() // positions are relative to fset
-
 	// Parse the file containing this very example
 	// but stop after processing the imports.
-	f, err := parser.ParseFile(fset, "testdata/test.cue", nil)
+	f, err := parser.ParseFile("testdata/test.cue", nil)
 	if err != nil {
 		fmt.Println(err)
 		return
diff --git a/cue/parser/interface.go b/cue/parser/interface.go
index d921adc..758e27f 100644
--- a/cue/parser/interface.go
+++ b/cue/parser/interface.go
@@ -134,10 +134,7 @@
 // errors were found, the result is a partial AST (with Bad* nodes
 // representing the fragments of erroneous source code). Multiple errors
 // are returned via a ErrorList which is sorted by file position.
-func ParseFile(p *token.FileSet, filename string, src interface{}, mode ...Option) (f *ast.File, err error) {
-	if p == nil {
-		panic("ParseFile: no file.FileSet provided (fset == nil)")
-	}
+func ParseFile(filename string, src interface{}, mode ...Option) (f *ast.File, err error) {
 
 	// get source
 	text, err := readSource(filename, src)
@@ -167,7 +164,7 @@
 	}()
 
 	// parse source
-	pp.init(p, filename, text, mode)
+	pp.init(filename, text, mode)
 	f = pp.parseFile()
 	if f == nil {
 		return nil, pp.errors
@@ -182,11 +179,7 @@
 // The arguments have the same meaning as for Parse, but the source must
 // be a valid CUE (type or value) expression. Specifically, fset must not
 // be nil.
-func ParseExpr(fset *token.FileSet, filename string, src interface{}, mode ...Option) (ast.Expr, error) {
-	if fset == nil {
-		panic("ParseExprFrom: no file.FileSet provided (fset == nil)")
-	}
-
+func ParseExpr(filename string, src interface{}, mode ...Option) (ast.Expr, error) {
 	// get source
 	text, err := readSource(filename, src)
 	if err != nil {
@@ -203,7 +196,7 @@
 	}()
 
 	// parse expr
-	p.init(fset, filename, text, mode)
+	p.init(filename, text, mode)
 	// Set up pkg-level scopes to avoid nil-pointer errors.
 	// This is not needed for a correct expression x as the
 	// parser will be ok with a nil topScope, but be cautious
@@ -232,5 +225,5 @@
 // expression x. The position information recorded in the AST is undefined. The
 // filename used in error messages is the empty string.
 func parseExprString(x string) (ast.Expr, error) {
-	return ParseExpr(token.NewFileSet(), "", []byte(x))
+	return ParseExpr("", []byte(x))
 }
diff --git a/cue/parser/interface_test.go b/cue/parser/interface_test.go
index 394a5a4..371f162 100644
--- a/cue/parser/interface_test.go
+++ b/cue/parser/interface_test.go
@@ -19,7 +19,6 @@
 	"testing"
 
 	"cuelang.org/go/cue/ast"
-	"cuelang.org/go/cue/token"
 )
 
 func Test_readSource(t *testing.T) {
@@ -49,7 +48,6 @@
 
 func TestParseFile(t *testing.T) {
 	type args struct {
-		fset     *token.FileSet
 		filename string
 		src      interface{}
 		options  []Option
@@ -63,7 +61,7 @@
 		// TODO: Add test cases.
 	}
 	for _, tt := range tests {
-		gotF, err := ParseFile(tt.args.fset, tt.args.filename, tt.args.src, tt.args.options...)
+		gotF, err := ParseFile(tt.args.filename, tt.args.src, tt.args.options...)
 		if (err != nil) != tt.wantErr {
 			t.Errorf("%q. ParseFile() error = %v, wantErr %v", tt.name, err, tt.wantErr)
 			continue
@@ -76,7 +74,6 @@
 
 func TestParseExprFrom(t *testing.T) {
 	type args struct {
-		fset     *token.FileSet
 		filename string
 		src      interface{}
 		mode     Option
@@ -90,7 +87,7 @@
 		// TODO: Add test cases.
 	}
 	for _, tt := range tests {
-		got, err := ParseExpr(tt.args.fset, tt.args.filename, tt.args.src, tt.args.mode)
+		got, err := ParseExpr(tt.args.filename, tt.args.src, tt.args.mode)
 		if (err != nil) != tt.wantErr {
 			t.Errorf("%q. ParseExprFrom() error = %v, wantErr %v", tt.name, err, tt.wantErr)
 			continue
diff --git a/cue/parser/parser.go b/cue/parser/parser.go
index a81a57b..20e63c4 100644
--- a/cue/parser/parser.go
+++ b/cue/parser/parser.go
@@ -61,7 +61,7 @@
 
 }
 
-func (p *parser) init(fset *token.FileSet, filename string, src []byte, mode []Option) {
+func (p *parser) init(filename string, src []byte, mode []Option) {
 	p.file = token.NewFile(filename, -1, len(src))
 	for _, f := range mode {
 		f(p)
diff --git a/cue/parser/parser_test.go b/cue/parser/parser_test.go
index 32c0bf8..d795f62 100644
--- a/cue/parser/parser_test.go
+++ b/cue/parser/parser_test.go
@@ -21,7 +21,6 @@
 	"testing"
 
 	"cuelang.org/go/cue/ast"
-	"cuelang.org/go/cue/token"
 )
 
 func TestParse(t *testing.T) {
@@ -352,12 +351,11 @@
 	}}
 	for _, tc := range testCases {
 		t.Run(tc.desc, func(t *testing.T) {
-			fset := token.NewFileSet()
 			mode := []Option{AllErrors}
 			if strings.Contains(tc.desc, "comments") {
 				mode = append(mode, ParseComments)
 			}
-			f, err := ParseFile(fset, "input", tc.in, mode...)
+			f, err := ParseFile("input", tc.in, mode...)
 			if err != nil {
 				t.Errorf("unexpected error: %v", err)
 			}
@@ -464,7 +462,7 @@
 	for path, isValid := range imports {
 		t.Run(path, func(t *testing.T) {
 			src := fmt.Sprintf("package p, import %s", path)
-			_, err := ParseFile(token.NewFileSet(), "", src)
+			_, err := ParseFile("", src)
 			switch {
 			case err != nil && isValid:
 				t.Errorf("ParseFile(%s): got %v; expected no error", src, err)
@@ -522,8 +520,7 @@
 		"{ a: fmt.\n\"a\": x }", // not at end of struct
 	} {
 		t.Run("", func(t *testing.T) {
-			fset := token.NewFileSet()
-			f, err := ParseFile(fset, "", src)
+			f, err := ParseFile("", src)
 			if err == nil {
 				t.Fatalf("ParseFile(%s) succeeded unexpectedly", src)
 			}
diff --git a/cue/parser/performance_test.go b/cue/parser/performance_test.go
index f08b9d4..33a4283 100644
--- a/cue/parser/performance_test.go
+++ b/cue/parser/performance_test.go
@@ -17,8 +17,6 @@
 import (
 	"io/ioutil"
 	"testing"
-
-	"cuelang.org/go/cue/token"
 )
 
 var src = readFile("testdata/commas.src")
@@ -34,7 +32,7 @@
 func BenchmarkParse(b *testing.B) {
 	b.SetBytes(int64(len(src)))
 	for i := 0; i < b.N; i++ {
-		if _, err := ParseFile(token.NewFileSet(), "", src, ParseComments); err != nil {
+		if _, err := ParseFile("", src, ParseComments); err != nil {
 			b.Fatalf("benchmark failed due to parse error: %s", err)
 		}
 	}
diff --git a/cue/resolve_test.go b/cue/resolve_test.go
index 262af6b..75ea63c 100644
--- a/cue/resolve_test.go
+++ b/cue/resolve_test.go
@@ -20,7 +20,6 @@
 
 	"cuelang.org/go/cue/errors"
 	"cuelang.org/go/cue/parser"
-	"cuelang.org/go/cue/token"
 )
 
 var traceOn = flag.Bool("debug", false, "enable tracing")
@@ -43,9 +42,8 @@
 func compileInstance(t *testing.T, body string) (*context, *Instance, errors.List) {
 	t.Helper()
 
-	fset := token.NewFileSet()
-	x := newIndex(fset).NewInstance(nil)
-	f, err := parser.ParseFile(fset, "test", body)
+	x := newIndex().NewInstance(nil)
+	f, err := parser.ParseFile("test", body)
 	ctx := x.newContext()
 
 	switch errs := err.(type) {
diff --git a/cue/scanner/scanner_test.go b/cue/scanner/scanner_test.go
index bf1521b..9b0a8f7 100644
--- a/cue/scanner/scanner_test.go
+++ b/cue/scanner/scanner_test.go
@@ -28,8 +28,6 @@
 	"github.com/google/go-cmp/cmp"
 )
 
-var fset = token.NewFileSet()
-
 const /* class */ (
 	special = iota
 	literal
diff --git a/cue/token/position.go b/cue/token/position.go
index ad51afd..a3bded3 100644
--- a/cue/token/position.go
+++ b/cue/token/position.go
@@ -190,7 +190,6 @@
 
 type index int
 
-// A File is a handle for a file belonging to a FileSet.
 // A File has a name, size, and line offset table.
 type File struct {
 	mutex sync.RWMutex
@@ -432,23 +431,6 @@
 	return f.PositionFor(p, true)
 }
 
-// A FileSet represents a set of source files.
-// Methods of file sets are synchronized; multiple goroutines
-// may invoke them concurrently.
-type FileSet struct {
-	mutex sync.RWMutex // protects the file set
-	base  int          // base offset for the next file
-	files []*File      // list of files in the order added to the set
-	last  *File        // cache of last file looked up
-}
-
-// NewFileSet creates a new file set.
-func NewFileSet() *FileSet {
-	return &FileSet{
-		base: 1, // 0 == NoPos
-	}
-}
-
 // -----------------------------------------------------------------------------
 // Helper functions
 
diff --git a/cue/token/position_test.go b/cue/token/position_test.go
index a855ebd..6acc6ee 100644
--- a/cue/token/position_test.go
+++ b/cue/token/position_test.go
@@ -68,7 +68,7 @@
 	return len(lines), offs - prevLineOffs + 1
 }
 
-func verifyPositions(t *testing.T, fset *FileSet, f *File, lines []int) {
+func verifyPositions(t *testing.T, f *File, lines []int) {
 	for offs := 0; offs < f.Size(); offs++ {
 		p := f.Pos(offs, 0)
 		offs2 := f.Offset(p)
@@ -94,7 +94,6 @@
 
 func TestPositions(t *testing.T) {
 	const delta = 7 // a non-zero base offset increment
-	fset := NewFileSet()
 	for _, test := range tests {
 		// verify consistency of test case
 		if test.source != nil && len(test.source) != test.size {
@@ -124,7 +123,7 @@
 			if f.LineCount() != i+1 {
 				t.Errorf("%s, AddLine: got unchanged line count %d; want %d", f.Name(), f.LineCount(), i+1)
 			}
-			verifyPositions(t, fset, f, test.lines[0:i+1])
+			verifyPositions(t, f, test.lines[0:i+1])
 		}
 
 		// add lines with SetLines and verify all positions
@@ -134,7 +133,7 @@
 		if f.LineCount() != len(test.lines) {
 			t.Errorf("%s, SetLines: got line count %d; want %d", f.Name(), f.LineCount(), len(test.lines))
 		}
-		verifyPositions(t, fset, f, test.lines)
+		verifyPositions(t, f, test.lines)
 
 		// add lines with SetLinesForContent and verify all positions
 		src := test.source
@@ -146,7 +145,7 @@
 		if f.LineCount() != len(test.lines) {
 			t.Errorf("%s, SetLinesForContent: got line count %d; want %d", f.Name(), f.LineCount(), len(test.lines))
 		}
-		verifyPositions(t, fset, f, test.lines)
+		verifyPositions(t, f, test.lines)
 	}
 }
 
diff --git a/cuego/cuego.go b/cuego/cuego.go
index 7e799c9..4c1e7de 100644
--- a/cuego/cuego.go
+++ b/cuego/cuego.go
@@ -22,7 +22,6 @@
 	"cuelang.org/go/cue"
 	"cuelang.org/go/cue/build"
 	"cuelang.org/go/cue/parser"
-	"cuelang.org/go/cue/token"
 	"cuelang.org/go/internal"
 )
 
@@ -136,7 +135,7 @@
 	mutex.Lock()
 	defer mutex.Unlock()
 
-	expr, err := parser.ParseExpr(fset, fmt.Sprintf("<%T>", x), constraints)
+	expr, err := parser.ParseExpr(fmt.Sprintf("<%T>", x), constraints)
 	if err != nil {
 		return err
 	}
@@ -161,12 +160,10 @@
 var (
 	mutex    sync.Mutex
 	instance *cue.Instance
-	fset     *token.FileSet
 )
 
 func init() {
 	context := build.NewContext()
-	fset = context.FileSet()
 	inst := context.NewInstance("<cuego>", nil)
 	if err := inst.AddFile("<cuego>", "{}"); err != nil {
 		panic(err)
diff --git a/internal/protobuf/parse.go b/internal/protobuf/parse.go
index b81bd5c..0298db3 100644
--- a/internal/protobuf/parse.go
+++ b/internal/protobuf/parse.go
@@ -596,8 +596,7 @@
 
 		case "(cue.val)":
 			// TODO: set filename and base offset.
-			fset := token.NewFileSet()
-			expr, err := parser.ParseExpr(fset, "", o.Constant.Source)
+			expr, err := parser.ParseExpr("", o.Constant.Source)
 			if err != nil {
 				failf("invalid cue.val value: %v", err)
 			}
diff --git a/internal/third_party/yaml/decode.go b/internal/third_party/yaml/decode.go
index 0626801..2b985b0 100644
--- a/internal/third_party/yaml/decode.go
+++ b/internal/third_party/yaml/decode.go
@@ -75,7 +75,7 @@
 	return ioutil.ReadFile(filename)
 }
 
-func newParser(fset *token.FileSet, filename string, src interface{}) (*parser, error) {
+func newParser(filename string, src interface{}) (*parser, error) {
 	b, err := readSource(filename, src)
 	if err != nil {
 		return nil, err
diff --git a/internal/third_party/yaml/decode_test.go b/internal/third_party/yaml/decode_test.go
index 2e2122d..71cbf3c 100644
--- a/internal/third_party/yaml/decode_test.go
+++ b/internal/third_party/yaml/decode_test.go
@@ -13,7 +13,6 @@
 
 	"cuelang.org/go/cue/ast"
 	"cuelang.org/go/cue/format"
-	"cuelang.org/go/cue/token"
 	"cuelang.org/go/internal/third_party/yaml"
 )
 
@@ -624,8 +623,6 @@
 	C int
 }
 
-var fset = token.NewFileSet()
-
 func cueStr(node ast.Node) string {
 	if s, ok := node.(*ast.StructLit); ok {
 		node = &ast.File{
@@ -638,7 +635,7 @@
 }
 
 func newDecoder(t *testing.T, data string) *yaml.Decoder {
-	dec, err := yaml.NewDecoder(fset, "test.yaml", strings.NewReader(data))
+	dec, err := yaml.NewDecoder("test.yaml", strings.NewReader(data))
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -646,7 +643,7 @@
 }
 
 func callUnmarshal(t *testing.T, data string) (ast.Expr, error) {
-	return yaml.Unmarshal(fset, "test.yaml", []byte(data))
+	return yaml.Unmarshal("test.yaml", []byte(data))
 }
 
 func TestUnmarshal(t *testing.T) {
@@ -806,7 +803,7 @@
 			if err != nil {
 				t.Fatal(err)
 			}
-			expr, err := yaml.Unmarshal(fset, "test.yaml", mergeTests)
+			expr, err := yaml.Unmarshal("test.yaml", mergeTests)
 			if err != nil {
 				t.Fatal(err)
 			}
diff --git a/internal/third_party/yaml/yaml.go b/internal/third_party/yaml/yaml.go
index 8251f39..955cd82 100644
--- a/internal/third_party/yaml/yaml.go
+++ b/internal/third_party/yaml/yaml.go
@@ -16,7 +16,6 @@
 	"sync"
 
 	"cuelang.org/go/cue/ast"
-	"cuelang.org/go/cue/token"
 )
 
 // MapSlice encodes and decodes as a YAML map.
@@ -81,8 +80,8 @@
 // See the documentation of Marshal for the format of tags and a list of
 // supported tag options.
 //
-func Unmarshal(fset *token.FileSet, filename string, in []byte) (expr ast.Expr, err error) {
-	return unmarshal(fset, filename, in)
+func Unmarshal(filename string, in []byte) (expr ast.Expr, err error) {
+	return unmarshal(filename, in)
 }
 
 // A Decorder reads and decodes YAML values from an input stream.
@@ -95,8 +94,8 @@
 //
 // The decoder introduces its own buffering and may read
 // data from r beyond the YAML values requested.
-func NewDecoder(fset *token.FileSet, filename string, r io.Reader) (*Decoder, error) {
-	d, err := newParser(fset, filename, r)
+func NewDecoder(filename string, r io.Reader) (*Decoder, error) {
+	d, err := newParser(filename, r)
 	if err != nil {
 		return nil, err
 	}
@@ -122,9 +121,9 @@
 	return expr, nil
 }
 
-func unmarshal(fset *token.FileSet, filename string, in []byte) (expr ast.Expr, err error) {
+func unmarshal(filename string, in []byte) (expr ast.Expr, err error) {
 	defer handleErr(&err)
-	p, err := newParser(fset, filename, in)
+	p, err := newParser(filename, in)
 	if err != nil {
 		return nil, err
 	}
diff --git a/pkg/encoding/json/manual.go b/pkg/encoding/json/manual.go
index 3af3d37..4f1ac41 100644
--- a/pkg/encoding/json/manual.go
+++ b/pkg/encoding/json/manual.go
@@ -22,7 +22,6 @@
 	"cuelang.org/go/cue"
 	"cuelang.org/go/cue/ast"
 	"cuelang.org/go/cue/parser"
-	"cuelang.org/go/cue/token"
 )
 
 // Compact generates the JSON-encoded src with insignificant space characters
@@ -95,8 +94,7 @@
 	if !json.Valid(b) {
 		return nil, fmt.Errorf("json: invalid JSON")
 	}
-	fset := token.NewFileSet()
-	expr, err := parser.ParseExpr(fset, "json", b)
+	expr, err := parser.ParseExpr("json", b)
 	if err != nil {
 		// NOTE: should never happen.
 		return nil, fmt.Errorf("json: could not parse JSON: %v", err)
diff --git a/pkg/encoding/yaml/manual.go b/pkg/encoding/yaml/manual.go
index 646e7aa..c6d5188 100644
--- a/pkg/encoding/yaml/manual.go
+++ b/pkg/encoding/yaml/manual.go
@@ -19,7 +19,6 @@
 
 	"cuelang.org/go/cue"
 	"cuelang.org/go/cue/ast"
-	"cuelang.org/go/cue/token"
 	"cuelang.org/go/internal/third_party/yaml"
 	goyaml "github.com/ghodss/yaml"
 )
@@ -53,6 +52,5 @@
 
 // Unmarshal parses the YAML to a CUE instance.
 func Unmarshal(data []byte) (ast.Expr, error) {
-	fset := token.NewFileSet()
-	return yaml.Unmarshal(fset, "", data)
+	return yaml.Unmarshal("", data)
 }
diff --git a/pkg/time/time_test.go b/pkg/time/time_test.go
index 11570a0..5955446 100644
--- a/pkg/time/time_test.go
+++ b/pkg/time/time_test.go
@@ -22,7 +22,6 @@
 	"cuelang.org/go/cue"
 	"cuelang.org/go/cue/load"
 	"cuelang.org/go/cue/parser"
-	"cuelang.org/go/cue/token"
 )
 
 func TestTime(t *testing.T) {
@@ -32,7 +31,7 @@
 	}
 
 	parseCUE := func(t *testing.T, time string) error {
-		expr, err := parser.ParseExpr(token.NewFileSet(), "test", "Time&"+time)
+		expr, err := parser.ParseExpr("test", "Time&"+time)
 		if err != nil {
 			t.Fatal(err)
 		}
diff --git a/pkg/tool/file/file_test.go b/pkg/tool/file/file_test.go
index d8531b3..097a5cb 100644
--- a/pkg/tool/file/file_test.go
+++ b/pkg/tool/file/file_test.go
@@ -23,19 +23,17 @@
 
 	"cuelang.org/go/cue"
 	"cuelang.org/go/cue/parser"
-	"cuelang.org/go/cue/token"
 	"cuelang.org/go/internal"
 )
 
 func parse(t *testing.T, kind, expr string) cue.Value {
 	t.Helper()
-	fset := token.NewFileSet()
 
-	x, err := parser.ParseExpr(fset, "test", expr)
+	x, err := parser.ParseExpr("test", expr)
 	if err != nil {
 		t.Fatal(err)
 	}
-	i, err := cue.FromExpr(fset, x)
+	i, err := cue.FromExpr(x)
 	if err != nil {
 		t.Fatal(err)
 	}