diff --git a/go.mod b/go.mod index 816015e568..cef81f69e7 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/bytedance/gopkg v0.1.1 github.com/bytedance/sonic v1.12.7 github.com/cloudwego/configmanager v0.2.2 - github.com/cloudwego/dynamicgo v0.5.0 + github.com/cloudwego/dynamicgo v0.5.1-0.20250115031329-d58b94fc7d71 github.com/cloudwego/fastpb v0.0.5 github.com/cloudwego/frugal v0.2.3 github.com/cloudwego/gopkg v0.1.4-0.20241217093255-8980b14172b7 diff --git a/go.sum b/go.sum index 1285dd6672..7c0756ee0b 100644 --- a/go.sum +++ b/go.sum @@ -15,8 +15,8 @@ github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/ github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= github.com/cloudwego/configmanager v0.2.2 h1:sVrJB8gWYTlPV2OS3wcgJSO9F2/9Zbkmcm1Z7jempOU= github.com/cloudwego/configmanager v0.2.2/go.mod h1:ppiyU+5TPLonE8qMVi/pFQk2eL3Q4P7d4hbiNJn6jwI= -github.com/cloudwego/dynamicgo v0.5.0 h1:wcmeZIRC6iW/36sId16ktIFvgnyKER9VzhjEsNhw2GU= -github.com/cloudwego/dynamicgo v0.5.0/go.mod h1:DknfxjIMuGvXow409bS/AWycXONdc02HECBL0qpNqTY= +github.com/cloudwego/dynamicgo v0.5.1-0.20250115031329-d58b94fc7d71 h1:J57+W8YYGJy0MCLk/yzuLehiQmKpOoQng+OBF/5204o= +github.com/cloudwego/dynamicgo v0.5.1-0.20250115031329-d58b94fc7d71/go.mod h1:DknfxjIMuGvXow409bS/AWycXONdc02HECBL0qpNqTY= github.com/cloudwego/fastpb v0.0.5 h1:vYnBPsfbAtU5TVz5+f9UTlmSCixG9F9vRwaqE0mZPZU= github.com/cloudwego/fastpb v0.0.5/go.mod h1:Bho7aAKBUtT9RPD2cNVkTdx4yQumfSv3If7wYnm1izk= github.com/cloudwego/frugal v0.2.3 h1:t1hhhAi8lXcx7Ncs4PR1pSZ90vlDU1cy5K2btDMFpoA= diff --git a/pkg/generic/thrift/parse.go b/pkg/generic/thrift/parse.go index 989ddb7a28..b77e23e366 100644 --- a/pkg/generic/thrift/parse.go +++ b/pkg/generic/thrift/parse.go @@ -77,22 +77,33 @@ func Parse(tree *parser.Thrift, mode ParseMode, opts ...ParseOption) (*descripto Router: descriptor.NewRouter(), } + pOpts := &parseOptions{} + pOpts.apply(opts) + // support one service svcs := tree.Services - switch mode { - case LastServiceOnly: - svcs = svcs[len(svcs)-1:] - sDsc.Name = svcs[len(svcs)-1].Name - case FirstServiceOnly: - svcs = svcs[:1] - sDsc.Name = svcs[0].Name - case CombineServices: - sDsc.Name = "CombinedServices" - sDsc.IsCombinedServices = true - } - pOpts := &parseOptions{} - pOpts.apply(opts) + // if an idl service name is specified, it takes precedence over parse mode + if pOpts.serviceName != "" { + var err error + svcs, err = getTargetService(svcs, pOpts.serviceName) + if err != nil { + return nil, err + } + sDsc.Name = pOpts.serviceName + } else { + switch mode { + case LastServiceOnly: + svcs = svcs[len(svcs)-1:] + sDsc.Name = svcs[len(svcs)-1].Name + case FirstServiceOnly: + svcs = svcs[:1] + sDsc.Name = svcs[0].Name + case CombineServices: + sDsc.Name = "CombinedServices" + sDsc.IsCombinedServices = true + } + } visitedSvcs := make(map[*parser.Service]bool, len(tree.Services)) for _, svc := range svcs { @@ -109,6 +120,15 @@ func Parse(tree *parser.Thrift, mode ParseMode, opts ...ParseOption) (*descripto return sDsc, nil } +func getTargetService(svcs []*parser.Service, serviceName string) ([]*parser.Service, error) { + for _, svc := range svcs { + if svc.Name == serviceName { + return []*parser.Service{svc}, nil + } + } + return nil, fmt.Errorf("the idl service name %s is not in the idl. Please check your idl", serviceName) +} + type pair struct { tree *parser.Thrift data interface{} diff --git a/pkg/generic/thrift/parse_option.go b/pkg/generic/thrift/parse_option.go index f29ff62030..9fffd321a2 100644 --- a/pkg/generic/thrift/parse_option.go +++ b/pkg/generic/thrift/parse_option.go @@ -19,7 +19,8 @@ package thrift import "github.com/cloudwego/kitex/pkg/generic/descriptor" type parseOptions struct { - goTag *descriptor.GoTagOption + goTag *descriptor.GoTagOption + serviceName string } type ParseOption struct { @@ -39,3 +40,11 @@ func WithGoTagDisabled(disable bool) ParseOption { } }} } + +// WithIDLServiceName specifies the target IDL service to be parsed. +// NOTE: with this option, the specified service is prioritized and parse mode will be ignored. +func WithIDLServiceName(serviceName string) ParseOption { + return ParseOption{F: func(opt *parseOptions) { + opt.serviceName = serviceName + }} +} diff --git a/pkg/generic/thrift/parse_test.go b/pkg/generic/thrift/parse_test.go index 30a1088f5e..b9fe9a6192 100644 --- a/pkg/generic/thrift/parse_test.go +++ b/pkg/generic/thrift/parse_test.go @@ -510,3 +510,18 @@ func defaultValueDeepEqual(t *testing.T, defaultValue func(name string) interfac "a": int32(56), })) } + +func TestParseWithIDLServiceName(t *testing.T) { + demo, err := parser.ParseString("demo.thrift", demoIDL) + test.Assert(t, err == nil) + + base, err := parser.ParseString("base.thrift", baseIDL) + test.Assert(t, err == nil) + + demo.Includes[0].Reference = base + + sDsc, err := Parse(demo, LastServiceOnly, WithIDLServiceName("DemoBaseService")) + test.Assert(t, err == nil) + // priority: service name specification > parse mode + test.Assert(t, sDsc.Name == "DemoBaseService") +} diff --git a/pkg/generic/thriftidl_provider.go b/pkg/generic/thriftidl_provider.go index 9a74b8761e..fc89e333ba 100644 --- a/pkg/generic/thriftidl_provider.go +++ b/pkg/generic/thriftidl_provider.go @@ -58,7 +58,7 @@ func NewThriftFileProviderWithOption(path string, opts []ThriftIDLProviderOption } tOpts := &thriftIDLProviderOptions{} tOpts.apply(opts) - svc, err := newServiceDescriptorFromPath(path, getParseMode(tOpts), tOpts.goTag, includeDirs...) + svc, err := newServiceDescriptorFromPath(path, getParseMode(tOpts), tOpts.goTag, tOpts.serviceName, includeDirs...) if err != nil { return nil, err } @@ -79,7 +79,7 @@ func NewThriftFileProviderWithDynamicgoWithOption(path string, opts []ThriftIDLP tOpts := &thriftIDLProviderOptions{} tOpts.apply(opts) parseMode := getParseMode(tOpts) - svc, err := newServiceDescriptorFromPath(path, parseMode, tOpts.goTag, includeDirs...) + svc, err := newServiceDescriptorFromPath(path, parseMode, tOpts.goTag, tOpts.serviceName, includeDirs...) if err != nil { return nil, err } @@ -90,7 +90,7 @@ func NewThriftFileProviderWithDynamicgoWithOption(path string, opts []ThriftIDLP return nil, err } handleGoTagForDynamicGo(tOpts.goTag) - dOpts := dthrift.Options{EnableThriftBase: true, ParseServiceMode: dParseMode, UseDefaultValue: true, SetOptionalBitmap: true} + dOpts := dthrift.Options{EnableThriftBase: true, ParseServiceMode: dParseMode, UseDefaultValue: true, SetOptionalBitmap: true, ServiceName: tOpts.serviceName} dsvc, err := dOpts.NewDescritorFromPath(context.Background(), path, includeDirs...) if err != nil { // fall back to the original way (without dynamicgo) @@ -105,7 +105,7 @@ func NewThriftFileProviderWithDynamicgoWithOption(path string, opts []ThriftIDLP return p, nil } -func newServiceDescriptorFromPath(path string, parseMode thrift.ParseMode, goTagOpt *goTagOption, includeDirs ...string) (*descriptor.ServiceDescriptor, error) { +func newServiceDescriptorFromPath(path string, parseMode thrift.ParseMode, goTagOpt *goTagOption, serviceName string, includeDirs ...string) (*descriptor.ServiceDescriptor, error) { tree, err := parser.ParseFile(path, includeDirs, true) if err != nil { return nil, err @@ -114,6 +114,9 @@ func newServiceDescriptorFromPath(path string, parseMode thrift.ParseMode, goTag if goTagOpt != nil { parseOpts = append(parseOpts, thrift.WithGoTagDisabled(goTagOpt.isGoTagAliasDisabled)) } + if serviceName != "" { + parseOpts = append(parseOpts, thrift.WithIDLServiceName(serviceName)) + } svc, err := thrift.Parse(tree, parseMode, parseOpts...) if err != nil { return nil, err @@ -143,11 +146,12 @@ func (p *thriftFileProvider) Option() ProviderOption { // ThriftContentProvider provide descriptor from contents type ThriftContentProvider struct { - closeOnce sync.Once - svcs chan *descriptor.ServiceDescriptor - opts *ProviderOption - parseMode thrift.ParseMode - goTagOpt *goTagOption + closeOnce sync.Once + svcs chan *descriptor.ServiceDescriptor + opts *ProviderOption + parseMode thrift.ParseMode + goTagOpt *goTagOption + serviceName string } var _ DescriptorProvider = (*ThriftContentProvider)(nil) @@ -161,12 +165,13 @@ func NewThriftContentProvider(main string, includes map[string]string, opts ...T parseMode := getParseMode(tOpts) p := &ThriftContentProvider{ - svcs: make(chan *descriptor.ServiceDescriptor, 1), // unblock with buffered channel - opts: &ProviderOption{DynamicGoEnabled: false}, - parseMode: parseMode, - goTagOpt: tOpts.goTag, + svcs: make(chan *descriptor.ServiceDescriptor, 1), // unblock with buffered channel + opts: &ProviderOption{DynamicGoEnabled: false}, + parseMode: parseMode, + goTagOpt: tOpts.goTag, + serviceName: tOpts.serviceName, } - svc, err := newServiceDescriptorFromContent(defaultMainIDLPath, main, includes, false, parseMode, tOpts.goTag) + svc, err := newServiceDescriptorFromContent(defaultMainIDLPath, main, includes, false, parseMode, tOpts.goTag, tOpts.serviceName) if err != nil { return nil, err } @@ -182,18 +187,19 @@ func NewThriftContentProviderWithDynamicGo(main string, includes map[string]stri parseMode := getParseMode(tOpts) p := &ThriftContentProvider{ - svcs: make(chan *descriptor.ServiceDescriptor, 1), // unblock with buffered channel - opts: &ProviderOption{DynamicGoEnabled: true}, - parseMode: parseMode, - goTagOpt: tOpts.goTag, + svcs: make(chan *descriptor.ServiceDescriptor, 1), // unblock with buffered channel + opts: &ProviderOption{DynamicGoEnabled: true}, + parseMode: parseMode, + goTagOpt: tOpts.goTag, + serviceName: tOpts.serviceName, } - svc, err := newServiceDescriptorFromContent(defaultMainIDLPath, main, includes, false, parseMode, tOpts.goTag) + svc, err := newServiceDescriptorFromContent(defaultMainIDLPath, main, includes, false, parseMode, tOpts.goTag, tOpts.serviceName) if err != nil { return nil, err } - p.newDynamicGoDsc(svc, defaultMainIDLPath, main, includes, parseMode, tOpts.goTag) + p.newDynamicGoDsc(svc, defaultMainIDLPath, main, includes, parseMode, tOpts.goTag, tOpts.serviceName) p.svcs <- svc return p, nil @@ -210,13 +216,16 @@ func (p *ThriftContentProvider) UpdateIDL(main string, includes map[string]strin if p.goTagOpt != nil { parseOpts = append(parseOpts, thrift.WithGoTagDisabled(p.goTagOpt.isGoTagAliasDisabled)) } + if p.serviceName != "" { + parseOpts = append(parseOpts, thrift.WithIDLServiceName(p.serviceName)) + } svc, err = thrift.Parse(tree, p.parseMode, parseOpts...) if err != nil { return err } if p.opts.DynamicGoEnabled { - p.newDynamicGoDsc(svc, defaultMainIDLPath, main, includes, p.parseMode, p.goTagOpt) + p.newDynamicGoDsc(svc, defaultMainIDLPath, main, includes, p.parseMode, p.goTagOpt, p.serviceName) } select { @@ -248,8 +257,8 @@ func (p *ThriftContentProvider) Option() ProviderOption { return *p.opts } -func (p *ThriftContentProvider) newDynamicGoDsc(svc *descriptor.ServiceDescriptor, path, content string, includes map[string]string, parseMode thrift.ParseMode, goTag *goTagOption) { - if err := newDynamicGoDscFromContent(svc, path, content, includes, false, parseMode, goTag); err != nil { +func (p *ThriftContentProvider) newDynamicGoDsc(svc *descriptor.ServiceDescriptor, path, content string, includes map[string]string, parseMode thrift.ParseMode, goTag *goTagOption, serviceName string) { + if err := newDynamicGoDscFromContent(svc, path, content, includes, false, parseMode, goTag, serviceName); err != nil { p.opts.DynamicGoEnabled = false } } @@ -313,11 +322,12 @@ func ParseContent(path, content string, includes map[string]string, isAbsInclude // ThriftContentWithAbsIncludePathProvider ... type ThriftContentWithAbsIncludePathProvider struct { - closeOnce sync.Once - svcs chan *descriptor.ServiceDescriptor - opts *ProviderOption - parseMode thrift.ParseMode - goTagOpt *goTagOption + closeOnce sync.Once + svcs chan *descriptor.ServiceDescriptor + opts *ProviderOption + parseMode thrift.ParseMode + goTagOpt *goTagOption + serviceName string } var _ DescriptorProvider = (*ThriftContentWithAbsIncludePathProvider)(nil) @@ -329,17 +339,18 @@ func NewThriftContentWithAbsIncludePathProvider(mainIDLPath string, includes map parseMode := getParseMode(tOpts) p := &ThriftContentWithAbsIncludePathProvider{ - svcs: make(chan *descriptor.ServiceDescriptor, 1), // unblock with buffered channel - opts: &ProviderOption{DynamicGoEnabled: false}, - parseMode: parseMode, - goTagOpt: tOpts.goTag, + svcs: make(chan *descriptor.ServiceDescriptor, 1), // unblock with buffered channel + opts: &ProviderOption{DynamicGoEnabled: false}, + parseMode: parseMode, + goTagOpt: tOpts.goTag, + serviceName: tOpts.serviceName, } mainIDLContent, ok := includes[mainIDLPath] if !ok { return nil, fmt.Errorf("miss main IDL content for main IDL path: %s", mainIDLPath) } - svc, err := newServiceDescriptorFromContent(mainIDLPath, mainIDLContent, includes, true, parseMode, tOpts.goTag) + svc, err := newServiceDescriptorFromContent(mainIDLPath, mainIDLContent, includes, true, parseMode, tOpts.goTag, tOpts.serviceName) if err != nil { return nil, err } @@ -355,22 +366,23 @@ func NewThriftContentWithAbsIncludePathProviderWithDynamicGo(mainIDLPath string, parseMode := getParseMode(tOpts) p := &ThriftContentWithAbsIncludePathProvider{ - svcs: make(chan *descriptor.ServiceDescriptor, 1), // unblock with buffered channel - opts: &ProviderOption{DynamicGoEnabled: true}, - parseMode: parseMode, - goTagOpt: tOpts.goTag, + svcs: make(chan *descriptor.ServiceDescriptor, 1), // unblock with buffered channel + opts: &ProviderOption{DynamicGoEnabled: true}, + parseMode: parseMode, + goTagOpt: tOpts.goTag, + serviceName: tOpts.serviceName, } mainIDLContent, ok := includes[mainIDLPath] if !ok { return nil, fmt.Errorf("miss main IDL content for main IDL path: %s", mainIDLPath) } - svc, err := newServiceDescriptorFromContent(mainIDLPath, mainIDLContent, includes, true, parseMode, tOpts.goTag) + svc, err := newServiceDescriptorFromContent(mainIDLPath, mainIDLContent, includes, true, parseMode, tOpts.goTag, tOpts.serviceName) if err != nil { return nil, err } - p.newDynamicGoDsc(svc, mainIDLPath, mainIDLContent, includes, parseMode, tOpts.goTag) + p.newDynamicGoDsc(svc, mainIDLPath, mainIDLContent, includes, parseMode, tOpts.goTag, tOpts.serviceName) p.svcs <- svc return p, nil @@ -391,13 +403,16 @@ func (p *ThriftContentWithAbsIncludePathProvider) UpdateIDL(mainIDLPath string, if p.goTagOpt != nil { parseOpts = append(parseOpts, thrift.WithGoTagDisabled(p.goTagOpt.isGoTagAliasDisabled)) } + if p.serviceName != "" { + parseOpts = append(parseOpts, thrift.WithIDLServiceName(p.serviceName)) + } svc, err = thrift.Parse(tree, p.parseMode, parseOpts...) if err != nil { return err } if p.opts.DynamicGoEnabled { - p.newDynamicGoDsc(svc, mainIDLPath, mainIDLContent, includes, p.parseMode, p.goTagOpt) + p.newDynamicGoDsc(svc, mainIDLPath, mainIDLContent, includes, p.parseMode, p.goTagOpt, p.serviceName) } // drain the channel @@ -430,8 +445,8 @@ func (p *ThriftContentWithAbsIncludePathProvider) Option() ProviderOption { return *p.opts } -func (p *ThriftContentWithAbsIncludePathProvider) newDynamicGoDsc(svc *descriptor.ServiceDescriptor, path, content string, includes map[string]string, parseMode thrift.ParseMode, goTag *goTagOption) { - if err := newDynamicGoDscFromContent(svc, path, content, includes, true, parseMode, goTag); err != nil { +func (p *ThriftContentWithAbsIncludePathProvider) newDynamicGoDsc(svc *descriptor.ServiceDescriptor, path, content string, includes map[string]string, parseMode thrift.ParseMode, goTag *goTagOption, serviceName string) { + if err := newDynamicGoDscFromContent(svc, path, content, includes, true, parseMode, goTag, serviceName); err != nil { p.opts.DynamicGoEnabled = false } } @@ -457,7 +472,7 @@ func getDynamicGoParseMode(parseMode thrift.ParseMode) (meta.ParseServiceMode, e } } -func newServiceDescriptorFromContent(path, content string, includes map[string]string, isAbsIncludePath bool, parseMode thrift.ParseMode, goTagOpt *goTagOption) (*descriptor.ServiceDescriptor, error) { +func newServiceDescriptorFromContent(path, content string, includes map[string]string, isAbsIncludePath bool, parseMode thrift.ParseMode, goTagOpt *goTagOption, serviceName string) (*descriptor.ServiceDescriptor, error) { tree, err := ParseContent(path, content, includes, isAbsIncludePath) if err != nil { return nil, err @@ -466,6 +481,9 @@ func newServiceDescriptorFromContent(path, content string, includes map[string]s if goTagOpt != nil { parseOpts = append(parseOpts, thrift.WithGoTagDisabled(goTagOpt.isGoTagAliasDisabled)) } + if serviceName != "" { + parseOpts = append(parseOpts, thrift.WithIDLServiceName(serviceName)) + } svc, err := thrift.Parse(tree, parseMode, parseOpts...) if err != nil { return nil, err @@ -473,14 +491,14 @@ func newServiceDescriptorFromContent(path, content string, includes map[string]s return svc, nil } -func newDynamicGoDscFromContent(svc *descriptor.ServiceDescriptor, path, content string, includes map[string]string, isAbsIncludePath bool, parseMode thrift.ParseMode, goTag *goTagOption) error { +func newDynamicGoDscFromContent(svc *descriptor.ServiceDescriptor, path, content string, includes map[string]string, isAbsIncludePath bool, parseMode thrift.ParseMode, goTag *goTagOption, serviceName string) error { handleGoTagForDynamicGo(goTag) // ServiceDescriptor of dynamicgo dParseMode, err := getDynamicGoParseMode(parseMode) if err != nil { return err } - dOpts := dthrift.Options{EnableThriftBase: true, ParseServiceMode: dParseMode, UseDefaultValue: true, SetOptionalBitmap: true} + dOpts := dthrift.Options{EnableThriftBase: true, ParseServiceMode: dParseMode, UseDefaultValue: true, SetOptionalBitmap: true, ServiceName: serviceName} dsvc, err := dOpts.NewDescritorFromContent(context.Background(), path, content, includes, isAbsIncludePath) if err != nil { klog.CtxWarnf(context.Background(), "KITEX: failed to get dynamicgo service descriptor, fall back to the original way, error=%s", err) diff --git a/pkg/generic/thriftidl_provider_option.go b/pkg/generic/thriftidl_provider_option.go index 7139b84760..f143855b28 100644 --- a/pkg/generic/thriftidl_provider_option.go +++ b/pkg/generic/thriftidl_provider_option.go @@ -19,8 +19,9 @@ package generic import "github.com/cloudwego/kitex/pkg/generic/thrift" type thriftIDLProviderOptions struct { - parseMode *thrift.ParseMode - goTag *goTagOption + parseMode *thrift.ParseMode + goTag *goTagOption + serviceName string } type goTagOption struct { @@ -37,6 +38,8 @@ func (o *thriftIDLProviderOptions) apply(opts []ThriftIDLProviderOption) { } } +// WithParseMode sets the parse mode. +// NOTE: when using WithIDLServiceName at the same time, parse mode will be ignored. func WithParseMode(parseMode thrift.ParseMode) ThriftIDLProviderOption { return ThriftIDLProviderOption{F: func(opt *thriftIDLProviderOptions) { opt.parseMode = &parseMode @@ -50,3 +53,11 @@ func WithGoTagDisabled(disable bool) ThriftIDLProviderOption { } }} } + +// WithIDLServiceName specifies the target IDL service to be parsed. +// NOTE: when using this option, the specified service is prioritized, and parse mode will be ignored. +func WithIDLServiceName(serviceName string) ThriftIDLProviderOption { + return ThriftIDLProviderOption{F: func(opt *thriftIDLProviderOptions) { + opt.serviceName = serviceName + }} +} diff --git a/pkg/generic/thriftidl_provider_test.go b/pkg/generic/thriftidl_provider_test.go index 016ad05537..989cc98df0 100644 --- a/pkg/generic/thriftidl_provider_test.go +++ b/pkg/generic/thriftidl_provider_test.go @@ -550,3 +550,111 @@ func TestDefaultValue(t *testing.T) { test.Assert(t, tree.DynamicGoDsc.Functions()["Example2Method"].Request().Struct().FieldById(1).Type().Struct().FieldById(4).DefaultValue().JSONValue() == "8") p.Close() } + +func TestParseWithIDLServiceName(t *testing.T) { + path := "json_test/idl/example_multi_service.thrift" + opts := []ThriftIDLProviderOption{WithIDLServiceName("ExampleService")} + p, err := NewThriftFileProviderWithOption(path, opts) + test.Assert(t, err == nil) + tree := <-p.Provide() + test.Assert(t, tree != nil) + test.Assert(t, tree.Name == "ExampleService") + p.Close() + + p, err = NewThriftFileProviderWithDynamicgoWithOption(path, opts) + test.Assert(t, err == nil) + tree = <-p.Provide() + test.Assert(t, tree != nil) + test.Assert(t, tree.Name == "ExampleService") + test.Assert(t, tree.DynamicGoDsc.Name() == "ExampleService") + p.Close() + + content := ` + namespace go thrift + + struct Request { + 1: required string message, + } + + struct Response { + 1: required string message, + } + + service Service1 { + Response Test(1: Request req) + } + + service Service2 { + Response Test(1: Request req) + } + + service Service3 { + Response Test(1: Request req) + } + ` + + updateContent := ` + namespace go thrift + + struct Request { + 1: required string message, + } + + struct Response { + 1: required string message, + } + + service Service1 { + Response Test(1: Request req) + } + + service Service2 { + Response Test(1: Request req) + } + ` + cp, err := NewThriftContentProvider(content, nil, WithIDLServiceName("Service2")) + test.Assert(t, err == nil) + tree = <-cp.Provide() + test.Assert(t, tree.Name == "Service2") + cp.Close() + + cp, err = NewThriftContentProvider(content, nil, WithIDLServiceName("UnknownService")) + test.Assert(t, err != nil) + test.Assert(t, err.Error() == "the idl service name UnknownService is not in the idl. Please check your idl") + test.Assert(t, cp == nil) + + cp, err = NewThriftContentProviderWithDynamicGo(content, nil, WithIDLServiceName("Service1")) + test.Assert(t, err == nil) + tree = <-cp.Provide() + test.Assert(t, tree.Name == "Service1") + test.Assert(t, tree.DynamicGoDsc != nil) + test.Assert(t, tree.DynamicGoDsc.Name() == "Service1") + + err = cp.UpdateIDL(updateContent, nil) + test.Assert(t, err == nil) + tree = <-cp.Provide() + test.Assert(t, tree.Name == "Service1") + test.Assert(t, tree.DynamicGoDsc != nil) + test.Assert(t, tree.DynamicGoDsc.Name() == "Service1") + cp.Close() + + path = "a/b/main.thrift" + includes := map[string]string{path: content} + ap, err := NewThriftContentWithAbsIncludePathProvider(path, includes, WithIDLServiceName("Service2")) + test.Assert(t, err == nil) + tree = <-ap.Provide() + test.Assert(t, tree.Name == "Service2") + ap.Close() + + ap, err = NewThriftContentWithAbsIncludePathProviderWithDynamicGo(path, includes, WithIDLServiceName("Service3")) + test.Assert(t, err == nil) + tree = <-ap.Provide() + test.Assert(t, tree.Name == "Service3") + test.Assert(t, tree.DynamicGoDsc != nil) + test.Assert(t, tree.DynamicGoDsc.Name() == "Service3") + + err = ap.UpdateIDL(path, map[string]string{path: updateContent}) + test.Assert(t, err != nil) + test.Assert(t, err.Error() == "the idl service name Service3 is not in the idl. Please check your idl") + ap.Close() +}