diff --git a/pkg/generic/pbidl_provider.go b/pkg/generic/pbidl_provider.go index f7d01f0c3b..d115c51054 100644 --- a/pkg/generic/pbidl_provider.go +++ b/pkg/generic/pbidl_provider.go @@ -123,6 +123,41 @@ func NewPbFileProviderWithDynamicGo(main string, ctx context.Context, options dp return p, nil } +// NewPbContentProviderWithDynamicGo creates PbFileProviderWithDynamicGo from memory. +// NOTICE: mainPath is used to store mainContent in includes, thus it MUST NOT conflict with original includes +func NewPbContentProviderWithDynamicGo(ctx context.Context, options dproto.Options, mainPath, mainContent string, includes map[string]string) (PbDescriptorProviderDynamicGo, error) { + p := &PbFileProviderWithDynamicGo{ + svcs: make(chan *dproto.ServiceDescriptor, 1), + } + + sd, err := options.NewDesccriptorFromContent(ctx, mainPath, mainContent, includes) + if err != nil { + return nil, err + } + p.svcs <- sd + + return p, nil +} + +func (p *PbFileProviderWithDynamicGo) UpdateIDL(ctx context.Context, options dproto.Options, mainPath, mainContent string, includes map[string]string) error { + sd, err := options.NewDesccriptorFromContent(ctx, mainPath, mainContent, includes) + if err != nil { + return err + } + + select { + case <-p.svcs: + default: + } + + select { + case p.svcs <- sd: + default: + } + + return nil +} + func (p *PbFileProviderWithDynamicGo) Provide() <-chan *dproto.ServiceDescriptor { return p.svcs } diff --git a/pkg/generic/pbidl_provider_test.go b/pkg/generic/pbidl_provider_test.go index 0d9019ce97..dbd395c566 100644 --- a/pkg/generic/pbidl_provider_test.go +++ b/pkg/generic/pbidl_provider_test.go @@ -18,6 +18,7 @@ package generic import ( "context" + "os" "testing" dproto "github.com/cloudwego/dynamicgo/proto" @@ -72,3 +73,27 @@ func TestPbFileProviderWithDynamicGo(t *testing.T) { svcDsc := <-p.Provide() test.Assert(t, svcDsc != nil) } + +func TestPbContentProviderWithDynamicGo(t *testing.T) { + mainbs, _ := os.ReadFile("./jsonpb_test/idl/echo_import.proto") + main := string(mainbs) + incbs, _ := os.ReadFile("./jsonpb_test/idl/echo.proto") + includes := map[string]string{ + "echo.proto": string(incbs), + } + opts := dproto.Options{} + p, err := NewPbContentProviderWithDynamicGo(context.Background(), opts, "main.proto", main, includes) + + test.Assert(t, err == nil) + + svcDsc := <-p.Provide() + test.Assert(t, svcDsc != nil) + test.Assert(t, svcDsc.Name() == "EchoService") + test.Assert(t, svcDsc.LookupMethodByName("Echo") != nil) + + p.(*PbFileProviderWithDynamicGo).UpdateIDL(context.Background(), opts, "main.proto", main, includes) + svcDsc1 := <-p.Provide() + test.Assert(t, svcDsc1 != nil) + test.Assert(t, svcDsc1.Name() == "EchoService") + test.Assert(t, svcDsc1.LookupMethodByName("Echo") != nil) +}