-
Notifications
You must be signed in to change notification settings - Fork 37
/
types.go
170 lines (152 loc) · 5.58 KB
/
types.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
// 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.
//go:build go1.19
// +build go1.19
package main
import (
"fmt"
"sort"
)
// Model contains the parsed version of the spec
type Model struct {
Version Metadata `json:"metaData"`
Requests []*Request `json:"requests"`
Notifications []*Notification `json:"notifications"`
Structures []*Structure `json:"structures"`
Enumerations []*Enumeration `json:"enumerations"`
TypeAliases []*TypeAlias `json:"typeAliases"`
Line int `json:"line"`
}
// Metadata is information about the version of the spec
type Metadata struct {
Version string `json:"version"`
Line int `json:"line"`
}
// A Request is the parsed version of an LSP request
type Request struct {
Documentation string `json:"documentation"`
ErrorData *Type `json:"errorData"`
Direction string `json:"messageDirection"`
Method string `json:"method"`
Params *Type `json:"params"`
PartialResult *Type `json:"partialResult"`
Proposed bool `json:"proposed"`
RegistrationMethod string `json:"registrationMethod"`
RegistrationOptions *Type `json:"registrationOptions"`
Result *Type `json:"result"`
Since string `json:"since"`
Line int `json:"line"`
}
// A Notificatin is the parsed version of an LSP notification
type Notification struct {
Documentation string `json:"documentation"`
Direction string `json:"messageDirection"`
Method string `json:"method"`
Params *Type `json:"params"`
Proposed bool `json:"proposed"`
RegistrationMethod string `json:"registrationMethod"`
RegistrationOptions *Type `json:"registrationOptions"`
Since string `json:"since"`
Line int `json:"line"`
}
// A Structure is the parsed version of an LSP structure from the spec
type Structure struct {
Documentation string `json:"documentation"`
Extends []*Type `json:"extends"`
Mixins []*Type `json:"mixins"`
Name string `json:"name"`
Properties []NameType `json:"properties"`
Proposed bool `json:"proposed"`
Since string `json:"since"`
Line int `json:"line"`
}
// An enumeration is the parsed version of an LSP enumeration from the spec
type Enumeration struct {
Documentation string `json:"documentation"`
Name string `json:"name"`
Proposed bool `json:"proposed"`
Since string `json:"since"`
SupportsCustomValues bool `json:"supportsCustomValues"`
Type *Type `json:"type"`
Values []NameValue `json:"values"`
Line int `json:"line"`
}
// A TypeAlias is the parsed version of an LSP type alias from the spec
type TypeAlias struct {
Documentation string `json:"documentation"`
Deprecated string `json:"deprecated"`
Name string `json:"name"`
Proposed bool `json:"proposed"`
Since string `json:"since"`
Type *Type `json:"type"`
Line int `json:"line"`
}
// A NameValue describes an enumeration constant
type NameValue struct {
Documentation string `json:"documentation"`
Name string `json:"name"`
Proposed bool `json:"proposed"`
Since string `json:"since"`
Value any `json:"value"` // number or string
Line int `json:"line"`
}
// A Type is the parsed version of an LSP type from the spec,
// or a Type the code constructs
type Type struct {
Kind string `json:"kind"` // -- which kind goes with which field --
Items []*Type `json:"items"` // "and", "or", "tuple"
Element *Type `json:"element"` // "array"
Name string `json:"name"` // "base", "reference"
Key *Type `json:"key"` // "map"
Value any `json:"value"` // "map", "stringLiteral", "literal"
Line int `json:"line"` // JSON source line
}
// ParsedLiteral is Type.Value when Type.Kind is "literal"
type ParseLiteral struct {
Properties `json:"properties"`
}
// A NameType represents the name and type of a structure element
type NameType struct {
Name string `json:"name"`
Type *Type `json:"type"`
Optional bool `json:"optional"`
Documentation string `json:"documentation"`
Deprecated string `json:"deprecated"`
Since string `json:"since"`
Proposed bool `json:"proposed"`
Line int `json:"line"`
}
// Properties are the collection of structure fields
type Properties []NameType
// addLineNumbers adds a "line" field to each object in the JSON.
func addLineNumbers(buf []byte) []byte {
var ans []byte
// In the specification .json file, the delimiter '{' is
// always followed by a newline. There are other {s embedded in strings.
// json.Token does not return \n, or :, or , so using it would
// require parsing the json to reconstruct the missing information.
for linecnt, i := 1, 0; i < len(buf); i++ {
ans = append(ans, buf[i])
switch buf[i] {
case '{':
if buf[i+1] == '\n' {
ans = append(ans, fmt.Sprintf(`"line": %d, `, linecnt)...)
// warning: this would fail if the spec file had
// `"value": {\n}`, but it does not, as comma is a separator.
}
case '\n':
linecnt++
}
}
return ans
}
type sortedMap[T any] map[string]T
func (s sortedMap[T]) keys() []string {
var keys []string
for k := range s {
keys = append(keys, k)
}
sort.Strings(keys)
return keys
}