Files
meowrain 3284ce07c7 feat: enhance API and session management with Nacos and Redis integration
- Add Nacos registry for service registration and deregistration.
- Implement Redis registry for session management with heartbeat and session claiming.
- Improve completion service with session handling and request validation.
- Enhance WebSocket handling for completion requests with JSON-RPC support.
- Add tests for new registry implementations and completion manager functionalities.
- Refactor existing code for better readability and maintainability.
2026-02-15 17:46:34 +08:00

105 lines
2.8 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package completion
import (
"context"
"errors"
"fmt"
"sync"
)
var ErrInvalidRequest = errors.New("invalid completion request")
// Request 是统一的补全请求模型。
type Request struct {
Language string `json:"language,omitempty"`
SessionID string `json:"sessionId,omitempty"`
URI string `json:"uri"`
Text string `json:"text"`
Line int `json:"line"`
Character int `json:"character"`
}
// Item 对应一个补全候选项。
type Item struct {
Label string `json:"label"`
Kind int `json:"kind,omitempty"`
Detail string `json:"detail,omitempty"`
Documentation string `json:"documentation,omitempty"`
InsertText string `json:"insertText,omitempty"`
SortText string `json:"sortText,omitempty"`
FilterText string `json:"filterText,omitempty"`
}
// Response 是补全结果集合。
type Response struct {
Items []Item `json:"items"`
IsIncomplete bool `json:"isIncomplete"`
}
// Client 抽象 LSP 客户端所需的最小能力。
type Client interface {
DidOpen(ctx context.Context, uri, text string, version int) error
DidChange(ctx context.Context, uri, text string, version int) error
Completion(ctx context.Context, uri string, line, character int) (Response, error)
}
type documentState struct {
version int
}
// Service 负责文档生命周期同步didOpen/didChange与补全调用。
type Service struct {
client Client
mu sync.Mutex
documents map[string]*documentState
}
func NewService(client Client) *Service {
return &Service{
client: client,
documents: make(map[string]*documentState),
}
}
// Complete 根据 URI 的历史状态决定发送 didOpen 或 didChange再请求补全。
func (s *Service) Complete(ctx context.Context, req Request) (Response, error) {
if err := validateRequest(req); err != nil {
return Response{}, err
}
s.mu.Lock()
defer s.mu.Unlock()
state, opened := s.documents[req.URI]
if !opened {
if err := s.client.DidOpen(ctx, req.URI, req.Text, 1); err != nil {
return Response{}, fmt.Errorf("didOpen failed: %w", err)
}
s.documents[req.URI] = &documentState{version: 1}
} else {
nextVersion := state.version + 1
if err := s.client.DidChange(ctx, req.URI, req.Text, nextVersion); err != nil {
return Response{}, fmt.Errorf("didChange failed: %w", err)
}
state.version = nextVersion
}
resp, err := s.client.Completion(ctx, req.URI, req.Line, req.Character)
if err != nil {
return Response{}, fmt.Errorf("completion failed: %w", err)
}
return resp, nil
}
// validateRequest 做基础参数校验,避免向 LSP 发送非法请求。
func validateRequest(req Request) error {
if req.URI == "" {
return ErrInvalidRequest
}
if req.Line < 0 || req.Character < 0 {
return ErrInvalidRequest
}
return nil
}