From b56b78bd257b49bf7d12794edb1926967902ae5d Mon Sep 17 00:00:00 2001 From: Igor Derkach Date: Wed, 4 Dec 2024 13:13:44 +0400 Subject: [PATCH] Intermediate commit --- cmd/go-asyncapi/generate.go | 2 - internal/asyncapi/amqp/channel.go | 3 +- internal/asyncapi/amqp/server.go | 2 +- internal/asyncapi/asyncapi.go | 2 +- internal/asyncapi/bindings.go | 4 +- internal/asyncapi/channel.go | 10 +- internal/asyncapi/correlationid.go | 4 +- internal/asyncapi/http/channel.go | 3 +- internal/asyncapi/http/server.go | 2 +- internal/asyncapi/ip/channel.go | 3 +- internal/asyncapi/ip/server.go | 2 +- internal/asyncapi/kafka/channel.go | 3 +- internal/asyncapi/kafka/server.go | 2 +- internal/asyncapi/message.go | 8 +- internal/asyncapi/mqtt/channel.go | 3 +- internal/asyncapi/mqtt/server.go | 2 +- internal/asyncapi/object.go | 7 +- internal/asyncapi/parameter.go | 4 +- internal/asyncapi/redis/channel.go | 3 +- internal/asyncapi/redis/server.go | 2 +- internal/asyncapi/server.go | 8 +- internal/asyncapi/servervariable.go | 4 +- internal/asyncapi/tcp/channel.go | 3 +- internal/asyncapi/tcp/server.go | 2 +- internal/asyncapi/udp/channel.go | 3 +- internal/asyncapi/udp/server.go | 2 +- internal/asyncapi/ws/channel.go | 3 +- internal/asyncapi/ws/server.go | 2 +- internal/common/compile_context.go | 19 +++- internal/common/promise.go | 4 +- internal/common/render.go | 12 +-- internal/compiler/compiler.go | 4 +- internal/linker/linker.go | 16 +-- internal/render/amqp/channel.go | 18 ++-- internal/render/amqp/server.go | 8 +- internal/render/asyncapi.go | 21 ++-- internal/render/bindings.go | 12 --- internal/render/channel.go | 26 +++-- internal/render/context/context.go | 101 ++++++++++++++--- internal/render/correlationid.go | 17 ++- internal/render/http/channel.go | 16 +-- internal/render/http/server.go | 8 +- internal/render/ip/channel.go | 16 +-- internal/render/ip/server.go | 8 +- internal/render/kafka/channel.go | 20 ++-- internal/render/kafka/server.go | 8 +- internal/render/lang/base.go | 39 +++++-- internal/render/lang/goarray.go | 6 +- internal/render/lang/gomap.go | 6 +- internal/render/lang/gopointer.go | 37 +++---- internal/render/lang/gosimple.go | 12 ++- internal/render/lang/gostruct.go | 10 +- internal/render/lang/gotypealias.go | 11 +- internal/render/lang/govalue.go | 121 +-------------------- internal/render/lang/promise.go | 52 ++++----- internal/render/lang/union.go | 11 +- internal/render/message.go | 14 ++- internal/render/mqtt/channel.go | 20 ++-- internal/render/mqtt/server.go | 8 +- internal/render/parameter.go | 5 - internal/render/proto/channel.go | 20 ++-- internal/render/proto/server.go | 22 ++-- internal/render/redis/channel.go | 16 +-- internal/render/redis/server.go | 8 +- internal/render/server.go | 16 +-- internal/render/servervariable.go | 4 - internal/render/tcp/channel.go | 16 +-- internal/render/tcp/server.go | 8 +- internal/render/template.go | 162 ++++++++++++++++++++-------- internal/render/udp/channel.go | 16 +-- internal/render/udp/server.go | 8 +- internal/render/ws/channel.go | 16 +-- internal/render/ws/server.go | 8 +- internal/selector/selector.go | 43 ++++++-- internal/tpl/load.go | 14 +++ internal/writer/render.go | 28 +++-- templates/amqp/channel.tmpl | 24 ++--- templates/amqp/server.tmpl | 8 +- templates/channel.tmpl | 6 +- templates/common/proto.tmpl | 83 ++++++++------ templates/decoding.tmpl | 29 ----- templates/encoding.tmpl | 29 ----- templates/http/channel.tmpl | 8 +- templates/http/server.tmpl | 8 +- templates/ip/channel.tmpl | 8 +- templates/ip/server.tmpl | 8 +- templates/kafka/channel.tmpl | 22 ++-- templates/kafka/server.tmpl | 8 +- templates/lang/goarray.tmpl | 6 +- templates/lang/gomap.tmpl | 6 +- templates/lang/gosimple.tmpl | 6 +- templates/lang/gostruct.tmpl | 6 +- templates/lang/gotypealias.tmpl | 6 +- templates/lang/govalue.tmpl | 23 ++-- templates/lang/union.tmpl | 5 +- templates/mqtt/channel.tmpl | 22 ++-- templates/mqtt/server.tmpl | 8 +- templates/redis/channel.tmpl | 8 +- templates/redis/server.tmpl | 8 +- templates/server.tmpl | 10 +- templates/tcp/channel.tmpl | 8 +- templates/tcp/server.tmpl | 8 +- templates/udp/channel.tmpl | 8 +- templates/udp/server.tmpl | 8 +- templates/ws/channel.tmpl | 8 +- templates/ws/server.tmpl | 8 +- 106 files changed, 797 insertions(+), 795 deletions(-) create mode 100644 internal/tpl/load.go delete mode 100644 templates/decoding.tmpl delete mode 100644 templates/encoding.tmpl diff --git a/cmd/go-asyncapi/generate.go b/cmd/go-asyncapi/generate.go index 57214cb..711f1bf 100644 --- a/cmd/go-asyncapi/generate.go +++ b/cmd/go-asyncapi/generate.go @@ -54,8 +54,6 @@ type generatePubSubArgs struct { ProjectModule string `arg:"-M,--project-module" help:"Project module name to use [default: extracted from go.mod file in the current working directory]" placeholder:"MODULE"` TargetPackage string `arg:"-T,--target-package" help:"Package for generated code [default: {target-dir-name}]" placeholder:"PACKAGE"` - //PackageScope string `arg:"--package-scope" default:"type" help:"How to split up the generated code on packages. Possible values: type, all" placeholder:"SCOPE"` - //FileScope string `arg:"--file-scope" default:"name" help:"How to split up the generated code on files inside packages. Possible values: name, type" placeholder:"SCOPE"` TemplateDir string `arg:"--template-dir" help:"Directory with custom templates" placeholder:"DIR"` generateObjectSelectionOpts ImplementationsOpts diff --git a/internal/asyncapi/amqp/channel.go b/internal/asyncapi/amqp/channel.go index f553963..67fdbb8 100644 --- a/internal/asyncapi/amqp/channel.go +++ b/internal/asyncapi/amqp/channel.go @@ -64,8 +64,7 @@ func (pb ProtoBuilder) BuildChannel(ctx *common.CompileContext, channel *asyncap return &render.ProtoChannel{ Channel: parent, - GolangNameProto: golangName, - Struct: chanStruct, + Type: chanStruct, ProtoName: pb.ProtoName, }, nil } diff --git a/internal/asyncapi/amqp/server.go b/internal/asyncapi/amqp/server.go index 8ff7352..ce815e5 100644 --- a/internal/asyncapi/amqp/server.go +++ b/internal/asyncapi/amqp/server.go @@ -18,7 +18,7 @@ func (pb ProtoBuilder) BuildServer(ctx *common.CompileContext, server *asyncapi. } return &render.ProtoServer{ Server: parent, - Struct: baseServer, + Type: baseServer, ProtoName: pb.ProtoName, }, nil } diff --git a/internal/asyncapi/asyncapi.go b/internal/asyncapi/asyncapi.go index 311ed54..da8202c 100644 --- a/internal/asyncapi/asyncapi.go +++ b/internal/asyncapi/asyncapi.go @@ -29,7 +29,7 @@ func (a AsyncAPI) Compile(ctx *common.CompileContext) error { } func (a AsyncAPI) build(ctx *common.CompileContext) *render.AsyncAPI { - allMessagesPrm := lang.NewListCbPromise[*render.Message](func(item common.Renderer, _ []string) bool { + allMessagesPrm := lang.NewListCbPromise[*render.Message](func(item common.Renderable, _ []string) bool { _, ok := item.(*render.Message) return ok }) diff --git a/internal/asyncapi/bindings.go b/internal/asyncapi/bindings.go index 1da44d4..b4447b0 100644 --- a/internal/asyncapi/bindings.go +++ b/internal/asyncapi/bindings.go @@ -31,10 +31,10 @@ func (b *Bindings) build( ctx *common.CompileContext, bindingsKind int, bindingsKey string, -) (common.Renderer, error) { +) (common.Renderable, error) { if b.Ref != "" { ctx.Logger.Trace("Ref", "$ref", b.Ref) - res := lang.NewRendererPromise(b.Ref, common.PromiseOriginUser) + res := lang.NewRenderablePromise(b.Ref, common.PromiseOriginUser) ctx.PutPromise(res) return res, nil } diff --git a/internal/asyncapi/channel.go b/internal/asyncapi/channel.go index 4e26489..fe25a0c 100644 --- a/internal/asyncapi/channel.go +++ b/internal/asyncapi/channel.go @@ -37,8 +37,8 @@ func (c Channel) Compile(ctx *common.CompileContext) error { return nil } -func (c Channel) buildChannels(ctx *common.CompileContext, channelKey string) ([]common.Renderer, error) { - var res []common.Renderer +func (c Channel) buildChannels(ctx *common.CompileContext, channelKey string) ([]common.Renderable, error) { + var res []common.Renderable _, isComponent := ctx.Stack.Top().Flags[common.SchemaTagComponent] ignore := c.XIgnore || @@ -51,7 +51,7 @@ func (c Channel) buildChannels(ctx *common.CompileContext, channelKey string) ([ } if c.Ref != "" { ctx.Logger.Trace("Ref", "$ref", c.Ref) - prm := lang.NewRendererPromise(c.Ref, common.PromiseOriginUser) + prm := lang.NewRenderablePromise(c.Ref, common.PromiseOriginUser) // Set a channel to be rendered if we reference it from `channels` document section prm.DirectRender = !isComponent ctx.PutPromise(prm) @@ -95,7 +95,7 @@ func (c Channel) buildChannels(ctx *common.CompileContext, channelKey string) ([ if c.Servers != nil { ctx.Logger.Trace("Channel servers", "names", *c.Servers) baseChan.SpecServerNames = *c.Servers - prm := lang.NewListCbPromise[*render.Server](func(item common.Renderer, path []string) bool { + prm := lang.NewListCbPromise[*render.Server](func(item common.Renderable, path []string) bool { srv, ok := item.(*render.Server) if !ok { return false @@ -105,7 +105,7 @@ func (c Channel) buildChannels(ctx *common.CompileContext, channelKey string) ([ baseChan.ServersPromise = prm } else { ctx.Logger.Trace("Channel for all servers") - prm := lang.NewListCbPromise[*render.Server](func(item common.Renderer, path []string) bool { + prm := lang.NewListCbPromise[*render.Server](func(item common.Renderable, path []string) bool { _, ok := item.(*render.Server) return ok }) diff --git a/internal/asyncapi/correlationid.go b/internal/asyncapi/correlationid.go index 4533dd4..d77c024 100644 --- a/internal/asyncapi/correlationid.go +++ b/internal/asyncapi/correlationid.go @@ -32,7 +32,7 @@ func (c CorrelationID) Compile(ctx *common.CompileContext) error { return nil } -func (c CorrelationID) build(ctx *common.CompileContext, correlationIDKey string) (common.Renderer, error) { +func (c CorrelationID) build(ctx *common.CompileContext, correlationIDKey string) (common.Renderable, error) { ignore := c.XIgnore || !ctx.CompileOpts.MessageOpts.Enable if ignore { ctx.Logger.Debug("CorrelationID denoted to be ignored") @@ -41,7 +41,7 @@ func (c CorrelationID) build(ctx *common.CompileContext, correlationIDKey string // TODO: move this ref code from everywhere to single place? if c.Ref != "" { ctx.Logger.Trace("Ref", "$ref", c.Ref) - res := lang.NewRendererPromise(c.Ref, common.PromiseOriginUser) + res := lang.NewRenderablePromise(c.Ref, common.PromiseOriginUser) ctx.PutPromise(res) return res, nil } diff --git a/internal/asyncapi/http/channel.go b/internal/asyncapi/http/channel.go index 122a40d..3cfb54a 100644 --- a/internal/asyncapi/http/channel.go +++ b/internal/asyncapi/http/channel.go @@ -27,8 +27,7 @@ func (pb ProtoBuilder) BuildChannel(ctx *common.CompileContext, channel *asyncap return &render.ProtoChannel{ Channel: parent, - GolangNameProto: golangName, - Struct: chanStruct, + Type: chanStruct, ProtoName: pb.ProtoName, }, nil } diff --git a/internal/asyncapi/http/server.go b/internal/asyncapi/http/server.go index 8449568..125016e 100644 --- a/internal/asyncapi/http/server.go +++ b/internal/asyncapi/http/server.go @@ -18,7 +18,7 @@ func (pb ProtoBuilder) BuildServer(ctx *common.CompileContext, server *asyncapi. } return &render.ProtoServer{ Server: parent, - Struct: baseServer, + Type: baseServer, ProtoName: pb.ProtoName, }, nil } diff --git a/internal/asyncapi/ip/channel.go b/internal/asyncapi/ip/channel.go index feeebec..7124d72 100644 --- a/internal/asyncapi/ip/channel.go +++ b/internal/asyncapi/ip/channel.go @@ -21,8 +21,7 @@ func (pb ProtoBuilder) BuildChannel(ctx *common.CompileContext, channel *asyncap return &render.ProtoChannel{ Channel: parent, - GolangNameProto: golangName, - Struct: chanStruct, + Type: chanStruct, ProtoName: pb.ProtoName, }, nil } diff --git a/internal/asyncapi/ip/server.go b/internal/asyncapi/ip/server.go index f4c46e5..8000e9a 100644 --- a/internal/asyncapi/ip/server.go +++ b/internal/asyncapi/ip/server.go @@ -18,7 +18,7 @@ func (pb ProtoBuilder) BuildServer(ctx *common.CompileContext, server *asyncapi. } return &render.ProtoServer{ Server: parent, - Struct: baseServer, + Type: baseServer, ProtoName: pb.ProtoName, }, nil } diff --git a/internal/asyncapi/kafka/channel.go b/internal/asyncapi/kafka/channel.go index bd0ea96..722bdaf 100644 --- a/internal/asyncapi/kafka/channel.go +++ b/internal/asyncapi/kafka/channel.go @@ -45,8 +45,7 @@ func (pb ProtoBuilder) BuildChannel(ctx *common.CompileContext, channel *asyncap return &render.ProtoChannel{ Channel: parent, - GolangNameProto: golangName, - Struct: chanStruct, + Type: chanStruct, ProtoName: pb.ProtoName, }, nil } diff --git a/internal/asyncapi/kafka/server.go b/internal/asyncapi/kafka/server.go index 3a45ff3..37471c4 100644 --- a/internal/asyncapi/kafka/server.go +++ b/internal/asyncapi/kafka/server.go @@ -23,7 +23,7 @@ func (pb ProtoBuilder) BuildServer(ctx *common.CompileContext, server *asyncapi. } return &render.ProtoServer{ Server: parent, - Struct: baseServer, + Type: baseServer, ProtoName: pb.ProtoName, }, nil } diff --git a/internal/asyncapi/message.go b/internal/asyncapi/message.go index 8377ff7..adb5e49 100644 --- a/internal/asyncapi/message.go +++ b/internal/asyncapi/message.go @@ -52,8 +52,8 @@ func (m Message) Compile(ctx *common.CompileContext) error { return nil } -func (m Message) build(ctx *common.CompileContext, messageKey string) ([]common.Renderer, error) { - var res []common.Renderer +func (m Message) build(ctx *common.CompileContext, messageKey string) ([]common.Renderable, error) { + var res []common.Renderable _, isComponent := ctx.Stack.Top().Flags[common.SchemaTagComponent] ignore := m.XIgnore || (isComponent && !ctx.CompileOpts.MessageOpts.IsAllowedName(messageKey)) @@ -64,7 +64,7 @@ func (m Message) build(ctx *common.CompileContext, messageKey string) ([]common. } if m.Ref != "" { ctx.Logger.Trace("Ref", "$ref", m.Ref) - prm := lang.NewRendererPromise(m.Ref, common.PromiseOriginUser) + prm := lang.NewRenderablePromise(m.Ref, common.PromiseOriginUser) ctx.PutPromise(prm) res = append(res, prm) return res, nil @@ -103,7 +103,7 @@ func (m Message) build(ctx *common.CompileContext, messageKey string) ([]common. ctx.Logger.Trace(fmt.Sprintf("Message content type is %q", baseMessage.ContentType)) // Lookup servers after linking to figure out all protocols the message is used in - prm := lang.NewListCbPromise[*render.Server](func(item common.Renderer, path []string) bool { + prm := lang.NewListCbPromise[*render.Server](func(item common.Renderable, path []string) bool { _, ok := item.(*render.Server) return ok }) diff --git a/internal/asyncapi/mqtt/channel.go b/internal/asyncapi/mqtt/channel.go index 81c0f06..46155b5 100644 --- a/internal/asyncapi/mqtt/channel.go +++ b/internal/asyncapi/mqtt/channel.go @@ -28,8 +28,7 @@ func (pb ProtoBuilder) BuildChannel(ctx *common.CompileContext, channel *asyncap return &render.ProtoChannel{ Channel: parent, - GolangNameProto: golangName, - Struct: chanStruct, + Type: chanStruct, ProtoName: pb.ProtoName, }, nil } diff --git a/internal/asyncapi/mqtt/server.go b/internal/asyncapi/mqtt/server.go index cd5d65c..956ea06 100644 --- a/internal/asyncapi/mqtt/server.go +++ b/internal/asyncapi/mqtt/server.go @@ -32,7 +32,7 @@ func (pb ProtoBuilder) BuildServer(ctx *common.CompileContext, server *asyncapi. } return &render.ProtoServer{ Server: parent, - Struct: baseServer, + Type: baseServer, ProtoName: pb.ProtoName, }, nil } diff --git a/internal/asyncapi/object.go b/internal/asyncapi/object.go index 437772c..9202500 100644 --- a/internal/asyncapi/object.go +++ b/internal/asyncapi/object.go @@ -120,8 +120,7 @@ func (o Object) build(ctx *common.CompileContext, flags map[common.SchemaTag]str nullable = nullable || lo.FromPtr(o.XNullable) if nullable { ctx.Logger.Trace("Object is nullable, make it pointer") - _, hasDefinition := flags[common.SchemaTagDefinition] - golangType = &lang.GoPointer{Type: golangType, HasDefinition: hasDefinition} + golangType = &lang.GoPointer{Type: golangType} } return golangType, nil } @@ -251,7 +250,7 @@ func (o Object) buildLangStruct(ctx *common.CompileContext, flags map[common.Sch var messagesPrm *lang.ListPromise[*render.Message] _, isMarshal := flags[common.SchemaTagMarshal] if isMarshal { - messagesPrm = lang.NewListCbPromise[*render.Message](func(item common.Renderer, _ []string) bool { + messagesPrm = lang.NewListCbPromise[*render.Message](func(item common.Renderable, _ []string) bool { _, ok := item.(*render.Message) return ok }) @@ -409,7 +408,7 @@ func (o Object) buildUnionStruct(ctx *common.CompileContext, flags map[common.Sc } // Collect all messages to retrieve struct field tags - messagesPrm := lang.NewListCbPromise[*render.Message](func(item common.Renderer, _ []string) bool { + messagesPrm := lang.NewListCbPromise[*render.Message](func(item common.Renderable, _ []string) bool { _, ok := item.(*render.Message) return ok }) diff --git a/internal/asyncapi/parameter.go b/internal/asyncapi/parameter.go index 5d915ca..7a27af3 100644 --- a/internal/asyncapi/parameter.go +++ b/internal/asyncapi/parameter.go @@ -28,7 +28,7 @@ func (p Parameter) Compile(ctx *common.CompileContext) error { return nil } -func (p Parameter) build(ctx *common.CompileContext, parameterKey string) (common.Renderer, error) { +func (p Parameter) build(ctx *common.CompileContext, parameterKey string) (common.Renderable, error) { ignore := !ctx.CompileOpts.ChannelOpts.Enable if ignore { ctx.Logger.Debug("Parameter denoted to be ignored along with all channels") @@ -36,7 +36,7 @@ func (p Parameter) build(ctx *common.CompileContext, parameterKey string) (commo } if p.Ref != "" { ctx.Logger.Trace("Ref", "$ref", p.Ref) - res := lang.NewRendererPromise(p.Ref, common.PromiseOriginUser) + res := lang.NewRenderablePromise(p.Ref, common.PromiseOriginUser) ctx.PutPromise(res) return res, nil } diff --git a/internal/asyncapi/redis/channel.go b/internal/asyncapi/redis/channel.go index f2f9ffa..3d8bab7 100644 --- a/internal/asyncapi/redis/channel.go +++ b/internal/asyncapi/redis/channel.go @@ -21,8 +21,7 @@ func (pb ProtoBuilder) BuildChannel(ctx *common.CompileContext, channel *asyncap return &render.ProtoChannel{ Channel: parent, - GolangNameProto: golangName, - Struct: chanStruct, + Type: chanStruct, ProtoName: pb.ProtoName, }, nil } diff --git a/internal/asyncapi/redis/server.go b/internal/asyncapi/redis/server.go index 7b2ee0b..79ea355 100644 --- a/internal/asyncapi/redis/server.go +++ b/internal/asyncapi/redis/server.go @@ -18,7 +18,7 @@ func (pb ProtoBuilder) BuildServer(ctx *common.CompileContext, server *asyncapi. } return &render.ProtoServer{ Server: parent, - Struct: baseServer, + Type: baseServer, ProtoName: pb.ProtoName, }, nil } diff --git a/internal/asyncapi/server.go b/internal/asyncapi/server.go index 684d0ec..7ca5d60 100644 --- a/internal/asyncapi/server.go +++ b/internal/asyncapi/server.go @@ -37,7 +37,7 @@ func (s Server) Compile(ctx *common.CompileContext) error { return nil } -func (s Server) build(ctx *common.CompileContext, serverKey string) (common.Renderer, error) { +func (s Server) build(ctx *common.CompileContext, serverKey string) (common.Renderable, error) { _, isComponent := ctx.Stack.Top().Flags[common.SchemaTagComponent] ignore := s.XIgnore || !ctx.CompileOpts.ServerOpts.IsAllowedName(serverKey) if ignore { @@ -46,7 +46,7 @@ func (s Server) build(ctx *common.CompileContext, serverKey string) (common.Rend } if s.Ref != "" { ctx.Logger.Trace("Ref", "$ref", s.Ref) - prm := lang.NewRendererPromise(s.Ref, common.PromiseOriginUser) + prm := lang.NewRenderablePromise(s.Ref, common.PromiseOriginUser) // Set a server to be rendered if we reference it from `servers` document section prm.DirectRender = !isComponent ctx.PutPromise(prm) @@ -65,7 +65,7 @@ func (s Server) build(ctx *common.CompileContext, serverKey string) (common.Rend } // Channels which are connected to this server - prm := lang.NewListCbPromise[*render.Channel](func(item common.Renderer, path []string) bool { + prm := lang.NewListCbPromise[*render.Channel](func(item common.Renderable, path []string) bool { _, ok := item.(*render.Channel) if !ok { return false @@ -107,7 +107,7 @@ func (s Server) build(ctx *common.CompileContext, serverKey string) (common.Rend if err != nil { return nil, err } - return &render.ProtoServer{Server: &baseServer, Struct: protoStruct}, nil + return &render.ProtoServer{Server: &baseServer, Type: protoStruct}, nil } ctx.Logger.Trace("Server", "proto", protoBuilder.ProtocolName()) diff --git a/internal/asyncapi/servervariable.go b/internal/asyncapi/servervariable.go index 52b5151..f2cac93 100644 --- a/internal/asyncapi/servervariable.go +++ b/internal/asyncapi/servervariable.go @@ -26,10 +26,10 @@ func (sv ServerVariable) Compile(ctx *common.CompileContext) error { return nil } -func (sv ServerVariable) build(ctx *common.CompileContext, serverVariableKey string) (common.Renderer, error) { +func (sv ServerVariable) build(ctx *common.CompileContext, serverVariableKey string) (common.Renderable, error) { if sv.Ref != "" { ctx.Logger.Trace("Ref", "$ref", sv.Ref) - res := lang.NewRendererPromise(sv.Ref, common.PromiseOriginUser) + res := lang.NewRenderablePromise(sv.Ref, common.PromiseOriginUser) ctx.PutPromise(res) return res, nil } diff --git a/internal/asyncapi/tcp/channel.go b/internal/asyncapi/tcp/channel.go index b58f681..d16eec7 100644 --- a/internal/asyncapi/tcp/channel.go +++ b/internal/asyncapi/tcp/channel.go @@ -21,8 +21,7 @@ func (pb ProtoBuilder) BuildChannel(ctx *common.CompileContext, channel *asyncap return &render.ProtoChannel{ Channel: parent, - GolangNameProto: golangName, - Struct: chanStruct, + Type: chanStruct, ProtoName: pb.ProtoName, }, nil } diff --git a/internal/asyncapi/tcp/server.go b/internal/asyncapi/tcp/server.go index a5c0c3e..6f20654 100644 --- a/internal/asyncapi/tcp/server.go +++ b/internal/asyncapi/tcp/server.go @@ -18,7 +18,7 @@ func (pb ProtoBuilder) BuildServer(ctx *common.CompileContext, server *asyncapi. } return &render.ProtoServer{ Server: parent, - Struct: baseServer, + Type: baseServer, ProtoName: pb.ProtoName, }, nil } diff --git a/internal/asyncapi/udp/channel.go b/internal/asyncapi/udp/channel.go index a813209..c5edcbb 100644 --- a/internal/asyncapi/udp/channel.go +++ b/internal/asyncapi/udp/channel.go @@ -21,8 +21,7 @@ func (pb ProtoBuilder) BuildChannel(ctx *common.CompileContext, channel *asyncap return &render.ProtoChannel{ Channel: parent, - GolangNameProto: golangName, - Struct: chanStruct, + Type: chanStruct, ProtoName: pb.ProtoName, }, nil } diff --git a/internal/asyncapi/udp/server.go b/internal/asyncapi/udp/server.go index 1be931f..06489e6 100644 --- a/internal/asyncapi/udp/server.go +++ b/internal/asyncapi/udp/server.go @@ -18,7 +18,7 @@ func (pb ProtoBuilder) BuildServer(ctx *common.CompileContext, server *asyncapi. } return &render.ProtoServer{ Server: parent, - Struct: baseServer, + Type: baseServer, ProtoName: pb.ProtoName, }, nil } diff --git a/internal/asyncapi/ws/channel.go b/internal/asyncapi/ws/channel.go index edc3563..c82106e 100644 --- a/internal/asyncapi/ws/channel.go +++ b/internal/asyncapi/ws/channel.go @@ -29,8 +29,7 @@ func (pb ProtoBuilder) BuildChannel(ctx *common.CompileContext, channel *asyncap return &render.ProtoChannel{ Channel: parent, - GolangNameProto: golangName, - Struct: chanStruct, + Type: chanStruct, ProtoName: pb.ProtoName, }, nil } diff --git a/internal/asyncapi/ws/server.go b/internal/asyncapi/ws/server.go index f994fb1..f5644a7 100644 --- a/internal/asyncapi/ws/server.go +++ b/internal/asyncapi/ws/server.go @@ -18,7 +18,7 @@ func (pb ProtoBuilder) BuildServer(ctx *common.CompileContext, server *asyncapi. } return &render.ProtoServer{ Server: parent, - Struct: baseServer, + Type: baseServer, ProtoName: pb.ProtoName, }, nil } diff --git a/internal/common/compile_context.go b/internal/common/compile_context.go index 278b2b1..e43387b 100644 --- a/internal/common/compile_context.go +++ b/internal/common/compile_context.go @@ -1,6 +1,7 @@ package common import ( + "errors" "path" "regexp" "strings" @@ -15,15 +16,23 @@ import ( const nameWordSep = "_" +var ErrDefinitionIsNotAssignedYet = errors.New("definition is not assigned yet") + +type GolangTypeDefinitionInfo struct { + Selection RenderSelectionConfig +} + type GolangType interface { - Renderer - TypeName() string + Renderable + TypeName() string // TODO: remove? D() string U() string + IsPointer() bool + DefinitionInfo() (*GolangTypeDefinitionInfo, error) } type CompilationStorage interface { - AddObject(stack []string, obj Renderer) + AddObject(stack []string, obj Renderable) RegisterProtocol(protoName string) AddExternalSpecPath(specPath *specurl.URL) AddPromise(p ObjectPromise) @@ -35,7 +44,7 @@ type CompileOpts struct { MessageOpts ObjectCompileOpts ModelOpts ObjectCompileOpts ServerOpts ObjectCompileOpts - NoEncodingPackage bool + NoEncodingPackage bool // TODO: remove in favor of selections AllowRemoteRefs bool RuntimeModule string GeneratePublishers bool @@ -83,7 +92,7 @@ type CompileContext struct { specRef *specurl.URL } -func (c *CompileContext) PutObject(obj Renderer) { +func (c *CompileContext) PutObject(obj Renderable) { c.Storage.AddObject(c.PathStack(), obj) } diff --git a/internal/common/promise.go b/internal/common/promise.go index 2e26d14..1f14355 100644 --- a/internal/common/promise.go +++ b/internal/common/promise.go @@ -10,7 +10,7 @@ const ( type ObjectPromise interface { Assign(obj any) Assigned() bool - FindCallback() func(item Renderer, path []string) bool + FindCallback() func(item Renderable, path []string) bool Ref() string Origin() PromiseOrigin } @@ -18,5 +18,5 @@ type ObjectPromise interface { type ObjectListPromise interface { AssignList(objs []any) Assigned() bool - FindCallback() func(item Renderer, path []string) bool + FindCallback() func(item Renderable, path []string) bool } diff --git a/internal/common/render.go b/internal/common/render.go index 8ee4ed7..43ce53d 100644 --- a/internal/common/render.go +++ b/internal/common/render.go @@ -19,11 +19,10 @@ const ( ObjectKindAsyncAPI ObjectKind = "asyncapi" // Utility object represents the entire AsyncAPI document ) -type Renderer interface { +type Renderable interface { Kind() ObjectKind // Selectable returns true if object can be selected to pass to the templates for rendering. Selectable() bool - RenderContext() RenderContext } type RenderOpts struct { @@ -67,9 +66,8 @@ type ( type RenderContext interface { RuntimeModule(subPackage string) string - GeneratedModule(subPackage string) string - QualifiedName(packageExpr string) string - QualifiedGeneratedName(subPackage, name string) string - QualifiedRuntimeName(subPackage, name string) string - SpecProtocols() []string + QualifiedName(parts ...string) string + QualifiedRuntimeName(parts ...string) string + QualifiedGeneratedPackage(obj GolangType) (string, error) + CurrentDefinitionInfo() *GolangTypeDefinitionInfo } diff --git a/internal/compiler/compiler.go b/internal/compiler/compiler.go index 12d2a06..de9da29 100644 --- a/internal/compiler/compiler.go +++ b/internal/compiler/compiler.go @@ -21,7 +21,7 @@ import ( type Object struct { - Object common.Renderer + Object common.Renderable ModuleURL specurl.URL } @@ -50,7 +50,7 @@ type Module struct { listPromises []common.ObjectListPromise } -func (c *Module) AddObject(stack []string, obj common.Renderer) { +func (c *Module) AddObject(stack []string, obj common.Renderable) { u := *c.specURL u.Pointer = stack c.objects = append(c.objects, Object{Object: obj, ModuleURL: u}) diff --git a/internal/linker/linker.go b/internal/linker/linker.go index 57a266b..2f01d9d 100644 --- a/internal/linker/linker.go +++ b/internal/linker/linker.go @@ -67,7 +67,7 @@ func AssignListPromises(sources map[string]ObjectSource) { } if res, ok := resolveListPromise(p, srcSpecID, sources); ok { targets := strings.Join( - lo.Map(lo.Slice(res, 0, 2), func(item common.Renderer, _ int) string { return item.String() }), + lo.Map(lo.Slice(res, 0, 2), func(item common.Renderable, _ int) string { return item.String() }), ", ", ) if len(res) > 2 { @@ -119,7 +119,7 @@ func Stats(sources map[string]ObjectSource) string { // TODO: detect ref loops to avoid infinite recursion // TODO: external refs can not be resolved at first time -- leave them unresolved -func resolvePromise(p common.ObjectPromise, srcSpecID string, sources map[string]ObjectSource) (common.Renderer, bool) { +func resolvePromise(p common.ObjectPromise, srcSpecID string, sources map[string]ObjectSource) (common.Renderable, bool) { tgtSpecID := srcSpecID ref := specurl.Parse(p.Ref()) @@ -131,7 +131,7 @@ func resolvePromise(p common.ObjectPromise, srcSpecID string, sources map[string } srcObjects := sources[tgtSpecID].AllObjects() - cb := func(_ common.Renderer, path []string) bool { return ref.MatchPointer(path) } + cb := func(_ common.Renderable, path []string) bool { return ref.MatchPointer(path) } if qcb := p.FindCallback(); qcb != nil { cb = qcb } @@ -149,7 +149,7 @@ func resolvePromise(p common.ObjectPromise, srcSpecID string, sources map[string return resolvePromise(v, tgtSpecID, sources) case common.ObjectListPromise: panic(fmt.Sprintf("Ref %q must point to one object, but it points to a another list promise", p.Ref())) - case common.Renderer: + case common.Renderable: return v, true default: panic(fmt.Sprintf("Ref %q points to an object of unexpected type %T", p.Ref(), v)) @@ -157,9 +157,9 @@ func resolvePromise(p common.ObjectPromise, srcSpecID string, sources map[string } // TODO: detect ref loops to avoid infinite recursion -func resolveListPromise(p common.ObjectListPromise, srcSpecID string, sources map[string]ObjectSource) ([]common.Renderer, bool) { +func resolveListPromise(p common.ObjectListPromise, srcSpecID string, sources map[string]ObjectSource) ([]common.Renderable, bool) { // Exclude links from selection in order to avoid duplicates in list - cb := func(obj common.Renderer, _ []string) bool { return !isPromise(obj) } + cb := func(obj common.Renderable, _ []string) bool { return !isPromise(obj) } if qcb := p.FindCallback(); qcb != nil { cb = qcb } @@ -168,7 +168,7 @@ func resolveListPromise(p common.ObjectListPromise, srcSpecID string, sources ma return cb(obj.Object, obj.ModuleURL.Pointer) }) - var results []common.Renderer + var results []common.Renderable for _, obj := range found { switch v := obj.Object.(type) { case common.ObjectPromise: @@ -189,7 +189,7 @@ func resolveListPromise(p common.ObjectListPromise, srcSpecID string, sources ma return results, false } results = append(results, resolved...) - case common.Renderer: + case common.Renderable: results = append(results, v) default: panic(fmt.Sprintf("Found an object of unexpected type %T", v)) diff --git a/internal/render/amqp/channel.go b/internal/render/amqp/channel.go index 95eda21..08b5d55 100644 --- a/internal/render/amqp/channel.go +++ b/internal/render/amqp/channel.go @@ -12,7 +12,7 @@ package amqp // //res = append(res, pc.ServerIface.D(ctx)...) // //res = append(res, pc.RenderOpenFunc(ctx)...) // res = append(res, pc.renderNewFunc(ctx)...) -// res = append(res, pc.Struct.D(ctx)...) +// res = append(res, pc.Type.D(ctx)...) // res = append(res, pc.RenderCommonMethods(ctx)...) // res = append(res, pc.renderProtoMethods(ctx)...) // if pc.Parent.Publisher { @@ -28,7 +28,7 @@ package amqp //func (pc ProtoChannel) U(ctx *common.RenderContext) []*j.Statement { // ctx.LogStartRender("Channel", "", pc.Parent.Name, "usage", pc.Selectable(), "proto", pc.ProtoName) // defer ctx.LogFinishRender() -// return pc.Struct.U(ctx) +// return pc.Type.U(ctx) //} //func (pc ProtoChannel) ID() string { @@ -43,7 +43,7 @@ package amqp // ctx.Logger.Trace("renderNewFunc", "proto", pc.ProtoName) // return []*j.Statement{ // // NewChannel1Proto(params Channel1Parameters, publisher proto.Publisher, subscriber proto.Subscriber) *Channel1Proto -// j.Func().Id(pc.Struct.NewFuncName()). +// j.Func().Id(pc.Type.NewFuncName()). // ParamsFunc(func(g *j.Group) { // if pc.Parent.ParametersType != nil { // g.Id("params").Add(utils.ToCode(pc.Parent.ParametersType.U(ctx))...) @@ -55,9 +55,9 @@ package amqp // g.Id("subscriber").Qual(ctx.RuntimeModule(pc.ProtoName), "Subscriber") // } // }). -// Op("*").Add(utils.ToCode(pc.Struct.U(ctx))...). +// Op("*").Add(utils.ToCode(pc.Type.U(ctx))...). // BlockFunc(func(bg *j.Group) { -// bg.Op("res := ").Add(utils.ToCode(pc.Struct.U(ctx))...).Values(j.DictFunc(func(d j.Dict) { +// bg.Op("res := ").Add(utils.ToCode(pc.Type.U(ctx))...).Values(j.DictFunc(func(d j.Dict) { // d[j.Id("name")] = j.Id(pc.Parent.TypeNamePrefix + "Name").CallFunc(func(g *j.Group) { // if pc.Parent.ParametersType != nil { // g.Id("params") @@ -98,8 +98,8 @@ package amqp //func (pc ProtoChannel) renderProtoMethods(ctx *common.RenderContext) []*j.Statement { // ctx.Logger.Trace("renderProtoMethods", "proto", pc.ProtoName) -// rn := pc.Struct.ReceiverName() -// receiver := j.Id(rn).Id(pc.Struct.Name) +// rn := pc.Type.ReceiverName() +// receiver := j.Id(rn).Id(pc.Type.Name) // // return []*j.Statement{ // // Method Exchange() string @@ -130,8 +130,8 @@ package amqp //func (pc ProtoChannel) renderProtoPublisherMethods(ctx *common.RenderContext) []*j.Statement { // ctx.Logger.Trace("renderProtoPublisherMethods", "proto", pc.ProtoName) -// rn := pc.Struct.ReceiverName() -// receiver := j.Id(rn).Id(pc.Struct.Name) +// rn := pc.Type.ReceiverName() +// receiver := j.Id(rn).Id(pc.Type.Name) // // var msgTyp common.GolangType = render.GoPointer{Type: pc.FallbackMessageType, HasDefinition: true} // if pc.PublisherMessageTypePromise != nil { diff --git a/internal/render/amqp/server.go b/internal/render/amqp/server.go index fab83f5..eeddb9b 100644 --- a/internal/render/amqp/server.go +++ b/internal/render/amqp/server.go @@ -2,7 +2,7 @@ package amqp //type ProtoServer struct { // *render.Server -// Struct *lang.GoStruct +// Type *lang.GoStruct // // ProtoName, ProtoTitle string //} @@ -17,7 +17,7 @@ package amqp // // var res []*j.Statement // res = append(res, ps.RenderNewFunc(ctx)...) -// res = append(res, ps.Struct.D(ctx)...) +// res = append(res, ps.Type.D(ctx)...) // res = append(res, ps.RenderCommonMethods(ctx)...) // res = append(res, ps.renderChannelMethods(ctx)...) // res = append(res, ps.RenderProducerMethods(ctx)...) @@ -28,7 +28,7 @@ package amqp //func (ps ProtoServer) U(ctx *common.RenderContext) []*j.Statement { // ctx.LogStartRender("Server", "", ps.Parent.Name, "usage", ps.Selectable(), "proto", ps.ProtoName) // defer ctx.LogFinishRender() -// return ps.Struct.U(ctx) +// return ps.Type.U(ctx) //} // //func (ps ProtoServer) ID() string { @@ -47,7 +47,7 @@ package amqp // for _, ch := range ps.Parent.GetRelevantChannels() { // protoChan := ch.AllProtoChannels[ps.ProtoName].(*ProtoChannel) // res = append(res, -// ps.RenderOpenChannelMethod(ctx, protoChan.Struct, protoChan, protoChan.Parent.ParametersType)..., +// ps.RenderOpenChannelMethod(ctx, protoChan.Type, protoChan, protoChan.Parent.ParametersType)..., // ) // } // return res diff --git a/internal/render/asyncapi.go b/internal/render/asyncapi.go index 7c9af46..7f82675 100644 --- a/internal/render/asyncapi.go +++ b/internal/render/asyncapi.go @@ -2,7 +2,6 @@ package render import ( "github.com/bdragon300/go-asyncapi/internal/common" - "github.com/bdragon300/go-asyncapi/internal/render/context" "github.com/bdragon300/go-asyncapi/internal/render/lang" "github.com/samber/lo" ) @@ -24,20 +23,16 @@ func (a AsyncAPI) Selectable() bool { return true } -func (a AsyncAPI) RenderContext() common.RenderContext { - return context.Context -} - func (a AsyncAPI) EffectiveDefaultContentType() string { res, _ := lo.Coalesce(a.DefaultContentType, fallbackContentType) return res } -// SpecEffectiveContentTypes returns a list of all unique content types used in the spec. This includes all content -// types from all messages and the default content type. -func (a AsyncAPI) SpecEffectiveContentTypes() []string { - return lo.Uniq(lo.Map(a.AllMessages.Targets(), func(item *Message, _ int) string { - contentType, _ := lo.Coalesce(item.ContentType, a.EffectiveDefaultContentType()) - return contentType - })) -} +//// SpecEffectiveContentTypes returns a list of all unique content types used in the spec. This includes all content +//// types from all messages and the default content type. +//func (a AsyncAPI) SpecEffectiveContentTypes() []string { +// return lo.Uniq(lo.Map(a.AllMessages.Targets(), func(item *Message, _ int) string { +// contentType, _ := lo.Coalesce(item.ContentType, a.EffectiveDefaultContentType()) +// return contentType +// })) +//} diff --git a/internal/render/bindings.go b/internal/render/bindings.go index 7c16462..42eb7da 100644 --- a/internal/render/bindings.go +++ b/internal/render/bindings.go @@ -2,7 +2,6 @@ package render import ( "github.com/bdragon300/go-asyncapi/internal/common" - "github.com/bdragon300/go-asyncapi/internal/render/context" "github.com/bdragon300/go-asyncapi/internal/render/lang" "github.com/bdragon300/go-asyncapi/internal/types" ) @@ -26,18 +25,7 @@ func (b Bindings) Selectable() bool { return false } -func (b Bindings) RenderContext() common.RenderContext { - return context.Context -} -//func (b *Bindings) D(_ *common.RenderContext) []*j.Statement { -// panic("not implemented") -//} -// -//func (b *Bindings) U(_ *common.RenderContext) []*j.Statement { -// panic("not implemented") -//} -// //func (b *Bindings) ID() string { // return b.Name //} diff --git a/internal/render/channel.go b/internal/render/channel.go index 2892bd7..51b271f 100644 --- a/internal/render/channel.go +++ b/internal/render/channel.go @@ -39,10 +39,6 @@ func (c Channel) Selectable() bool { return !c.Dummy } -func (c Channel) RenderContext() common.RenderContext { - return context.Context -} - //func (c Channel) Selectable() bool { // return c.HasDefinition && !c.Dummy //} @@ -161,11 +157,23 @@ func (c Channel) ServersProtocols() []string { return res } -func (c Channel) BindingsProtocols() []string { - panic("not implemented") +func (c Channel) BindingsProtocols() (res []string) { + if c.BindingsChannelPromise != nil { + res = append(res, c.BindingsChannelPromise.Target().Values.Keys()...) + res = append(res, c.BindingsChannelPromise.Target().JSONValues.Keys()...) + } + if c.BindingsPublishPromise != nil { + res = append(res, c.BindingsPublishPromise.Target().Values.Keys()...) + res = append(res, c.BindingsPublishPromise.Target().JSONValues.Keys()...) + } + if c.BindingsSubscribePromise != nil { + res = append(res, c.BindingsSubscribePromise.Target().Values.Keys()...) + res = append(res, c.BindingsSubscribePromise.Target().JSONValues.Keys()...) + } + return lo.Uniq(res) } -func (c Channel) ProtoBindingsValue(protoName string) common.Renderer { +func (c Channel) ProtoBindingsValue(protoName string) common.Renderable { res := &lang.GoValue{ Type: &lang.GoSimple{Name: "ChannelBindings", Import: context.Context.RuntimeModule(protoName)}, EmptyCurlyBrackets: true, @@ -193,9 +201,7 @@ func (c Channel) ProtoBindingsValue(protoName string) common.Renderer { type ProtoChannel struct { *Channel - GolangNameProto string // Channel TypeNamePrefix name concatenated with protocol name, e.g. Channel1Kafka - Struct *lang.GoStruct + Type *lang.GoStruct ProtoName string } - diff --git a/internal/render/context/context.go b/internal/render/context/context.go index d425455..a87fe88 100644 --- a/internal/render/context/context.go +++ b/internal/render/context/context.go @@ -1,46 +1,83 @@ package context import ( + "fmt" "github.com/bdragon300/go-asyncapi/internal/common" + "github.com/samber/lo" "path" + "strings" ) var Context common.RenderContext +type ImportItem struct { + Alias string + PackageName string +} + // TODO: add object path? type RenderContextImpl struct { RenderOpts common.RenderOpts + CurrentSelectionConfig common.RenderSelectionConfig + imports map[string]ImportItem // Key: package path } func (c *RenderContextImpl) RuntimeModule(subPackage string) string { return path.Join(c.RenderOpts.RuntimeModule, subPackage) } -func (c *RenderContextImpl) GeneratedModule(subPackage string) string { - //switch c.RenderOpts.PackageScope { - //case PackageScopeAll: - // return c.RenderOpts.ImportBase // Everything in one package - //case PackageScopeType: - // return path.Join(c.RenderOpts.ImportBase, subPackage) // Everything split up into packages by entity type - //} - //panic(fmt.Sprintf("Unknown package scope %q", c.RenderOpts.PackageScope)) - panic("not implemented") +func (c *RenderContextImpl) QualifiedName(parts ...string) string { + name, pkgPath, pkgName := qualifiedToImport(parts) + return fmt.Sprintf("%s.%s", c.importPackage(pkgPath, pkgName), name) } -func (c *RenderContextImpl) QualifiedName(packageExpr string) string { - panic("not implemented") +// QualifiedGeneratedPackage checks if the object is in the generated package of CurrentSelectionConfig and returns +// the package name if it is. If the object is not in the generated package, it returns an empty string. +func (c *RenderContextImpl) QualifiedGeneratedPackage(obj common.GolangType) (string, error) { + defInfo, err := obj.DefinitionInfo() + if err != nil { + return "", err + } + if defInfo == nil { + return "", nil // Object has no definition (e.g. Go built-in types) + } + d := path.Dir(defInfo.Selection.File) + if d == path.Dir(c.CurrentSelectionConfig.File) { + return "", nil // Object is defined in the current package, it name doesn't require a package name + } + + b, _ := path.Split(d) + pkgPath := path.Join(c.RenderOpts.ImportBase, b, defInfo.Selection.Package) + return c.importPackage(pkgPath, defInfo.Selection.Package), nil } -func (c *RenderContextImpl) QualifiedGeneratedName(subPackage, name string) string { - panic("not implemented") +func (c *RenderContextImpl) QualifiedRuntimeName(parts ...string) string { + p := append([]string{c.RenderOpts.ImportBase}, parts...) + name, pkgPath, pkgName := qualifiedToImport(p) + return fmt.Sprintf("%s.%s", c.importPackage(pkgPath, pkgName), name) } -func (c *RenderContextImpl) QualifiedRuntimeName(subPackage, name string) string { - panic("not implemented") +func (c *RenderContextImpl) importPackage(pkgPath string, pkgName string) string { + if _, ok := c.imports[pkgPath]; !ok { + res := ImportItem{PackageName: pkgName} + // Find imports with the same package name + namesakes := lo.Filter(lo.Entries(c.imports), func(item lo.Entry[string, ImportItem], _ int) bool { + return item.Key != pkgPath && item.Value.PackageName == pkgName + }) + if len(namesakes) > 0 { + res.Alias = fmt.Sprintf("%s%d", pkgName, len(namesakes)+1) // Generate a new alias to avoid package name conflict + } + c.imports[pkgPath] = res + } + + if v := c.imports[pkgPath]; v.Alias != "" { + return v.Alias // Return alias + } + return pkgName } -func (c *RenderContextImpl) SpecProtocols() []string { - panic("not implemented") +func (c *RenderContextImpl) CurrentDefinitionInfo() *common.GolangTypeDefinitionInfo { + return &common.GolangTypeDefinitionInfo{Selection: c.CurrentSelectionConfig} } //// LogStartRender is typically called at the beginning of a D or U method and logs that the @@ -70,3 +107,33 @@ func (c *RenderContextImpl) SpecProtocols() []string { // c.logCallLvl-- // } //} + +// qualifiedToImport converts the qual* template function parameters to qualified name and import package path. +// And also it returns the package name (the last part of the package path). +func qualifiedToImport(parts []string) (name string, pkgPath string, pkgName string) { + // parts["a"] -> ["", "a", "a"] + // parts["", "a"] -> ["a", "", ""] + // parts["a.x"] -> ["x", "a", "a"] + // parts["a/b/c"] -> ["", "a/b/c", "c"] + // parts["a", "x"] -> ["x", "a", "a"] + // parts["a/b.c", "x"] -> ["x", "a/b.c", "bc"] + // parts["n", "d", "a/b.c", "x"] -> ["x", "n/d/a/b.c", "bc"] + switch len(parts) { + case 0: + panic("Empty parameters, at least one is required") + case 1: + pkgPath = parts[0] + default: + pkgPath = path.Join(parts[:len(parts)-1]...) + "." + parts[len(parts)-1] + } + if pos := strings.LastIndex(pkgPath, "."); pos >= 0 { + name = pkgPath[pos+1:] + pkgPath = pkgPath[:pos] + } + pkgName = pkgPath + if pos := strings.LastIndex(pkgPath, "/"); pos >= 0 { + pkgName = pkgPath[pos+1:] + } + pkgName = strings.ReplaceAll(pkgName, ".", "") + return +} \ No newline at end of file diff --git a/internal/render/correlationid.go b/internal/render/correlationid.go index e019e1d..8651f5f 100644 --- a/internal/render/correlationid.go +++ b/internal/render/correlationid.go @@ -4,6 +4,7 @@ import ( "fmt" "github.com/bdragon300/go-asyncapi/internal/render/context" "github.com/bdragon300/go-asyncapi/internal/render/lang" + "github.com/bdragon300/go-asyncapi/internal/tpl" "net/url" "strconv" "strings" @@ -25,7 +26,7 @@ const ( type CorrelationID struct { Name string Description string - StructField CorrelationIDStructField // Struct field name to store the value to or to load the value from + StructField CorrelationIDStructField // Type field name to store the value to or to load the value from LocationPath []string // JSONPointer path to the field in the message, should be non-empty } @@ -37,10 +38,6 @@ func (c CorrelationID) Selectable() bool { return false } -func (c CorrelationID) RenderContext() common.RenderContext { - return context.Context -} - //func (c CorrelationID) D(_ *common.RenderContext) []*j.Statement { // panic("not implemented") //} @@ -284,7 +281,7 @@ func (c CorrelationID) renderValueExtractionCode( case *lang.GoMap: // TODO: x-parameter in correlationIDs spec section to set numbers as "0" for string keys or 0 for int keys ctx.Logger.Trace("In GoMap", "path", path[:pathIdx], "name", typ.ID(), "member", memberName) - varValueStmts = fmt.Sprintf("%s[%s]", anchor, TemplateGoLit(memberName)) + varValueStmts = fmt.Sprintf("%s[%s]", anchor, tpl.templateGoLit(memberName)) baseType = typ.ValueType varExpr := fmt.Sprintf("var %s %s", nextAnchor, typ.ValueType.U()) if t, ok := typ.ValueType.(lang.GolangPointerType); ok && t.IsPointer() { @@ -300,7 +297,7 @@ func (c CorrelationID) renderValueExtractionCode( ifExpr += fmt.Sprintf(` else { err = %s("key %%q not found in map on path /%s", %s) return - }`, fmtErrorf, strings.Join(path[:pathIdx], "/"), TemplateGoLit(memberName)) + }`, fmtErrorf, strings.Join(path[:pathIdx], "/"), tpl.templateGoLit(memberName)) } body = []string{ fmt.Sprintf(`if %s == nil { @@ -325,9 +322,9 @@ func (c CorrelationID) renderValueExtractionCode( body = append(body, fmt.Sprintf(`if len(%s) <= %s { err = %s("index %%q is out of range in array of length %%d on path /%s", %s, len(%s)) return - }`, anchor, TemplateGoLit(memberName), fmtErrorf, strings.Join(path[:pathIdx], "/"), TemplateGoLit(memberName), anchor)) + }`, anchor, tpl.templateGoLit(memberName), fmtErrorf, strings.Join(path[:pathIdx], "/"), tpl.templateGoLit(memberName), anchor)) } - varValueStmts = fmt.Sprintf("%s[%s]", anchor, TemplateGoLit(memberName)) + varValueStmts = fmt.Sprintf("%s[%s]", anchor, tpl.templateGoLit(memberName)) baseType = typ.ItemsType body = append(body, fmt.Sprintf("%s := %s", nextAnchor, varValueStmts)) case *lang.GoSimple: // Should be a terminal type in chain, raise error otherwise (if any path parts left to resolve) @@ -346,7 +343,7 @@ func (c CorrelationID) renderValueExtractionCode( "In wrapper type", "path", path[:pathIdx], "name", typ.String(), "type", fmt.Sprintf("%T", typ), "member", memberName, ) - t, ok := typ.WrappedGolangType() + t, ok := typ.UnwrapGolangType() if !ok { err = fmt.Errorf( "wrapped type %T does not contain a wrapped GolangType, path: /%s", diff --git a/internal/render/http/channel.go b/internal/render/http/channel.go index 86eddb7..5051de9 100644 --- a/internal/render/http/channel.go +++ b/internal/render/http/channel.go @@ -3,7 +3,7 @@ package http //type ProtoChannel struct { // *render.Channel // GolangNameProto string // Channel TypeNamePrefix name concatenated with protocol name, e.g. Channel1Kafka -// Struct *render.GoStruct +// Type *render.GoStruct // // ProtoName, ProtoTitle string //} @@ -19,7 +19,7 @@ package http // res = append(res, pc.ServerIface.D(ctx)...) // res = append(res, pc.RenderOpenFunc(ctx)...) // res = append(res, pc.renderNewFunc(ctx)...) -// res = append(res, pc.Struct.D(ctx)...) +// res = append(res, pc.Type.D(ctx)...) // res = append(res, pc.RenderCommonMethods(ctx)...) // res = append(res, pc.renderProtoMethods(ctx)...) // if pc.Parent.Publisher { @@ -35,7 +35,7 @@ package http //func (pc ProtoChannel) U(ctx *common.RenderContext) []*j.Statement { // ctx.LogStartRender("Channel", "", pc.Parent.Name, "usage", pc.Selectable(), "proto", pc.ProtoName) // defer ctx.LogFinishRender() -// return pc.Struct.U(ctx) +// return pc.Type.U(ctx) //} //func (pc ProtoChannel) ID() string { @@ -51,7 +51,7 @@ package http // // return []*j.Statement{ // // NewChannel1Proto(params Channel1Parameters, publisher proto.Publisher, subscriber proto.Subscriber) *Channel1Proto -// j.Func().Id(pc.Struct.NewFuncName()). +// j.Func().Id(pc.Type.NewFuncName()). // ParamsFunc(func(g *j.Group) { // if pc.Parent.ParametersType != nil { // g.Id("params").Add(utils.ToCode(pc.Parent.ParametersType.U(ctx))...) @@ -63,9 +63,9 @@ package http // g.Id("subscriber").Qual(ctx.RuntimeModule(pc.ProtoName), "Subscriber") // } // }). -// Op("*").Add(utils.ToCode(pc.Struct.U(ctx))...). +// Op("*").Add(utils.ToCode(pc.Type.U(ctx))...). // BlockFunc(func(bg *j.Group) { -// bg.Op("res := ").Add(utils.ToCode(pc.Struct.U(ctx))...).Values(j.DictFunc(func(d j.Dict) { +// bg.Op("res := ").Add(utils.ToCode(pc.Type.U(ctx))...).Values(j.DictFunc(func(d j.Dict) { // d[j.Id("name")] = j.Id(pc.Parent.TypeNamePrefix + "Name").CallFunc(func(g *j.Group) { // if pc.Parent.ParametersType != nil { // g.Id("params") @@ -90,8 +90,8 @@ package http //func (pc ProtoChannel) renderProtoPublisherMethods(ctx *common.RenderContext) []*j.Statement { // ctx.Logger.Trace("renderProtoPublisherMethods", "proto", pc.ProtoName) // -// rn := pc.Struct.ReceiverName() -// receiver := j.Id(rn).Id(pc.Struct.Name) +// rn := pc.Type.ReceiverName() +// receiver := j.Id(rn).Id(pc.Type.Name) // // var msgTyp common.GolangType = render.GoPointer{Type: pc.Parent.FallbackMessageType, HasDefinition: true} // if pc.Parent.PublisherMessageTypePromise != nil { diff --git a/internal/render/http/server.go b/internal/render/http/server.go index f720097..78b1918 100644 --- a/internal/render/http/server.go +++ b/internal/render/http/server.go @@ -2,7 +2,7 @@ package http //type ProtoServer struct { // Parent *render.Server -// Struct *render.GoStruct +// Type *render.GoStruct // // ProtoName, ProtoTitle string //} @@ -16,7 +16,7 @@ package http // defer ctx.LogFinishRender() // var res []*j.Statement // res = append(res, ps.RenderNewFunc(ctx)...) -// res = append(res, ps.Struct.D(ctx)...) +// res = append(res, ps.Type.D(ctx)...) // res = append(res, ps.RenderCommonMethods(ctx)...) // res = append(res, ps.renderChannelMethods(ctx)...) // res = append(res, ps.RenderProducerMethods(ctx)...) @@ -27,7 +27,7 @@ package http //func (ps ProtoServer) U(ctx *common.RenderContext) []*j.Statement { // ctx.LogStartRender("Server", "", ps.Parent.Name, "usage", ps.Selectable(), "proto", ps.ProtoName) // defer ctx.LogFinishRender() -// return ps.Struct.U(ctx) +// return ps.Type.U(ctx) //} // //func (ps ProtoServer) ID() string { @@ -46,7 +46,7 @@ package http // for _, ch := range ps.Parent.GetRelevantChannels() { // protoChan := ch.AllProtoChannels[ps.ProtoName].(*ProtoChannel) // res = append(res, -// ps.RenderOpenChannelMethod(ctx, protoChan.Struct, protoChan, protoChan.Parent.ParametersType)..., +// ps.RenderOpenChannelMethod(ctx, protoChan.Type, protoChan, protoChan.Parent.ParametersType)..., // ) // } // return res diff --git a/internal/render/ip/channel.go b/internal/render/ip/channel.go index 3ad1002..0915cb5 100644 --- a/internal/render/ip/channel.go +++ b/internal/render/ip/channel.go @@ -3,7 +3,7 @@ package ip //type ProtoChannel struct { // *render.Channel // GolangNameProto string // Channel TypeNamePrefix name concatenated with protocol name, e.g. Channel1Kafka -// Struct *render.GoStruct +// Type *render.GoStruct // // ProtoName, ProtoTitle string //} @@ -19,7 +19,7 @@ package ip // res = append(res, pc.ServerIface.D(ctx)...) // res = append(res, pc.RenderOpenFunc(ctx)...) // res = append(res, pc.renderNewFunc(ctx)...) -// res = append(res, pc.Struct.D(ctx)...) +// res = append(res, pc.Type.D(ctx)...) // res = append(res, pc.RenderCommonMethods(ctx)...) // res = append(res, pc.renderProtoMethods(ctx)...) // if pc.Parent.Publisher { @@ -35,7 +35,7 @@ package ip //func (pc ProtoChannel) U(ctx *common.RenderContext) []*j.Statement { // ctx.LogStartRender("Channel", "", pc.Parent.Name, "usage", pc.Selectable(), "proto", pc.ProtoName) // defer ctx.LogFinishRender() -// return pc.Struct.U(ctx) +// return pc.Type.U(ctx) //} // //func (pc ProtoChannel) ID() string { @@ -51,7 +51,7 @@ package ip // // return []*j.Statement{ // // NewChannel1Proto(params Channel1Parameters, publisher proto.Publisher, subscriber proto.Subscriber) *Channel1Proto -// j.Func().Id(pc.Struct.NewFuncName()). +// j.Func().Id(pc.Type.NewFuncName()). // ParamsFunc(func(g *j.Group) { // if pc.Parent.ParametersType != nil { // g.Id("params").Add(utils.ToCode(pc.Parent.ParametersType.U(ctx))...) @@ -63,9 +63,9 @@ package ip // g.Id("subscriber").Qual(ctx.RuntimeModule(pc.ProtoName), "Subscriber") // } // }). -// Op("*").Add(utils.ToCode(pc.Struct.U(ctx))...). +// Op("*").Add(utils.ToCode(pc.Type.U(ctx))...). // BlockFunc(func(bg *j.Group) { -// bg.Op("res := ").Add(utils.ToCode(pc.Struct.U(ctx))...).Values(j.DictFunc(func(d j.Dict) { +// bg.Op("res := ").Add(utils.ToCode(pc.Type.U(ctx))...).Values(j.DictFunc(func(d j.Dict) { // d[j.Id("name")] = j.Id(pc.Parent.TypeNamePrefix + "Name").CallFunc(func(g *j.Group) { // if pc.Parent.ParametersType != nil { // g.Id("params") @@ -90,8 +90,8 @@ package ip //func (pc ProtoChannel) renderProtoPublisherMethods(ctx *common.RenderContext) []*j.Statement { // ctx.Logger.Trace("renderProtoPublisherMethods", "proto", pc.ProtoName) // -// rn := pc.Struct.ReceiverName() -// receiver := j.Id(rn).Id(pc.Struct.Name) +// rn := pc.Type.ReceiverName() +// receiver := j.Id(rn).Id(pc.Type.Name) // // var msgTyp common.GolangType = render.GoPointer{Type: pc.Parent.FallbackMessageType, HasDefinition: true} // if pc.Parent.PublisherMessageTypePromise != nil { diff --git a/internal/render/ip/server.go b/internal/render/ip/server.go index 9400e30..ebea892 100644 --- a/internal/render/ip/server.go +++ b/internal/render/ip/server.go @@ -2,7 +2,7 @@ package ip //type ProtoServer struct { // Parent *render.Server -// Struct *render.GoStruct +// Type *render.GoStruct // // ProtoName, ProtoTitle string //} @@ -16,7 +16,7 @@ package ip // defer ctx.LogFinishRender() // var res []*j.Statement // res = append(res, ps.RenderNewFunc(ctx)...) -// res = append(res, ps.Struct.D(ctx)...) +// res = append(res, ps.Type.D(ctx)...) // res = append(res, ps.RenderCommonMethods(ctx)...) // res = append(res, ps.renderChannelMethods(ctx)...) // res = append(res, ps.RenderProducerMethods(ctx)...) @@ -27,7 +27,7 @@ package ip //func (ps ProtoServer) U(ctx *common.RenderContext) []*j.Statement { // ctx.LogStartRender("Server", "", ps.Parent.Name, "usage", ps.Selectable(), "proto", ps.ProtoName) // defer ctx.LogFinishRender() -// return ps.Struct.U(ctx) +// return ps.Type.U(ctx) //} // //func (ps ProtoServer) ID() string { @@ -46,7 +46,7 @@ package ip // for _, ch := range ps.Parent.GetRelevantChannels() { // protoChan := ch.AllProtoChannels[ps.ProtoName].(*ProtoChannel) // res = append(res, -// ps.RenderOpenChannelMethod(ctx, protoChan.Struct, protoChan, protoChan.Parent.ParametersType)..., +// ps.RenderOpenChannelMethod(ctx, protoChan.Type, protoChan, protoChan.Parent.ParametersType)..., // ) // } // return res diff --git a/internal/render/kafka/channel.go b/internal/render/kafka/channel.go index 1ba4d69..8d8efd3 100644 --- a/internal/render/kafka/channel.go +++ b/internal/render/kafka/channel.go @@ -3,7 +3,7 @@ package kafka //type ProtoChannel struct { // *render.Channel // GolangNameProto string // Channel TypeNamePrefix name concatenated with protocol name, e.g. Channel1Kafka -// Struct *render.GoStruct +// Type *render.GoStruct // // ProtoName, ProtoTitle string //} @@ -19,7 +19,7 @@ package kafka // res = append(res, pc.ServerIface.D(ctx)...) // res = append(res, pc.RenderOpenFunc(ctx)...) // res = append(res, pc.renderNewFunc(ctx)...) -// res = append(res, pc.Struct.D(ctx)...) +// res = append(res, pc.Type.D(ctx)...) // res = append(res, pc.RenderCommonMethods(ctx)...) // res = append(res, pc.renderProtoMethods(ctx)...) // if pc.Parent.Publisher { @@ -35,7 +35,7 @@ package kafka //func (pc ProtoChannel) U(ctx *common.RenderContext) []*j.Statement { // ctx.LogStartRender("Channel", "", pc.Parent.Name, "usage", pc.Selectable(), "proto", pc.ProtoName) // defer ctx.LogFinishRender() -// return pc.Struct.U(ctx) +// return pc.Type.U(ctx) //} // //func (pc ProtoChannel) ID() string { @@ -51,7 +51,7 @@ package kafka // // return []*j.Statement{ // // NewChannel1Proto(params Channel1Parameters, publisher proto.Publisher, subscriber proto.Subscriber) *Channel1Proto -// j.Func().Id(pc.Struct.NewFuncName()). +// j.Func().Id(pc.Type.NewFuncName()). // ParamsFunc(func(g *j.Group) { // if pc.Parent.ParametersType != nil { // g.Id("params").Add(utils.ToCode(pc.Parent.ParametersType.U(ctx))...) @@ -63,9 +63,9 @@ package kafka // g.Id("subscriber").Qual(ctx.RuntimeModule(pc.ProtoName), "Subscriber") // } // }). -// Op("*").Add(utils.ToCode(pc.Struct.U(ctx))...). +// Op("*").Add(utils.ToCode(pc.Type.U(ctx))...). // BlockFunc(func(bg *j.Group) { -// bg.Op("res := ").Add(utils.ToCode(pc.Struct.U(ctx))...).Values(j.DictFunc(func(d j.Dict) { +// bg.Op("res := ").Add(utils.ToCode(pc.Type.U(ctx))...).Values(j.DictFunc(func(d j.Dict) { // d[j.Id("name")] = j.Id(pc.Parent.TypeNamePrefix + "Name").CallFunc(func(g *j.Group) { // if pc.Parent.ParametersType != nil { // g.Id("params") @@ -94,8 +94,8 @@ package kafka //func (pc ProtoChannel) renderProtoMethods(ctx *common.RenderContext) []*j.Statement { // ctx.Logger.Trace("renderProtoMethods", "proto", pc.ProtoName) // -// rn := pc.Struct.ReceiverName() -// receiver := j.Id(rn).Id(pc.Struct.Name) +// rn := pc.Type.ReceiverName() +// receiver := j.Id(rn).Id(pc.Type.Name) // // return []*j.Statement{ // // Method Topic() string @@ -111,8 +111,8 @@ package kafka //func (pc ProtoChannel) renderProtoPublisherMethods(ctx *common.RenderContext) []*j.Statement { // ctx.Logger.Trace("renderProtoPublisherMethods", "proto", pc.ProtoName) // -// rn := pc.Struct.ReceiverName() -// receiver := j.Id(rn).Id(pc.Struct.Name) +// rn := pc.Type.ReceiverName() +// receiver := j.Id(rn).Id(pc.Type.Name) // // var msgTyp common.GolangType = render.GoPointer{Type: pc.Parent.FallbackMessageType, HasDefinition: true} // if pc.Parent.PublisherMessageTypePromise != nil { diff --git a/internal/render/kafka/server.go b/internal/render/kafka/server.go index 193701a..31c05d6 100644 --- a/internal/render/kafka/server.go +++ b/internal/render/kafka/server.go @@ -2,7 +2,7 @@ package kafka //type ProtoServer struct { // Parent *render.Server -// Struct *render.GoStruct +// Type *render.GoStruct // // ProtoName, ProtoTitle string //} @@ -16,7 +16,7 @@ package kafka // defer ctx.LogFinishRender() // var res []*j.Statement // res = append(res, ps.RenderNewFunc(ctx)...) -// res = append(res, ps.Struct.D(ctx)...) +// res = append(res, ps.Type.D(ctx)...) // res = append(res, ps.RenderCommonMethods(ctx)...) // res = append(res, ps.renderChannelMethods(ctx)...) // res = append(res, ps.RenderProducerMethods(ctx)...) @@ -27,7 +27,7 @@ package kafka //func (ps ProtoServer) U(ctx *common.RenderContext) []*j.Statement { // ctx.LogStartRender("Server", "", ps.Parent.Name, "usage", ps.Selectable(), "proto", ps.ProtoName) // defer ctx.LogFinishRender() -// return ps.Struct.U(ctx) +// return ps.Type.U(ctx) //} // //func (ps ProtoServer) ID() string { @@ -46,7 +46,7 @@ package kafka // for _, ch := range ps.Parent.GetRelevantChannels() { // protoChan := ch.AllProtoChannels[ps.ProtoName].(*ProtoChannel) // res = append(res, -// ps.RenderOpenChannelMethod(ctx, protoChan.Struct, protoChan, protoChan.Parent.ParametersType)..., +// ps.RenderOpenChannelMethod(ctx, protoChan.Type, protoChan, protoChan.Parent.ParametersType)..., // ) // } // return res diff --git a/internal/render/lang/base.go b/internal/render/lang/base.go index 0bd87f1..56d6cc8 100644 --- a/internal/render/lang/base.go +++ b/internal/render/lang/base.go @@ -2,7 +2,10 @@ package lang import ( "github.com/bdragon300/go-asyncapi/internal/common" + "github.com/bdragon300/go-asyncapi/internal/render" "github.com/bdragon300/go-asyncapi/internal/render/context" + "github.com/bdragon300/go-asyncapi/internal/tpl" + "strings" ) type BaseType struct { @@ -13,7 +16,8 @@ type BaseType struct { // inline type. Such as inlined `field struct{...}` and separate `field StructName`, or `field []type` // and `field ArrayName` HasDefinition bool - Import string // optional module to import a type from + Import string // optional external (or runtime) module to import a type from + definitionInfo *common.GolangTypeDefinitionInfo } func (b *BaseType) Kind() common.ObjectKind { @@ -24,10 +28,6 @@ func (b *BaseType) Selectable() bool { return b.HasDefinition } -func (b *BaseType) RenderContext() common.RenderContext { - return context.Context -} - func (b *BaseType) TypeName() string { return b.Name } @@ -39,15 +39,40 @@ func (b *BaseType) String() string { return "GoType " + b.Name } +func (b *BaseType) IsPointer() bool { + return false +} + +func (b *BaseType) DefinitionInfo() (*common.GolangTypeDefinitionInfo, error) { + if b.definitionInfo == nil { + return nil, common.ErrDefinitionIsNotAssignedYet + } + return b.definitionInfo, nil +} + type GolangTypeWrapperType interface { - WrappedGolangType() (common.GolangType, bool) + UnwrapGolangType() (common.GolangType, bool) String() string } -type GolangPointerType interface { +type GolangPointerType interface { // TODO: replace with common.GolangType? or move where it is used IsPointer() bool } type golangStructType interface { IsStruct() bool } + +func renderTemplate[T common.Renderable](name string, obj T) string { + var b strings.Builder + tmpl := tpl.LoadTemplate(name) + if tmpl == nil { + panic("template not found: " + name) + } + + tmpl = tmpl.Funcs(render.GetTemplateFunctions(context.Context)) + if err := tmpl.Execute(&b, obj); err != nil { + panic(err) + } + return b.String() +} \ No newline at end of file diff --git a/internal/render/lang/goarray.go b/internal/render/lang/goarray.go index 380f686..6adac01 100644 --- a/internal/render/lang/goarray.go +++ b/internal/render/lang/goarray.go @@ -2,6 +2,7 @@ package lang import ( "github.com/bdragon300/go-asyncapi/internal/common" + "github.com/bdragon300/go-asyncapi/internal/render/context" ) type GoArray struct { @@ -29,7 +30,8 @@ func (a GoArray) D() string { //res = append(res, stmt.Add(items...)) // //return res - panic("not implemented") + a.definitionInfo = context.Context.CurrentDefinitionInfo() + return renderTemplate("lang/goarray/definition", &a) } func (a GoArray) U() string { @@ -49,5 +51,5 @@ func (a GoArray) U() string { //} // //return []*jen.Statement{jen.Index().Add(items...)} - panic("not implemented") + return renderTemplate("lang/goarray/usage", &a) } diff --git a/internal/render/lang/gomap.go b/internal/render/lang/gomap.go index 0e2a919..818d6b1 100644 --- a/internal/render/lang/gomap.go +++ b/internal/render/lang/gomap.go @@ -2,6 +2,7 @@ package lang import ( "github.com/bdragon300/go-asyncapi/internal/common" + "github.com/bdragon300/go-asyncapi/internal/render/context" ) type GoMap struct { @@ -25,7 +26,8 @@ func (m GoMap) D() string { //res = append(res, stmt.Map((&jen.Statement{}).Add(keyType...)).Add(valueType...)) // //return res - panic("not implemented") + m.definitionInfo = context.Context.CurrentDefinitionInfo() + return renderTemplate("lang/gomap/definition", &m) } func (m GoMap) U() string { @@ -42,5 +44,5 @@ func (m GoMap) U() string { //keyType := utils.ToCode(m.KeyType.U()) //valueType := utils.ToCode(m.ValueType.U()) //return []*jen.Statement{jen.Map((&jen.Statement{}).Add(keyType...)).Add(valueType...)} - panic("not implemented") + return renderTemplate("lang/gomap/usage", &m) } diff --git a/internal/render/lang/gopointer.go b/internal/render/lang/gopointer.go index 4e347a1..2b63899 100644 --- a/internal/render/lang/gopointer.go +++ b/internal/render/lang/gopointer.go @@ -2,13 +2,10 @@ package lang import ( "github.com/bdragon300/go-asyncapi/internal/common" - "github.com/bdragon300/go-asyncapi/internal/render/context" ) type GoPointer struct { Type common.GolangType - // HasDefinition forces the GoPointer to be rendered as definition, even if type it points marked not to do so. - HasDefinition bool } func (p GoPointer) Kind() common.ObjectKind { @@ -16,32 +13,25 @@ func (p GoPointer) Kind() common.ObjectKind { } func (p GoPointer) Selectable() bool { - return p.HasDefinition -} - -func (p GoPointer) RenderContext() common.RenderContext { - return context.Context + return p.Selectable() } func (p GoPointer) D() string { - ctx.LogStartRender("GoPointer", "", "", "definition", p.IsDefinition()) - defer ctx.LogFinishRender() + //ctx.LogStartRender("GoPointer", "", "", "definition", p.IsDefinition()) + //defer ctx.LogFinishRender() return p.Type.D() } func (p GoPointer) U() string { - ctx.LogStartRender("GoPointer", "", "", "usage", p.IsDefinition()) - defer ctx.LogFinishRender() + //ctx.LogStartRender("GoPointer", "", "", "usage", p.IsDefinition()) + //defer ctx.LogFinishRender() - isPtr := true - switch v := p.Type.(type) { - case GolangPointerType: - isPtr = !v.IsPointer() // Prevent appearing pointer to pointer - case *GoSimple: - isPtr = !v.IsInterface + drawPtr := true + if v, ok := p.Type.(GolangPointerType); ok { + drawPtr = !v.IsPointer() // Prevent appearing pointer to pointer } - if isPtr { + if drawPtr { return "*" + p.Type.U() } return p.Type.U() @@ -55,10 +45,17 @@ func (p GoPointer) String() string { return "GoPointer -> " + p.Type.String() } -func (p GoPointer) WrappedGolangType() (common.GolangType, bool) { +func (p GoPointer) UnwrapGolangType() (common.GolangType, bool) { + if v, ok := p.Type.(GolangTypeWrapperType); ok { + return v.UnwrapGolangType() + } return p.Type, p.Type != nil } func (p GoPointer) IsPointer() bool { return true } + +func (p GoPointer) DefinitionInfo() (*common.GolangTypeDefinitionInfo, error) { + return p.Type.DefinitionInfo() +} \ No newline at end of file diff --git a/internal/render/lang/gosimple.go b/internal/render/lang/gosimple.go index 89042bd..483456b 100644 --- a/internal/render/lang/gosimple.go +++ b/internal/render/lang/gosimple.go @@ -2,7 +2,6 @@ package lang import ( "github.com/bdragon300/go-asyncapi/internal/common" - "github.com/bdragon300/go-asyncapi/internal/render/context" ) type GoSimple struct { @@ -19,8 +18,8 @@ func (p GoSimple) Selectable() bool { return false } -func (p GoSimple) RenderContext() common.RenderContext { - return context.Context +func (p GoSimple) IsPointer() bool { + return false } func (p GoSimple) D() string { @@ -29,7 +28,7 @@ func (p GoSimple) D() string { // //stmt := jen.Id(p.Name) //return []*jen.Statement{stmt} - panic("not implemented") + return renderTemplate("lang/gosimple/definition", &p) } func (p GoSimple) U() string { @@ -45,7 +44,7 @@ func (p GoSimple) U() string { //} // //return []*jen.Statement{stmt} - panic("not implemented") + return renderTemplate("lang/gosimple/usage", &p) } func (p GoSimple) TypeName() string { @@ -59,3 +58,6 @@ func (p GoSimple) String() string { return "GoSimple " + p.Name } +func (p GoSimple) DefinitionInfo() (*common.GolangTypeDefinitionInfo, error) { + return nil, nil +} \ No newline at end of file diff --git a/internal/render/lang/gostruct.go b/internal/render/lang/gostruct.go index bab5b77..61c8157 100644 --- a/internal/render/lang/gostruct.go +++ b/internal/render/lang/gostruct.go @@ -3,6 +3,7 @@ package lang import ( "fmt" "github.com/bdragon300/go-asyncapi/internal/render" + "github.com/bdragon300/go-asyncapi/internal/render/context" "slices" "strconv" "strings" @@ -37,9 +38,10 @@ func (s GoStruct) D() string { //code := lo.FlatMap(s.Fields, func(item GoStructField, _ int) []*jen.Statement { // return item.renderDefinition(ctx) //}) - //res = append(res, jen.Type().Id(s.Name).Struct(utils.ToCode(code)...)) + //res = append(res, jen.Type().Id(s.Name).Type(utils.ToCode(code)...)) //return res - panic("not implemented") + s.definitionInfo = context.Context.CurrentDefinitionInfo() + return renderTemplate("lang/gostruct/definition", &s) } func (s GoStruct) U() string { @@ -57,8 +59,8 @@ func (s GoStruct) U() string { // return item.renderDefinition() //}) // - //return []*jen.Statement{jen.Struct(utils.ToCode(code)...)} - panic("not implemented") + //return []*jen.Statement{jen.Type(utils.ToCode(code)...)} + return renderTemplate("lang/gostruct/usage", &s) } //func (s GoStruct) NewFuncName() string { diff --git a/internal/render/lang/gotypealias.go b/internal/render/lang/gotypealias.go index d3f39f5..f73cd2e 100644 --- a/internal/render/lang/gotypealias.go +++ b/internal/render/lang/gotypealias.go @@ -2,6 +2,7 @@ package lang import ( "github.com/bdragon300/go-asyncapi/internal/common" + "github.com/bdragon300/go-asyncapi/internal/render/context" ) type GoTypeAlias struct { @@ -21,7 +22,8 @@ func (p GoTypeAlias) D() string { //aliasedStmt := utils.ToCode(p.AliasedType.D()) //res = append(res, jen.Type().Id(p.Name).Add(aliasedStmt...)) //return res - panic("not implemented") + p.definitionInfo = context.Context.CurrentDefinitionInfo() + return renderTemplate("lang/gotypealias/definition", &p) } func (p GoTypeAlias) U() string { @@ -39,10 +41,13 @@ func (p GoTypeAlias) U() string { //// Just use the underlying type then //aliasedStmt := utils.ToCode(p.AliasedType.U()) //return []*jen.Statement{jen.Add(aliasedStmt...)} - panic("not implemented") + return renderTemplate("lang/gotypealias/usage", &p) } -func (p GoTypeAlias) WrappedGolangType() (common.GolangType, bool) { +func (p GoTypeAlias) UnwrapGolangType() (common.GolangType, bool) { + if v, ok := p.AliasedType.(GolangTypeWrapperType); ok { + return v.UnwrapGolangType() + } return p.AliasedType, p.AliasedType != nil } diff --git a/internal/render/lang/govalue.go b/internal/render/lang/govalue.go index 46fd2c8..1f94312 100644 --- a/internal/render/lang/govalue.go +++ b/internal/render/lang/govalue.go @@ -2,7 +2,6 @@ package lang import ( "fmt" - "github.com/bdragon300/go-asyncapi/internal/render/context" "reflect" "github.com/bdragon300/go-asyncapi/internal/common" @@ -32,119 +31,8 @@ func (gv GoValue) Selectable() bool { return false } -func (gv GoValue) RenderContext() common.RenderContext { - return context.Context -} - func (gv GoValue) U() string { - //ctx.LogStartRender("GoValue", "", "", "usage", gv.IsDefinition(), "type", gv.Type) - //defer ctx.LogFinishRender() - // - //var valueStmt *j.Statement - //switch { - //case gv.LiteralValue != nil: - // ctx.Logger.Trace("LiteralValue", "value", gv.LiteralValue) - // valueStmt = j.Lit(gv.LiteralValue) - // if v, ok := gv.LiteralValue.(common.Renderer); ok { - // valueStmt = j.Add(utils.ToCode(v.RenderUsage())...) - // } - //case gv.MapValues.Len() > 0: - // ctx.Logger.Trace("MapValues", "value", gv.MapValues) - // valueStmt = j.Values(j.DictFunc(func(d j.Dict) { - // for _, e := range gv.MapValues.Entries() { - // l := []j.Code{j.Lit(e.Value)} - // if v, ok := e.Value.(common.Renderer); ok { - // l = utils.ToCode(v.RenderUsage()) - // } - // d[j.Lit(e.Key)] = j.Add(l...) - // } - // })) - //case gv.StructValues.Len() > 0: - // ctx.Logger.Trace("StructValues", "value", gv.StructValues) - // valueStmt = j.Values(j.DictFunc(func(d j.Dict) { - // for _, e := range gv.StructValues.Entries() { - // l := []j.Code{j.Lit(e.Value)} - // if v, ok := e.Value.(common.Renderer); ok { - // l = utils.ToCode(v.RenderUsage()) - // } - // d[j.Id(e.Key)] = j.Add(l...) - // } - // })) - //case gv.ArrayValues != nil: - // ctx.Logger.Trace("ArrayValues", "value", gv.ArrayValues) - // valueStmt = j.ValuesFunc(func(g *j.Group) { - // for _, v := range gv.ArrayValues { - // l := []j.Code{j.Lit(v)} - // if v, ok := v.(common.Renderer); ok { - // l = utils.ToCode(v.RenderUsage()) - // } - // g.Add(l...) - // } - // }) - //default: - // ctx.Logger.Trace("Empty", "value", lo.Ternary(gv.EmptyCurlyBrackets, "{}", "nil")) - // valueStmt = lo.Ternary(gv.EmptyCurlyBrackets, j.Values(), j.Nil()) - //} - // - //if gv.Type == nil { - // return []*j.Statement{valueStmt} - //} - // - //stmt := &j.Statement{} - //if v, ok := gv.Type.(GolangPointerWrapperType); ok && v.IsPointer() { - // ctx.Logger.Trace("pointer") - // if gv.Empty() { - // if gv.EmptyCurlyBrackets { - // // &{} -> ToPtr({}) - // return []*j.Statement{j.Qual(context.Context.RuntimeModule(""), "ToPtr").Call(j.Values())} - // } - // // &nil -> nil - // return []*j.Statement{j.Nil()} - // } - // if gv.LiteralValue != nil { - // if t, hasType := v.WrappedGolangType(); hasType { - // // &int(123) -> ToPtr(int(123)) - // return []*j.Statement{j.Qual(context.Context.RuntimeModule(""), "ToPtr").Call( - // j.Add(utils.ToCode(t.U())...).Call(valueStmt), - // )} - // } - // // &123 -> ToPtr(123) - // return []*j.Statement{j.Qual(context.Context.RuntimeModule(""), "ToPtr").Call(valueStmt)} - // } - // - // // &AnyType{} - // // &map[string]int{} - // // &[]int{} - // stmt = stmt.Op("&") - //} - //stmt = stmt.Add(utils.ToCode(gv.Type.U())...) - //if gv.LiteralValue != nil { - // // int(123) - // return []*j.Statement{stmt.Call(j.Add(valueStmt))} - //} - //return []*j.Statement{stmt.Add(valueStmt)} - panic("not implemented") -} - -func (gv GoValue) AsRenderer(v any) common.Renderer { - if r, ok := v.(common.Renderer); ok { - return r - } - return nil -} - -func (gv GoValue) AsPointerWrapperType(v any) GolangPointerWrapperType { - if r, ok := v.(GolangPointerWrapperType); ok { - return r - } - return nil -} - -func (gv GoValue) AsGolangType(v GolangPointerWrapperType) common.GolangType { - if r, ok := v.WrappedGolangType(); ok { - return r - } - return nil + return renderTemplate("lang/govalue/usage", &gv) } func (gv GoValue) Empty() bool { @@ -165,11 +53,12 @@ func (gv GoValue) String() string { return "GoValue nil" } -type stringAnyMap interface { - Entries() []lo.Entry[string, any] -} func ConstructGoValue(value any, excludeFields []string, overrideType common.GolangType) *GoValue { + type stringAnyMap interface { + Entries() []lo.Entry[string, any] + } + res := GoValue{Type: overrideType} if value == nil { return &res diff --git a/internal/render/lang/promise.go b/internal/render/lang/promise.go index a0a0dc6..3192716 100644 --- a/internal/render/lang/promise.go +++ b/internal/render/lang/promise.go @@ -3,7 +3,6 @@ package lang import ( "fmt" "github.com/bdragon300/go-asyncapi/internal/common" - "github.com/bdragon300/go-asyncapi/internal/render/context" "github.com/samber/lo" ) @@ -11,7 +10,7 @@ func NewPromise[T any](ref string, origin common.PromiseOrigin) *Promise[T] { return &Promise[T]{ref: ref, origin: origin} } -func NewCbPromise[T any](findCb func(item common.Renderer, path []string) bool, origin common.PromiseOrigin) *Promise[T] { +func NewCbPromise[T any](findCb func(item common.Renderable, path []string) bool, origin common.PromiseOrigin) *Promise[T] { return &Promise[T]{findCb: findCb, origin: origin} } @@ -19,7 +18,7 @@ type Promise[T any] struct { AssignErrorNote string // Optional error message additional note to be shown when assignment fails ref string origin common.PromiseOrigin - findCb func(item common.Renderer, path []string) bool + findCb func(item common.Renderable, path []string) bool target T assigned bool @@ -38,7 +37,7 @@ func (r *Promise[T]) Assigned() bool { return r.assigned } -func (r *Promise[T]) FindCallback() func(item common.Renderer, path []string) bool { +func (r *Promise[T]) FindCallback() func(item common.Renderable, path []string) bool { return r.findCb } @@ -54,10 +53,13 @@ func (r *Promise[T]) Origin() common.PromiseOrigin { return r.origin } -func (r *Promise[T]) WrappedGolangType() (common.GolangType, bool) { +func (r *Promise[T]) UnwrapGolangType() (common.GolangType, bool) { if !r.assigned { return nil, false } + if v, ok := any(r.target).(GolangTypeWrapperType); ok { + return v.UnwrapGolangType() + } v, ok := any(r.target).(common.GolangType) return v, ok } @@ -83,13 +85,13 @@ func (r *Promise[T]) IsStruct() bool { } // List links can only be PromiseOriginInternal, no way to set a callback in spec -func NewListCbPromise[T any](findCb func(item common.Renderer, path []string) bool) *ListPromise[T] { +func NewListCbPromise[T any](findCb func(item common.Renderable, path []string) bool) *ListPromise[T] { return &ListPromise[T]{findCb: findCb} } type ListPromise[T any] struct { AssignErrorNote string // Optional error message additional note to be shown when assignment fails - findCb func(item common.Renderer, path []string) bool + findCb func(item common.Renderable, path []string) bool targets []T assigned bool @@ -108,7 +110,7 @@ func (r *ListPromise[T]) Assigned() bool { return r.assigned } -func (r *ListPromise[T]) FindCallback() func(item common.Renderer, path []string) bool { +func (r *ListPromise[T]) FindCallback() func(item common.Renderable, path []string) bool { return r.findCb } @@ -116,42 +118,38 @@ func (r *ListPromise[T]) Targets() []T { return r.targets } -func NewRendererPromise(ref string, origin common.PromiseOrigin) *RendererPromise { - return &RendererPromise{ - Promise: *NewPromise[common.Renderer](ref, origin), +func NewRenderablePromise(ref string, origin common.PromiseOrigin) *RenderablePromise { + return &RenderablePromise{ + Promise: *NewPromise[common.Renderable](ref, origin), } } -type RendererPromise struct { - Promise[common.Renderer] +type RenderablePromise struct { + Promise[common.Renderable] // DirectRender marks the promise to be rendered directly, even if object it points to not marked to do so. // Be careful, in order to avoid duplicated object appearing in the output, this flag should be set only for // objects which are not marked to be rendered directly DirectRender bool } -func (r *RendererPromise) Kind() common.ObjectKind { +func (r *RenderablePromise) Kind() common.ObjectKind { return r.target.Kind() } -func (r *RendererPromise) D() string { +func (r *RenderablePromise) D() string { return r.target.D() } -func (r *RendererPromise) U() string { +func (r *RenderablePromise) U() string { return r.target.U() } -func (r *RendererPromise) Selectable() bool { +func (r *RenderablePromise) Selectable() bool { return r.DirectRender // Prevent rendering the object we're point to for several times } -func (r *RendererPromise) RenderContext() common.RenderContext { - return context.Context -} - -func (r *RendererPromise) String() string { - return "RendererPromise -> " + r.ref +func (r *RenderablePromise) String() string { + return "RenderablePromise -> " + r.ref } func NewGolangTypePromise(ref string, origin common.PromiseOrigin) *GolangTypePromise { @@ -180,8 +178,8 @@ func (r *GolangTypePromise) Selectable() bool { return r.DirectRender // Prevent rendering the object we're point to for several times } -func (r *GolangTypePromise) RenderContext() common.RenderContext { - return context.Context +func (r *GolangTypePromise) IsPointer() bool { + return r.target.IsPointer() } func (r *GolangTypePromise) D() string { @@ -192,6 +190,10 @@ func (r *GolangTypePromise) U() string { return r.target.U() } +func (r *GolangTypePromise) DefinitionInfo() (*common.GolangTypeDefinitionInfo, error) { + return r.target.DefinitionInfo() +} + func (r *GolangTypePromise) String() string { return "GolangTypePromise -> " + r.ref } diff --git a/internal/render/lang/union.go b/internal/render/lang/union.go index 31fee8d..797d7ec 100644 --- a/internal/render/lang/union.go +++ b/internal/render/lang/union.go @@ -33,7 +33,7 @@ func (s UnionStruct) D() string { // res = append(res, s.renderMethods()...) //} //return res - panic("not implemented") + return renderTemplate("lang/union/definition", &s) } func (s UnionStruct) UnionStruct() common.GolangType { @@ -93,19 +93,12 @@ func (s UnionStruct) UnionStruct() common.GolangType { // return res //} -func (s UnionStruct) AsGolangPointerType(v any) GolangPointerType { - if r, ok := v.(GolangPointerType); ok { - return r - } - return nil -} - func isTypeStruct(typ common.GolangType) bool { switch v := typ.(type) { case golangStructType: return v.IsStruct() case GolangTypeWrapperType: - t, ok := v.WrappedGolangType() + t, ok := v.UnwrapGolangType() return !ok || isTypeStruct(t) } return false diff --git a/internal/render/message.go b/internal/render/message.go index bf90da2..f682204 100644 --- a/internal/render/message.go +++ b/internal/render/message.go @@ -1,7 +1,6 @@ package render import ( - "github.com/bdragon300/go-asyncapi/internal/render/context" "github.com/bdragon300/go-asyncapi/internal/render/lang" "github.com/samber/lo" "sort" @@ -33,15 +32,20 @@ func (m Message) Selectable() bool { return !m.Dummy } -func (m Message) RenderContext() common.RenderContext { - return context.Context -} - func (m Message) EffectiveContentType() string { res, _ := lo.Coalesce(m.ContentType, m.AsyncAPIPromise.Target().EffectiveDefaultContentType()) return res } +func (m Message) BindingsProtocols() (res []string) { + if m.BindingsPromise != nil { + res = append(res, m.BindingsPromise.Target().Values.Keys()...) + res = append(res, m.BindingsPromise.Target().JSONValues.Keys()...) + } + return lo.Uniq(res) +} + + //func (m Message) Selectable() bool { // return !m.Dummy //} diff --git a/internal/render/mqtt/channel.go b/internal/render/mqtt/channel.go index 70a7292..7a8aeb7 100644 --- a/internal/render/mqtt/channel.go +++ b/internal/render/mqtt/channel.go @@ -3,7 +3,7 @@ package mqtt //type ProtoChannel struct { // *render.Channel // GolangNameProto string // Channel TypeNamePrefix name concatenated with protocol name, e.g. Channel1Kafka -// Struct *render.GoStruct +// Type *render.GoStruct // // ProtoName, ProtoTitle string //} @@ -19,7 +19,7 @@ package mqtt // res = append(res, pc.ServerIface.D(ctx)...) // res = append(res, pc.RenderOpenFunc(ctx)...) // res = append(res, pc.renderNewFunc(ctx)...) -// res = append(res, pc.Struct.D(ctx)...) +// res = append(res, pc.Type.D(ctx)...) // res = append(res, pc.RenderCommonMethods(ctx)...) // res = append(res, pc.renderProtoMethods(ctx)...) // if pc.Parent.Publisher { @@ -35,7 +35,7 @@ package mqtt //func (pc ProtoChannel) U(ctx *common.RenderContext) []*j.Statement { // ctx.LogStartRender("Channel", "", pc.Parent.Name, "usage", pc.Selectable(), "proto", pc.ProtoName) // defer ctx.LogFinishRender() -// return pc.Struct.U(ctx) +// return pc.Type.U(ctx) //} // //func (pc ProtoChannel) ID() string { @@ -51,7 +51,7 @@ package mqtt // // return []*j.Statement{ // // NewChannel1Proto(params Channel1Parameters, publisher proto.Publisher, subscriber proto.Subscriber) *Channel1Proto -// j.Func().Id(pc.Struct.NewFuncName()). +// j.Func().Id(pc.Type.NewFuncName()). // ParamsFunc(func(g *j.Group) { // if pc.Parent.ParametersType != nil { // g.Id("params").Add(utils.ToCode(pc.Parent.ParametersType.U(ctx))...) @@ -63,9 +63,9 @@ package mqtt // g.Id("subscriber").Qual(ctx.RuntimeModule(pc.ProtoName), "Subscriber") // } // }). -// Op("*").Add(utils.ToCode(pc.Struct.U(ctx))...). +// Op("*").Add(utils.ToCode(pc.Type.U(ctx))...). // BlockFunc(func(bg *j.Group) { -// bg.Op("res := ").Add(utils.ToCode(pc.Struct.U(ctx))...).Values(j.DictFunc(func(d j.Dict) { +// bg.Op("res := ").Add(utils.ToCode(pc.Type.U(ctx))...).Values(j.DictFunc(func(d j.Dict) { // d[j.Id("name")] = j.Id(pc.Parent.TypeNamePrefix + "Name").CallFunc(func(g *j.Group) { // if pc.Parent.ParametersType != nil { // g.Id("params") @@ -87,8 +87,8 @@ package mqtt //func (pc ProtoChannel) renderProtoMethods(ctx *common.RenderContext) []*j.Statement { // ctx.Logger.Trace("renderProtoMethods", "proto", pc.ProtoName) // -// rn := pc.Struct.ReceiverName() -// receiver := j.Id(rn).Id(pc.Struct.Name) +// rn := pc.Type.ReceiverName() +// receiver := j.Id(rn).Id(pc.Type.Name) // // return []*j.Statement{ // // Method Topic() string @@ -104,8 +104,8 @@ package mqtt //func (pc ProtoChannel) renderProtoPublisherMethods(ctx *common.RenderContext) []*j.Statement { // ctx.Logger.Trace("renderProtoPublisherMethods", "proto", pc.ProtoName) // -// rn := pc.Struct.ReceiverName() -// receiver := j.Id(rn).Id(pc.Struct.Name) +// rn := pc.Type.ReceiverName() +// receiver := j.Id(rn).Id(pc.Type.Name) // // var msgTyp common.GolangType = render.GoPointer{Type: pc.Parent.FallbackMessageType, HasDefinition: true} // if pc.Parent.PublisherMessageTypePromise != nil { diff --git a/internal/render/mqtt/server.go b/internal/render/mqtt/server.go index 347881d..353acbf 100644 --- a/internal/render/mqtt/server.go +++ b/internal/render/mqtt/server.go @@ -2,7 +2,7 @@ package mqtt //type ProtoServer struct { // Parent *render.Server -// Struct *render.GoStruct +// Type *render.GoStruct // // ProtoName, ProtoTitle string //} @@ -16,7 +16,7 @@ package mqtt // defer ctx.LogFinishRender() // var res []*j.Statement // res = append(res, ps.RenderNewFunc(ctx)...) -// res = append(res, ps.Struct.D(ctx)...) +// res = append(res, ps.Type.D(ctx)...) // res = append(res, ps.RenderCommonMethods(ctx)...) // res = append(res, ps.renderChannelMethods(ctx)...) // res = append(res, ps.RenderProducerMethods(ctx)...) @@ -27,7 +27,7 @@ package mqtt //func (ps ProtoServer) U(ctx *common.RenderContext) []*j.Statement { // ctx.LogStartRender("Server", "", ps.Parent.Name, "usage", ps.Selectable(), "proto", ps.ProtoName) // defer ctx.LogFinishRender() -// return ps.Struct.U(ctx) +// return ps.Type.U(ctx) //} // //func (ps ProtoServer) ID() string { @@ -46,7 +46,7 @@ package mqtt // for _, ch := range ps.Parent.GetRelevantChannels() { // protoChan := ch.AllProtoChannels[ps.ProtoName].(*ProtoChannel) // res = append(res, -// ps.RenderOpenChannelMethod(ctx, protoChan.Struct, protoChan, protoChan.Parent.ParametersType)..., +// ps.RenderOpenChannelMethod(ctx, protoChan.Type, protoChan, protoChan.Parent.ParametersType)..., // ) // } // return res diff --git a/internal/render/parameter.go b/internal/render/parameter.go index 694fca7..2242fd4 100644 --- a/internal/render/parameter.go +++ b/internal/render/parameter.go @@ -2,7 +2,6 @@ package render import ( "github.com/bdragon300/go-asyncapi/internal/common" - "github.com/bdragon300/go-asyncapi/internal/render/context" ) type Parameter struct { @@ -20,10 +19,6 @@ func (p Parameter) Selectable() bool { return !p.Dummy && p.Type.Selectable() } -func (p Parameter) RenderContext() common.RenderContext { - return context.Context -} - //func (p Parameter) D(ctx *common.RenderContext) []*j.Statement { // var res []*j.Statement // ctx.LogStartRender("Parameter", "", p.Name, "definition", p.Selectable()) diff --git a/internal/render/proto/channel.go b/internal/render/proto/channel.go index e3a85d0..bc08707 100644 --- a/internal/render/proto/channel.go +++ b/internal/render/proto/channel.go @@ -3,7 +3,7 @@ package proto //type ProtoChannel struct { // *render.Channel // GolangNameProto string // Channel TypeNamePrefix name concatenated with protocol name, e.g. Channel1Kafka -// Struct *render.GoStruct +// Type *render.GoStruct // // ProtoName, ProtoTitle string //} @@ -13,7 +13,7 @@ package proto //type BaseProtoChannel struct { // Parent *render.Channel // GolangNameProto string // Channel TypeNamePrefix name concatenated with protocol name, e.g. Channel1Kafka -// Struct *render.GoStruct +// Type *render.GoStruct // //ServerIface *render.GoInterface // // ProtoName, ProtoTitle string @@ -22,8 +22,8 @@ package proto //func (pc BaseProtoChannel) RenderCommonSubscriberMethods(ctx *common.RenderContext) []*j.Statement { // ctx.Logger.Trace("RenderCommonSubscriberMethods", "proto", pc.ProtoName) // -// rn := pc.Struct.ReceiverName() -// receiver := j.Id(rn).Id(pc.Struct.Name) +// rn := pc.Type.ReceiverName() +// receiver := j.Id(rn).Id(pc.Type.Name) // var msgTyp common.GolangType = render.GoPointer{Type: pc.Parent.FallbackMessageType, HasDefinition: true} // if pc.Parent.SubscribeMessageTypePromise != nil { // msgTyp = render.GoPointer{Type: pc.Parent.SubscribeMessageTypePromise.Target().InType, HasDefinition: true} @@ -74,8 +74,8 @@ package proto //func (pc BaseProtoChannel) RenderCommonPublisherMethods(ctx *common.RenderContext) []*j.Statement { // ctx.Logger.Trace("RenderCommonPublisherMethods", "proto", pc.ProtoName) // -// rn := pc.Struct.ReceiverName() -// receiver := j.Id(rn).Id(pc.Struct.Name) +// rn := pc.Type.ReceiverName() +// receiver := j.Id(rn).Id(pc.Type.Name) // // return []*j.Statement{ // // Method Publisher() proto.Publisher @@ -102,8 +102,8 @@ package proto //func (pc BaseProtoChannel) RenderCommonMethods(ctx *common.RenderContext) []*j.Statement { // ctx.Logger.Trace("RenderCommonMethods", "proto", pc.ProtoName) // -// rn := pc.Struct.ReceiverName() -// receiver := j.Id(rn).Id(pc.Struct.Name) +// rn := pc.Type.ReceiverName() +// receiver := j.Id(rn).Id(pc.Type.Name) // // return []*j.Statement{ // // Method Name() string @@ -147,7 +147,7 @@ package proto // } // g.Id("servers").Op("...").Add(utils.ToCode(pc.ServerIface.U(ctx))...) // }). -// Params(j.Op("*").Ad d(utils.ToCode(pc.Struct.U(ctx))...), j.Error()). +// Params(j.Op("*").Ad d(utils.ToCode(pc.Type.U(ctx))...), j.Error()). // BlockFunc(func(bg *j.Group) { // bg.Op("if len(servers) == 0").Block(j.Op("return nil, ").Qual(ctx.RuntimeModule(""), "ErrEmptyServers")) // if pc.Parent.Publisher || pc.Parent.Subscriber { @@ -226,7 +226,7 @@ package proto // Types(j.Qual(ctx.RuntimeModule(pc.ProtoName), "EnvelopeReader"), j.Qual(ctx.RuntimeModule(pc.ProtoName), "Subscriber")). // Op("{Subscribers: subs}") // } -// bg.Op("ch := ").Id(pc.Struct.NewFuncName()).CallFunc(func(g *j.Group) { +// bg.Op("ch := ").Id(pc.Type.NewFuncName()).CallFunc(func(g *j.Group) { // if pc.Parent.ParametersType != nil { // g.Id("params") // } diff --git a/internal/render/proto/server.go b/internal/render/proto/server.go index d29565f..ae76ad2 100644 --- a/internal/render/proto/server.go +++ b/internal/render/proto/server.go @@ -2,7 +2,7 @@ package proto //type BaseProtoServer struct { // Parent *render.Server -// Struct *render.GoStruct +// Type *render.GoStruct // // ProtoName, ProtoTitle string //} @@ -12,14 +12,14 @@ package proto // // return []*j.Statement{ // // NewServer1(producer proto.Producer, consumer proto.Consumer) *Server1 -// j.Func().Id(ps.Struct.NewFuncName()). +// j.Func().Id(ps.Type.NewFuncName()). // ParamsFunc(func(g *j.Group) { // g.Id("producer").Qual(ctx.RuntimeModule(ps.ProtoName), "Producer") // g.Id("consumer").Qual(ctx.RuntimeModule(ps.ProtoName), "Consumer") // }). -// Op("*").Add(utils.ToCode(ps.Struct.U(ctx))...). +// Op("*").Add(utils.ToCode(ps.Type.U(ctx))...). // Block( -// j.Return(j.Op("&").Add(utils.ToCode(ps.Struct.U(ctx))...).Values(j.DictFunc(func(d j.Dict) { +// j.Return(j.Op("&").Add(utils.ToCode(ps.Type.U(ctx))...).Values(j.DictFunc(func(d j.Dict) { // d[j.Id("producer")] = j.Id("producer") // d[j.Id("consumer")] = j.Id("consumer") // }))), @@ -30,7 +30,7 @@ package proto //func (ps BaseProtoServer) RenderCommonMethods(ctx *common.RenderContext) []*j.Statement { // ctx.Logger.Trace("RenderCommonMethods", "proto", ps.ProtoName) // -// receiver := j.Id(ps.Struct.ReceiverName()).Id(ps.Struct.Name) +// receiver := j.Id(ps.Type.ReceiverName()).Id(ps.Type.Name) // // return []*j.Statement{ // // Method Name() string @@ -46,8 +46,8 @@ package proto //func (ps BaseProtoServer) RenderOpenChannelMethod(ctx *common.RenderContext, channelStruct *render.GoStruct, channel common.Renderer, channelParametersStructNoRender *render.GoStruct) []*j.Statement { // ctx.Logger.Trace("RenderOpenChannelMethod", "proto", ps.ProtoName) // -// rn := ps.Struct.ReceiverName() -// receiver := j.Id(rn).Id(ps.Struct.Name) +// rn := ps.Type.ReceiverName() +// receiver := j.Id(rn).Id(ps.Type.Name) // // return []*j.Statement{ // // Method OpenChannel1Proto(ctx context.Context, params Channel1Parameters) (*Channel1Proto, error) @@ -74,8 +74,8 @@ package proto //func (ps BaseProtoServer) RenderProducerMethods(ctx *common.RenderContext) []*j.Statement { // ctx.Logger.Trace("RenderProducerMethods", "proto", ps.ProtoName) // -// rn := ps.Struct.ReceiverName() -// receiver := j.Id(rn).Id(ps.Struct.Name) +// rn := ps.Type.ReceiverName() +// receiver := j.Id(rn).Id(ps.Type.Name) // // return []*j.Statement{ // // Method Producer() proto.Producer @@ -91,8 +91,8 @@ package proto //func (ps BaseProtoServer) RenderConsumerMethods(ctx *common.RenderContext) []*j.Statement { // ctx.Logger.Trace("RenderConsumerMethods", "proto", ps.ProtoName) // -// rn := ps.Struct.ReceiverName() -// receiver := j.Id(rn).Id(ps.Struct.Name) +// rn := ps.Type.ReceiverName() +// receiver := j.Id(rn).Id(ps.Type.Name) // // return []*j.Statement{ // // Method Consumer() proto.Consumer diff --git a/internal/render/redis/channel.go b/internal/render/redis/channel.go index 1cca9e4..448d1a4 100644 --- a/internal/render/redis/channel.go +++ b/internal/render/redis/channel.go @@ -3,7 +3,7 @@ package redis //type ProtoChannel struct { // *render.Channel // GolangNameProto string // Channel TypeNamePrefix name concatenated with protocol name, e.g. Channel1Kafka -// Struct *render.GoStruct +// Type *render.GoStruct // // ProtoName, ProtoTitle string //} @@ -19,7 +19,7 @@ package redis // res = append(res, pc.ServerIface.D(ctx)...) // res = append(res, pc.RenderOpenFunc(ctx)...) // res = append(res, pc.renderNewFunc(ctx)...) -// res = append(res, pc.Struct.D(ctx)...) +// res = append(res, pc.Type.D(ctx)...) // res = append(res, pc.RenderCommonMethods(ctx)...) // res = append(res, pc.renderProtoMethods(ctx)...) // if pc.Parent.Publisher { @@ -35,7 +35,7 @@ package redis //func (pc ProtoChannel) U(ctx *common.RenderContext) []*j.Statement { // ctx.LogStartRender("Channel", "", pc.Parent.Name, "usage", pc.Selectable(), "proto", pc.ProtoName) // defer ctx.LogFinishRender() -// return pc.Struct.U(ctx) +// return pc.Type.U(ctx) //} // //func (pc ProtoChannel) ID() string { @@ -51,7 +51,7 @@ package redis // // return []*j.Statement{ // // NewChannel1Proto(params Channel1Parameters, publisher proto.Publisher, subscriber proto.Subscriber) *Channel1Proto -// j.Func().Id(pc.Struct.NewFuncName()). +// j.Func().Id(pc.Type.NewFuncName()). // ParamsFunc(func(g *j.Group) { // if pc.Parent.ParametersType != nil { // g.Id("params").Add(utils.ToCode(pc.Parent.ParametersType.U(ctx))...) @@ -63,9 +63,9 @@ package redis // g.Id("subscriber").Qual(ctx.RuntimeModule(pc.ProtoName), "Subscriber") // } // }). -// Op("*").Add(utils.ToCode(pc.Struct.U(ctx))...). +// Op("*").Add(utils.ToCode(pc.Type.U(ctx))...). // BlockFunc(func(bg *j.Group) { -// bg.Op("res := ").Add(utils.ToCode(pc.Struct.U(ctx))...).Values(j.DictFunc(func(d j.Dict) { +// bg.Op("res := ").Add(utils.ToCode(pc.Type.U(ctx))...).Values(j.DictFunc(func(d j.Dict) { // d[j.Id("name")] = j.Id(pc.Parent.TypeNamePrefix + "Name").CallFunc(func(g *j.Group) { // if pc.Parent.ParametersType != nil { // g.Id("params") @@ -90,8 +90,8 @@ package redis //func (pc ProtoChannel) renderProtoPublisherMethods(ctx *common.RenderContext) []*j.Statement { // ctx.Logger.Trace("renderProtoPublisherMethods", "proto", pc.ProtoName) // -// rn := pc.Struct.ReceiverName() -// receiver := j.Id(rn).Id(pc.Struct.Name) +// rn := pc.Type.ReceiverName() +// receiver := j.Id(rn).Id(pc.Type.Name) // // var msgTyp common.GolangType = render.GoPointer{Type: pc.Parent.FallbackMessageType, HasDefinition: true} // if pc.Parent.PublisherMessageTypePromise != nil { diff --git a/internal/render/redis/server.go b/internal/render/redis/server.go index a750579..e5a5081 100644 --- a/internal/render/redis/server.go +++ b/internal/render/redis/server.go @@ -2,7 +2,7 @@ package redis //type ProtoServer struct { // Parent *render.Server -// Struct *render.GoStruct +// Type *render.GoStruct // // ProtoName, ProtoTitle string //} @@ -16,7 +16,7 @@ package redis // defer ctx.LogFinishRender() // var res []*j.Statement // res = append(res, ps.RenderNewFunc(ctx)...) -// res = append(res, ps.Struct.D(ctx)...) +// res = append(res, ps.Type.D(ctx)...) // res = append(res, ps.RenderCommonMethods(ctx)...) // res = append(res, ps.renderChannelMethods(ctx)...) // res = append(res, ps.RenderProducerMethods(ctx)...) @@ -27,7 +27,7 @@ package redis //func (ps ProtoServer) U(ctx *common.RenderContext) []*j.Statement { // ctx.LogStartRender("Server", "", ps.Parent.Name, "usage", ps.Selectable(), "proto", ps.ProtoName) // defer ctx.LogFinishRender() -// return ps.Struct.U(ctx) +// return ps.Type.U(ctx) //} // //func (ps ProtoServer) ID() string { @@ -46,7 +46,7 @@ package redis // for _, ch := range ps.Parent.GetRelevantChannels() { // protoChan := ch.AllProtoChannels[ps.ProtoName].(*ProtoChannel) // res = append(res, -// ps.RenderOpenChannelMethod(ctx, protoChan.Struct, protoChan, protoChan.Parent.ParametersType)..., +// ps.RenderOpenChannelMethod(ctx, protoChan.Type, protoChan, protoChan.Parent.ParametersType)..., // ) // } // return res diff --git a/internal/render/server.go b/internal/render/server.go index 8b6337b..8762d43 100644 --- a/internal/render/server.go +++ b/internal/render/server.go @@ -33,10 +33,6 @@ func (s Server) Selectable() bool { return !s.Dummy } -func (s Server) RenderContext() common.RenderContext { - return context.Context -} - //func (s Server) D(ctx *common.RenderContext) []*j.Statement { // var res []*j.Statement // ctx.LogStartRender("Server", "", s.Name, "definition", s.Selectable()) @@ -135,11 +131,15 @@ func (s Server) GetRelevantChannels() []*Channel { }) } -func (c Server) BindingsProtocols() []string { - panic("not implemented") +func (c Server) BindingsProtocols() (res []string) { + if c.BindingsPromise != nil { + res = append(res, c.BindingsPromise.Target().Values.Keys()...) + res = append(res, c.BindingsPromise.Target().JSONValues.Keys()...) + } + return lo.Uniq(res) } -func (c Server) ProtoBindingsValue(protoName string) common.Renderer { +func (c Server) ProtoBindingsValue(protoName string) common.Renderable { res := &lang.GoValue{ Type: &lang.GoSimple{Name: "ServerBindings", Import: context.Context.RuntimeModule(protoName)}, EmptyCurlyBrackets: true, @@ -155,7 +155,7 @@ func (c Server) ProtoBindingsValue(protoName string) common.Renderer { type ProtoServer struct { *Server - Struct *lang.GoStruct // Nil if server is dummy or has unsupported protocol + Type *lang.GoStruct // Nil if server is dummy or has unsupported protocol ProtoName string } \ No newline at end of file diff --git a/internal/render/servervariable.go b/internal/render/servervariable.go index a759493..fdcecc3 100644 --- a/internal/render/servervariable.go +++ b/internal/render/servervariable.go @@ -2,7 +2,6 @@ package render import ( "github.com/bdragon300/go-asyncapi/internal/common" - "github.com/bdragon300/go-asyncapi/internal/render/context" ) type ServerVariable struct { @@ -20,9 +19,6 @@ func (s ServerVariable) Selectable() bool { return false } -func (s ServerVariable) RenderContext() common.RenderContext { - return context.Context -} // //func (s ServerVariable) D(_ *common.RenderContext) []*j.Statement { // panic("not implemented") diff --git a/internal/render/tcp/channel.go b/internal/render/tcp/channel.go index b50bc75..807d1f6 100644 --- a/internal/render/tcp/channel.go +++ b/internal/render/tcp/channel.go @@ -3,7 +3,7 @@ package tcp //type ProtoChannel struct { // *render.Channel // GolangNameProto string // Channel TypeNamePrefix name concatenated with protocol name, e.g. Channel1Kafka -// Struct *render.GoStruct +// Type *render.GoStruct // // ProtoName, ProtoTitle string //} @@ -19,7 +19,7 @@ package tcp // res = append(res, pc.ServerIface.D(ctx)...) // res = append(res, pc.RenderOpenFunc(ctx)...) // res = append(res, pc.renderNewFunc(ctx)...) -// res = append(res, pc.Struct.D(ctx)...) +// res = append(res, pc.Type.D(ctx)...) // res = append(res, pc.RenderCommonMethods(ctx)...) // res = append(res, pc.renderProtoMethods(ctx)...) // if pc.Parent.Publisher { @@ -35,7 +35,7 @@ package tcp //func (pc ProtoChannel) U(ctx *common.RenderContext) []*j.Statement { // ctx.LogStartRender("Channel", "", pc.Parent.Name, "usage", pc.Selectable(), "proto", pc.ProtoName) // defer ctx.LogFinishRender() -// return pc.Struct.U(ctx) +// return pc.Type.U(ctx) //} //func (pc ProtoChannel) ID() string { @@ -51,7 +51,7 @@ package tcp // // return []*j.Statement{ // // NewChannel1Proto(params Channel1Parameters, publisher proto.Publisher, subscriber proto.Subscriber) *Channel1Proto -// j.Func().Id(pc.Struct.NewFuncName()). +// j.Func().Id(pc.Type.NewFuncName()). // ParamsFunc(func(g *j.Group) { // if pc.Parent.ParametersType != nil { // g.Id("params").Add(utils.ToCode(pc.Parent.ParametersType.U(ctx))...) @@ -63,9 +63,9 @@ package tcp // g.Id("subscriber").Qual(ctx.RuntimeModule(pc.ProtoName), "Subscriber") // } // }). -// Op("*").Add(utils.ToCode(pc.Struct.U(ctx))...). +// Op("*").Add(utils.ToCode(pc.Type.U(ctx))...). // BlockFunc(func(bg *j.Group) { -// bg.Op("res := ").Add(utils.ToCode(pc.Struct.U(ctx))...).Values(j.DictFunc(func(d j.Dict) { +// bg.Op("res := ").Add(utils.ToCode(pc.Type.U(ctx))...).Values(j.DictFunc(func(d j.Dict) { // d[j.Id("name")] = j.Id(pc.Parent.TypeNamePrefix + "Name").CallFunc(func(g *j.Group) { // if pc.Parent.ParametersType != nil { // g.Id("params") @@ -90,8 +90,8 @@ package tcp //func (pc ProtoChannel) renderProtoPublisherMethods(ctx *common.RenderContext) []*j.Statement { // ctx.Logger.Trace("renderProtoPublisherMethods", "proto", pc.ProtoName) // -// rn := pc.Struct.ReceiverName() -// receiver := j.Id(rn).Id(pc.Struct.Name) +// rn := pc.Type.ReceiverName() +// receiver := j.Id(rn).Id(pc.Type.Name) // // var msgTyp common.GolangType = render.GoPointer{Type: pc.Parent.FallbackMessageType, HasDefinition: true} // if pc.Parent.PublisherMessageTypePromise != nil { diff --git a/internal/render/tcp/server.go b/internal/render/tcp/server.go index a70f355..9f916d8 100644 --- a/internal/render/tcp/server.go +++ b/internal/render/tcp/server.go @@ -2,7 +2,7 @@ package tcp //type ProtoServer struct { // Parent *render.Server -// Struct *render.GoStruct +// Type *render.GoStruct // // ProtoName, ProtoTitle string //} @@ -16,7 +16,7 @@ package tcp // defer ctx.LogFinishRender() // var res []*j.Statement // res = append(res, ps.RenderNewFunc(ctx)...) -// res = append(res, ps.Struct.D(ctx)...) +// res = append(res, ps.Type.D(ctx)...) // res = append(res, ps.RenderCommonMethods(ctx)...) // res = append(res, ps.renderChannelMethods(ctx)...) // res = append(res, ps.RenderProducerMethods(ctx)...) @@ -27,7 +27,7 @@ package tcp //func (ps ProtoServer) U(ctx *common.RenderContext) []*j.Statement { // ctx.LogStartRender("Server", "", ps.Parent.Name, "usage", ps.Selectable(), "proto", ps.ProtoName) // defer ctx.LogFinishRender() -// return ps.Struct.U(ctx) +// return ps.Type.U(ctx) //} // //func (ps ProtoServer) ID() string { @@ -46,7 +46,7 @@ package tcp // for _, ch := range ps.Parent.GetRelevantChannels() { // protoChan := ch.AllProtoChannels[ps.ProtoName].(*ProtoChannel) // res = append(res, -// ps.RenderOpenChannelMethod(ctx, protoChan.Struct, protoChan, protoChan.Parent.ParametersType)..., +// ps.RenderOpenChannelMethod(ctx, protoChan.Type, protoChan, protoChan.Parent.ParametersType)..., // ) // } // return res diff --git a/internal/render/template.go b/internal/render/template.go index e465d87..6f05aa0 100644 --- a/internal/render/template.go +++ b/internal/render/template.go @@ -1,14 +1,17 @@ package render import ( + "fmt" "github.com/bdragon300/go-asyncapi/internal/common" "github.com/bdragon300/go-asyncapi/internal/render/context" "github.com/bdragon300/go-asyncapi/internal/render/lang" - "github.com/bdragon300/go-asyncapi/templates" + "github.com/bdragon300/go-asyncapi/internal/tpl" + "github.com/bdragon300/go-asyncapi/internal/utils" "github.com/go-sprout/sprout" "github.com/samber/lo" "strings" "text/template" + "unicode" ) var templateFunctions sprout.FunctionMap @@ -19,11 +22,11 @@ func init() { } type TemplateSelections struct { - Objects []common.Renderer + Objects []common.Renderable } -func (r TemplateSelections) SelectLangs() []common.Renderer { - return lo.Filter(r.Objects, func(item common.Renderer, _ int) bool { +func (r TemplateSelections) SelectLangs() []common.Renderable { + return lo.Filter(r.Objects, func(item common.Renderable, _ int) bool { return item.Kind() == common.ObjectKindLang }) } @@ -80,6 +83,7 @@ func (r TemplateSelections) SelectAsyncAPI() *AsyncAPI { return res[0] } + func NewTemplateContext(renderContext *context.RenderContextImpl, selections TemplateSelections) TemplateContext { return TemplateContext{ renderContext: renderContext, @@ -88,7 +92,7 @@ func NewTemplateContext(renderContext *context.RenderContextImpl, selections Tem } type TemplateContext struct { - renderContext *context.RenderContextImpl + renderContext *context.RenderContextImpl objectSelections TemplateSelections } @@ -96,62 +100,126 @@ func (t TemplateContext) Selections() TemplateSelections { return t.objectSelections } -func (t TemplateContext) RenderContext() common.RenderContext { - return t.renderContext -} -// TODO: make just functions? -func (t TemplateContext) templateGoLit(val any) string { - panic("not implemented") +func GetTemplateFunctions(ctx common.RenderContext) template.FuncMap { + extraFuncs := template.FuncMap{ + "golit": func(val any) string { return templateGoLit(val) }, + "goptr": func(val common.GolangType) (*lang.GoPointer, error) { return templateGoPtr(val) }, + "unwrapgoptr": func(val common.GolangType) common.GolangType { + if v, ok := any(val).(lang.GolangTypeWrapperType); ok { + if wt, ok := v.UnwrapGolangType(); ok { + return wt + } + } + return nil + }, + "goid": func(name string) string { return templateGoID(name) }, + "gocomment": func(text string) (string, error) { return templateGoComment(text) }, + "qual": func(parts ...string) string { return ctx.QualifiedName(parts...) }, + "qualgenpkg": func(obj common.GolangType) (string, error) { + pkg, err := ctx.QualifiedGeneratedPackage(obj) + if pkg == "" { + return "", err + } + return pkg + ".", err + }, + "qualrun": func(parts ...string) string { return ctx.QualifiedRuntimeName(parts...) }, // TODO: check if .Import and qual is enough + "runTemplate": func(templateName string, ctx any) (string, error) { + tmpl := tpl.LoadTemplate(templateName) + var bld strings.Builder + if err := tmpl.Execute(&bld, ctx); err != nil { + return "", err + } + return bld.String(), nil + }, + } + + return lo.Assign(templateFunctions, extraFuncs) } -func (t TemplateContext) templateGoPtr(val any) string { - panic("not implemented") + +func templateGoLit(val any) string { + type usageDrawable interface { + U() string + } + + var res string + switch val.(type) { + case usageDrawable: + return val.(usageDrawable).U() + case bool, string, int, complex128: + // default constant types can be left bare + return fmt.Sprintf("%#v", val) + case float64: + res = fmt.Sprintf("%#v", val) + if !strings.Contains(res, ".") && !strings.Contains(res, "e") { + // If the formatted value is not in scientific notation, and does not have a dot, then + // we add ".0". Otherwise, it will be interpreted as an int. + // See: + // https://github.com/dave/jennifer/issues/39 + // https://github.com/golang/go/issues/26363 + res += ".0" + } + return res + case float32, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, uintptr: + // other built-in types need specific type info + return fmt.Sprintf("%T(%#v)", val, val) + case complex64: + // fmt package already renders parenthesis for complex64 + return fmt.Sprintf("%T%#v", val, val) + } + + panic(fmt.Sprintf("unsupported type for literal: %T", val)) } -func (t TemplateContext) templateGoID(val any) string { - panic("not implemented") +func templateGoPtr(val common.GolangType) (*lang.GoPointer, error) { + if val == nil { + return nil, fmt.Errorf("cannot get a pointer to nil") + } + return &lang.GoPointer{Type: val}, nil } -func (t TemplateContext) templateGoComment(text string) string { - panic("not implemented") +func templateGoID(val string) string { + if val == "" { + return "" + } + return utils.ToGolangName(val, unicode.IsUpper(rune(val[0]))) } -func GetTemplateFunctions(t *TemplateContext) template.FuncMap { - extraFuncs := template.FuncMap{ - "golit": func(val any) string { return t.templateGoLit(val) }, - "goptr": func(val any) string { return t.templateGoPtr(val) }, - "goid": func(val any) string { return t.templateGoID(val) }, - "gocomment": func(text string) string { return t.templateGoComment(text) }, - "qual": func(pkgExpr string) string { return t.renderContext.QualifiedName(pkgExpr) }, - "qualg": func(subPkg, name string) string { return t.renderContext.QualifiedGeneratedName(subPkg, name) }, - "qualr": func(subPkg, name string) string { return t.renderContext.QualifiedRuntimeName(subPkg, name) }, - "runTemplate": func(templateName string, ctx any) (string, error) { - // TODO: template dir - tpl := template.Must(template.ParseFS(templates.Templates)) - var bld strings.Builder - if err := tpl.Execute(&bld, ctx); err != nil { +func templateGoComment(text string) (string, error) { + if strings.HasPrefix(text, "//") || strings.HasPrefix(text, "/*") { + // automatic formatting disabled. + return text, nil + } + + var b strings.Builder + if strings.Contains(text, "\n") { + if _, err := b.WriteString("/*\n"); err != nil { + return "", err + } + } else { + if _, err := b.WriteString("// "); err != nil { + return "", err + } + } + if _, err := b.WriteString(text); err != nil { + return "", err + } + if strings.Contains(text, "\n") { + if !strings.HasSuffix(text, "\n") { + if _, err := b.WriteString("\n"); err != nil { return "", err } - return bld.String(), nil - }, - "contentTypeID": func(contentType string) string { - // TODO: add other formats: protobuf, avro, etc. - switch { - case strings.HasSuffix(contentType, "json"): - return "json" - case strings.HasSuffix(contentType, "yaml"): - return "yaml" - } - return "" - }, + } + if _, err := b.WriteString("*/"); err != nil { + return "", err + } } - - return lo.Assign(templateFunctions, extraFuncs) + return b.String(), nil } -func selectObjects[T common.Renderer](selections []common.Renderer, kind common.ObjectKind) []T { - return lo.FilterMap(selections, func(item common.Renderer, _ int) (T, bool) { +func selectObjects[T common.Renderable](selections []common.Renderable, kind common.ObjectKind) []T { + return lo.FilterMap(selections, func(item common.Renderable, _ int) (T, bool) { if item.Kind() == kind { return item.(T), true } diff --git a/internal/render/udp/channel.go b/internal/render/udp/channel.go index 886b664..96a47bf 100644 --- a/internal/render/udp/channel.go +++ b/internal/render/udp/channel.go @@ -3,7 +3,7 @@ package udp //type ProtoChannel struct { // *render.Channel // GolangNameProto string // Channel TypeNamePrefix name concatenated with protocol name, e.g. Channel1Kafka -// Struct *render.GoStruct +// Type *render.GoStruct // // ProtoName, ProtoTitle string //} @@ -19,7 +19,7 @@ package udp // res = append(res, pc.ServerIface.D(ctx)...) // res = append(res, pc.RenderOpenFunc(ctx)...) // res = append(res, pc.renderNewFunc(ctx)...) -// res = append(res, pc.Struct.D(ctx)...) +// res = append(res, pc.Type.D(ctx)...) // res = append(res, pc.RenderCommonMethods(ctx)...) // res = append(res, pc.renderProtoMethods(ctx)...) // if pc.Parent.Publisher { @@ -35,7 +35,7 @@ package udp //func (pc ProtoChannel) U(ctx *common.RenderContext) []*j.Statement { // ctx.LogStartRender("Channel", "", pc.Parent.Name, "usage", pc.Selectable(), "proto", pc.ProtoName) // defer ctx.LogFinishRender() -// return pc.Struct.U(ctx) +// return pc.Type.U(ctx) //} // //func (pc ProtoChannel) ID() string { @@ -51,7 +51,7 @@ package udp // // return []*j.Statement{ // // NewChannel1Proto(params Channel1Parameters, publisher proto.Publisher, subscriber proto.Subscriber) *Channel1Proto -// j.Func().Id(pc.Struct.NewFuncName()). +// j.Func().Id(pc.Type.NewFuncName()). // ParamsFunc(func(g *j.Group) { // if pc.Parent.ParametersType != nil { // g.Id("params").Add(utils.ToCode(pc.Parent.ParametersType.U(ctx))...) @@ -63,9 +63,9 @@ package udp // g.Id("subscriber").Qual(ctx.RuntimeModule(pc.ProtoName), "Subscriber") // } // }). -// Op("*").Add(utils.ToCode(pc.Struct.U(ctx))...). +// Op("*").Add(utils.ToCode(pc.Type.U(ctx))...). // BlockFunc(func(bg *j.Group) { -// bg.Op("res := ").Add(utils.ToCode(pc.Struct.U(ctx))...).Values(j.DictFunc(func(d j.Dict) { +// bg.Op("res := ").Add(utils.ToCode(pc.Type.U(ctx))...).Values(j.DictFunc(func(d j.Dict) { // d[j.Id("name")] = j.Id(pc.Parent.TypeNamePrefix + "Name").CallFunc(func(g *j.Group) { // if pc.Parent.ParametersType != nil { // g.Id("params") @@ -90,8 +90,8 @@ package udp //func (pc ProtoChannel) renderProtoPublisherMethods(ctx *common.RenderContext) []*j.Statement { // ctx.Logger.Trace("renderProtoPublisherMethods", "proto", pc.ProtoName) // -// rn := pc.Struct.ReceiverName() -// receiver := j.Id(rn).Id(pc.Struct.Name) +// rn := pc.Type.ReceiverName() +// receiver := j.Id(rn).Id(pc.Type.Name) // // var msgTyp common.GolangType = render.GoPointer{Type: pc.Parent.FallbackMessageType, HasDefinition: true} // if pc.Parent.PublisherMessageTypePromise != nil { diff --git a/internal/render/udp/server.go b/internal/render/udp/server.go index ff053d0..8a4a77b 100644 --- a/internal/render/udp/server.go +++ b/internal/render/udp/server.go @@ -2,7 +2,7 @@ package udp //type ProtoServer struct { // Parent *render.Server -// Struct *render.GoStruct +// Type *render.GoStruct // // ProtoName, ProtoTitle string //} @@ -16,7 +16,7 @@ package udp // defer ctx.LogFinishRender() // var res []*j.Statement // res = append(res, ps.RenderNewFunc(ctx)...) -// res = append(res, ps.Struct.D(ctx)...) +// res = append(res, ps.Type.D(ctx)...) // res = append(res, ps.RenderCommonMethods(ctx)...) // res = append(res, ps.renderChannelMethods(ctx)...) // res = append(res, ps.RenderProducerMethods(ctx)...) @@ -27,7 +27,7 @@ package udp //func (ps ProtoServer) U(ctx *common.RenderContext) []*j.Statement { // ctx.LogStartRender("Server", "", ps.Parent.Name, "usage", ps.Selectable(), "proto", ps.ProtoName) // defer ctx.LogFinishRender() -// return ps.Struct.U(ctx) +// return ps.Type.U(ctx) //} // //func (ps ProtoServer) ID() string { @@ -46,7 +46,7 @@ package udp // for _, ch := range ps.Parent.GetRelevantChannels() { // protoChan := ch.AllProtoChannels[ps.ProtoName].(*ProtoChannel) // res = append(res, -// ps.RenderOpenChannelMethod(ctx, protoChan.Struct, protoChan, protoChan.Parent.ParametersType)..., +// ps.RenderOpenChannelMethod(ctx, protoChan.Type, protoChan, protoChan.Parent.ParametersType)..., // ) // } // return res diff --git a/internal/render/ws/channel.go b/internal/render/ws/channel.go index 6a33b80..6bcd294 100644 --- a/internal/render/ws/channel.go +++ b/internal/render/ws/channel.go @@ -3,7 +3,7 @@ package ws //type ProtoChannel struct { // *render.Channel // GolangNameProto string // Channel TypeNamePrefix name concatenated with protocol name, e.g. Channel1Kafka -// Struct *render.GoStruct +// Type *render.GoStruct // // ProtoName, ProtoTitle string //} @@ -19,7 +19,7 @@ package ws // res = append(res, pc.ServerIface.D(ctx)...) // res = append(res, pc.RenderOpenFunc(ctx)...) // res = append(res, pc.renderNewFunc(ctx)...) -// res = append(res, pc.Struct.D(ctx)...) +// res = append(res, pc.Type.D(ctx)...) // res = append(res, pc.RenderCommonMethods(ctx)...) // res = append(res, pc.renderProtoMethods(ctx)...) // if pc.Parent.Publisher { @@ -35,7 +35,7 @@ package ws //func (pc ProtoChannel) U(ctx *common.RenderContext) []*j.Statement { // ctx.LogStartRender("Channel", "", pc.Parent.Name, "usage", pc.Selectable(), "proto", pc.ProtoName) // defer ctx.LogFinishRender() -// return pc.Struct.U(ctx) +// return pc.Type.U(ctx) //} // //func (pc ProtoChannel) ID() string { @@ -51,7 +51,7 @@ package ws // // return []*j.Statement{ // // NewChannel1Proto(params Channel1Parameters, publisher proto.Publisher, subscriber proto.Subscriber) *Channel1Proto -// j.Func().Id(pc.Struct.NewFuncName()). +// j.Func().Id(pc.Type.NewFuncName()). // ParamsFunc(func(g *j.Group) { // if pc.Parent.ParametersType != nil { // g.Id("params").Add(utils.ToCode(pc.Parent.ParametersType.U(ctx))...) @@ -63,9 +63,9 @@ package ws // g.Id("subscriber").Qual(ctx.RuntimeModule(pc.ProtoName), "Subscriber") // } // }). -// Op("*").Add(utils.ToCode(pc.Struct.U(ctx))...). +// Op("*").Add(utils.ToCode(pc.Type.U(ctx))...). // BlockFunc(func(bg *j.Group) { -// bg.Op("res := ").Add(utils.ToCode(pc.Struct.U(ctx))...).Values(j.DictFunc(func(d j.Dict) { +// bg.Op("res := ").Add(utils.ToCode(pc.Type.U(ctx))...).Values(j.DictFunc(func(d j.Dict) { // d[j.Id("name")] = j.Id(pc.Parent.TypeNamePrefix + "Name").CallFunc(func(g *j.Group) { // if pc.Parent.ParametersType != nil { // g.Id("params") @@ -91,8 +91,8 @@ package ws //func (pc ProtoChannel) renderProtoPublisherMethods(ctx *common.RenderContext) []*j.Statement { // ctx.Logger.Trace("renderProtoPublisherMethods", "proto", pc.ProtoName) // -// rn := pc.Struct.ReceiverName() -// receiver := j.Id(rn).Id(pc.Struct.Name) +// rn := pc.Type.ReceiverName() +// receiver := j.Id(rn).Id(pc.Type.Name) // // var msgTyp common.GolangType = render.GoPointer{Type: pc.Parent.FallbackMessageType, HasDefinition: true} // if pc.Parent.PublisherMessageTypePromise != nil { diff --git a/internal/render/ws/server.go b/internal/render/ws/server.go index fe83eb3..c995a99 100644 --- a/internal/render/ws/server.go +++ b/internal/render/ws/server.go @@ -2,7 +2,7 @@ package ws //type ProtoServer struct { // Parent *render.Server -// Struct *render.GoStruct +// Type *render.GoStruct // // ProtoName, ProtoTitle string //} @@ -16,7 +16,7 @@ package ws // defer ctx.LogFinishRender() // var res []*j.Statement // res = append(res, ps.RenderNewFunc(ctx)...) -// res = append(res, ps.Struct.D(ctx)...) +// res = append(res, ps.Type.D(ctx)...) // res = append(res, ps.RenderCommonMethods(ctx)...) // res = append(res, ps.renderChannelMethods(ctx)...) // res = append(res, ps.RenderProducerMethods(ctx)...) @@ -27,7 +27,7 @@ package ws //func (ps ProtoServer) U(ctx *common.RenderContext) []*j.Statement { // ctx.LogStartRender("Server", "", ps.Parent.Name, "usage", ps.Selectable(), "proto", ps.ProtoName) // defer ctx.LogFinishRender() -// return ps.Struct.U(ctx) +// return ps.Type.U(ctx) //} // //func (ps ProtoServer) ID() string { @@ -46,7 +46,7 @@ package ws // for _, ch := range ps.Parent.GetRelevantChannels() { // protoChan := ch.AllProtoChannels[ps.ProtoName].(*ProtoChannel) // res = append(res, -// ps.RenderOpenChannelMethod(ctx, protoChan.Struct, protoChan, protoChan.Parent.ParametersType)..., +// ps.RenderOpenChannelMethod(ctx, protoChan.Type, protoChan, protoChan.Parent.ParametersType)..., // ) // } // return res diff --git a/internal/selector/selector.go b/internal/selector/selector.go index a6c13a1..fe248aa 100644 --- a/internal/selector/selector.go +++ b/internal/selector/selector.go @@ -8,12 +8,41 @@ import ( ) func SelectObjects(objects []compiler.Object, filters common.RenderSelectionFilterConfig) []compiler.Object { - var filterChain []func(compiler.Object) bool + filterChain := getFiltersChain(filters) + + return lo.Filter(objects, func(object compiler.Object, _ int) bool { + for _, filter := range filterChain { + if !filter(object) { + return false + } + } + return true + }) +} + +//func FindSelectionByObject(object compiler.Object, selections []common.RenderSelectionConfig) *common.RenderSelectionConfig { +// // TODO: nested structures defined in Channel or smth like this will not work (ObjectKind==lang), they have no explicit selections +// for _, selection := range selections { +// filtersChain := getFiltersChain(selection.RenderSelectionFilterConfig) +// match := lo.ContainsBy(filtersChain, func(f filterFunc) bool { +// return f(object) +// }) +// if match { +// return &selection +// } +// } +// return nil +//} + +type filterFunc func(compiler.Object) bool + +func getFiltersChain(filters common.RenderSelectionFilterConfig) []filterFunc { + var filterChain []filterFunc filterChain = append(filterChain, func(object compiler.Object) bool { return object.Object.Selectable() }) if filters.ObjectKindRe != "" { - re := regexp.MustCompile(filters.ObjectKindRe) + re := regexp.MustCompile(filters.ObjectKindRe) // TODO: compile 1 time (and below) filterChain = append(filterChain, func(object compiler.Object) bool { return re.MatchString(string(object.Object.Kind())) }) @@ -30,13 +59,5 @@ func SelectObjects(objects []compiler.Object, filters common.RenderSelectionFilt return re.MatchString(object.ModuleURL.PointerRef()) }) } - - return lo.Filter(objects, func(object compiler.Object, _ int) bool { - for _, filter := range filterChain { - if !filter(object) { - return false - } - } - return true - }) + return filterChain } diff --git a/internal/tpl/load.go b/internal/tpl/load.go new file mode 100644 index 0000000..2841ced --- /dev/null +++ b/internal/tpl/load.go @@ -0,0 +1,14 @@ +package tpl + +import ( + "github.com/bdragon300/go-asyncapi/templates" + "text/template" +) + +var inlineTemplates = template.Must(template.ParseFS(templates.Templates)) + +func LoadTemplate(name string) *template.Template { + // TODO: template dir + // TODO: cache + return inlineTemplates.Lookup(name) +} \ No newline at end of file diff --git a/internal/writer/render.go b/internal/writer/render.go index a7b778b..66d6497 100644 --- a/internal/writer/render.go +++ b/internal/writer/render.go @@ -7,12 +7,12 @@ import ( "github.com/bdragon300/go-asyncapi/internal/render" "github.com/bdragon300/go-asyncapi/internal/render/context" "github.com/bdragon300/go-asyncapi/internal/selector" + "github.com/bdragon300/go-asyncapi/internal/tpl" "github.com/bdragon300/go-asyncapi/internal/types" - "github.com/bdragon300/go-asyncapi/templates" "github.com/samber/lo" - "html/template" "os" "path" + "text/template" "github.com/bdragon300/go-asyncapi/internal/compiler" ) @@ -55,8 +55,6 @@ type renderSource interface { func RenderPackages(source renderSource, opts common.RenderOpts) (fileContents map[string]*bytes.Buffer, err error) { fileContents = make(map[string]*bytes.Buffer) - tmpl := template.Must(template.ParseFS(templates.Templates)) - // TODO: template dir // TODO: logging for _, selection := range opts.Selections { objects := selector.SelectObjects(source.AllObjects(), selection.RenderSelectionFilterConfig) @@ -64,22 +62,30 @@ func RenderPackages(source renderSource, opts common.RenderOpts) (fileContents m continue } - ctx := &context.RenderContextImpl{ - RenderOpts: opts, - } - selectionObjects := lo.Map(objects, func(item compiler.Object, _ int) common.Renderer { return item.Object}) + ctx := &context.RenderContextImpl{RenderOpts: opts} + selectionObjects := lo.Map(objects, func(item compiler.Object, _ int) common.Renderable { return item.Object}) tplCtx := render.NewTemplateContext(ctx, render.TemplateSelections{Objects: selectionObjects}) - tmpl = tmpl.Funcs(render.GetTemplateFunctions(&tplCtx)) context.Context = ctx // TODO: template in file name if _, ok := fileContents[selection.File]; !ok { fileContents[selection.File] = &bytes.Buffer{} } + // TODO: redefinition preambule in config/cli args - if err = tmpl.ExecuteTemplate(fileContents[selection.File], "preamble", tplCtx); err != nil { + var tmpl *template.Template + if tmpl = tpl.LoadTemplate("preamble"); tmpl == nil { + return nil, fmt.Errorf("template not found: preamble") + } + tmpl = tmpl.Funcs(render.GetTemplateFunctions(ctx)) + if err = tmpl.Execute(fileContents[selection.File], tplCtx); err != nil { return } - if err = tmpl.ExecuteTemplate(fileContents[selection.File], selection.Template, tplCtx); err != nil { + + if tmpl = tpl.LoadTemplate(selection.Template); tmpl == nil { + return nil, fmt.Errorf("template not found: %s", selection.Template) + } + tmpl = tmpl.Funcs(render.GetTemplateFunctions(ctx)) + if err = tmpl.Execute(fileContents[selection.File], tplCtx); err != nil { return } } diff --git a/templates/amqp/channel.tmpl b/templates/amqp/channel.tmpl index abb3764..7589177 100644 --- a/templates/amqp/channel.tmpl +++ b/templates/amqp/channel.tmpl @@ -1,23 +1,23 @@ -type {{(print ..RenderContextProto "Server") | toCamelCase}} interface { - Open{{..RenderContextProto}}(ctx {{qual "context.Context"}}, {{if .ParametersType}}params {{.ParametersType.U}}{{end}}) (*{{.Struct.U}}, error) - {{if .IsPublisher}}Producer() {{qualr .ProtoName "Producer"}}{{end}} - {{if .IsSubscriber}}Consumer() {{qualr .ProtoName "Consumer"}}{{end}} +type {{(print .Type.Name "Server") | toCamelCase}} interface { + Open{{.Type.Name}}(ctx {{qual "context.Context"}}, {{if .ParametersType}}params {{.ParametersType.U}}{{end}}) (*{{.Struct.U}}, error) + {{if .IsPublisher}}Producer() {{qualrun .ProtoName "Producer"}}{{end}} + {{if .IsSubscriber}}Consumer() {{qualrun .ProtoName "Consumer"}}{{end}} } func New{{.Struct.Name}}( {{if .ParametersType}}params {{.ParametersType.U}},{{end}} - {{if .IsPublisher}}publisher {{qualr .ProtoName "Publisher"}},{{end}} - {{if .IsSubscriber}}subscriber {{qualr .ProtoName "Subscriber"}},{{end}} + {{if .IsPublisher}}publisher {{qualrun .ProtoName "Publisher"}},{{end}} + {{if .IsSubscriber}}subscriber {{qualrun .ProtoName "Subscriber"}},{{end}} ) *{{.Struct.U}} { res := {{.Struct.U}}{ - name: {{..RenderContext}}Name({{if .ParametersType}}params{{end}}), + name: {{.TypeNamePrefix}}Name({{if .ParametersType}}params{{end}}), {{if .IsPublisher}}publisher: publisher,{{end}} {{if .IsSubscriber}}subscriber: subscriber,{{end}} } {{if .BindingsType}} bindings := {{.BindingsType.U}}{}.{{.ProtoName | capitalize}}() switch bindings.ChannelType { - case {{qualr .ProtoName "ChannelTypeQueue"}}: + case {{qualrun .ProtoName "ChannelTypeQueue"}}: res.queue = res.name.String() default: res.routingKey = res.name.String() @@ -53,13 +53,7 @@ func (c {{.Struct.U}}) RoutingKey() string { {{if .IsPublisher}} {{template "proto/channel/outputMethods" .}} - - {{$pubMessageType := goptr "any"}} - {{if .PublisherMessageTypePromise }} - {{$pubMessageType = goptr .PublisherMessageTypePromise.T.OutType}} - {{end}} - - func (c {{.Struct.U}}) SealEnvelope(envelope {{qualr .ProtoName "EnvelopeWriter"}}, message {{$pubMessageType.U}}) error { + func (c {{.Struct.U}}) SealEnvelope(envelope {{qualrun .ProtoName "EnvelopeWriter"}}, message {{if .PublisherMessageTypePromise}}{{goptr .PublisherMessageTypePromise.T.OutType.U}}{{else}}any{{end}}) error { envelope.ResetPayload() {{if .PublisherMessageTypePromise /*Message is set for Channel in spec*/ }} if err := message.Marshal{{.ProtoName | capitalize}}Envelope(envelope); err != nil { diff --git a/templates/amqp/server.tmpl b/templates/amqp/server.tmpl index 67ea2b2..6c4c4f9 100644 --- a/templates/amqp/server.tmpl +++ b/templates/amqp/server.tmpl @@ -1,4 +1,4 @@ -func New{{.Struct.Name}}(producer {{qualr .ProtoName "Producer"}}, consumer {{qualr .ProtoName "Consumer"}}) *{{.Struct.U}} { +func New{{.Struct.Name}}(producer {{qualrun .ProtoName "Producer"}}, consumer {{qualrun .ProtoName "Consumer"}}) *{{.Struct.U}} { return &{{.Struct.U}}{ producer: producer, consumer: consumer, @@ -11,11 +11,11 @@ func (s {{.Struct.U}}) Name() string { return "{{.Name}}" } -func (s {{.Struct.U}}) Producer() {{qualr .ProtoName "Producer"}} { +func (s {{.Struct.U}}) Producer() {{qualrun .ProtoName "Producer"}} { return s.producer } -func (s {{.Struct.U}}) Consumer() {{qualr .ProtoName "Consumer"}} { +func (s {{.Struct.U}}) Consumer() {{qualrun .ProtoName "Consumer"}} { return s.consumer } @@ -24,7 +24,7 @@ func (s {{.Struct.D}}) Open{{$channel.Struct.Name}}( ctx {{qual "context.Context"}}, {{if $channel.ParametersType}}params {{$channel.ParametersType.U}},{{end}} ) (ch *{{$channel.Struct.U}}, err error) { - return {{qualg $channel.Struct.Import (print "Open" $channel.Struct.Name)}}( + return {{qualgenpkg $channel.Struct}}{{print "Open" $channel.Struct.Name | goid}}( ctx, {{if $channel.ParametersType}}params,{{end}} {{if $channel.IsPublisher}}s.producer,{{end}} diff --git a/templates/channel.tmpl b/templates/channel.tmpl index 415ab31..d1a27aa 100644 --- a/templates/channel.tmpl +++ b/templates/channel.tmpl @@ -34,18 +34,18 @@ {{end}} {{end}} -func {{..RenderContext}}Name({{if .ParametersType}}params {{.ParametersType.U}}{{end}}) {{qualr "" "ParamString"}} { +func {{.TypeNamePrefix}}Name({{if .ParametersType}}params {{.ParametersType.U}}{{end}}) {{qualrun "ParamString"}} { {{if .ParametersType}} paramMap := map[string]string{ {{range $f := .ParametersType.Fields}}params.{{$f.Name}}.Name(): params.{{$f.Name}}.String(), {{end}} } - return {{qualr "" "ParamString"}}{ + return {{qualrun "ParamString"}}{ Expr: "{{.SpecKey | golit}}", Parameters: paramMap, } {{else}} - return {{qualr "" "ParamString"}}{ + return {{qualrun "ParamString"}}{ Expr: "{{.SpecKey | golit}}", } {{end}} diff --git a/templates/common/proto.tmpl b/templates/common/proto.tmpl index b3dbebc..7182a0b 100644 --- a/templates/common/proto.tmpl +++ b/templates/common/proto.tmpl @@ -1,5 +1,5 @@ {{define "proto/channel/commonMethods"}} -func (c {{.Struct.U}}) Name() {{qualr "" "ParamString"}} { +func (c {{.Struct.U}}) Name() {{qualrun "ParamString"}} { return c.name } @@ -19,11 +19,11 @@ func (c {{.Struct.U}}) Close() (err error) { {{end}} {{define "proto/channel/outputMethods"}} -func (c {{.Struct.U}}) Publisher() {{qualr .ProtoName "Producer"}} { +func (c {{.Struct.U}}) Publisher() {{qualrun .ProtoName "Producer"}} { return c.publisher } -func (c {{.Struct.U}}) Publish(ctx {{qual "context.Context"}}, envelopes ...{{qualr .ProtoName "EnvelopeWriter"}}) error { +func (c {{.Struct.U}}) Publish(ctx {{qual "context.Context"}}, envelopes ...{{qualrun .ProtoName "EnvelopeWriter"}}) error { return c.publisher.Publish(ctx, envelopes...) } {{end}} @@ -32,12 +32,7 @@ func (c {{.Struct.U}}) Publish(ctx {{qual "context.Context"}}, envelopes ...{{qu define "proto/channel/barePublishMethods"}} {{template "proto/channel/outputMethods" .}} - {{$pubMessageType := "any"}} - {{if .PublisherMessageTypePromise }} - {{$pubMessageType = goptr .PublisherMessageTypePromise.T.OutType}} - {{end}} - - func (c {{.Struct.U}}) SealEnvelope(envelope {{qualr .ProtoName "EnvelopeWriter"}}, message {{$pubMessageType.U}}) error { + func (c {{.Struct.U}}) SealEnvelope(envelope {{qualrun .ProtoName "EnvelopeWriter"}}, message {{if .PublisherMessageTypePromise}}{{goptr .PublisherMessageTypePromise.T.OutType.U}}{{else}}any{{end}}) error { envelope.ResetPayload() {{if .PublisherMessageTypePromise /*Message is set for Channel in spec*/ }} if err := message.Marshal{{.ProtoName | capitalize}}Envelope(envelope); err != nil { @@ -58,11 +53,7 @@ define "proto/channel/barePublishMethods"}} {{end}} {{define "proto/channel/subscribeMethods"}} -{{$subMessageType := "any"}} -{{if .PublisherMessageTypePromise }} - {{$subMessageType = goptr .SubscriberMessageTypePromise.T.InType}} -{{end}} -func (c {{.Struct.U}}) ExtractEnvelope(envelope {{qualr .ProtoName "EnvelopeReader"}}, message {{$subMessageType.U}}) error { +func (c {{.Struct.U}}) ExtractEnvelope(envelope {{qualrun .ProtoName "EnvelopeReader"}}, message {{if .SubscriberMessageTypePromise}}{{goptr .SubscriberMessageTypePromise.T.InType.U}}{{else}}any{{end}}) error { {{if .SubscriberMessageTypePromise}} {{/*Message set for Channel in spec*/}} return message.Unmarshal{{.ProtoName | capitalize}}Envelope(envelope) @@ -73,11 +64,11 @@ func (c {{.Struct.U}}) ExtractEnvelope(envelope {{qualr .ProtoName "EnvelopeRead {{end}} } -func (c {{.Struct.U}}) IsSubscriber() {{qualr .ProtoName "Subscriber"}} { +func (c {{.Struct.U}}) IsSubscriber() {{qualrun .ProtoName "Subscriber"}} { return c.subscriber } -func (c {{.Struct.U}}) Subscribe(ctx {{qual "context.Context"}}, cb func(envelope {{qualr .ProtoName "EnvelopeReader"}})) error { +func (c {{.Struct.U}}) Subscribe(ctx {{qual "context.Context"}}, cb func(envelope {{qualrun .ProtoName "EnvelopeReader"}})) error { return c.subscriber.Receive(ctx, cb) } {{end}} @@ -87,14 +78,14 @@ define "proto/channel/openFunction"}} func Open{{.Struct.Name}}( ctx {{qual "context.Context"}}, {{if .ParametersType}}params {{.ParametersType.U}},{{end}} - {{if .IsPublisher}}producer {{qualr .ProtoName "Producer"}},{{end}} - {{if .IsSubscriber}}consumer {{qualr .ProtoName "Consumer"}},{{end}} + {{if .IsPublisher}}producer {{qualrun .ProtoName "Producer"}},{{end}} + {{if .IsSubscriber}}consumer {{qualrun .ProtoName "Consumer"}},{{end}} ) (ch *{{.Struct.U}}, err error) { - name := {{..RenderContext}}Name({{if .ParametersType}}params{{end}}) + name := {{.TypeNamePrefix}}Name({{if .ParametersType}}params{{end}}) bindings := {{.BindingsType.U}}{}.{{.ProtoName | capitalize}}() {{if .IsPublisher}} - var publisher {{qualr .ProtoName "Publisher"}} + var publisher {{qualrun .ProtoName "Publisher"}} if producer != nil { if publisher, err = producer.Publisher(ctx, name, {{if .BindingsType}}&bindings{{else}}nil{{end}}); err != nil { return nil, err @@ -102,7 +93,7 @@ define "proto/channel/openFunction"}} } {{end}} {{if .IsSubscriber}} - var subscriber {{qualr .ProtoName "Subscriber"}} + var subscriber {{qualrun .ProtoName "Subscriber"}} if consumer != nil { if subscriber, err = consumer.Consumer(ctx, name, {{if .BindingsType}}&bindings{{else}}nil{{end}}); err != nil { return nil, err @@ -122,11 +113,11 @@ define "proto/channel/openFunction"}} define "proto/channel/bareNewFunction"}} func New{{.Struct.Name}}( {{if .ParametersType}}params {{.ParametersType.U}},{{end}} - {{if .IsPublisher}}publisher {{qualr .ProtoName "Publisher"}},{{end}} - {{if .IsSubscriber}}subscriber {{qualr .ProtoName "Subscriber"}},{{end}} + {{if .IsPublisher}}publisher {{qualrun .ProtoName "Publisher"}},{{end}} + {{if .IsSubscriber}}subscriber {{qualrun .ProtoName "Subscriber"}},{{end}} ) *{{.Struct.U}} { res := {{.Struct.U}}{ - name: {{..RenderContext}}Name({{if .ParametersType}}params{{end}}), + name: {{.TypeNamePrefix}}Name({{if .ParametersType}}params{{end}}), {{if .IsPublisher}}publisher: publisher,{{end}} {{if .IsSubscriber}}subscriber: subscriber,{{end}} } @@ -135,11 +126,8 @@ define "proto/channel/bareNewFunction"}} {{end}} {{define "proto/message/marshalUnmarshalMethods"}} -func (m *{{.OutType.Name}}) Marshal{{ .ProtoName | capitalize }}Envelope(envelope {{qualr .ProtoName "EnvelopeWriter"}} error { - enc := {{qualg "encoding.NewEncoder"}}({{.ContentType | golit}}, envelope) - if err := enc.Encode(m.Payload); err != nil { - return err - } +func (m *{{.OutType.Name}}) Marshal{{ .ProtoName | capitalize }}Envelope(envelope {{qualrun .ProtoName "EnvelopeWriter"}} error { + {{template "proto/message/encodeExpr" .}} envelope.SetContentType({{.ContentType | golit}}) {{if .HeadersTypePromise}} envelope.SetHeaders({ @@ -147,16 +135,13 @@ func (m *{{.OutType.Name}}) Marshal{{ .ProtoName | capitalize }}Envelope(envelop {{end}} }) {{else}} - envelope.SetHeaders({{qualr "" "Headers"}}(m.Headers)) + envelope.SetHeaders({{qualrun "Headers"}}(m.Headers)) {{end}} return nil } -func (m *{{.InType.Name}}) Unmarshal{{ .ProtoName | capitalize }}Envelope(envelope {{qualr .ProtoName "EnvelopeReader"}} error { - dec := {{qualg "encoding.NewDecoder"}}({{.ContentType | golit}}, envelope) - if err := dec.Decode(&m.Payload); err != nil { - return err - } +func (m *{{.InType.Name}}) Unmarshal{{ .ProtoName | capitalize }}Envelope(envelope {{qualrun .ProtoName "EnvelopeReader"}} error { + {{template "proto/message/decodeExpr" .}} {{if .HeadersTypePromise }} {{/* Empty headers should not generate code */}} {{if gt (len .HeadersTypePromise.T.Fields) 0}} @@ -173,3 +158,31 @@ func (m *{{.InType.Name}}) Unmarshal{{ .ProtoName | capitalize }}Envelope(envelo return nil } {{end}} + +{{define "proto/message/encodeExpr"}} +{{if .EffectiveContentType | hasSuffix "yaml"}} + enc := {{qual "encoding/yaml.v3.NewEncoder"}}(envelope) + if err := enc.Encode(m.Payload); err != nil { + return err + } +{{else /*Use json even we dealing with unknown content type*/}} + enc := {{qual "encoding/json.NewEncoder"}}(envelope) + if err := enc.Encode(m.Payload); err != nil { + return err + } +{{end}} +{{end}} + +{{define "proto/message/decodeExpr"}} +{{if .EffectiveContentType | hasSuffix "yaml"}} + dec := {{qual "encoding/yaml.v3.NewDecoder"}}(envelope) + if err := dec.Decode(&m.Payload); err != nil { + return err + } +{{else /*Use json even we dealing with unknown content type*/}} + dec := {{qual "encoding/json.NewDecoder"}}(envelope) + if err := dec.Decode(&m.Payload); err != nil { + return err + } +{{end}} +{{end}} diff --git a/templates/decoding.tmpl b/templates/decoding.tmpl deleted file mode 100644 index e8319b0..0000000 --- a/templates/decoding.tmpl +++ /dev/null @@ -1,29 +0,0 @@ -type Decoder interface { - Decode(v any) error -} -var Decoders = map[string]func(w {{qual "io.Reader"}}) Decoder { -{{range $ct := .SpecEffectiveContentTypes}} - {{$format := contentTypeID $ct}} - {{if eq $format "json"}}{{$ct | golit}}: {{template "decoder/json"}}{{end}} - {{if eq $format "yaml"}}{{$ct | golit}}: {{template "decoder/yaml"}}{{end}} - {{if not $format}}{{$ct | golit}}: func(_ {{qual "io.Reader"}}) Decoder { panic("No decoder is set for content type {{$ct}}") }{{end}} -{{end}} - -func NewDecoder(contentType string, r {{qual "io.Reader"}}) Decoder { - if v, ok := Decoders[contentType]; ok { - return v(r) - } - panic("Unknown content type " + contentType) -} - - -{{define "decoder/json"}} -func(r {{qual "io.Reader"}}) Decoder { - return {{qual "encoding/json.NewDecoder"}}(r) -} -{{end}} -{{define "decoder/yaml"}} -func(r {{qual "io.Reader"}}) Decoder { - return {{qual "encoding/yaml.v3.NewDecoder"}}(r) -} -{{end}} diff --git a/templates/encoding.tmpl b/templates/encoding.tmpl deleted file mode 100644 index 8b937d7..0000000 --- a/templates/encoding.tmpl +++ /dev/null @@ -1,29 +0,0 @@ -type Encoder interface { - Encode(v any) error -} -var Encoders = map[string]func(w {{qual "io.Writer"}}) Encoder { -{{range $ct := .SpecEffectiveContentTypes}} - {{$format := contentTypeID $ct}} - {{if eq $format "json"}}{{$ct | golit}}: {{template "encoder/json"}}{{end}} - {{if eq $format "yaml"}}{{$ct | golit}}: {{template "encoder/yaml"}}{{end}} - {{if not $format}}{{$ct | golit}}: func(_ {{qual "io.Writer"}}) Encoder { panic("No encoder is set for content type {{$ct}}") }{{end}} -{{end}} - -func NewEncoder(contentType string, w {{qual "io.Writer"}}) Encoder { - if v, ok := Encoders[contentType]; ok { - return v(w) - } - panic("Unknown content type " + contentType) -} - - -{{define "encoder/json"}} -func(w {{qual "io.Writer"}}) Encoder { - return {{qual "encoding/json.NewEncoder"}}(w) -} -{{end}} -{{define "encoder/yaml"}} -func(w {{qual "io.Writer"}}) Encoder { - return {{qual "encoding/yaml.v3.NewEncoder"}}(w) -} -{{end}} diff --git a/templates/http/channel.tmpl b/templates/http/channel.tmpl index 561d990..a64c4df 100644 --- a/templates/http/channel.tmpl +++ b/templates/http/channel.tmpl @@ -1,7 +1,7 @@ -type {{(print ..RenderContextProto "Server") | toCamelCase}} interface { - Open{{..RenderContextProto}}(ctx {{qual "context.Context"}}, {{if .ParametersType}}params {{.ParametersType.U}}{{end}}) (*{{.Struct.U}}, error) - {{if .IsPublisher}}Producer() {{qualr .ProtoName "Producer"}}{{end}} - {{if .IsSubscriber}}Consumer() {{qualr .ProtoName "Consumer"}}{{end}} +type {{(print .Type.Name "Server") | toCamelCase}} interface { + Open{{.Type.Name}}(ctx {{qual "context.Context"}}, {{if .ParametersType}}params {{.ParametersType.U}}{{end}}) (*{{.Struct.U}}, error) + {{if .IsPublisher}}Producer() {{qualrun .ProtoName "Producer"}}{{end}} + {{if .IsSubscriber}}Consumer() {{qualrun .ProtoName "Consumer"}}{{end}} } {{template "proto/channel/bareNewFunction" .}} diff --git a/templates/http/server.tmpl b/templates/http/server.tmpl index 67ea2b2..6c4c4f9 100644 --- a/templates/http/server.tmpl +++ b/templates/http/server.tmpl @@ -1,4 +1,4 @@ -func New{{.Struct.Name}}(producer {{qualr .ProtoName "Producer"}}, consumer {{qualr .ProtoName "Consumer"}}) *{{.Struct.U}} { +func New{{.Struct.Name}}(producer {{qualrun .ProtoName "Producer"}}, consumer {{qualrun .ProtoName "Consumer"}}) *{{.Struct.U}} { return &{{.Struct.U}}{ producer: producer, consumer: consumer, @@ -11,11 +11,11 @@ func (s {{.Struct.U}}) Name() string { return "{{.Name}}" } -func (s {{.Struct.U}}) Producer() {{qualr .ProtoName "Producer"}} { +func (s {{.Struct.U}}) Producer() {{qualrun .ProtoName "Producer"}} { return s.producer } -func (s {{.Struct.U}}) Consumer() {{qualr .ProtoName "Consumer"}} { +func (s {{.Struct.U}}) Consumer() {{qualrun .ProtoName "Consumer"}} { return s.consumer } @@ -24,7 +24,7 @@ func (s {{.Struct.D}}) Open{{$channel.Struct.Name}}( ctx {{qual "context.Context"}}, {{if $channel.ParametersType}}params {{$channel.ParametersType.U}},{{end}} ) (ch *{{$channel.Struct.U}}, err error) { - return {{qualg $channel.Struct.Import (print "Open" $channel.Struct.Name)}}( + return {{qualgenpkg $channel.Struct}}{{print "Open" $channel.Struct.Name | goid}}( ctx, {{if $channel.ParametersType}}params,{{end}} {{if $channel.IsPublisher}}s.producer,{{end}} diff --git a/templates/ip/channel.tmpl b/templates/ip/channel.tmpl index 561d990..a64c4df 100644 --- a/templates/ip/channel.tmpl +++ b/templates/ip/channel.tmpl @@ -1,7 +1,7 @@ -type {{(print ..RenderContextProto "Server") | toCamelCase}} interface { - Open{{..RenderContextProto}}(ctx {{qual "context.Context"}}, {{if .ParametersType}}params {{.ParametersType.U}}{{end}}) (*{{.Struct.U}}, error) - {{if .IsPublisher}}Producer() {{qualr .ProtoName "Producer"}}{{end}} - {{if .IsSubscriber}}Consumer() {{qualr .ProtoName "Consumer"}}{{end}} +type {{(print .Type.Name "Server") | toCamelCase}} interface { + Open{{.Type.Name}}(ctx {{qual "context.Context"}}, {{if .ParametersType}}params {{.ParametersType.U}}{{end}}) (*{{.Struct.U}}, error) + {{if .IsPublisher}}Producer() {{qualrun .ProtoName "Producer"}}{{end}} + {{if .IsSubscriber}}Consumer() {{qualrun .ProtoName "Consumer"}}{{end}} } {{template "proto/channel/bareNewFunction" .}} diff --git a/templates/ip/server.tmpl b/templates/ip/server.tmpl index 67ea2b2..6c4c4f9 100644 --- a/templates/ip/server.tmpl +++ b/templates/ip/server.tmpl @@ -1,4 +1,4 @@ -func New{{.Struct.Name}}(producer {{qualr .ProtoName "Producer"}}, consumer {{qualr .ProtoName "Consumer"}}) *{{.Struct.U}} { +func New{{.Struct.Name}}(producer {{qualrun .ProtoName "Producer"}}, consumer {{qualrun .ProtoName "Consumer"}}) *{{.Struct.U}} { return &{{.Struct.U}}{ producer: producer, consumer: consumer, @@ -11,11 +11,11 @@ func (s {{.Struct.U}}) Name() string { return "{{.Name}}" } -func (s {{.Struct.U}}) Producer() {{qualr .ProtoName "Producer"}} { +func (s {{.Struct.U}}) Producer() {{qualrun .ProtoName "Producer"}} { return s.producer } -func (s {{.Struct.U}}) Consumer() {{qualr .ProtoName "Consumer"}} { +func (s {{.Struct.U}}) Consumer() {{qualrun .ProtoName "Consumer"}} { return s.consumer } @@ -24,7 +24,7 @@ func (s {{.Struct.D}}) Open{{$channel.Struct.Name}}( ctx {{qual "context.Context"}}, {{if $channel.ParametersType}}params {{$channel.ParametersType.U}},{{end}} ) (ch *{{$channel.Struct.U}}, err error) { - return {{qualg $channel.Struct.Import (print "Open" $channel.Struct.Name)}}( + return {{qualgenpkg $channel.Struct}}{{print "Open" $channel.Struct.Name | goid}}( ctx, {{if $channel.ParametersType}}params,{{end}} {{if $channel.IsPublisher}}s.producer,{{end}} diff --git a/templates/kafka/channel.tmpl b/templates/kafka/channel.tmpl index 4efcae9..93bf521 100644 --- a/templates/kafka/channel.tmpl +++ b/templates/kafka/channel.tmpl @@ -1,16 +1,16 @@ -type {{(print ..RenderContextProto "Server") | toCamelCase}} interface { - Open{{..RenderContextProto}}(ctx {{qual "context.Context"}}, {{if .ParametersType}}params {{.ParametersType.U}}{{end}}) (*{{.Struct.U}}, error) - {{if .IsPublisher}}Producer() {{qualr .ProtoName "Producer"}}{{end}} - {{if .IsSubscriber}}Consumer() {{qualr .ProtoName "Consumer"}}{{end}} +type {{(print .Type.Name "Server") | toCamelCase}} interface { + Open{{.Type.Name}}(ctx {{qual "context.Context"}}, {{if .ParametersType}}params {{.ParametersType.U}}{{end}}) (*{{.Struct.U}}, error) + {{if .IsPublisher}}Producer() {{qualrun .ProtoName "Producer"}}{{end}} + {{if .IsSubscriber}}Consumer() {{qualrun .ProtoName "Consumer"}}{{end}} } func New{{.Struct.Name}}( {{if .ParametersType}}params {{.ParametersType.U}},{{end}} - {{if .IsPublisher}}publisher {{qualr .ProtoName "Publisher"}},{{end}} - {{if .IsSubscriber}}subscriber {{qualr .ProtoName "Subscriber"}},{{end}} + {{if .IsPublisher}}publisher {{qualrun .ProtoName "Publisher"}},{{end}} + {{if .IsSubscriber}}subscriber {{qualrun .ProtoName "Subscriber"}},{{end}} ) *{{.Struct.U}} { res := {{.Struct.U}}{ - name: {{..RenderContext}}Name({{if .ParametersType}}params{{end}}), + name: {{.TypeNamePrefix}}Name({{if .ParametersType}}params{{end}}), {{if .IsPublisher}}publisher: publisher,{{end}} {{if .IsSubscriber}}subscriber: subscriber,{{end}} } @@ -37,13 +37,7 @@ func (c {{.Struct.U}}) Topic() string { {{if .IsPublisher}} {{template "proto/channel/outputMethods" .}} - - {{$pubMessageType := goptr "any"}} - {{if .PublisherMessageTypePromise }} - {{$pubMessageType = goptr .PublisherMessageTypePromise.T.OutType}} - {{end}} - - func (c {{.Struct.U}}) SealEnvelope(envelope {{qualr .ProtoName "EnvelopeWriter"}}, message {{$pubMessageType.U}}) error { + func (c {{.Struct.U}}) SealEnvelope(envelope {{qualrun .ProtoName "EnvelopeWriter"}}, message {{if .PublisherMessageTypePromise}}{{goptr .PublisherMessageTypePromise.T.OutType.U}}{{else}}any{{end}}) error { envelope.ResetPayload() {{if .PublisherMessageTypePromise /*Message is set for Channel in spec*/ }} if err := message.Marshal{{.ProtoName | capitalize}}Envelope(envelope); err != nil { diff --git a/templates/kafka/server.tmpl b/templates/kafka/server.tmpl index 67ea2b2..6c4c4f9 100644 --- a/templates/kafka/server.tmpl +++ b/templates/kafka/server.tmpl @@ -1,4 +1,4 @@ -func New{{.Struct.Name}}(producer {{qualr .ProtoName "Producer"}}, consumer {{qualr .ProtoName "Consumer"}}) *{{.Struct.U}} { +func New{{.Struct.Name}}(producer {{qualrun .ProtoName "Producer"}}, consumer {{qualrun .ProtoName "Consumer"}}) *{{.Struct.U}} { return &{{.Struct.U}}{ producer: producer, consumer: consumer, @@ -11,11 +11,11 @@ func (s {{.Struct.U}}) Name() string { return "{{.Name}}" } -func (s {{.Struct.U}}) Producer() {{qualr .ProtoName "Producer"}} { +func (s {{.Struct.U}}) Producer() {{qualrun .ProtoName "Producer"}} { return s.producer } -func (s {{.Struct.U}}) Consumer() {{qualr .ProtoName "Consumer"}} { +func (s {{.Struct.U}}) Consumer() {{qualrun .ProtoName "Consumer"}} { return s.consumer } @@ -24,7 +24,7 @@ func (s {{.Struct.D}}) Open{{$channel.Struct.Name}}( ctx {{qual "context.Context"}}, {{if $channel.ParametersType}}params {{$channel.ParametersType.U}},{{end}} ) (ch *{{$channel.Struct.U}}, err error) { - return {{qualg $channel.Struct.Import (print "Open" $channel.Struct.Name)}}( + return {{qualgenpkg $channel.Struct}}{{print "Open" $channel.Struct.Name | goid}}( ctx, {{if $channel.ParametersType}}params,{{end}} {{if $channel.IsPublisher}}s.producer,{{end}} diff --git a/templates/lang/goarray.tmpl b/templates/lang/goarray.tmpl index 787de39..47f21cd 100644 --- a/templates/lang/goarray.tmpl +++ b/templates/lang/goarray.tmpl @@ -6,10 +6,10 @@ {{end}} {{define "usage"}} {{- if .HasDefinition -}} - {{- if and .Import (ne .Import .RenderContext.CurrentPackage) -}} - {{ qualg .Import .Name }} + {{if .Import -}} + {{ qual .Import .Name }} {{- else -}} - {{ .Name | goid }} + {{ qualgenpkg . }}{{.Name | goid}} {{- end -}} {{- else -}} [{{ if .Size }}{{ .Size }}{{ end }}]{{.ItemsType.U}} diff --git a/templates/lang/gomap.tmpl b/templates/lang/gomap.tmpl index c753fec..bf6971f 100644 --- a/templates/lang/gomap.tmpl +++ b/templates/lang/gomap.tmpl @@ -6,10 +6,10 @@ {{end}} {{define "usage"}} {{- if .HasDefinition -}} - {{- if and .Import (ne .Import .RenderContext.CurrentPackage) -}} - {{ qualg .Import .Name }} + {{if .Import -}} + {{ qual .Import .Name }} {{- else -}} - {{ .Name | goid }} + {{ qualgenpkg . }}{{.Name | goid}} {{- end -}} {{- else -}} map[{{.KeyType.U}}]{{.ValueType.U}} diff --git a/templates/lang/gosimple.tmpl b/templates/lang/gosimple.tmpl index 692cf46..106f83b 100644 --- a/templates/lang/gosimple.tmpl +++ b/templates/lang/gosimple.tmpl @@ -2,9 +2,9 @@ {{ .Name | goid }} {{end}} {{define "usage"}} - {{- if and .Import (ne .Import .RenderContext.CurrentPackage) -}} - {{ qual (print .Import "." .Name) }} + {{if .Import -}} + {{ qual .Import .Name }} {{- else -}} - {{ .Name | goid }} + {{ qualgenpkg . }}{{.Name | goid}} {{- end -}} {{end}} \ No newline at end of file diff --git a/templates/lang/gostruct.tmpl b/templates/lang/gostruct.tmpl index 5ea9e70..c860655 100644 --- a/templates/lang/gostruct.tmpl +++ b/templates/lang/gostruct.tmpl @@ -13,10 +13,10 @@ {{end}} {{define "usage"}} {{- if .HasDefinition -}} - {{- if and .Import (ne .Import .RenderContext.CurrentPackage) -}} - {{ qualg .Import .Name }} + {{if .Import -}} + {{ qual .Import .Name }} {{- else -}} - {{ .Name | goid }} + {{ qualgenpkg . }}{{.Name | goid}} {{- end -}} {{- else -}} struct { diff --git a/templates/lang/gotypealias.tmpl b/templates/lang/gotypealias.tmpl index 4682310..b371ecc 100644 --- a/templates/lang/gotypealias.tmpl +++ b/templates/lang/gotypealias.tmpl @@ -6,10 +6,10 @@ {{end}} {{define "usage"}} {{- if .HasDefinition -}} - {{- if and .Import (ne .Import .RenderContext.CurrentPackage) -}} - {{ qualg .Import .Name }} + {{if .Import -}} + {{ qual .Import .Name }} {{- else -}} - {{ .Name | goid }} + {{ qualgenpkg . }}{{.Name | goid}} {{- end -}} {{- else -}} {{.AliasedType.U}} diff --git a/templates/lang/govalue.tmpl b/templates/lang/govalue.tmpl index d7f0c4c..57a1339 100644 --- a/templates/lang/govalue.tmpl +++ b/templates/lang/govalue.tmpl @@ -1,15 +1,14 @@ {{define "usage"}} {{if .Type}} - {{$pt := .AsPointerWrapperType .Type}} - {{if and $pt $pt.IsPointer}} + {{if .Type.IsPointer}} {{if .Empty}} - {{if .EmptyCurlyBrakets /* &{} -> ToPtr({}) */ }}{{qualr "" "ToPtr"}}({}){{else /* &nil -> nil */}}nil{{end}} + {{if .EmptyCurlyBrakets /* &{} -> ToPtr({}) */ }}{{qualrun "ToPtr"}}({}){{else /* &nil -> nil */}}nil{{end}} {{else if .LiteralValue}} - {{$t := .AsGolangType $pt}} + {{$t := unwrapgoptr .Type}} {{if $t /* &int(123) -> ToPtr(int(123)) */}} - {{qualr "" "ToPtr"}}({{$t.U}}({{template "value_expr" .}})) + {{qualrun "ToPtr"}}({{$t.U}}({{template "value_expr" .}})) {{else /* &123 -> ToPtr(123) */}} - {{qualr "" "ToPtr"}}({{template "value_expr" .}}) + {{qualrun "ToPtr"}}({{template "value_expr" .}}) {{end}} {{else /* &AnyType{}; &map[string]int{}; &[]int{} */}} &{{.Type.U}}{{if .LiteralValue /* int(123) */}}({{template "value_expr" .}}){{else}}{{template "value_expr" .}}{{end}} @@ -24,27 +23,23 @@ {{define "value_expr"}} {{if .LiteralValue /* Literal */}} - {{$v := .AsRenderer .LiteralValue}} - {{if $v}}{{ $v.U }}{{else}}{{ .LiteralValue | golit }}{{end}} + {{ .LiteralValue | golit }} {{else if .MapValues.Len /* Map */}} { {{range .MapValues.Entries}} - {{$v := .AsRenderer .Value}} - {{.Key | golit }}: {{if $v}}{{ $v.U }}{{else}}{{ .Value | golit }}{{end}}, + {{.Key | golit }}: {{ .Value | golit }}, {{end}} } {{else if .StructValues.Len /* Struct */}} { {{range .StructValues.Entries}} - {{$v := .AsRenderer .Value}} - {{.Key | goid }}: {{if $v}}{{ $v.U }}{{else}}{{ .Value | golit }}{{end}}, + {{.Key | goid }}: {{ .Value | golit }}, {{end}} } {{else if .ArrayValues /* Array/slice */}} { {{range .ArrayValues}} - {{$v := .AsRenderer .}} - {{if $v}}{{ $v.U }}{{else}}{{ . | golit }}{{end}}, + {{ . | golit }}, {{end}} } {{else /*Empty value*/ }} diff --git a/templates/lang/union.tmpl b/templates/lang/union.tmpl index 9864bda..4fbbaab 100644 --- a/templates/lang/union.tmpl +++ b/templates/lang/union.tmpl @@ -2,9 +2,8 @@ {{.UnionStruct.D}} func (u *{{.Name}}) UnmarshalJSON(data []byte) (err error) { -{{range $field := .GoStruct.Fields}} - {{$fpt := .AsGolangPointerType $field.Type}} - if err = {{qual "encoding/json.Unmarshal"}}(bytes, {{if not (and $fpt $fpt.IsPointer)}}&{{end}}u{{$field.Type.TypeName}}; err == nil { +{{range $field := .Fields}} + if err = {{qual "encoding/json.Unmarshal"}}(bytes, {{if not $field.Type.IsPointer}}&{{end}}u{{$field.Type.TypeName}}; err == nil { return } {{end}} diff --git a/templates/mqtt/channel.tmpl b/templates/mqtt/channel.tmpl index 66fd029..fa0b85d 100644 --- a/templates/mqtt/channel.tmpl +++ b/templates/mqtt/channel.tmpl @@ -1,16 +1,16 @@ -type {{(print ..RenderContextProto "Server") | toCamelCase}} interface { - Open{{..RenderContextProto}}(ctx {{qual "context.Context"}}, {{if .ParametersType}}params {{.ParametersType.U}}{{end}}) (*{{.Struct.U}}, error) - {{if .IsPublisher}}Producer() {{qualr .ProtoName "Producer"}}{{end}} - {{if .IsSubscriber}}Consumer() {{qualr .ProtoName "Consumer"}}{{end}} +type {{(print .Type.Name "Server") | toCamelCase}} interface { + Open{{.Type.Name}}(ctx {{qual "context.Context"}}, {{if .ParametersType}}params {{.ParametersType.U}}{{end}}) (*{{.Struct.U}}, error) + {{if .IsPublisher}}Producer() {{qualrun .ProtoName "Producer"}}{{end}} + {{if .IsSubscriber}}Consumer() {{qualrun .ProtoName "Consumer"}}{{end}} } func New{{.Struct.Name}}( {{if .ParametersType}}params {{.ParametersType.U}},{{end}} - {{if .IsPublisher}}publisher {{qualr .ProtoName "Publisher"}},{{end}} - {{if .IsSubscriber}}subscriber {{qualr .ProtoName "Subscriber"}},{{end}} + {{if .IsPublisher}}publisher {{qualrun .ProtoName "Publisher"}},{{end}} + {{if .IsSubscriber}}subscriber {{qualrun .ProtoName "Subscriber"}},{{end}} ) *{{.Struct.U}} { res := {{.Struct.U}}{ - name: {{..RenderContext}}Name({{if .ParametersType}}params{{end}}), + name: {{.TypeNamePrefix}}Name({{if .ParametersType}}params{{end}}), {{if .IsPublisher}}publisher: publisher,{{end}} {{if .IsSubscriber}}subscriber: subscriber,{{end}} } @@ -30,13 +30,7 @@ func (c {{.Struct.U}}) Topic() string { {{if .IsPublisher}} {{template "proto/channel/outputMethods" .}} - - {{$pubMessageType := goptr "any"}} - {{if .PublisherMessageTypePromise }} - {{$pubMessageType = goptr .PublisherMessageTypePromise.T.OutType}} - {{end}} - - func (c {{.Struct.U}}) SealEnvelope(envelope {{qualr .ProtoName "EnvelopeWriter"}}, message {{$pubMessageType.U}}) error { + func (c {{.Struct.U}}) SealEnvelope(envelope {{qualrun .ProtoName "EnvelopeWriter"}}, message {{if .PublisherMessageTypePromise}}{{goptr .PublisherMessageTypePromise.T.OutType.U}}{{else}}any{{end}}) error { envelope.ResetPayload() {{if .PublisherMessageTypePromise /*Message is set for Channel in spec*/ }} if err := message.Marshal{{.ProtoName | capitalize}}Envelope(envelope); err != nil { diff --git a/templates/mqtt/server.tmpl b/templates/mqtt/server.tmpl index 67ea2b2..6c4c4f9 100644 --- a/templates/mqtt/server.tmpl +++ b/templates/mqtt/server.tmpl @@ -1,4 +1,4 @@ -func New{{.Struct.Name}}(producer {{qualr .ProtoName "Producer"}}, consumer {{qualr .ProtoName "Consumer"}}) *{{.Struct.U}} { +func New{{.Struct.Name}}(producer {{qualrun .ProtoName "Producer"}}, consumer {{qualrun .ProtoName "Consumer"}}) *{{.Struct.U}} { return &{{.Struct.U}}{ producer: producer, consumer: consumer, @@ -11,11 +11,11 @@ func (s {{.Struct.U}}) Name() string { return "{{.Name}}" } -func (s {{.Struct.U}}) Producer() {{qualr .ProtoName "Producer"}} { +func (s {{.Struct.U}}) Producer() {{qualrun .ProtoName "Producer"}} { return s.producer } -func (s {{.Struct.U}}) Consumer() {{qualr .ProtoName "Consumer"}} { +func (s {{.Struct.U}}) Consumer() {{qualrun .ProtoName "Consumer"}} { return s.consumer } @@ -24,7 +24,7 @@ func (s {{.Struct.D}}) Open{{$channel.Struct.Name}}( ctx {{qual "context.Context"}}, {{if $channel.ParametersType}}params {{$channel.ParametersType.U}},{{end}} ) (ch *{{$channel.Struct.U}}, err error) { - return {{qualg $channel.Struct.Import (print "Open" $channel.Struct.Name)}}( + return {{qualgenpkg $channel.Struct}}{{print "Open" $channel.Struct.Name | goid}}( ctx, {{if $channel.ParametersType}}params,{{end}} {{if $channel.IsPublisher}}s.producer,{{end}} diff --git a/templates/redis/channel.tmpl b/templates/redis/channel.tmpl index 561d990..a64c4df 100644 --- a/templates/redis/channel.tmpl +++ b/templates/redis/channel.tmpl @@ -1,7 +1,7 @@ -type {{(print ..RenderContextProto "Server") | toCamelCase}} interface { - Open{{..RenderContextProto}}(ctx {{qual "context.Context"}}, {{if .ParametersType}}params {{.ParametersType.U}}{{end}}) (*{{.Struct.U}}, error) - {{if .IsPublisher}}Producer() {{qualr .ProtoName "Producer"}}{{end}} - {{if .IsSubscriber}}Consumer() {{qualr .ProtoName "Consumer"}}{{end}} +type {{(print .Type.Name "Server") | toCamelCase}} interface { + Open{{.Type.Name}}(ctx {{qual "context.Context"}}, {{if .ParametersType}}params {{.ParametersType.U}}{{end}}) (*{{.Struct.U}}, error) + {{if .IsPublisher}}Producer() {{qualrun .ProtoName "Producer"}}{{end}} + {{if .IsSubscriber}}Consumer() {{qualrun .ProtoName "Consumer"}}{{end}} } {{template "proto/channel/bareNewFunction" .}} diff --git a/templates/redis/server.tmpl b/templates/redis/server.tmpl index 67ea2b2..6c4c4f9 100644 --- a/templates/redis/server.tmpl +++ b/templates/redis/server.tmpl @@ -1,4 +1,4 @@ -func New{{.Struct.Name}}(producer {{qualr .ProtoName "Producer"}}, consumer {{qualr .ProtoName "Consumer"}}) *{{.Struct.U}} { +func New{{.Struct.Name}}(producer {{qualrun .ProtoName "Producer"}}, consumer {{qualrun .ProtoName "Consumer"}}) *{{.Struct.U}} { return &{{.Struct.U}}{ producer: producer, consumer: consumer, @@ -11,11 +11,11 @@ func (s {{.Struct.U}}) Name() string { return "{{.Name}}" } -func (s {{.Struct.U}}) Producer() {{qualr .ProtoName "Producer"}} { +func (s {{.Struct.U}}) Producer() {{qualrun .ProtoName "Producer"}} { return s.producer } -func (s {{.Struct.U}}) Consumer() {{qualr .ProtoName "Consumer"}} { +func (s {{.Struct.U}}) Consumer() {{qualrun .ProtoName "Consumer"}} { return s.consumer } @@ -24,7 +24,7 @@ func (s {{.Struct.D}}) Open{{$channel.Struct.Name}}( ctx {{qual "context.Context"}}, {{if $channel.ParametersType}}params {{$channel.ParametersType.U}},{{end}} ) (ch *{{$channel.Struct.U}}, err error) { - return {{qualg $channel.Struct.Import (print "Open" $channel.Struct.Name)}}( + return {{qualgenpkg $channel.Struct}}{{print "Open" $channel.Struct.Name | goid}}( ctx, {{if $channel.ParametersType}}params,{{end}} {{if $channel.IsPublisher}}s.producer,{{end}} diff --git a/templates/server.tmpl b/templates/server.tmpl index 9db2ee2..64b6fd0 100644 --- a/templates/server.tmpl +++ b/templates/server.tmpl @@ -1,10 +1,10 @@ {{if .ProtocolVersion}} -const {{..RenderContext}}ProtocolVersion = "{{.ProtocolVersion | golit}}" +const {{.TypeNamePrefix}}ProtocolVersion = "{{.ProtocolVersion | golit}}" {{end}} -func {{..RenderContext}}URL( +func {{.TypeNamePrefix}}URL( {{range s.VariablesPromises.Entries}}{{.Key | goid}} string,{{end}} -) {{qualr "" "ParamString"}} { +) {{qualrun "ParamString"}} { {{if gt s.VariablesPromises.Len 0}} {{range s.VariablesPromises.Entries}} {{if .Value.T.Default}} @@ -16,12 +16,12 @@ func {{..RenderContext}}URL( paramMap := map[string]string{ {{range s.VariablesPromises.Entries}}{{.Key | golit}}: {{.Value.T.Name | goid}},{{end}} } - return {{qualr "" "ParamString"}}{ + return {{qualrun "ParamString"}}{ Expr: {{.URL | golit}}, Parameters: paramMap, } {{else}} - return {{qualr "" "ParamString"}}{ + return {{qualrun "ParamString"}}{ Expr: {{.URL | golit}}, } {{end}} diff --git a/templates/tcp/channel.tmpl b/templates/tcp/channel.tmpl index 561d990..a64c4df 100644 --- a/templates/tcp/channel.tmpl +++ b/templates/tcp/channel.tmpl @@ -1,7 +1,7 @@ -type {{(print ..RenderContextProto "Server") | toCamelCase}} interface { - Open{{..RenderContextProto}}(ctx {{qual "context.Context"}}, {{if .ParametersType}}params {{.ParametersType.U}}{{end}}) (*{{.Struct.U}}, error) - {{if .IsPublisher}}Producer() {{qualr .ProtoName "Producer"}}{{end}} - {{if .IsSubscriber}}Consumer() {{qualr .ProtoName "Consumer"}}{{end}} +type {{(print .Type.Name "Server") | toCamelCase}} interface { + Open{{.Type.Name}}(ctx {{qual "context.Context"}}, {{if .ParametersType}}params {{.ParametersType.U}}{{end}}) (*{{.Struct.U}}, error) + {{if .IsPublisher}}Producer() {{qualrun .ProtoName "Producer"}}{{end}} + {{if .IsSubscriber}}Consumer() {{qualrun .ProtoName "Consumer"}}{{end}} } {{template "proto/channel/bareNewFunction" .}} diff --git a/templates/tcp/server.tmpl b/templates/tcp/server.tmpl index 67ea2b2..6c4c4f9 100644 --- a/templates/tcp/server.tmpl +++ b/templates/tcp/server.tmpl @@ -1,4 +1,4 @@ -func New{{.Struct.Name}}(producer {{qualr .ProtoName "Producer"}}, consumer {{qualr .ProtoName "Consumer"}}) *{{.Struct.U}} { +func New{{.Struct.Name}}(producer {{qualrun .ProtoName "Producer"}}, consumer {{qualrun .ProtoName "Consumer"}}) *{{.Struct.U}} { return &{{.Struct.U}}{ producer: producer, consumer: consumer, @@ -11,11 +11,11 @@ func (s {{.Struct.U}}) Name() string { return "{{.Name}}" } -func (s {{.Struct.U}}) Producer() {{qualr .ProtoName "Producer"}} { +func (s {{.Struct.U}}) Producer() {{qualrun .ProtoName "Producer"}} { return s.producer } -func (s {{.Struct.U}}) Consumer() {{qualr .ProtoName "Consumer"}} { +func (s {{.Struct.U}}) Consumer() {{qualrun .ProtoName "Consumer"}} { return s.consumer } @@ -24,7 +24,7 @@ func (s {{.Struct.D}}) Open{{$channel.Struct.Name}}( ctx {{qual "context.Context"}}, {{if $channel.ParametersType}}params {{$channel.ParametersType.U}},{{end}} ) (ch *{{$channel.Struct.U}}, err error) { - return {{qualg $channel.Struct.Import (print "Open" $channel.Struct.Name)}}( + return {{qualgenpkg $channel.Struct}}{{print "Open" $channel.Struct.Name | goid}}( ctx, {{if $channel.ParametersType}}params,{{end}} {{if $channel.IsPublisher}}s.producer,{{end}} diff --git a/templates/udp/channel.tmpl b/templates/udp/channel.tmpl index 561d990..a64c4df 100644 --- a/templates/udp/channel.tmpl +++ b/templates/udp/channel.tmpl @@ -1,7 +1,7 @@ -type {{(print ..RenderContextProto "Server") | toCamelCase}} interface { - Open{{..RenderContextProto}}(ctx {{qual "context.Context"}}, {{if .ParametersType}}params {{.ParametersType.U}}{{end}}) (*{{.Struct.U}}, error) - {{if .IsPublisher}}Producer() {{qualr .ProtoName "Producer"}}{{end}} - {{if .IsSubscriber}}Consumer() {{qualr .ProtoName "Consumer"}}{{end}} +type {{(print .Type.Name "Server") | toCamelCase}} interface { + Open{{.Type.Name}}(ctx {{qual "context.Context"}}, {{if .ParametersType}}params {{.ParametersType.U}}{{end}}) (*{{.Struct.U}}, error) + {{if .IsPublisher}}Producer() {{qualrun .ProtoName "Producer"}}{{end}} + {{if .IsSubscriber}}Consumer() {{qualrun .ProtoName "Consumer"}}{{end}} } {{template "proto/channel/bareNewFunction" .}} diff --git a/templates/udp/server.tmpl b/templates/udp/server.tmpl index 67ea2b2..6c4c4f9 100644 --- a/templates/udp/server.tmpl +++ b/templates/udp/server.tmpl @@ -1,4 +1,4 @@ -func New{{.Struct.Name}}(producer {{qualr .ProtoName "Producer"}}, consumer {{qualr .ProtoName "Consumer"}}) *{{.Struct.U}} { +func New{{.Struct.Name}}(producer {{qualrun .ProtoName "Producer"}}, consumer {{qualrun .ProtoName "Consumer"}}) *{{.Struct.U}} { return &{{.Struct.U}}{ producer: producer, consumer: consumer, @@ -11,11 +11,11 @@ func (s {{.Struct.U}}) Name() string { return "{{.Name}}" } -func (s {{.Struct.U}}) Producer() {{qualr .ProtoName "Producer"}} { +func (s {{.Struct.U}}) Producer() {{qualrun .ProtoName "Producer"}} { return s.producer } -func (s {{.Struct.U}}) Consumer() {{qualr .ProtoName "Consumer"}} { +func (s {{.Struct.U}}) Consumer() {{qualrun .ProtoName "Consumer"}} { return s.consumer } @@ -24,7 +24,7 @@ func (s {{.Struct.D}}) Open{{$channel.Struct.Name}}( ctx {{qual "context.Context"}}, {{if $channel.ParametersType}}params {{$channel.ParametersType.U}},{{end}} ) (ch *{{$channel.Struct.U}}, err error) { - return {{qualg $channel.Struct.Import (print "Open" $channel.Struct.Name)}}( + return {{qualgenpkg $channel.Struct}}{{print "Open" $channel.Struct.Name | goid}}( ctx, {{if $channel.ParametersType}}params,{{end}} {{if $channel.IsPublisher}}s.producer,{{end}} diff --git a/templates/ws/channel.tmpl b/templates/ws/channel.tmpl index 561d990..a64c4df 100644 --- a/templates/ws/channel.tmpl +++ b/templates/ws/channel.tmpl @@ -1,7 +1,7 @@ -type {{(print ..RenderContextProto "Server") | toCamelCase}} interface { - Open{{..RenderContextProto}}(ctx {{qual "context.Context"}}, {{if .ParametersType}}params {{.ParametersType.U}}{{end}}) (*{{.Struct.U}}, error) - {{if .IsPublisher}}Producer() {{qualr .ProtoName "Producer"}}{{end}} - {{if .IsSubscriber}}Consumer() {{qualr .ProtoName "Consumer"}}{{end}} +type {{(print .Type.Name "Server") | toCamelCase}} interface { + Open{{.Type.Name}}(ctx {{qual "context.Context"}}, {{if .ParametersType}}params {{.ParametersType.U}}{{end}}) (*{{.Struct.U}}, error) + {{if .IsPublisher}}Producer() {{qualrun .ProtoName "Producer"}}{{end}} + {{if .IsSubscriber}}Consumer() {{qualrun .ProtoName "Consumer"}}{{end}} } {{template "proto/channel/bareNewFunction" .}} diff --git a/templates/ws/server.tmpl b/templates/ws/server.tmpl index 67ea2b2..6c4c4f9 100644 --- a/templates/ws/server.tmpl +++ b/templates/ws/server.tmpl @@ -1,4 +1,4 @@ -func New{{.Struct.Name}}(producer {{qualr .ProtoName "Producer"}}, consumer {{qualr .ProtoName "Consumer"}}) *{{.Struct.U}} { +func New{{.Struct.Name}}(producer {{qualrun .ProtoName "Producer"}}, consumer {{qualrun .ProtoName "Consumer"}}) *{{.Struct.U}} { return &{{.Struct.U}}{ producer: producer, consumer: consumer, @@ -11,11 +11,11 @@ func (s {{.Struct.U}}) Name() string { return "{{.Name}}" } -func (s {{.Struct.U}}) Producer() {{qualr .ProtoName "Producer"}} { +func (s {{.Struct.U}}) Producer() {{qualrun .ProtoName "Producer"}} { return s.producer } -func (s {{.Struct.U}}) Consumer() {{qualr .ProtoName "Consumer"}} { +func (s {{.Struct.U}}) Consumer() {{qualrun .ProtoName "Consumer"}} { return s.consumer } @@ -24,7 +24,7 @@ func (s {{.Struct.D}}) Open{{$channel.Struct.Name}}( ctx {{qual "context.Context"}}, {{if $channel.ParametersType}}params {{$channel.ParametersType.U}},{{end}} ) (ch *{{$channel.Struct.U}}, err error) { - return {{qualg $channel.Struct.Import (print "Open" $channel.Struct.Name)}}( + return {{qualgenpkg $channel.Struct}}{{print "Open" $channel.Struct.Name | goid}}( ctx, {{if $channel.ParametersType}}params,{{end}} {{if $channel.IsPublisher}}s.producer,{{end}}