mirror of
https://github.com/Myzel394/config-lsp.git
synced 2025-06-18 15:05:28 +02:00
refactor(server): Improve Wireguard AST, analyzer and indexes
Signed-off-by: Myzel394 <github.7a2op@simplelogin.co>
This commit is contained in:
parent
ba056d6ae9
commit
36950fe271
@ -22,7 +22,7 @@ func (c *WGConfig) Clear() {
|
|||||||
|
|
||||||
var commentPattern = regexp.MustCompile(`^\s*([;#])`)
|
var commentPattern = regexp.MustCompile(`^\s*([;#])`)
|
||||||
var emptyPattern = regexp.MustCompile(`^\s*$`)
|
var emptyPattern = regexp.MustCompile(`^\s*$`)
|
||||||
var headerPattern = regexp.MustCompile(`^\s*\[(\w+)]?`)
|
var headerPattern = regexp.MustCompile(`^\s*\[(\w+)?]?`)
|
||||||
var linePattern = regexp.MustCompile(`^\s*(?P<key>.+?)\s*(?P<separator>=)\s*(?P<value>\S.*?)?\s*(?:[;#].*)?\s*$`)
|
var linePattern = regexp.MustCompile(`^\s*(?P<key>.+?)\s*(?P<separator>=)\s*(?P<value>\S.*?)?\s*(?:[;#].*)?\s*$`)
|
||||||
|
|
||||||
func (c *WGConfig) Parse(input string) []common.LSPError {
|
func (c *WGConfig) Parse(input string) []common.LSPError {
|
||||||
@ -177,11 +177,13 @@ func (c *WGConfig) Parse(input string) []common.LSPError {
|
|||||||
|
|
||||||
// Construct value
|
// Construct value
|
||||||
var value *WGPropertyValue
|
var value *WGPropertyValue
|
||||||
|
propertyEnd := uint32(len(line))
|
||||||
|
|
||||||
if indexes[6] != -1 && indexes[7] != -1 {
|
if indexes[6] != -1 && indexes[7] != -1 {
|
||||||
// value exists
|
// value exists
|
||||||
valueStart := uint32(indexes[6])
|
valueStart := uint32(indexes[6])
|
||||||
valueEnd := uint32(indexes[7])
|
valueEnd := uint32(indexes[7])
|
||||||
|
propertyEnd = valueEnd
|
||||||
|
|
||||||
value = &WGPropertyValue{
|
value = &WGPropertyValue{
|
||||||
LocationRange: common.LocationRange{
|
LocationRange: common.LocationRange{
|
||||||
@ -200,6 +202,16 @@ func (c *WGConfig) Parse(input string) []common.LSPError {
|
|||||||
|
|
||||||
// And lastly, add the property
|
// And lastly, add the property
|
||||||
currentSection.Properties[lineNumber] = &WGProperty{
|
currentSection.Properties[lineNumber] = &WGProperty{
|
||||||
|
LocationRange: common.LocationRange{
|
||||||
|
Start: common.Location{
|
||||||
|
Line: lineNumber,
|
||||||
|
Character: keyStart,
|
||||||
|
},
|
||||||
|
End: common.Location{
|
||||||
|
Line: lineNumber,
|
||||||
|
Character: propertyEnd,
|
||||||
|
},
|
||||||
|
},
|
||||||
Key: key,
|
Key: key,
|
||||||
Separator: &separator,
|
Separator: &separator,
|
||||||
Value: value,
|
Value: value,
|
||||||
|
@ -19,6 +19,7 @@ type WGPropertySeparator struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type WGProperty struct {
|
type WGProperty struct {
|
||||||
|
common.LocationRange
|
||||||
Key WGPropertyKey
|
Key WGPropertyKey
|
||||||
Separator *WGPropertySeparator
|
Separator *WGPropertySeparator
|
||||||
Value *WGPropertyValue
|
Value *WGPropertyValue
|
||||||
|
@ -37,3 +37,13 @@ func (c *WGConfig) FindPropertyByLine(line uint32) *WGProperty {
|
|||||||
|
|
||||||
return section.Properties[line]
|
return section.Properties[line]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *WGSection) FindFirstPropertyByName(name string) *WGProperty {
|
||||||
|
for _, property := range s.Properties {
|
||||||
|
if property.Key.Name == name {
|
||||||
|
return property
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
package lsp
|
|
||||||
|
|
||||||
import (
|
|
||||||
"config-lsp/handlers/wireguard/parser"
|
|
||||||
protocol "github.com/tliron/glsp/protocol_3_16"
|
|
||||||
)
|
|
||||||
|
|
||||||
var documentParserMap = map[protocol.DocumentUri]*parser.WireguardParser{}
|
|
@ -2,8 +2,10 @@ package lsp
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"config-lsp/common"
|
"config-lsp/common"
|
||||||
"config-lsp/handlers/wireguard/handlers"
|
"config-lsp/handlers/wireguard"
|
||||||
|
"config-lsp/handlers/wireguard/analyzer"
|
||||||
"config-lsp/utils"
|
"config-lsp/utils"
|
||||||
|
|
||||||
"github.com/tliron/glsp"
|
"github.com/tliron/glsp"
|
||||||
protocol "github.com/tliron/glsp/protocol_3_16"
|
protocol "github.com/tliron/glsp/protocol_3_16"
|
||||||
)
|
)
|
||||||
@ -15,22 +17,22 @@ func TextDocumentDidChange(
|
|||||||
content := params.ContentChanges[0].(protocol.TextDocumentContentChangeEventWhole).Text
|
content := params.ContentChanges[0].(protocol.TextDocumentContentChangeEventWhole).Text
|
||||||
common.ClearDiagnostics(context, params.TextDocument.URI)
|
common.ClearDiagnostics(context, params.TextDocument.URI)
|
||||||
|
|
||||||
p := documentParserMap[params.TextDocument.URI]
|
document := wireguard.DocumentParserMap[params.TextDocument.URI]
|
||||||
p.Clear()
|
document.Config.Clear()
|
||||||
|
|
||||||
diagnostics := make([]protocol.Diagnostic, 0)
|
diagnostics := make([]protocol.Diagnostic, 0)
|
||||||
errors := p.ParseFromString(content)
|
errors := document.Config.Parse(content)
|
||||||
|
|
||||||
if len(errors) > 0 {
|
if len(errors) > 0 {
|
||||||
diagnostics = append(diagnostics, utils.Map(
|
diagnostics = append(diagnostics, utils.Map(
|
||||||
errors,
|
errors,
|
||||||
func(err common.ParseError) protocol.Diagnostic {
|
func(err common.LSPError) protocol.Diagnostic {
|
||||||
return err.ToDiagnostic()
|
return err.ToDiagnostic()
|
||||||
},
|
},
|
||||||
)...)
|
)...)
|
||||||
}
|
}
|
||||||
|
|
||||||
diagnostics = append(diagnostics, handlers.Analyze(*p)...)
|
diagnostics = append(diagnostics, analyzer.Analyze(document)...)
|
||||||
|
|
||||||
if len(diagnostics) > 0 {
|
if len(diagnostics) > 0 {
|
||||||
common.SendDiagnostics(context, params.TextDocument.URI, diagnostics)
|
common.SendDiagnostics(context, params.TextDocument.URI, diagnostics)
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
package lsp
|
package lsp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"config-lsp/handlers/wireguard"
|
||||||
|
|
||||||
"github.com/tliron/glsp"
|
"github.com/tliron/glsp"
|
||||||
protocol "github.com/tliron/glsp/protocol_3_16"
|
protocol "github.com/tliron/glsp/protocol_3_16"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TextDocumentDidClose(context *glsp.Context, params *protocol.DidCloseTextDocumentParams) error {
|
func TextDocumentDidClose(context *glsp.Context, params *protocol.DidCloseTextDocumentParams) error {
|
||||||
delete(documentParserMap, params.TextDocument.URI)
|
delete(wireguard.DocumentParserMap, params.TextDocument.URI)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,12 @@ package lsp
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"config-lsp/common"
|
"config-lsp/common"
|
||||||
"config-lsp/handlers/wireguard/parser"
|
"config-lsp/handlers/wireguard"
|
||||||
|
"config-lsp/handlers/wireguard/analyzer"
|
||||||
|
"config-lsp/handlers/wireguard/ast"
|
||||||
|
"config-lsp/handlers/wireguard/indexes"
|
||||||
"config-lsp/utils"
|
"config-lsp/utils"
|
||||||
|
|
||||||
"github.com/tliron/glsp"
|
"github.com/tliron/glsp"
|
||||||
protocol "github.com/tliron/glsp/protocol_3_16"
|
protocol "github.com/tliron/glsp/protocol_3_16"
|
||||||
)
|
)
|
||||||
@ -14,17 +18,21 @@ func TextDocumentDidOpen(
|
|||||||
) error {
|
) error {
|
||||||
common.ClearDiagnostics(context, params.TextDocument.URI)
|
common.ClearDiagnostics(context, params.TextDocument.URI)
|
||||||
|
|
||||||
p := parser.CreateWireguardParser()
|
document := &wireguard.WGDocument{
|
||||||
documentParserMap[params.TextDocument.URI] = &p
|
Config: ast.NewWGConfig(),
|
||||||
|
Indexes: &indexes.WGIndexes{},
|
||||||
|
}
|
||||||
|
wireguard.DocumentParserMap[params.TextDocument.URI] = document
|
||||||
|
|
||||||
errors := p.ParseFromString(params.TextDocument.Text)
|
errors := document.Config.Parse(params.TextDocument.Text)
|
||||||
|
|
||||||
diagnostics := utils.Map(
|
diagnostics := utils.Map(
|
||||||
errors,
|
errors,
|
||||||
func(err common.ParseError) protocol.Diagnostic {
|
func(err common.LSPError) protocol.Diagnostic {
|
||||||
return err.ToDiagnostic()
|
return err.ToDiagnostic()
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
diagnostics = append(diagnostics, analyzer.Analyze(document)...)
|
||||||
|
|
||||||
if len(diagnostics) > 0 {
|
if len(diagnostics) > 0 {
|
||||||
common.SendDiagnostics(context, params.TextDocument.URI, diagnostics)
|
common.SendDiagnostics(context, params.TextDocument.URI, diagnostics)
|
||||||
|
@ -2,6 +2,7 @@ package parser
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"config-lsp/common"
|
"config-lsp/common"
|
||||||
|
"config-lsp/handlers/wireguard/ast"
|
||||||
"regexp"
|
"regexp"
|
||||||
"slices"
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
@ -11,33 +12,7 @@ var commentPattern = regexp.MustCompile(`^\s*(;|#)`)
|
|||||||
var emptyLinePattern = regexp.MustCompile(`^\s*$`)
|
var emptyLinePattern = regexp.MustCompile(`^\s*$`)
|
||||||
var headerPattern = regexp.MustCompile(`^\s*\[`)
|
var headerPattern = regexp.MustCompile(`^\s*\[`)
|
||||||
|
|
||||||
type CharacterLocation struct {
|
func (p *ast.WGConfig) ParseFromString(input string) []common.ParseError {
|
||||||
Start uint32
|
|
||||||
End uint32
|
|
||||||
}
|
|
||||||
|
|
||||||
type wireguardLineIndex struct {
|
|
||||||
Type LineType
|
|
||||||
BelongingSection *WireguardSection
|
|
||||||
}
|
|
||||||
|
|
||||||
type WireguardParser struct {
|
|
||||||
// <key = name>: if nil then does not belong to a section
|
|
||||||
Sections []*WireguardSection
|
|
||||||
// Used to identify where not to show diagnostics
|
|
||||||
commentLines map[uint32]struct{}
|
|
||||||
|
|
||||||
// Indexes
|
|
||||||
linesIndexes map[uint32]wireguardLineIndex
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *WireguardParser) Clear() {
|
|
||||||
p.Sections = []*WireguardSection{}
|
|
||||||
p.commentLines = map[uint32]struct{}{}
|
|
||||||
p.linesIndexes = map[uint32]wireguardLineIndex{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *WireguardParser) ParseFromString(input string) []common.ParseError {
|
|
||||||
var errors []common.ParseError
|
var errors []common.ParseError
|
||||||
lines := strings.Split(
|
lines := strings.Split(
|
||||||
input,
|
input,
|
||||||
@ -116,7 +91,7 @@ func (p *WireguardParser) ParseFromString(input string) []common.ParseError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var emptySection *WireguardSection
|
var emptySection *ast.WGSection
|
||||||
|
|
||||||
if len(collectedProperties) > 0 {
|
if len(collectedProperties) > 0 {
|
||||||
var endLine uint32
|
var endLine uint32
|
||||||
@ -127,7 +102,7 @@ func (p *WireguardParser) ParseFromString(input string) []common.ParseError {
|
|||||||
endLine = p.Sections[len(p.Sections)-1].StartLine
|
endLine = p.Sections[len(p.Sections)-1].StartLine
|
||||||
}
|
}
|
||||||
|
|
||||||
emptySection = &WireguardSection{
|
emptySection = &ast.WGSection{
|
||||||
StartLine: 0,
|
StartLine: 0,
|
||||||
EndLine: endLine,
|
EndLine: endLine,
|
||||||
Properties: collectedProperties,
|
Properties: collectedProperties,
|
||||||
@ -152,7 +127,7 @@ func (p *WireguardParser) ParseFromString(input string) []common.ParseError {
|
|||||||
|
|
||||||
// Add empty section
|
// Add empty section
|
||||||
if endLine != 0 {
|
if endLine != 0 {
|
||||||
emptySection = &WireguardSection{
|
emptySection = &ast.WGSection{
|
||||||
StartLine: 0,
|
StartLine: 0,
|
||||||
EndLine: endLine,
|
EndLine: endLine,
|
||||||
Properties: collectedProperties,
|
Properties: collectedProperties,
|
||||||
@ -203,7 +178,7 @@ func (p *WireguardParser) ParseFromString(input string) []common.ParseError {
|
|||||||
return errors
|
return errors
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *WireguardParser) GetSectionByLine(line uint32) *WireguardSection {
|
func (p *ast.WGConfig) GetSectionByLine(line uint32) *ast.WGSection {
|
||||||
for _, section := range p.Sections {
|
for _, section := range p.Sections {
|
||||||
if section.StartLine <= line && section.EndLine >= line {
|
if section.StartLine <= line && section.EndLine >= line {
|
||||||
return section
|
return section
|
||||||
@ -215,7 +190,7 @@ func (p *WireguardParser) GetSectionByLine(line uint32) *WireguardSection {
|
|||||||
|
|
||||||
// Search for a property by name
|
// Search for a property by name
|
||||||
// Returns (line number, property)
|
// Returns (line number, property)
|
||||||
func (p *WireguardParser) FindFirstPropertyByName(name string) (*uint32, *WireguardProperty) {
|
func (p *ast.WGConfig) FindFirstPropertyByName(name string) (*uint32, *ast.WGProperty) {
|
||||||
for _, section := range p.Sections {
|
for _, section := range p.Sections {
|
||||||
for lineNumber, property := range section.Properties {
|
for lineNumber, property := range section.Properties {
|
||||||
if property.Key.Name == name {
|
if property.Key.Name == name {
|
||||||
@ -227,9 +202,9 @@ func (p *WireguardParser) FindFirstPropertyByName(name string) (*uint32, *Wiregu
|
|||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p WireguardParser) GetInterfaceSection() (*WireguardSection, bool) {
|
func (p ast.WGConfig) GetInterfaceSection() (*ast.WGSection, bool) {
|
||||||
for _, section := range p.Sections {
|
for _, section := range p.Sections {
|
||||||
if section.Name != nil && *section.Name == "Interface" {
|
if section.Header != nil && *section.Header == "Interface" {
|
||||||
return section, true
|
return section, true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -237,7 +212,7 @@ func (p WireguardParser) GetInterfaceSection() (*WireguardSection, bool) {
|
|||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p WireguardParser) GetTypeByLine(line uint32) LineType {
|
func (p ast.WGConfig) GetTypeByLine(line uint32) LineType {
|
||||||
// Check if line is a comment
|
// Check if line is a comment
|
||||||
if _, found := p.commentLines[line]; found {
|
if _, found := p.commentLines[line]; found {
|
||||||
return LineTypeComment
|
return LineTypeComment
|
||||||
@ -250,53 +225,8 @@ func (p WireguardParser) GetTypeByLine(line uint32) LineType {
|
|||||||
return LineTypeEmpty
|
return LineTypeEmpty
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the section that the line belongs to
|
func CreateWireguardParser() ast.WGConfig {
|
||||||
// Example:
|
parser := ast.WGConfig{}
|
||||||
// [Interface]
|
|
||||||
// Address = 10.0.0.1
|
|
||||||
//
|
|
||||||
// <line here>
|
|
||||||
// [Peer]
|
|
||||||
//
|
|
||||||
// This would return the section [Interface]
|
|
||||||
func (p *WireguardParser) GetBelongingSectionByLine(line uint32) *WireguardSection {
|
|
||||||
if info, found := p.linesIndexes[line]; found {
|
|
||||||
return info.BelongingSection
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *WireguardParser) GetPropertyByLine(line uint32) (*WireguardSection, *WireguardProperty) {
|
|
||||||
section := p.GetSectionByLine(line)
|
|
||||||
|
|
||||||
if section == nil || section.Name == nil {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
property, _ := section.GetPropertyByLine(line)
|
|
||||||
|
|
||||||
if property == nil {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return section, property
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *WireguardParser) GetSectionsByName(name string) []*WireguardSection {
|
|
||||||
var sections []*WireguardSection
|
|
||||||
|
|
||||||
for _, section := range p.Sections {
|
|
||||||
if section.Name != nil && *section.Name == name {
|
|
||||||
sections = append(sections, section)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return sections
|
|
||||||
}
|
|
||||||
|
|
||||||
func CreateWireguardParser() WireguardParser {
|
|
||||||
parser := WireguardParser{}
|
|
||||||
parser.Clear()
|
parser.Clear()
|
||||||
|
|
||||||
return parser
|
return parser
|
||||||
|
@ -35,7 +35,7 @@ PublicKey = 5555
|
|||||||
t.Fatalf("parseFromString failed to collect comment lines %v", parser.commentLines)
|
t.Fatalf("parseFromString failed to collect comment lines %v", parser.commentLines)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !((len(parser.Sections) == 3) && (*parser.Sections[0].Name == "Interface") && (*parser.Sections[1].Name == "Peer") && (*parser.Sections[2].Name == "Peer")) {
|
if !((len(parser.Sections) == 3) && (*parser.Sections[0].Header == "Interface") && (*parser.Sections[1].Header == "Peer") && (*parser.Sections[2].Header == "Peer")) {
|
||||||
t.Fatalf("parseFromString failed to collect sections %v", parser.Sections)
|
t.Fatalf("parseFromString failed to collect sections %v", parser.Sections)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,7 +93,7 @@ PublicKey = 1234567890
|
|||||||
t.Fatalf("parseFromString failed with error %v", errors)
|
t.Fatalf("parseFromString failed with error %v", errors)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !((len(parser.Sections) == 2) && (*parser.Sections[0].Name == "Interface") && (*parser.Sections[1].Name == "Peer")) {
|
if !((len(parser.Sections) == 2) && (*parser.Sections[0].Header == "Interface") && (*parser.Sections[1].Header == "Peer")) {
|
||||||
t.Fatalf("parseFromString failed to collect sections %v", parser.Sections)
|
t.Fatalf("parseFromString failed to collect sections %v", parser.Sections)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -120,7 +120,7 @@ PrivateKey = 1234567890
|
|||||||
t.Fatalf("parseFromString failed with error %v", errors)
|
t.Fatalf("parseFromString failed with error %v", errors)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !((len(parser.Sections) == 2) && (*parser.Sections[0].Name == "Inteface") && (*parser.Sections[1].Name == "Peer")) {
|
if !((len(parser.Sections) == 2) && (*parser.Sections[0].Header == "Inteface") && (*parser.Sections[1].Header == "Peer")) {
|
||||||
t.Fatalf("parseFromString failed to collect sections %v", parser.Sections)
|
t.Fatalf("parseFromString failed to collect sections %v", parser.Sections)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -168,7 +168,7 @@ PublicKey = 1234567890
|
|||||||
t.Fatalf("parseFromString failed with error %v", errors)
|
t.Fatalf("parseFromString failed with error %v", errors)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !((len(parser.Sections) == 2) && (*parser.Sections[0].Name == "Inte") && (*parser.Sections[1].Name == "Peer")) {
|
if !((len(parser.Sections) == 2) && (*parser.Sections[0].Header == "Inte") && (*parser.Sections[1].Header == "Peer")) {
|
||||||
t.Fatalf("parseFromString failed to collect sections: %v", parser.Sections)
|
t.Fatalf("parseFromString failed to collect sections: %v", parser.Sections)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -202,7 +202,7 @@ PrivateKey = 1234567890
|
|||||||
t.Fatalf("parseFromString failed with error: %v", errors)
|
t.Fatalf("parseFromString failed with error: %v", errors)
|
||||||
}
|
}
|
||||||
|
|
||||||
if !((len(parser.Sections) == 2) && (*parser.Sections[0].Name == "Inte") && (*parser.Sections[1].Name == "Peer")) {
|
if !((len(parser.Sections) == 2) && (*parser.Sections[0].Header == "Inte") && (*parser.Sections[1].Header == "Peer")) {
|
||||||
t.Fatalf("parseFromString failed to collect sections: %v", parser.Sections)
|
t.Fatalf("parseFromString failed to collect sections: %v", parser.Sections)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ package parser
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
docvalues "config-lsp/doc-values"
|
docvalues "config-lsp/doc-values"
|
||||||
|
"config-lsp/handlers/wireguard/ast"
|
||||||
"config-lsp/utils"
|
"config-lsp/utils"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
@ -11,71 +12,8 @@ import (
|
|||||||
|
|
||||||
var linePattern = regexp.MustCompile(`^\s*(?P<key>.+?)\s*(?P<separator>=)\s*(?P<value>\S.*?)?\s*(?:(?:;|#).*)?\s*$`)
|
var linePattern = regexp.MustCompile(`^\s*(?P<key>.+?)\s*(?P<separator>=)\s*(?P<value>\S.*?)?\s*(?:(?:;|#).*)?\s*$`)
|
||||||
|
|
||||||
type WireguardPropertyKey struct {
|
|
||||||
Location CharacterLocation
|
|
||||||
Name string
|
|
||||||
}
|
|
||||||
|
|
||||||
type WireguardPropertyValue struct {
|
|
||||||
Location CharacterLocation
|
|
||||||
Value string
|
|
||||||
}
|
|
||||||
|
|
||||||
type WireguardPropertySeparator struct {
|
|
||||||
Location CharacterLocation
|
|
||||||
}
|
|
||||||
|
|
||||||
type WireguardProperty struct {
|
|
||||||
Key WireguardPropertyKey
|
|
||||||
Separator *WireguardPropertySeparator
|
|
||||||
Value *WireguardPropertyValue
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p WireguardProperty) String() string {
|
|
||||||
if p.Value == nil {
|
|
||||||
return p.Key.Name
|
|
||||||
}
|
|
||||||
|
|
||||||
return p.Key.Name + "=" + p.Value.Value
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p WireguardProperty) GetLineRange(line uint32) protocol.Range {
|
|
||||||
return protocol.Range{
|
|
||||||
Start: protocol.Position{
|
|
||||||
Line: line,
|
|
||||||
Character: p.Key.Location.Start,
|
|
||||||
},
|
|
||||||
End: protocol.Position{
|
|
||||||
Line: line,
|
|
||||||
Character: p.Key.Location.End,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p WireguardProperty) GetInsertRange(line uint32) protocol.Range {
|
|
||||||
var insertPosition uint32 = p.Separator.Location.End
|
|
||||||
var length uint32 = 0
|
|
||||||
|
|
||||||
if p.Value != nil {
|
|
||||||
insertPosition = p.Value.Location.Start - 1
|
|
||||||
// Length of the value; +1 because of the starting space
|
|
||||||
length = (p.Value.Location.End - p.Value.Location.Start) + 1
|
|
||||||
}
|
|
||||||
|
|
||||||
return protocol.Range{
|
|
||||||
Start: protocol.Position{
|
|
||||||
Line: line,
|
|
||||||
Character: insertPosition,
|
|
||||||
},
|
|
||||||
End: protocol.Position{
|
|
||||||
Line: line,
|
|
||||||
Character: insertPosition + length,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// WireguardProperties [<line number>]: <property>
|
// WireguardProperties [<line number>]: <property>
|
||||||
type WireguardProperties map[uint32]WireguardProperty
|
type WireguardProperties map[uint32]ast.WGProperty
|
||||||
|
|
||||||
func (p *WireguardProperties) AddLine(lineNumber uint32, line string) error {
|
func (p *WireguardProperties) AddLine(lineNumber uint32, line string) error {
|
||||||
property, err := CreateWireguardProperty(line)
|
property, err := CreateWireguardProperty(line)
|
||||||
@ -89,7 +27,7 @@ func (p *WireguardProperties) AddLine(lineNumber uint32, line string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func CreateWireguardProperty(line string) (*WireguardProperty, error) {
|
func CreateWireguardProperty(line string) (*ast.WGProperty, error) {
|
||||||
if !strings.Contains(line, "=") {
|
if !strings.Contains(line, "=") {
|
||||||
indexes := utils.GetTrimIndex(line)
|
indexes := utils.GetTrimIndex(line)
|
||||||
|
|
||||||
@ -98,8 +36,8 @@ func CreateWireguardProperty(line string) (*WireguardProperty, error) {
|
|||||||
return nil, &docvalues.MalformedLineError{}
|
return nil, &docvalues.MalformedLineError{}
|
||||||
}
|
}
|
||||||
|
|
||||||
return &WireguardProperty{
|
return &ast.WGProperty{
|
||||||
Key: WireguardPropertyKey{
|
Key: ast.WGPropertyKey{
|
||||||
Name: line[indexes[0]:indexes[1]],
|
Name: line[indexes[0]:indexes[1]],
|
||||||
Location: CharacterLocation{
|
Location: CharacterLocation{
|
||||||
Start: uint32(indexes[0]),
|
Start: uint32(indexes[0]),
|
||||||
@ -117,7 +55,7 @@ func CreateWireguardProperty(line string) (*WireguardProperty, error) {
|
|||||||
|
|
||||||
keyStart := uint32(indexes[2])
|
keyStart := uint32(indexes[2])
|
||||||
keyEnd := uint32(indexes[3])
|
keyEnd := uint32(indexes[3])
|
||||||
key := WireguardPropertyKey{
|
key := ast.WGPropertyKey{
|
||||||
Location: CharacterLocation{
|
Location: CharacterLocation{
|
||||||
Start: keyStart,
|
Start: keyStart,
|
||||||
End: keyEnd,
|
End: keyEnd,
|
||||||
@ -127,21 +65,21 @@ func CreateWireguardProperty(line string) (*WireguardProperty, error) {
|
|||||||
|
|
||||||
separatorStart := uint32(indexes[4])
|
separatorStart := uint32(indexes[4])
|
||||||
separatorEnd := uint32(indexes[5])
|
separatorEnd := uint32(indexes[5])
|
||||||
separator := WireguardPropertySeparator{
|
separator := ast.WGPropertySeparator{
|
||||||
Location: CharacterLocation{
|
Location: CharacterLocation{
|
||||||
Start: separatorStart,
|
Start: separatorStart,
|
||||||
End: separatorEnd,
|
End: separatorEnd,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var value *WireguardPropertyValue
|
var value *ast.WGPropertyValue
|
||||||
|
|
||||||
if indexes[6] != -1 && indexes[7] != -1 {
|
if indexes[6] != -1 && indexes[7] != -1 {
|
||||||
// value exists
|
// value exists
|
||||||
valueStart := uint32(indexes[6])
|
valueStart := uint32(indexes[6])
|
||||||
valueEnd := uint32(indexes[7])
|
valueEnd := uint32(indexes[7])
|
||||||
|
|
||||||
value = &WireguardPropertyValue{
|
value = &ast.WGPropertyValue{
|
||||||
Location: CharacterLocation{
|
Location: CharacterLocation{
|
||||||
Start: valueStart,
|
Start: valueStart,
|
||||||
End: valueEnd,
|
End: valueEnd,
|
||||||
@ -150,7 +88,7 @@ func CreateWireguardProperty(line string) (*WireguardProperty, error) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return &WireguardProperty{
|
return &ast.WGProperty{
|
||||||
Key: key,
|
Key: key,
|
||||||
Separator: &separator,
|
Separator: &separator,
|
||||||
Value: value,
|
Value: value,
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
package parser
|
package parser
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"config-lsp/handlers/wireguard/ast"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
|
||||||
protocol "github.com/tliron/glsp/protocol_3_16"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type PropertyNotFoundError struct{}
|
type PropertyNotFoundError struct{}
|
||||||
@ -19,52 +17,7 @@ func (e PropertyNotFullyTypedError) Error() string {
|
|||||||
return "Property not fully typed"
|
return "Property not fully typed"
|
||||||
}
|
}
|
||||||
|
|
||||||
type WireguardSection struct {
|
func (s ast.WGSection) FetchFirstProperty(name string) (*uint32, *ast.WGProperty) {
|
||||||
Name *string
|
|
||||||
StartLine uint32
|
|
||||||
EndLine uint32
|
|
||||||
Properties WireguardProperties
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s WireguardSection) String() string {
|
|
||||||
var name string
|
|
||||||
|
|
||||||
if s.Name == nil {
|
|
||||||
name = "<nil>"
|
|
||||||
} else {
|
|
||||||
name = *s.Name
|
|
||||||
}
|
|
||||||
|
|
||||||
return fmt.Sprintf("[%s]; %d-%d: %v", name, s.StartLine, s.EndLine, s.Properties)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s WireguardSection) GetHeaderLineRange() protocol.Range {
|
|
||||||
return protocol.Range{
|
|
||||||
Start: protocol.Position{
|
|
||||||
Line: s.StartLine,
|
|
||||||
Character: 0,
|
|
||||||
},
|
|
||||||
End: protocol.Position{
|
|
||||||
Line: s.StartLine,
|
|
||||||
Character: 99999999,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s WireguardSection) GetRange() protocol.Range {
|
|
||||||
return protocol.Range{
|
|
||||||
Start: protocol.Position{
|
|
||||||
Line: s.StartLine,
|
|
||||||
Character: 0,
|
|
||||||
},
|
|
||||||
End: protocol.Position{
|
|
||||||
Line: s.EndLine,
|
|
||||||
Character: 99999999,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s WireguardSection) FetchFirstProperty(name string) (*uint32, *WireguardProperty) {
|
|
||||||
for line, property := range s.Properties {
|
for line, property := range s.Properties {
|
||||||
if property.Key.Name == name {
|
if property.Key.Name == name {
|
||||||
return &line, &property
|
return &line, &property
|
||||||
@ -74,13 +27,13 @@ func (s WireguardSection) FetchFirstProperty(name string) (*uint32, *WireguardPr
|
|||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s WireguardSection) ExistsProperty(name string) bool {
|
func (s ast.WGSection) ExistsProperty(name string) bool {
|
||||||
_, property := s.FetchFirstProperty(name)
|
_, property := s.FetchFirstProperty(name)
|
||||||
|
|
||||||
return property != nil
|
return property != nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s WireguardSection) GetPropertyByLine(lineNumber uint32) (*WireguardProperty, error) {
|
func (s ast.WGSection) GetPropertyByLine(lineNumber uint32) (*ast.WGProperty, error) {
|
||||||
property, found := s.Properties[lineNumber]
|
property, found := s.Properties[lineNumber]
|
||||||
|
|
||||||
if !found {
|
if !found {
|
||||||
@ -99,7 +52,7 @@ func CreateWireguardSection(
|
|||||||
endLine uint32,
|
endLine uint32,
|
||||||
headerLine string,
|
headerLine string,
|
||||||
props WireguardProperties,
|
props WireguardProperties,
|
||||||
) WireguardSection {
|
) ast.WGSection {
|
||||||
match := validHeaderPattern.FindStringSubmatch(headerLine)
|
match := validHeaderPattern.FindStringSubmatch(headerLine)
|
||||||
|
|
||||||
var header string
|
var header string
|
||||||
@ -111,8 +64,8 @@ func CreateWireguardSection(
|
|||||||
header = match[1]
|
header = match[1]
|
||||||
}
|
}
|
||||||
|
|
||||||
return WireguardSection{
|
return ast.WGSection{
|
||||||
Name: &header,
|
Header: &header,
|
||||||
StartLine: startLine,
|
StartLine: startLine,
|
||||||
EndLine: endLine,
|
EndLine: endLine,
|
||||||
Properties: props,
|
Properties: props,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user