diff options
Diffstat (limited to 'workhorse/internal/lsif_transformer/parser/docs.go')
-rw-r--r-- | workhorse/internal/lsif_transformer/parser/docs.go | 144 |
1 files changed, 144 insertions, 0 deletions
diff --git a/workhorse/internal/lsif_transformer/parser/docs.go b/workhorse/internal/lsif_transformer/parser/docs.go new file mode 100644 index 00000000000..c626e07d3fe --- /dev/null +++ b/workhorse/internal/lsif_transformer/parser/docs.go @@ -0,0 +1,144 @@ +package parser + +import ( + "archive/zip" + "bufio" + "encoding/json" + "io" + "strings" +) + +const maxScanTokenSize = 1024 * 1024 + +type Line struct { + Type string `json:"label"` +} + +type Docs struct { + Root string + Entries map[Id]string + DocRanges map[Id][]Id + Ranges *Ranges +} + +type Document struct { + Id Id `json:"id"` + Uri string `json:"uri"` +} + +type DocumentRange struct { + OutV Id `json:"outV"` + RangeIds []Id `json:"inVs"` +} + +type Metadata struct { + Root string `json:"projectRoot"` +} + +func NewDocs(config Config) (*Docs, error) { + ranges, err := NewRanges(config) + if err != nil { + return nil, err + } + + return &Docs{ + Root: "file:///", + Entries: make(map[Id]string), + DocRanges: make(map[Id][]Id), + Ranges: ranges, + }, nil +} + +func (d *Docs) Parse(r io.Reader) error { + scanner := bufio.NewScanner(r) + buf := make([]byte, 0, bufio.MaxScanTokenSize) + scanner.Buffer(buf, maxScanTokenSize) + + for scanner.Scan() { + if err := d.process(scanner.Bytes()); err != nil { + return err + } + } + + return scanner.Err() +} + +func (d *Docs) process(line []byte) error { + l := Line{} + if err := json.Unmarshal(line, &l); err != nil { + return err + } + + switch l.Type { + case "metaData": + if err := d.addMetadata(line); err != nil { + return err + } + case "document": + if err := d.addDocument(line); err != nil { + return err + } + case "contains": + if err := d.addDocRanges(line); err != nil { + return err + } + default: + return d.Ranges.Read(l.Type, line) + } + + return nil +} + +func (d *Docs) Close() error { + return d.Ranges.Close() +} + +func (d *Docs) SerializeEntries(w *zip.Writer) error { + for id, path := range d.Entries { + filePath := Lsif + "/" + path + ".json" + + f, err := w.Create(filePath) + if err != nil { + return err + } + + if err := d.Ranges.Serialize(f, d.DocRanges[id], d.Entries); err != nil { + return err + } + } + + return nil +} + +func (d *Docs) addMetadata(line []byte) error { + var metadata Metadata + if err := json.Unmarshal(line, &metadata); err != nil { + return err + } + + d.Root = strings.TrimSpace(metadata.Root) + "/" + + return nil +} + +func (d *Docs) addDocument(line []byte) error { + var doc Document + if err := json.Unmarshal(line, &doc); err != nil { + return err + } + + d.Entries[doc.Id] = strings.TrimPrefix(doc.Uri, d.Root) + + return nil +} + +func (d *Docs) addDocRanges(line []byte) error { + var docRange DocumentRange + if err := json.Unmarshal(line, &docRange); err != nil { + return err + } + + d.DocRanges[docRange.OutV] = append(d.DocRanges[docRange.OutV], docRange.RangeIds...) + + return nil +} |