Skip to content

Commit

Permalink
add ability to configure custom protobuf definitions path
Browse files Browse the repository at this point in the history
  • Loading branch information
BrotifyPacha committed Jul 12, 2024
1 parent d589143 commit f0ae0b5
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 1 deletion.
56 changes: 56 additions & 0 deletions proto/view/settings.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package view

import (
"errors"
"fmt"
)

const (
additionalProtoDirsKey = "additional-proto-dirs"
)

type Settings struct {
AdditionalProtoDirs []string
}

var (
ErrRepackingSettings = errors.New("failed repacking settings")
)

func SettingsFromInterface(in interface{}) (*Settings, error) {
settingsMap, ok := in.(map[string]interface{})
if !ok {
return nil, fmt.Errorf("%w: settings should have a map[string]interface{} type", ErrRepackingSettings)
}

var settings Settings

if value, ok := settingsMap[additionalProtoDirsKey]; ok {
protoDirs, err := StringsSliceFromInterface(value)
if err != nil {
return nil, fmt.Errorf("%w: %s: key = %s", ErrRepackingSettings, err.Error(), additionalProtoDirsKey)
}
settings.AdditionalProtoDirs = protoDirs
}

return &settings, nil
}

func StringsSliceFromInterface(in interface{}) ([]string, error) {
interfaceSlice, ok := in.([]interface{})
if !ok {
return nil, errors.New("field should have a []interface{} type")
}

var result []string

for i, item := range interfaceSlice {
str, ok := item.(string)
if !ok {
return nil, fmt.Errorf("item [%d] should have a string type", i)
}
result = append(result, str)
}

return result, nil
}
15 changes: 15 additions & 0 deletions proto/view/view.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ type view struct {

pbHeaders map[defines.DocumentUri][]string
Server *lsp.Server
settings Settings
fs fs.FS
}

Expand Down Expand Up @@ -294,6 +295,12 @@ func (v *view) GetDocumentUriFromImportPath(cwd defines.DocumentUri, import_name
if v.fs.FileExists(abs_name) {
return defines.DocumentUri(uri.New(path.Clean(abs_name))), nil
}
for _, additionalProtoDir := range v.settings.AdditionalProtoDirs {
abs_name := path.Join(pos, additionalProtoDir, import_name)
if v.fs.FileExists(abs_name) {
return defines.DocumentUri(uri.New(path.Clean(abs_name))), nil
}
}
pos = path.Join(pos, "..")
}
return res, fmt.Errorf("%w: import %s", ErrNotFound, import_name)
Expand Down Expand Up @@ -371,6 +378,14 @@ func onInitialized(ctx context.Context, req *defines.InitializeParams) (err erro
}

func onDidChangeConfiguration(ctx context.Context, req *defines.DidChangeConfigurationParams) (err error) {
if ViewManager == nil {
return nil
}
settings, err := SettingsFromInterface(req.Settings)
if err != nil {
return err
}
ViewManager.settings = *settings
return nil
}

Expand Down
18 changes: 17 additions & 1 deletion proto/view/view_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ func Test_view_GetDocumentUriFromImportPath(t *testing.T) {
tests := []struct {
name string
existingFiles []string
settings Settings
cwd defines.DocumentUri
import_name string
want defines.DocumentUri
Expand Down Expand Up @@ -43,12 +44,27 @@ func Test_view_GetDocumentUriFromImportPath(t *testing.T) {
want: defines.DocumentUri(""),
wantErr: ErrNotFound,
},
{
name: "all sub-directories set via settings.additional-proto-dirs are searched for proto definitions",
existingFiles: []string{
"/project-dir/api/my-service.proto",
"/project-dir/protobuf-dependencies/google/protobuf/empty.proto",
},
settings: Settings{
AdditionalProtoDirs: []string{"protobuf-dependencies"},
},
cwd: defines.DocumentUri("file:///project-dir/api/my-service.proto"),
import_name: "google/protobuf/empty.proto",

want: defines.DocumentUri("file:///project-dir/protobuf-dependencies/google/protobuf/empty.proto"),
wantErr: nil,
},
}
for i, tt := range tests {
t.Run(fmt.Sprint(i), func(t *testing.T) {
mockFS := &MockFS{ExistingFiles: tt.existingFiles}

v := &view{fs: mockFS}
v := &view{fs: mockFS, settings: tt.settings}

got, err := v.GetDocumentUriFromImportPath(tt.cwd, tt.import_name)
require.ErrorIs(t, err, tt.wantErr)
Expand Down

0 comments on commit f0ae0b5

Please sign in to comment.