golang.org/x/tools/gopls@v0.15.3/internal/cache/fs_overlay.go (about)

     1  // Copyright 2023 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package cache
     6  
     7  import (
     8  	"context"
     9  	"sync"
    10  
    11  	"golang.org/x/tools/gopls/internal/file"
    12  	"golang.org/x/tools/gopls/internal/protocol"
    13  )
    14  
    15  // An overlayFS is a file.Source that keeps track of overlays on top of a
    16  // delegate FileSource.
    17  type overlayFS struct {
    18  	delegate file.Source
    19  
    20  	mu       sync.Mutex
    21  	overlays map[protocol.DocumentURI]*overlay
    22  }
    23  
    24  func newOverlayFS(delegate file.Source) *overlayFS {
    25  	return &overlayFS{
    26  		delegate: delegate,
    27  		overlays: make(map[protocol.DocumentURI]*overlay),
    28  	}
    29  }
    30  
    31  // Overlays returns a new unordered array of overlays.
    32  func (fs *overlayFS) Overlays() []*overlay {
    33  	fs.mu.Lock()
    34  	defer fs.mu.Unlock()
    35  	overlays := make([]*overlay, 0, len(fs.overlays))
    36  	for _, overlay := range fs.overlays {
    37  		overlays = append(overlays, overlay)
    38  	}
    39  	return overlays
    40  }
    41  
    42  func (fs *overlayFS) ReadFile(ctx context.Context, uri protocol.DocumentURI) (file.Handle, error) {
    43  	fs.mu.Lock()
    44  	overlay, ok := fs.overlays[uri]
    45  	fs.mu.Unlock()
    46  	if ok {
    47  		return overlay, nil
    48  	}
    49  	return fs.delegate.ReadFile(ctx, uri)
    50  }
    51  
    52  // An overlay is a file open in the editor. It may have unsaved edits.
    53  // It implements the file.Handle interface, and the implicit contract
    54  // of the debug.FileTmpl template.
    55  type overlay struct {
    56  	uri     protocol.DocumentURI
    57  	content []byte
    58  	hash    file.Hash
    59  	version int32
    60  	kind    file.Kind
    61  
    62  	// saved is true if a file matches the state on disk,
    63  	// and therefore does not need to be part of the overlay sent to go/packages.
    64  	saved bool
    65  }
    66  
    67  func (o *overlay) URI() protocol.DocumentURI { return o.uri }
    68  
    69  func (o *overlay) Identity() file.Identity {
    70  	return file.Identity{
    71  		URI:  o.uri,
    72  		Hash: o.hash,
    73  	}
    74  }
    75  
    76  func (o *overlay) Content() ([]byte, error) { return o.content, nil }
    77  func (o *overlay) Version() int32           { return o.version }
    78  func (o *overlay) SameContentsOnDisk() bool { return o.saved }
    79  func (o *overlay) Kind() file.Kind          { return o.kind }