MCP Language Server

// 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 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 } // ParseLiteral 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 }