| // Copyright 2022 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| package protocol |
| |
| import ( |
| "encoding/json" |
| "fmt" |
| ) |
| |
| // DocumentChange is a union of various file edit operations. |
| // |
| // Exactly one field of this struct is non-nil; see [DocumentChange.Valid]. |
| // |
| // See https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#resourceChanges |
| type DocumentChange struct { |
| TextDocumentEdit *TextDocumentEdit |
| CreateFile *CreateFile |
| RenameFile *RenameFile |
| DeleteFile *DeleteFile |
| } |
| |
| // Valid reports whether the DocumentChange sum-type value is valid, |
| // that is, exactly one of create, delete, edit, or rename. |
| func (ch DocumentChange) Valid() bool { |
| n := 0 |
| if ch.TextDocumentEdit != nil { |
| n++ |
| } |
| if ch.CreateFile != nil { |
| n++ |
| } |
| if ch.RenameFile != nil { |
| n++ |
| } |
| if ch.DeleteFile != nil { |
| n++ |
| } |
| return n == 1 |
| } |
| |
| func (d *DocumentChange) UnmarshalJSON(data []byte) error { |
| var m map[string]any |
| if err := json.Unmarshal(data, &m); err != nil { |
| return err |
| } |
| |
| if _, ok := m["textDocument"]; ok { |
| d.TextDocumentEdit = new(TextDocumentEdit) |
| return json.Unmarshal(data, d.TextDocumentEdit) |
| } |
| |
| // The {Create,Rename,Delete}File types all share a 'kind' field. |
| kind := m["kind"] |
| switch kind { |
| case "create": |
| d.CreateFile = new(CreateFile) |
| return json.Unmarshal(data, d.CreateFile) |
| case "rename": |
| d.RenameFile = new(RenameFile) |
| return json.Unmarshal(data, d.RenameFile) |
| case "delete": |
| d.DeleteFile = new(DeleteFile) |
| return json.Unmarshal(data, d.DeleteFile) |
| } |
| return fmt.Errorf("DocumentChanges: unexpected kind: %q", kind) |
| } |
| |
| func (d *DocumentChange) MarshalJSON() ([]byte, error) { |
| if d.TextDocumentEdit != nil { |
| return json.Marshal(d.TextDocumentEdit) |
| } else if d.CreateFile != nil { |
| return json.Marshal(d.CreateFile) |
| } else if d.RenameFile != nil { |
| return json.Marshal(d.RenameFile) |
| } else if d.DeleteFile != nil { |
| return json.Marshal(d.DeleteFile) |
| } |
| return nil, fmt.Errorf("empty DocumentChanges union value") |
| } |