diff --git a/codegen/cli/cli.go b/codegen/cli/cli.go index 4e2f0f61e3..affdbfccd4 100644 --- a/codegen/cli/cli.go +++ b/codegen/cli/cli.go @@ -58,6 +58,8 @@ type ( Conversion string // Example is a valid command invocation, starting with the command name. Example string + // Interceptors contains the data for client interceptors if any apply to the endpoint method. + Interceptors *InterceptorData } // InterceptorData contains the data needed to generate interceptor code. @@ -181,22 +183,16 @@ func BuildCommandData(data *service.Data) *CommandData { // BuildSubcommandData builds the data needed by CLI code generators to render // the CLI parsing of the service sub-command. -func BuildSubcommandData(svcName string, m *service.MethodData, buildFunction *BuildFunctionData, flags []*FlagData) *SubcommandData { - var ( - name string - fullName string - description string - - conversion string - ) +func BuildSubcommandData(data *service.Data, m *service.MethodData, buildFunction *BuildFunctionData, flags []*FlagData) *SubcommandData { en := m.Name - name = codegen.KebabCase(en) - fullName = goifyTerms(svcName, en) - description = m.Description + name := codegen.KebabCase(en) + fullName := goifyTerms(data.Name, en) + description := m.Description if description == "" { description = fmt.Sprintf("Make request to the %q endpoint", m.Name) } + var conversion string if m.Payload != "" && buildFunction == nil && len(flags) > 0 { // No build function, just convert the arg to the body type var convPre, convSuff string @@ -226,6 +222,14 @@ func BuildSubcommandData(svcName string, m *service.MethodData, buildFunction *B conversion += "\n}" } } + + var interceptors *InterceptorData + if len(m.ClientInterceptors) > 0 { + interceptors = &InterceptorData{ + VarName: "inter", + PkgName: data.PkgName, + } + } sub := &SubcommandData{ Name: name, FullName: fullName, @@ -234,8 +238,9 @@ func BuildSubcommandData(svcName string, m *service.MethodData, buildFunction *B MethodVarName: m.VarName, BuildFunction: buildFunction, Conversion: conversion, + Interceptors: interceptors, } - generateExample(sub, svcName) + generateExample(sub, data.Name) return sub } diff --git a/codegen/service/interceptors.go b/codegen/service/interceptors.go index 4933909d38..aa4bdfc0e9 100644 --- a/codegen/service/interceptors.go +++ b/codegen/service/interceptors.go @@ -78,6 +78,7 @@ func interceptorFile(svc *Data, server bool) *codegen.File { }, } if len(interceptors) > 0 { + codegen.AddImport(sections[0], svc.UserTypeImports...) sections = append(sections, &codegen.SectionTemplate{ Name: "interceptor-types", Source: readTemplate("interceptors_types"), @@ -139,7 +140,34 @@ func wrapperFile(svc *Data) *codegen.File { codegen.GoaImport(""), })) - // Generate the interceptor wrapper functions first (only once) + // Generate any interceptor stream wrapper struct types first + var wrappedServerStreams, wrappedClientStreams []*StreamInterceptorData + if len(svc.ServerInterceptors) > 0 { + wrappedServerStreams = collectWrappedStreams(svc.ServerInterceptors, true) + if len(wrappedServerStreams) > 0 { + sections = append(sections, &codegen.SectionTemplate{ + Name: "server-interceptor-stream-wrapper-types", + Source: readTemplate("server_interceptor_stream_wrapper_types"), + Data: map[string]interface{}{ + "WrappedServerStreams": wrappedServerStreams, + }, + }) + } + } + if len(svc.ClientInterceptors) > 0 { + wrappedClientStreams = collectWrappedStreams(svc.ClientInterceptors, false) + if len(wrappedClientStreams) > 0 { + sections = append(sections, &codegen.SectionTemplate{ + Name: "client-interceptor-stream-wrapper-types", + Source: readTemplate("client_interceptor_stream_wrapper_types"), + Data: map[string]interface{}{ + "WrappedClientStreams": wrappedClientStreams, + }, + }) + } + } + + // Generate the interceptor wrapper functions next (only once) if len(svc.ServerInterceptors) > 0 { sections = append(sections, &codegen.SectionTemplate{ Name: "server-interceptor-wrappers", @@ -161,6 +189,26 @@ func wrapperFile(svc *Data) *codegen.File { }) } + // Generate any interceptor stream wrapper struct methods last + if len(wrappedServerStreams) > 0 { + sections = append(sections, &codegen.SectionTemplate{ + Name: "server-interceptor-stream-wrappers", + Source: readTemplate("server_interceptor_stream_wrappers"), + Data: map[string]interface{}{ + "WrappedServerStreams": wrappedServerStreams, + }, + }) + } + if len(wrappedClientStreams) > 0 { + sections = append(sections, &codegen.SectionTemplate{ + Name: "client-interceptor-stream-wrappers", + Source: readTemplate("client_interceptor_stream_wrappers"), + Data: map[string]interface{}{ + "WrappedClientStreams": wrappedClientStreams, + }, + }) + } + return &codegen.File{ Path: path, SectionTemplates: sections, @@ -171,9 +219,35 @@ func wrapperFile(svc *Data) *codegen.File { // private implementation types. func hasPrivateImplementationTypes(interceptors []*InterceptorData) bool { for _, intr := range interceptors { - if intr.ReadPayload != nil || intr.WritePayload != nil || intr.ReadResult != nil || intr.WriteResult != nil { + if intr.ReadPayload != nil || intr.WritePayload != nil || intr.ReadResult != nil || intr.WriteResult != nil || intr.ReadStreamingPayload != nil || intr.WriteStreamingPayload != nil || intr.ReadStreamingResult != nil || intr.WriteStreamingResult != nil { return true } } return false } + +// collectWrappedStreams returns a slice of streams to be wrapped by interceptor wrapper functions. +func collectWrappedStreams(interceptors []*InterceptorData, server bool) []*StreamInterceptorData { + var ( + streams []*StreamInterceptorData + streamNames = make(map[string]struct{}) + ) + for _, intr := range interceptors { + if intr.HasStreamingPayloadAccess || intr.HasStreamingResultAccess { + for _, method := range intr.Methods { + if server { + if _, ok := streamNames[method.ServerStream.Interface]; !ok { + streams = append(streams, method.ServerStream) + streamNames[method.ServerStream.Interface] = struct{}{} + } + } else { + if _, ok := streamNames[method.ClientStream.Interface]; !ok { + streams = append(streams, method.ClientStream) + streamNames[method.ClientStream.Interface] = struct{}{} + } + } + } + } + } + return streams +} diff --git a/codegen/service/interceptors.md b/codegen/service/interceptors.md index 80795d3d56..f5fd436c30 100644 --- a/codegen/service/interceptors.md +++ b/codegen/service/interceptors.md @@ -1,6 +1,6 @@ # Interceptors Code Generation -Goa generates interceptor code to enable request/response interception and payload/result access. +Goa generates interceptor code to enable request/response interception and payload/result access. --- @@ -10,8 +10,8 @@ Goa generates interceptor code to enable request/response interception and paylo Client and server interceptor code is generated in: -- `gen/client_interceptors.go` -- `gen/service_interceptors.go` +* `gen/client_interceptors.go` +* `gen/service_interceptors.go` ### Templates Used @@ -26,12 +26,13 @@ Client and server interceptor code is generated in: 3. **`client_wrappers.go.tpl`** and **`endpoint_wrappers.go.tpl`** Generate code that wraps client and service endpoints with interceptor callbacks. Each template takes a map with: + ```go map[string]any{ - "MethodVarName": - "Method": - "Service": - "Interceptors": + "MethodVarName": + "Method": + "Service": + "Interceptors": } ``` @@ -43,12 +44,13 @@ Client and server interceptor code is generated in: Endpoint wrapper code for both client and server interceptors is generated in: -- `gen/interceptor_wrappers.go` +* `gen/interceptor_wrappers.go` ### Templates Used 1. **`server_interceptor_wrappers.go.tpl`** Generates server-specific wrapper implementations. This template receives a map with: + ```go map[string]any{ "Service": svc.Name, @@ -58,6 +60,7 @@ Endpoint wrapper code for both client and server interceptors is generated in: 2. **`client_interceptor_wrappers.go.tpl`** Generates client-specific wrapper implementations. This template receives a map with: + ```go map[string]any{ "Service": svc.Name, @@ -78,6 +81,7 @@ Example interceptors are generated by the example command in an interceptors sub 1. **`example_client_interceptor.go.tpl` and `example_server_interceptor.go.tpl`** Generate example interceptor implementations. Each template takes a map with: + ```go map[string]any{ "StructName": @@ -122,10 +126,16 @@ The main structure describing each interceptor’s metadata and requirements: * `Description`: Interceptor description from the design * `HasPayloadAccess`: Indicates if any method requires payload access * `HasResultAccess`: Indicates if any method requires result access +* `HasStreamingPayloadAccess`: Indicates if any method requires streaming payload access +* `HasStreamingResultAccess`: Indicates if any method requires streaming result access * `ReadPayload`: List of readable payload fields ([]AttributeData) * `WritePayload`: List of writable payload fields ([]AttributeData) * `ReadResult`: List of readable result fields ([]AttributeData) * `WriteResult`: List of writable result fields ([]AttributeData) +* `ReadStreamingPayload`: List of readable streaming payload fields ([]AttributeData) +* `WriteStreamingPayload`: List of writable streaming payload fields ([]AttributeData) +* `ReadStreamingResult`: List of readable streaming result fields ([]AttributeData) +* `WriteStreamingResult`: List of writable streaming result fields ([]AttributeData) * `Methods`: A list of MethodInterceptorData containing method-specific interceptor information * `ServerStreamInputStruct`: Server stream variable name (used if streaming) * `ClientStreamInputStruct`: Client stream variable name (used if streaming) @@ -137,8 +147,12 @@ Stores per-method interceptor configuration: * `MethodName`: The method’s Go variable name * `PayloadAccess`: Name of the payload access type * `ResultAccess`: Name of the result access type +* `StreamingPayloadAccess`: Name of the streaming payload access type +* `StreamingResultAccess`: Name of the streaming result access type * `PayloadRef`: Reference to the method's payload type * `ResultRef`: Reference to the method's result type +* `StreamingPayloadRef`: Reference to the method's streaming payload type +* `StreamingResultRef`: Reference to the method's streaming result type ### `AttributeData` diff --git a/codegen/service/interceptors_test.go b/codegen/service/interceptors_test.go index 6fa7c3ab14..e20c1cc79f 100644 --- a/codegen/service/interceptors_test.go +++ b/codegen/service/interceptors_test.go @@ -42,7 +42,9 @@ func TestInterceptors(t *testing.T) { {"interceptor-with-read-result", testdata.InterceptorWithReadResultDSL, 3}, {"interceptor-with-write-result", testdata.InterceptorWithWriteResultDSL, 3}, {"interceptor-with-read-write-result", testdata.InterceptorWithReadWriteResultDSL, 3}, - {"streaming-interceptors", testdata.StreamingInterceptorsDSL, 2}, + {"streaming-interceptors", testdata.StreamingInterceptorsDSL, 3}, + {"streaming-interceptors-with-read-payload-and-read-streaming-payload", testdata.StreamingInterceptorsWithReadPayloadAndReadStreamingPayloadDSL, 3}, + {"streaming-interceptors-with-read-streaming-result", testdata.StreamingInterceptorsWithReadStreamingResultDSL, 3}, {"streaming-interceptors-with-read-payload", testdata.StreamingInterceptorsWithReadPayloadDSL, 2}, {"streaming-interceptors-with-read-result", testdata.StreamingInterceptorsWithReadResultDSL, 2}, } diff --git a/codegen/service/service.go b/codegen/service/service.go index fccefc360e..bc900ce79f 100644 --- a/codegen/service/service.go +++ b/codegen/service/service.go @@ -47,7 +47,7 @@ func Files(genpkg string, service *expr.ServiceExpr, userTypePkgs map[string][]s if m.StreamingPayloadDef != "" { if _, ok := seen[m.StreamingPayload]; !ok { addTypeDefSection(payloadPath, m.StreamingPayload, &codegen.SectionTemplate{ - Name: "service-streamig-payload", + Name: "service-streaming-payload", Source: readTemplate("streaming_payload"), Data: m, }) diff --git a/codegen/service/service_data.go b/codegen/service/service_data.go index 12cced8e58..c552d30235 100644 --- a/codegen/service/service_data.go +++ b/codegen/service/service_data.go @@ -203,6 +203,10 @@ type ( SendName string // SendDesc is the description for the send function. SendDesc string + // SendWithContextName is the name of the send function with context. + SendWithContextName string + // SendWithContextDesc is the description for the send function with context. + SendWithContextDesc string // SendTypeName is the type name sent through the stream. SendTypeName string // SendTypeRef is the reference to the type sent through the stream. @@ -211,6 +215,10 @@ type ( RecvName string // RecvDesc is the description for the recv function. RecvDesc string + // RecvWithContextName is the name of the receive function with context. + RecvWithContextName string + // RecvWithContextDesc is the description for the recv function with context. + RecvWithContextDesc string // RecvTypeName is the type name received from the stream. RecvTypeName string // RecvTypeRef is the reference to the type received from the stream. @@ -269,12 +277,26 @@ type ( // WriteResult contains result attributes that the interceptor can // write. WriteResult []*AttributeData + // ReadStreamingPayload contains streaming payload attributes that the interceptor can read. + ReadStreamingPayload []*AttributeData + // WriteStreamingPayload contains streaming payload attributes that the interceptor can write. + WriteStreamingPayload []*AttributeData + // ReadStreamingResult contains streaming result attributes that the interceptor can read. + ReadStreamingResult []*AttributeData + // WriteStreamingResult contains streaming result attributes that the interceptor can write. + WriteStreamingResult []*AttributeData // HasPayloadAccess indicates that the interceptor info object has a // payload access interface. HasPayloadAccess bool // HasResultAccess indicates that the interceptor info object has a // result access interface. HasResultAccess bool + // HasStreamingPayloadAccess indicates that the interceptor info object has a + // streaming payload access interface. + HasStreamingPayloadAccess bool + // HasStreamingResultAccess indicates that the interceptor info object has a + // streaming result access interface. + HasStreamingResultAccess bool } // MethodInterceptorData contains the data required to render the @@ -286,16 +308,43 @@ type ( PayloadAccess string // ResultAccess is the name of the result access struct. ResultAccess string + // StreamingPayloadAccess is the name of the streaming payload access struct. + StreamingPayloadAccess string + // StreamingResultAccess is the name of the streaming result access struct. + StreamingResultAccess string // PayloadRef is the reference to the method payload type. PayloadRef string // ResultRef is the reference to the method result type. ResultRef string - // ServerStreamInputStruct is the name of the server stream input - // struct if the endpoint defines a server stream. - ServerStreamInputStruct string - // ClientStreamInputStruct is the name of the client stream input - // struct if the endpoint defines a client stream. - ClientStreamInputStruct string + // StreamingPayloadRef is the reference to the streaming payload type. + StreamingPayloadRef string + // StreamingResultRef is the reference to the streaming result type. + StreamingResultRef string + // ServerStream is the stream data if the endpoint defines a server stream. + ServerStream *StreamInterceptorData + // ClientStream is the stream data if the endpoint defines a client stream. + ClientStream *StreamInterceptorData + } + + // StreamInterceptorData is the stream data for an interceptor. + StreamInterceptorData struct { + // Interface is the name of the stream interface. + Interface string + // SendName is the name of the send function. + SendName string + // SendWithContextName is the name of the send function with context. + SendWithContextName string + // SendTypeRef is the reference to the type sent through the stream. + SendTypeRef string + // RecvName is the name of the recv function. + RecvName string + // RecvWithContextName is the name of the recv function with context. + RecvWithContextName string + // RecvTypeRef is the reference to the type received from the stream. + RecvTypeRef string + // MustClose indicates whether the stream should implement the Close() + // function. + MustClose bool } // AttributeData describes a single attribute. @@ -632,30 +681,22 @@ func (s SchemesData) Append(d *SchemeData) SchemesData { // It records the user types needed by the service definition in userTypes. func (d ServicesData) analyze(service *expr.ServiceExpr) *Data { var ( - scope *codegen.NameScope - viewScope *codegen.NameScope - pkgName string - viewspkg string types []*UserTypeData errTypes []*UserTypeData errorInits []*ErrorInitData projTypes []*ProjectedTypeData viewedUnionMeths []*UnionValueMethodData viewedRTs []*ViewedResultTypeData - seenErrors map[string]struct{} - seen map[string]struct{} - seenProj map[string]*ProjectedTypeData - seenViewed map[string]*ViewedResultTypeData ) - scope = codegen.NewNameScope() + scope := codegen.NewNameScope() scope.Unique("Use") // Reserve "Use" for Endpoints struct Use method. - viewScope = codegen.NewNameScope() - pkgName = scope.HashedUnique(service, strings.ToLower(codegen.Goify(service.Name, false)), "svc") - viewspkg = pkgName + "views" - seen = make(map[string]struct{}) - seenErrors = make(map[string]struct{}) - seenProj = make(map[string]*ProjectedTypeData) - seenViewed = make(map[string]*ViewedResultTypeData) + viewScope := codegen.NewNameScope() + pkgName := scope.HashedUnique(service, strings.ToLower(codegen.Goify(service.Name, false)), "svc") + viewspkg := pkgName + "views" + seen := make(map[string]struct{}) + seenErrors := make(map[string]struct{}) + seenProj := make(map[string]*ProjectedTypeData) + seenViewed := make(map[string]*ViewedResultTypeData) // A function to collect user types from an error expression recordError := func(er *expr.ErrorExpr) { @@ -780,10 +821,8 @@ func (d ServicesData) analyze(service *expr.ServiceExpr) *Data { seenViewed[vrt.Name+"::"+view] = vrt } - var ( - unionMethods []*UnionValueMethodData - ms []*UnionValueMethodData - ) + var unionMethods []*UnionValueMethodData + var ms []*UnionValueMethodData seen = make(map[string]struct{}) for _, t := range types { ms = append(ms, collectUnionMethods(&expr.AttributeExpr{Type: t.Type}, scope, t.Loc, seen)...) @@ -1130,24 +1169,28 @@ func initStreamData(data *MethodData, m *expr.MethodExpr, vname, rname, resultRe spayloadEx = m.StreamingPayload.Example(expr.Root.API.ExampleGenerator) } svrStream := &StreamData{ - Interface: vname + "ServerStream", - VarName: scope.Unique(codegen.Goify(m.Name, true), "ServerStream"), - EndpointStruct: vname + "EndpointInput", - Kind: m.Stream, - SendName: "Send", - SendDesc: fmt.Sprintf("Send streams instances of %q.", rname), - SendTypeName: rname, - SendTypeRef: resultRef, - MustClose: true, + Interface: vname + "ServerStream", + VarName: scope.Unique(codegen.Goify(m.Name, true), "ServerStream"), + EndpointStruct: vname + "EndpointInput", + Kind: m.Stream, + SendName: "Send", + SendDesc: fmt.Sprintf("Send streams instances of %q.", rname), + SendWithContextName: "SendWithContext", + SendWithContextDesc: fmt.Sprintf("SendWithContext streams instances of %q with context.", rname), + SendTypeName: rname, + SendTypeRef: resultRef, + MustClose: true, } cliStream := &StreamData{ - Interface: vname + "ClientStream", - VarName: scope.Unique(codegen.Goify(m.Name, true), "ClientStream"), - Kind: m.Stream, - RecvName: "Recv", - RecvDesc: fmt.Sprintf("Recv reads instances of %q from the stream.", rname), - RecvTypeName: rname, - RecvTypeRef: resultRef, + Interface: vname + "ClientStream", + VarName: scope.Unique(codegen.Goify(m.Name, true), "ClientStream"), + Kind: m.Stream, + RecvName: "Recv", + RecvDesc: fmt.Sprintf("Recv reads instances of %q from the stream.", rname), + RecvWithContextName: "RecvWithContext", + RecvWithContextDesc: fmt.Sprintf("RecvWithContext reads instances of %q from the stream with context.", rname), + RecvTypeName: rname, + RecvTypeRef: resultRef, } if m.Stream == expr.ClientStreamKind || m.Stream == expr.BidirectionalStreamKind { switch m.Stream { @@ -1155,9 +1198,13 @@ func initStreamData(data *MethodData, m *expr.MethodExpr, vname, rname, resultRe if resultRef != "" { svrStream.SendName = "SendAndClose" svrStream.SendDesc = fmt.Sprintf("SendAndClose streams instances of %q and closes the stream.", rname) + svrStream.SendWithContextName = "SendAndCloseWithContext" + svrStream.SendWithContextDesc = fmt.Sprintf("SendAndCloseWithContext streams instances of %q and closes the stream with context.", rname) svrStream.MustClose = false cliStream.RecvName = "CloseAndRecv" cliStream.RecvDesc = fmt.Sprintf("CloseAndRecv stops sending messages to the stream and reads instances of %q from the stream.", rname) + cliStream.RecvWithContextName = "CloseAndRecvWithContext" + cliStream.RecvWithContextDesc = fmt.Sprintf("CloseAndRecvWithContext stops sending messages to the stream and reads instances of %q from the stream with context.", rname) } else { cliStream.MustClose = true } @@ -1166,10 +1213,14 @@ func initStreamData(data *MethodData, m *expr.MethodExpr, vname, rname, resultRe } svrStream.RecvName = "Recv" svrStream.RecvDesc = fmt.Sprintf("Recv reads instances of %q from the stream.", spayloadName) + svrStream.RecvWithContextName = "RecvWithContext" + svrStream.RecvWithContextDesc = fmt.Sprintf("RecvWithContext reads instances of %q from the stream with context.", spayloadName) svrStream.RecvTypeName = spayloadName svrStream.RecvTypeRef = spayloadRef cliStream.SendName = "Send" cliStream.SendDesc = fmt.Sprintf("Send streams instances of %q.", spayloadName) + cliStream.SendWithContextName = "SendWithContext" + cliStream.SendWithContextDesc = fmt.Sprintf("SendWithContext streams instances of %q with context.", spayloadName) cliStream.SendTypeName = spayloadName cliStream.SendTypeRef = spayloadRef } @@ -1177,7 +1228,7 @@ func initStreamData(data *MethodData, m *expr.MethodExpr, vname, rname, resultRe data.ServerStream = svrStream data.StreamingPayload = spayloadName data.StreamingPayloadDef = spayloadDef - data.StreamingPayloadRef = spayloadDef + data.StreamingPayloadRef = spayloadRef data.StreamingPayloadDesc = spayloadDesc data.StreamingPayloadEx = spayloadEx } @@ -1192,17 +1243,7 @@ func buildInterceptorData(svc *expr.ServiceExpr, methods []*MethodData, i *expr. if len(svc.Methods) == 0 { return data } - payload, result := svc.Methods[0].Payload, svc.Methods[0].Result - data.ReadPayload = collectAttributes(i.ReadPayload, payload, scope) - data.WritePayload = collectAttributes(i.WritePayload, payload, scope) - data.ReadResult = collectAttributes(i.ReadResult, result, scope) - data.WriteResult = collectAttributes(i.WriteResult, result, scope) - if len(data.ReadPayload) > 0 || len(data.WritePayload) > 0 { - data.HasPayloadAccess = true - } - if len(data.ReadResult) > 0 || len(data.WriteResult) > 0 { - data.HasResultAccess = true - } + attributesCollected := false for _, m := range svc.Methods { applies := false intExprs := m.ServerInterceptors @@ -1211,6 +1252,30 @@ func buildInterceptorData(svc *expr.ServiceExpr, methods []*MethodData, i *expr. } for _, in := range intExprs { if in.Name == i.Name { + if !attributesCollected { + payload, result, streamingPayload := m.Payload, m.Result, m.StreamingPayload + data.ReadPayload = collectAttributes(i.ReadPayload, payload, scope) + data.WritePayload = collectAttributes(i.WritePayload, payload, scope) + data.ReadResult = collectAttributes(i.ReadResult, result, scope) + data.WriteResult = collectAttributes(i.WriteResult, result, scope) + data.ReadStreamingPayload = collectAttributes(i.ReadStreamingPayload, streamingPayload, scope) + data.WriteStreamingPayload = collectAttributes(i.WriteStreamingPayload, streamingPayload, scope) + data.ReadStreamingResult = collectAttributes(i.ReadStreamingResult, result, scope) + data.WriteStreamingResult = collectAttributes(i.WriteStreamingResult, result, scope) + if len(data.ReadPayload) > 0 || len(data.WritePayload) > 0 { + data.HasPayloadAccess = true + } + if len(data.ReadResult) > 0 || len(data.WriteResult) > 0 { + data.HasResultAccess = true + } + if len(data.ReadStreamingPayload) > 0 || len(data.WriteStreamingPayload) > 0 { + data.HasStreamingPayloadAccess = true + } + if len(data.ReadStreamingResult) > 0 || len(data.WriteStreamingResult) > 0 { + data.HasStreamingResultAccess = true + } + attributesCollected = true + } applies = true break } @@ -1235,31 +1300,59 @@ func buildInterceptorData(svc *expr.ServiceExpr, methods []*MethodData, i *expr. return data } -// buildIntercetorMethodData creates the data needed to generate interceptor +// buildInterceptorMethodData creates the data needed to generate interceptor // method code. func buildInterceptorMethodData(i *expr.InterceptorExpr, md *MethodData) *MethodInterceptorData { - var serverStream, clientStream string + var serverStream, clientStream *StreamInterceptorData if md.ServerStream != nil { - serverStream = md.ServerStream.VarName + serverStream = &StreamInterceptorData{ + Interface: md.ServerStream.Interface, + SendName: md.ServerStream.SendName, + SendWithContextName: md.ServerStream.SendWithContextName, + SendTypeRef: md.ServerStream.SendTypeRef, + RecvName: md.ServerStream.RecvName, + RecvWithContextName: md.ServerStream.RecvWithContextName, + RecvTypeRef: md.ServerStream.RecvTypeRef, + MustClose: md.ServerStream.MustClose, + } } if md.ClientStream != nil { - clientStream = md.ClientStream.VarName - } - var payloadAccess, resultAccess string + clientStream = &StreamInterceptorData{ + Interface: md.ClientStream.Interface, + SendName: md.ClientStream.SendName, + SendWithContextName: md.ClientStream.SendWithContextName, + SendTypeRef: md.ClientStream.SendTypeRef, + RecvName: md.ClientStream.RecvName, + RecvWithContextName: md.ClientStream.RecvWithContextName, + RecvTypeRef: md.ClientStream.RecvTypeRef, + MustClose: md.ClientStream.MustClose, + } + } + var payloadAccess, resultAccess, streamingPayloadAccess, streamingResultAccess string if i.ReadPayload != nil || i.WritePayload != nil { payloadAccess = codegen.Goify(i.Name, false) + md.VarName + "Payload" } if i.ReadResult != nil || i.WriteResult != nil { resultAccess = codegen.Goify(i.Name, false) + md.VarName + "Result" } + if i.ReadStreamingPayload != nil || i.WriteStreamingPayload != nil { + streamingPayloadAccess = codegen.Goify(i.Name, false) + md.VarName + "StreamingPayload" + } + if i.ReadStreamingResult != nil || i.WriteStreamingResult != nil { + streamingResultAccess = codegen.Goify(i.Name, false) + md.VarName + "StreamingResult" + } return &MethodInterceptorData{ - MethodName: md.VarName, - PayloadAccess: payloadAccess, - ResultAccess: resultAccess, - PayloadRef: md.PayloadRef, - ResultRef: md.ResultRef, - ClientStreamInputStruct: clientStream, - ServerStreamInputStruct: serverStream, + MethodName: md.VarName, + PayloadAccess: payloadAccess, + ResultAccess: resultAccess, + PayloadRef: md.PayloadRef, + ResultRef: md.ResultRef, + StreamingPayloadAccess: streamingPayloadAccess, + StreamingPayloadRef: md.StreamingPayloadRef, + StreamingResultAccess: streamingResultAccess, + StreamingResultRef: md.ResultRef, + ClientStream: clientStream, + ServerStream: serverStream, } } @@ -1505,7 +1598,6 @@ func buildProjectedType(projected, att *expr.AttributeExpr, viewspkg string, sco var ( projections []*InitData typeInits []*InitData - validations []*ValidateData views []*ViewData varname = viewScope.GoTypeName(projected) @@ -1516,7 +1608,7 @@ func buildProjectedType(projected, att *expr.AttributeExpr, viewspkg string, sco projections = buildProjections(projected, att, viewspkg, scope, viewScope) views = buildViews(att.Type.(*expr.ResultTypeExpr), viewScope) } - validations = buildValidations(projected, viewScope) + validations := buildValidations(projected, viewScope) removeMeta(projected) return &ProjectedTypeData{ UserTypeData: &UserTypeData{ @@ -1558,23 +1650,18 @@ func buildViews(rt *expr.ResultTypeExpr, viewScope *codegen.NameScope) []*ViewDa // and projected type. func buildViewedResultType(att, projected *expr.AttributeExpr, viewspkg string, scope, viewScope *codegen.NameScope) *ViewedResultTypeData { // collect result type views - var ( - viewName string - views []*ViewData - ) - rt := att.Type.(*expr.ResultTypeExpr) isarr := expr.IsArray(att.Type) + var viewName string if !rt.HasMultipleViews() { viewName = expr.DefaultView } if v, ok := att.Meta.Last(expr.ViewMetaKey); ok { viewName = v } - views = buildViews(rt, viewScope) + views := buildViews(rt, viewScope) // build validation data - var validate *ValidateData resvar := scope.GoTypeName(att) resref := scope.GoTypeRef(att) data := map[string]any{ @@ -1589,7 +1676,7 @@ func buildViewedResultType(att, projected *expr.AttributeExpr, viewspkg string, panic(err) // bug } name := "Validate" + resvar - validate = &ValidateData{ + validate := &ValidateData{ Name: name, Description: fmt.Sprintf("%s runs the validations defined on the viewed result type %s.", name, resvar), Ref: resref, @@ -1597,7 +1684,6 @@ func buildViewedResultType(att, projected *expr.AttributeExpr, viewspkg string, } // build constructor to initialize viewed result type from result type - var init *InitData vresref := viewScope.GoFullTypeRef(att, viewspkg) data = map[string]any{ "ToViewed": true, @@ -1618,7 +1704,7 @@ func buildViewedResultType(att, projected *expr.AttributeExpr, viewspkg string, pkg = loc.PackageName() } name = "NewViewed" + resvar - init = &InitData{ + init := &InitData{ Name: name, Description: fmt.Sprintf("%s initializes viewed result type %s from result type %s using the given view.", name, resvar, resvar), Args: []*InitArgData{ @@ -1630,7 +1716,6 @@ func buildViewedResultType(att, projected *expr.AttributeExpr, viewspkg string, } // build constructor to initialize result type from viewed result type - var resinit *InitData if loc := codegen.UserTypeLocation(att.Type); loc != nil { resref = scope.GoFullTypeRef(att, loc.PackageName()) } @@ -1647,7 +1732,7 @@ func buildViewedResultType(att, projected *expr.AttributeExpr, viewspkg string, panic(err) // bug } name = "New" + resvar - resinit = &InitData{ + resinit := &InitData{ Name: name, Description: fmt.Sprintf("%s initializes result type %s from viewed result type %s.", name, resvar, resvar), Args: []*InitArgData{{Name: "vres", Ref: scope.GoFullTypeRef(att, viewspkg)}}, @@ -1744,20 +1829,14 @@ func buildTypeInits(projected, att *expr.AttributeExpr, viewspkg string, scope, }, } - var ( - name string - code string - helpers []*codegen.TransformFunctionData - ) - srcCtx := projectedTypeContext(viewspkg, true, viewScope) tgtCtx := typeContext("", scope) resvar := scope.GoTypeName(att) - name = "new" + resvar + name := "new" + resvar if view.Name != expr.DefaultView { name += codegen.Goify(view.Name, true) } - code, helpers = buildConstructorCode(src, att, "vres", "res", srcCtx, tgtCtx, view.Name) + code, helpers := buildConstructorCode(src, att, "vres", "res", srcCtx, tgtCtx, view.Name) pkg := "" if loc := codegen.UserTypeLocation(att.Type); loc != nil { @@ -1778,9 +1857,8 @@ func buildTypeInits(projected, att *expr.AttributeExpr, viewspkg string, scope, // buildProjections builds the data to generate the constructor code to // project a result type to a projected type based on a view. func buildProjections(projected, att *expr.AttributeExpr, viewspkg string, scope, viewScope *codegen.NameScope) []*InitData { - var projections []*InitData rt := att.Type.(*expr.ResultTypeExpr) - projections = make([]*InitData, 0, len(rt.Views)) + projections := make([]*InitData, 0, len(rt.Views)) for _, view := range rt.Views { var typ expr.DataType obj := &expr.Object{} @@ -1815,19 +1893,14 @@ func buildProjections(projected, att *expr.AttributeExpr, viewspkg string, scope }, } - var ( - name string - code string - helpers []*codegen.TransformFunctionData - ) srcCtx := typeContext("", scope) tgtCtx := projectedTypeContext(viewspkg, true, viewScope) tname := scope.GoTypeName(projected) - name = "new" + tname + name := "new" + tname if view.Name != expr.DefaultView { name += codegen.Goify(view.Name, true) } - code, helpers = buildConstructorCode(att, tgt, "res", "vres", srcCtx, tgtCtx, view.Name) + code, helpers := buildConstructorCode(att, tgt, "res", "vres", srcCtx, tgtCtx, view.Name) pkg := "" if loc := codegen.UserTypeLocation(att.Type); loc != nil { @@ -1848,9 +1921,9 @@ func buildProjections(projected, att *expr.AttributeExpr, viewspkg string, scope // buildValidations builds the data required to generate validations for the // projected types. func buildValidations(projected *expr.AttributeExpr, scope *codegen.NameScope) []*ValidateData { - var validations []*ValidateData ut := projected.Type.(expr.UserType) tname := scope.GoTypeName(projected) + var validations []*ValidateData if rt, isrt := ut.(*expr.ResultTypeExpr); isrt { // for result types we create a validation function containing view // specific validation logic for each view @@ -1862,11 +1935,8 @@ func buildValidations(projected *expr.AttributeExpr, scope *codegen.NameScope) [ "Source": "result", "IsCollection": arr != nil, } - var ( - name string - vn string - ) - name = "Validate" + tname + var vn string + name := "Validate" + tname if view.Name != expr.DefaultView { vn = codegen.Goify(view.Name, true) name += vn @@ -1877,10 +1947,7 @@ func buildValidations(projected *expr.AttributeExpr, scope *codegen.NameScope) [ data["Source"] = "item" data["ValidateVar"] = "Validate" + scope.GoTypeName(arr.ElemType) + vn } else { - var ( - ctx *codegen.AttributeContext - fields []map[string]any - ) + var fields []map[string]any o := &expr.Object{} walkViewAttrs(expr.AsObject(projected.Type), view, func(name string, attr, vatt *expr.AttributeExpr) { if rt, ok := attr.Type.(*expr.ResultTypeExpr); ok { @@ -1899,7 +1966,7 @@ func buildValidations(projected *expr.AttributeExpr, scope *codegen.NameScope) [ o.Set(name, attr) } }) - ctx = projectedTypeContext("", !expr.IsPrimitive(projected.Type), scope) + ctx := projectedTypeContext("", !expr.IsPrimitive(projected.Type), scope) data["Validate"] = codegen.ValidationCode(&expr.AttributeExpr{Type: o, Validation: rt.Validation}, rt, ctx, true, false, true, "result") data["Fields"] = fields } @@ -2030,7 +2097,7 @@ func walkViewAttrs(obj *expr.Object, view *expr.ViewExpr, walker func(name strin } // removeMeta removes the meta attributes from the given attribute. This is -// needed to make sure that any field name overridding is removed when +// needed to make sure that any field name overriding is removed when // generating protobuf types (as protogen itself won't honor these overrides). func removeMeta(att *expr.AttributeExpr) { _ = codegen.Walk(att, func(a *expr.AttributeExpr) error { diff --git a/codegen/service/templates/client_interceptor_stream_wrapper_types.go.tpl b/codegen/service/templates/client_interceptor_stream_wrapper_types.go.tpl new file mode 100644 index 0000000000..9a250d08f6 --- /dev/null +++ b/codegen/service/templates/client_interceptor_stream_wrapper_types.go.tpl @@ -0,0 +1,14 @@ +{{- range .WrappedClientStreams }} + +{{ comment (printf "wrapped%s is a client interceptor wrapper for the %s stream." .Interface .Interface) }} +type wrapped{{ .Interface }} struct { + ctx context.Context + {{- if ne .SendTypeRef "" }} + sendWithContext func(context.Context, {{ .SendTypeRef }}) error + {{- end }} + {{- if ne .RecvTypeRef "" }} + recvWithContext func(context.Context) ({{ .RecvTypeRef }}, error) + {{- end }} + stream {{ .Interface }} +} +{{- end }} diff --git a/codegen/service/templates/client_interceptor_stream_wrappers.go.tpl b/codegen/service/templates/client_interceptor_stream_wrappers.go.tpl new file mode 100644 index 0000000000..e1f3e2c5a2 --- /dev/null +++ b/codegen/service/templates/client_interceptor_stream_wrappers.go.tpl @@ -0,0 +1,40 @@ +{{- range .WrappedClientStreams }} + + {{- if ne .SendTypeRef "" }} + +{{ comment (printf "%s streams instances of \"%s\" after executing the applied interceptor." .SendName .Interface) }} +func (w *wrapped{{ .Interface }}) {{ .SendName }}(v {{ .SendTypeRef }}) error { + return w.SendWithContext(w.ctx, v) +} + +{{ comment (printf "%s streams instances of \"%s\" after executing the applied interceptor with context." .SendWithContextName .Interface) }} +func (w *wrapped{{ .Interface }}) {{ .SendWithContextName }}(ctx context.Context, v {{ .SendTypeRef }}) error { + if w.sendWithContext == nil { + return w.stream.{{ .SendWithContextName }}(ctx, v) + } + return w.sendWithContext(ctx, v) +} + {{- end }} + {{- if ne .RecvTypeRef "" }} + +{{ comment (printf "%s reads instances of \"%s\" from the stream after executing the applied interceptor." .RecvName .Interface) }} +func (w *wrapped{{ .Interface }}) {{ .RecvName }}() ({{ .RecvTypeRef }}, error) { + return w.RecvWithContext(w.ctx) +} + +{{ comment (printf "%s reads instances of \"%s\" from the stream after executing the applied interceptor with context." .RecvWithContextName .Interface) }} +func (w *wrapped{{ .Interface }}) {{ .RecvWithContextName }}(ctx context.Context) ({{ .RecvTypeRef }}, error) { + if w.recvWithContext == nil { + return w.stream.{{ .RecvWithContextName }}(ctx) + } + return w.recvWithContext(ctx) +} + {{- end }} + {{- if .MustClose }} + +// Close closes the stream. +func (w *wrapped{{ .Interface }}) Close() error { + return w.stream.Close() +} + {{- end }} +{{- end }} diff --git a/codegen/service/templates/client_interceptor_wrappers.go.tpl b/codegen/service/templates/client_interceptor_wrappers.go.tpl index cc0ff52a7b..c01590d59c 100644 --- a/codegen/service/templates/client_interceptor_wrappers.go.tpl +++ b/codegen/service/templates/client_interceptor_wrappers.go.tpl @@ -4,19 +4,66 @@ {{ comment (printf "wrapClient%s%s applies the %s client interceptor to endpoints." $interceptor.Name .MethodName $interceptor.DesignName) }} func wrapClient{{ .MethodName }}{{ $interceptor.Name }}(endpoint goa.Endpoint, i ClientInterceptors) goa.Endpoint { - return func(ctx context.Context, req any) (any, error) { - info := &{{ $interceptor.Name }}Info{ - Service: "{{ $.Service }}", - Method: "{{ .MethodName }}", - Endpoint: endpoint, - {{- if .ClientStreamInputStruct }} - RawPayload: req.(*{{ .ClientStreamInputStruct }}).Payload, - {{- else }} - RawPayload: req, - {{- end }} - } - return i.{{ $interceptor.Name }}(ctx, info, endpoint) - } + return func(ctx context.Context, req any) (any, error) { + {{- if or $interceptor.HasStreamingPayloadAccess $interceptor.HasStreamingResultAccess }} + {{- if $interceptor.HasPayloadAccess }} + info := &{{ $interceptor.Name }}Info{ + service: "{{ $.Service }}", + method: "{{ .MethodName }}", + callType: goa.InterceptorUnary, + rawPayload: req, + } + res, err := i.{{ $interceptor.Name }}(ctx, info, endpoint) + {{- else }} + res, err := endpoint(ctx, req) + {{- end }} + if err != nil { + return res, err + } + stream := res.({{ .ClientStream.Interface }}) + return &wrapped{{ .ClientStream.Interface }}{ + ctx: ctx, + {{- if $interceptor.HasStreamingPayloadAccess }} + sendWithContext: func(ctx context.Context, req {{ .ClientStream.SendTypeRef }}) error { + info := &{{ $interceptor.Name }}Info{ + service: "{{ $.Service }}", + method: "{{ .MethodName }}", + callType: goa.InterceptorStreamingSend, + rawPayload: req, + } + _, err := i.{{ $interceptor.Name }}(ctx, info, func(ctx context.Context, req any) (any, error) { + castReq, _ := req.({{ .ClientStream.SendTypeRef }}) + return nil, stream.{{ .ClientStream.SendWithContextName }}(ctx, castReq) + }) + return err + }, + {{- end }} + {{- if $interceptor.HasStreamingResultAccess }} + recvWithContext: func(ctx context.Context) ({{ .ClientStream.RecvTypeRef }}, error) { + info := &{{ $interceptor.Name }}Info{ + service: "{{ $.Service }}", + method: "{{ .MethodName }}", + callType: goa.InterceptorStreamingRecv, + } + res, err := i.{{ $interceptor.Name }}(ctx, info, func(ctx context.Context, _ any) (any, error) { + return stream.{{ .ClientStream.RecvWithContextName }}(ctx) + }) + castRes, _ := res.({{ .ClientStream.RecvTypeRef }}) + return castRes, err + }, + {{- end }} + stream: stream, + }, nil + {{- else }} + info := &{{ $interceptor.Name }}Info{ + service: "{{ $.Service }}", + method: "{{ .MethodName }}", + callType: goa.InterceptorUnary, + rawPayload: req, + } + return i.{{ $interceptor.Name }}(ctx, info, endpoint) + {{- end }} + } } -{{ end }} +{{- end }} {{- end }} diff --git a/codegen/service/templates/client_wrappers.go.tpl b/codegen/service/templates/client_wrappers.go.tpl index 9287d25b35..711e632e72 100644 --- a/codegen/service/templates/client_wrappers.go.tpl +++ b/codegen/service/templates/client_wrappers.go.tpl @@ -1,8 +1,8 @@ {{ comment (printf "Wrap%sClientEndpoint wraps the %s endpoint with the client interceptors defined in the design." .MethodVarName .Method) }} func Wrap{{ .MethodVarName }}ClientEndpoint(endpoint goa.Endpoint, i ClientInterceptors) goa.Endpoint { - {{- range .Interceptors }} - endpoint = wrapClient{{ $.MethodVarName }}{{ . }}(endpoint, i) - {{- end }} - return endpoint + {{- range .Interceptors }} + endpoint = wrapClient{{ $.MethodVarName }}{{ . }}(endpoint, i) + {{- end }} + return endpoint } diff --git a/codegen/service/templates/example_client_interceptor.go.tpl b/codegen/service/templates/example_client_interceptor.go.tpl index 455c74c9f4..4dad48f184 100644 --- a/codegen/service/templates/example_client_interceptor.go.tpl +++ b/codegen/service/templates/example_client_interceptor.go.tpl @@ -12,8 +12,8 @@ func New{{ .StructName }}ClientInterceptors() *{{ .StructName }}ClientIntercepto {{ comment .Description }} {{- end }} func (i *{{ $.StructName }}ClientInterceptors) {{ .Name }}(ctx context.Context, info *{{ $.PkgName }}.{{ .Name }}Info, next goa.Endpoint) (any, error) { - log.Printf(ctx, "[{{ .Name }}] Sending request: %v", info.RawPayload) - resp, err := next(ctx, info.RawPayload) + log.Printf(ctx, "[{{ .Name }}] Sending request: %v", info.RawPayload()) + resp, err := next(ctx, info.RawPayload()) if err != nil { log.Printf(ctx, "[{{ .Name }}] Error: %v", err) return nil, err @@ -21,4 +21,4 @@ func (i *{{ $.StructName }}ClientInterceptors) {{ .Name }}(ctx context.Context, log.Printf(ctx, "[{{ .Name }}] Received response: %v", resp) return resp, nil } -{{- end }} \ No newline at end of file +{{- end }} diff --git a/codegen/service/templates/example_server_interceptor.go.tpl b/codegen/service/templates/example_server_interceptor.go.tpl index dfbb7d93bb..9e1ed5086e 100644 --- a/codegen/service/templates/example_server_interceptor.go.tpl +++ b/codegen/service/templates/example_server_interceptor.go.tpl @@ -12,8 +12,8 @@ func New{{ .StructName }}ServerInterceptors() *{{ .StructName }}ServerIntercepto {{ comment .Description }} {{- end }} func (i *{{ $.StructName }}ServerInterceptors) {{ .Name }}(ctx context.Context, info *{{ $.PkgName }}.{{ .Name }}Info, next goa.Endpoint) (any, error) { - log.Printf(ctx, "[{{ .Name }}] Processing request: %v", info.RawPayload) - resp, err := next(ctx, info.RawPayload) + log.Printf(ctx, "[{{ .Name }}] Processing request: %v", info.RawPayload()) + resp, err := next(ctx, info.RawPayload()) if err != nil { log.Printf(ctx, "[{{ .Name }}] Error: %v", err) return nil, err @@ -21,4 +21,4 @@ func (i *{{ $.StructName }}ServerInterceptors) {{ .Name }}(ctx context.Context, log.Printf(ctx, "[{{ .Name }}] Response: %v", resp) return resp, nil } -{{- end }} \ No newline at end of file +{{- end }} diff --git a/codegen/service/templates/interceptors.go.tpl b/codegen/service/templates/interceptors.go.tpl index ea3b0b5e86..43f17a32dc 100644 --- a/codegen/service/templates/interceptors.go.tpl +++ b/codegen/service/templates/interceptors.go.tpl @@ -1,21 +1,41 @@ {{- if hasPrivateImplementationTypes . }} // Public accessor methods for Info types {{- range . }} + +// Service returns the name of the service handling the request. +func (info *{{ .Name }}Info) Service() string { + return info.service +} + +// Method returns the name of the method handling the request. +func (info *{{ .Name }}Info) Method() string { + return info.method +} + +// CallType returns the type of call the interceptor is handling. +func (info *{{ .Name }}Info) CallType() goa.InterceptorCallType { + return info.callType +} + +// RawPayload returns the raw payload of the request. +func (info *{{ .Name }}Info) RawPayload() any { + return info.rawPayload +} {{- if .HasPayloadAccess }} // Payload returns a type-safe accessor for the method payload. func (info *{{ .Name }}Info) Payload() {{ .Name }}Payload { {{- if gt (len .Methods) 1 }} - switch info.Method { + switch info.Method() { {{- range .Methods }} case "{{ .MethodName }}": - return &{{ .PayloadAccess }}{payload: info.RawPayload.({{ .PayloadRef }})} + return &{{ .PayloadAccess }}{payload: info.RawPayload().({{ .PayloadRef }})} {{- end }} default: return nil } {{- else }} - return &{{ (index .Methods 0).PayloadAccess }}{payload: info.RawPayload.({{ (index .Methods 0).PayloadRef }})} + return &{{ (index .Methods 0).PayloadAccess }}{payload: info.RawPayload().({{ (index .Methods 0).PayloadRef }})} {{- end }} } {{- end }} @@ -24,7 +44,7 @@ func (info *{{ .Name }}Info) Payload() {{ .Name }}Payload { // Result returns a type-safe accessor for the method result. func (info *{{ .Name }}Info) Result(res any) {{ .Name }}Result { {{- if gt (len .Methods) 1 }} - switch info.Method { + switch info.Method() { {{- range .Methods }} case "{{ .MethodName }}": return &{{ .ResultAccess }}{result: res.({{ .ResultRef }})} @@ -35,6 +55,78 @@ func (info *{{ .Name }}Info) Result(res any) {{ .Name }}Result { {{- else }} return &{{ (index .Methods 0).ResultAccess }}{result: res.({{ (index .Methods 0).ResultRef }})} {{- end }} +} + {{- end }} + + {{- if .HasStreamingPayloadAccess }} +// ClientStreamingPayload returns a type-safe accessor for the method streaming payload for a client-side interceptor. +func (info *{{ .Name }}Info) ClientStreamingPayload() {{ .Name }}StreamingPayload { + {{- if gt (len .Methods) 1 }} + switch info.Method() { + {{- range .Methods }} + case "{{ .MethodName }}": + return &{{ .StreamingPayloadAccess }}{payload: info.RawPayload().({{ .StreamingPayloadRef }})} + {{- end }} + default: + return nil + } + {{- else }} + return &{{ (index .Methods 0).StreamingPayloadAccess }}{payload: info.RawPayload().({{ (index .Methods 0).StreamingPayloadRef }})} + {{- end }} +} + {{- end }} + + {{- if .HasStreamingResultAccess }} +// ClientStreamingResult returns a type-safe accessor for the method streaming result for a client-side interceptor. +func (info *{{ .Name }}Info) ClientStreamingResult(res any) {{ .Name }}StreamingResult { + {{- if gt (len .Methods) 1 }} + switch info.Method() { + {{- range .Methods }} + case "{{ .MethodName }}": + return &{{ .StreamingResultAccess }}{result: res.({{ .StreamingResultRef }})} + {{- end }} + default: + return nil + } + {{- else }} + return &{{ (index .Methods 0).StreamingResultAccess }}{result: res.({{ (index .Methods 0).StreamingResultRef }})} + {{- end }} +} + {{- end }} + + {{- if .HasStreamingPayloadAccess }} +// ServerStreamingPayload returns a type-safe accessor for the method streaming payload for a server-side interceptor. +func (info *{{ .Name }}Info) ServerStreamingPayload(pay any) {{ .Name }}StreamingPayload { + {{- if gt (len .Methods) 1 }} + switch info.Method() { + {{- range .Methods }} + case "{{ .MethodName }}": + return &{{ .StreamingPayloadAccess }}{payload: pay.({{ .StreamingPayloadRef }})} + {{- end }} + default: + return nil + } + {{- else }} + return &{{ (index .Methods 0).StreamingPayloadAccess }}{payload: pay.({{ (index .Methods 0).StreamingPayloadRef }})} + {{- end }} +} + {{- end }} + + {{- if .HasStreamingResultAccess }} +// ServerStreamingResult returns a type-safe accessor for the method streaming result for a server-side interceptor. +func (info *{{ .Name }}Info) ServerStreamingResult() {{ .Name }}StreamingResult { + {{- if gt (len .Methods) 1 }} + switch info.Method() { + {{- range .Methods }} + case "{{ .MethodName }}": + return &{{ .StreamingResultAccess }}{result: info.RawPayload().({{ .StreamingResultRef }})} + {{- end }} + default: + return nil + } + {{- else }} + return &{{ (index .Methods 0).StreamingResultAccess }}{result: info.RawPayload().({{ (index .Methods 0).StreamingResultRef }})} + {{- end }} } {{- end }} {{- end }} @@ -89,6 +181,54 @@ func (r *{{ $method.ResultAccess }}) Set{{ .Name }}(v {{ .TypeRef }}) { {{- else }} r.result.{{ .Name }} = v {{- end }} +} + {{- end }} + + {{- range $interceptor.ReadStreamingPayload }} +func (p *{{ $method.StreamingPayloadAccess }}) {{ .Name }}() {{ .TypeRef }} { + {{- if .Pointer }} + if p.payload.{{ .Name }} == nil { + var zero {{ .TypeRef }} + return zero + } + return *p.payload.{{ .Name }} + {{- else }} + return p.payload.{{ .Name }} + {{- end }} +} + {{- end }} + + {{- range $interceptor.WriteStreamingPayload }} +func (p *{{ $method.StreamingPayloadAccess }}) Set{{ .Name }}(v {{ .TypeRef }}) { + {{- if .Pointer }} + p.payload.{{ .Name }} = &v + {{- else }} + p.payload.{{ .Name }} = v + {{- end }} +} + {{- end }} + + {{- range $interceptor.ReadStreamingResult }} +func (r *{{ $method.StreamingResultAccess }}) {{ .Name }}() {{ .TypeRef }} { + {{- if .Pointer }} + if r.result.{{ .Name }} == nil { + var zero {{ .TypeRef }} + return zero + } + return *r.result.{{ .Name }} + {{- else }} + return r.result.{{ .Name }} + {{- end }} +} + {{- end }} + + {{- range $interceptor.WriteStreamingResult }} +func (r *{{ $method.StreamingResultAccess }}) Set{{ .Name }}(v {{ .TypeRef }}) { + {{- if .Pointer }} + r.result.{{ .Name }} = &v + {{- else }} + r.result.{{ .Name }} = v + {{- end }} } {{- end }} {{- end }} diff --git a/codegen/service/templates/interceptors_types.go.tpl b/codegen/service/templates/interceptors_types.go.tpl index 0c542b089e..10b890f470 100644 --- a/codegen/service/templates/interceptors_types.go.tpl +++ b/codegen/service/templates/interceptors_types.go.tpl @@ -4,7 +4,12 @@ type ( {{- range . }} // {{ .Name }}Info provides metadata about the current interception. // It includes service name, method name, and access to the endpoint. - {{ .Name }}Info goa.InterceptorInfo + {{ .Name }}Info struct { + service string + method string + callType goa.InterceptorCallType + rawPayload any + } {{- if .HasPayloadAccess }} // {{ .Name }}Payload provides type-safe access to the method payload. @@ -33,6 +38,34 @@ type ( {{- end }} } {{- end }} + {{- if .HasStreamingPayloadAccess }} + + // {{ .Name }}StreamingPayload provides type-safe access to the method streaming payload. + // It allows reading and writing specific fields of the streaming payload as defined + // in the design. + {{ .Name }}StreamingPayload interface { + {{- range .ReadStreamingPayload }} + {{ .Name }}() {{ .TypeRef }} + {{- end }} + {{- range .WriteStreamingPayload }} + Set{{ .Name }}({{ .TypeRef }}) + {{- end }} + } + {{- end }} + {{- if .HasStreamingResultAccess }} + + // {{ .Name }}StreamingResult provides type-safe access to the method streaming result. + // It allows reading and writing specific fields of the streaming result as defined + // in the design. + {{ .Name }}StreamingResult interface { + {{- range .ReadStreamingResult }} + {{ .Name }}() {{ .TypeRef }} + {{- end }} + {{- range .WriteStreamingResult }} + Set{{ .Name }}({{ .TypeRef }}) + {{- end }} + } + {{- end }} {{- end }} ) {{- if hasPrivateImplementationTypes . }} @@ -58,5 +91,25 @@ type ( {{- end }} {{- end }} {{- end }} + + {{- range . }} + {{- range .Methods }} + {{- if .StreamingPayloadAccess }} + {{ .StreamingPayloadAccess }} struct { + payload {{ .StreamingPayloadRef }} + } + {{- end }} + {{- end }} + {{- end }} + + {{- range . }} + {{- range .Methods }} + {{- if .StreamingResultAccess }} + {{ .StreamingResultAccess }} struct { + result {{ .StreamingResultRef }} + } + {{- end }} + {{- end }} + {{- end }} ) {{- end }} diff --git a/codegen/service/templates/server_interceptor_stream_wrapper_types.go.tpl b/codegen/service/templates/server_interceptor_stream_wrapper_types.go.tpl new file mode 100644 index 0000000000..a33a45fa2a --- /dev/null +++ b/codegen/service/templates/server_interceptor_stream_wrapper_types.go.tpl @@ -0,0 +1,14 @@ +{{- range .WrappedServerStreams }} + +{{ comment (printf "wrapped%s is a server interceptor wrapper for the %s stream." .Interface .Interface) }} +type wrapped{{ .Interface }} struct { + ctx context.Context + {{- if ne .SendTypeRef "" }} + sendWithContext func(context.Context, {{ .SendTypeRef }}) error + {{- end }} + {{- if ne .RecvTypeRef "" }} + recvWithContext func(context.Context) ({{ .RecvTypeRef }}, error) + {{- end }} + stream {{ .Interface }} +} +{{- end }} diff --git a/codegen/service/templates/server_interceptor_stream_wrappers.go.tpl b/codegen/service/templates/server_interceptor_stream_wrappers.go.tpl new file mode 100644 index 0000000000..f07af48ca7 --- /dev/null +++ b/codegen/service/templates/server_interceptor_stream_wrappers.go.tpl @@ -0,0 +1,40 @@ +{{- range .WrappedServerStreams }} + + {{- if ne .SendTypeRef "" }} + +{{ comment (printf "%s streams instances of \"%s\" after executing the applied interceptor." .SendName .Interface) }} +func (w *wrapped{{ .Interface }}) {{ .SendName }}(v {{ .SendTypeRef }}) error { + return w.SendWithContext(w.ctx, v) +} + +{{ comment (printf "%s streams instances of \"%s\" after executing the applied interceptor with context." .SendWithContextName .Interface) }} +func (w *wrapped{{ .Interface }}) {{ .SendWithContextName }}(ctx context.Context, v {{ .SendTypeRef }}) error { + if w.sendWithContext == nil { + return w.stream.{{ .SendWithContextName }}(ctx, v) + } + return w.sendWithContext(ctx, v) +} + {{- end }} + {{- if ne .RecvTypeRef "" }} + +{{ comment (printf "%s reads instances of \"%s\" from the stream after executing the applied interceptor." .RecvName .Interface) }} +func (w *wrapped{{ .Interface }}) {{ .RecvName }}() ({{ .RecvTypeRef }}, error) { + return w.RecvWithContext(w.ctx) +} + +{{ comment (printf "%s reads instances of \"%s\" from the stream after executing the applied interceptor with context." .RecvWithContextName .Interface) }} +func (w *wrapped{{ .Interface }}) {{ .RecvWithContextName }}(ctx context.Context) ({{ .RecvTypeRef }}, error) { + if w.recvWithContext == nil { + return w.stream.{{ .RecvWithContextName }}(ctx) + } + return w.recvWithContext(ctx) +} + {{- end }} + {{- if .MustClose }} + +// Close closes the stream. +func (w *wrapped{{ .Interface }}) Close() error { + return w.stream.Close() +} + {{- end }} +{{- end }} diff --git a/codegen/service/templates/server_interceptor_wrappers.go.tpl b/codegen/service/templates/server_interceptor_wrappers.go.tpl index cb0f5d9c44..0fd7366a9a 100644 --- a/codegen/service/templates/server_interceptor_wrappers.go.tpl +++ b/codegen/service/templates/server_interceptor_wrappers.go.tpl @@ -5,18 +5,65 @@ {{ comment (printf "wrap%s%s applies the %s server interceptor to endpoints." $interceptor.Name .MethodName $interceptor.DesignName) }} func wrap{{ .MethodName }}{{ $interceptor.Name }}(endpoint goa.Endpoint, i ServerInterceptors) goa.Endpoint { return func(ctx context.Context, req any) (any, error) { + {{- if or $interceptor.HasStreamingPayloadAccess $interceptor.HasStreamingResultAccess }} + {{- if $interceptor.HasPayloadAccess }} info := &{{ $interceptor.Name }}Info{ - Service: "{{ $.Service }}", - Method: "{{ .MethodName }}", - Endpoint: endpoint, - {{- if .ServerStreamInputStruct }} - RawPayload: req.(*{{ .ServerStreamInputStruct }}).Payload, - {{- else }} - RawPayload: req, - {{- end }} + service: "{{ $.Service }}", + method: "{{ .MethodName }}", + callType: goa.InterceptorUnary, + rawPayload: req, + } + res, err := i.{{ $interceptor.Name }}(ctx, info, endpoint) + {{- else }} + res, err := endpoint(ctx, req) + {{- end }} + if err != nil { + return res, err + } + stream := res.({{ .ServerStream.Interface }}) + return &wrapped{{ .ServerStream.Interface }}{ + ctx: ctx, + {{- if $interceptor.HasStreamingResultAccess }} + sendWithContext: func(ctx context.Context, req {{ .ServerStream.SendTypeRef }}) error { + info := &{{ $interceptor.Name }}Info{ + service: "{{ $.Service }}", + method: "{{ .MethodName }}", + callType: goa.InterceptorStreamingSend, + rawPayload: req, + } + _, err := i.{{ $interceptor.Name }}(ctx, info, func(ctx context.Context, req any) (any, error) { + castReq, _ := req.({{ .ServerStream.SendTypeRef }}) + return nil, stream.{{ .ServerStream.SendWithContextName }}(ctx, castReq) + }) + return err + }, + {{- end }} + {{- if $interceptor.HasStreamingPayloadAccess }} + recvWithContext: func(ctx context.Context) ({{ .ServerStream.RecvTypeRef }}, error) { + info := &{{ $interceptor.Name }}Info{ + service: "{{ $.Service }}", + method: "{{ .MethodName }}", + callType: goa.InterceptorStreamingRecv, + } + res, err := i.{{ $interceptor.Name }}(ctx, info, func(ctx context.Context, _ any) (any, error) { + return stream.{{ .ServerStream.RecvWithContextName }}(ctx) + }) + castRes, _ := res.({{ .ServerStream.RecvTypeRef }}) + return castRes, err + }, + {{- end }} + stream: stream, + }, nil + {{- else }} + info := &{{ $interceptor.Name }}Info{ + service: "{{ $.Service }}", + method: "{{ .MethodName }}", + callType: goa.InterceptorUnary, + rawPayload: req, } return i.{{ $interceptor.Name }}(ctx, info, endpoint) + {{- end }} } } {{- end }} -{{- end }} \ No newline at end of file +{{- end }} diff --git a/codegen/service/templates/server_interceptors.go.tpl b/codegen/service/templates/server_interceptors.go.tpl index cdfb9287ec..3bd263dc95 100644 --- a/codegen/service/templates/server_interceptors.go.tpl +++ b/codegen/service/templates/server_interceptors.go.tpl @@ -9,4 +9,4 @@ type ServerInterceptors interface { {{- end }} {{ .Name }}(ctx context.Context, info *{{ .Name }}Info, next goa.Endpoint) (any, error) {{- end }} -} \ No newline at end of file +} diff --git a/codegen/service/templates/service.go.tpl b/codegen/service/templates/service.go.tpl index 5164c62016..6a3334a5bd 100644 --- a/codegen/service/templates/service.go.tpl +++ b/codegen/service/templates/service.go.tpl @@ -64,10 +64,14 @@ type {{ .Stream.Interface }} interface { {{- if .Stream.SendTypeRef }} {{ comment .Stream.SendDesc }} {{ .Stream.SendName }}({{ .Stream.SendTypeRef }}) error + {{ comment .Stream.SendWithContextDesc }} + {{ .Stream.SendWithContextName }}(context.Context, {{ .Stream.SendTypeRef }}) error {{- end }} {{- if .Stream.RecvTypeRef }} {{ comment .Stream.RecvDesc }} {{ .Stream.RecvName }}() ({{ .Stream.RecvTypeRef }}, error) + {{ comment .Stream.RecvWithContextDesc }} + {{ .Stream.RecvWithContextName }}(context.Context) ({{ .Stream.RecvTypeRef }}, error) {{- end }} {{- if .Stream.MustClose }} {{ comment "Close closes the stream." }} diff --git a/codegen/service/templates/service_interceptor.go.tpl b/codegen/service/templates/service_interceptor.go.tpl deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/codegen/service/testdata/example_interceptors/api_interceptor_service_client.golden b/codegen/service/testdata/example_interceptors/api_interceptor_service_client.golden index 5188cca366..57b92d14f2 100644 --- a/codegen/service/testdata/example_interceptors/api_interceptor_service_client.golden +++ b/codegen/service/testdata/example_interceptors/api_interceptor_service_client.golden @@ -24,8 +24,8 @@ func NewAPIInterceptorServiceClientInterceptors() *APIInterceptorServiceClientIn return &APIInterceptorServiceClientInterceptors{} } func (i *APIInterceptorServiceClientInterceptors) API(ctx context.Context, info *interceptors.APIInfo, next goa.Endpoint) (any, error) { - log.Printf(ctx, "[API] Sending request: %v", info.RawPayload) - resp, err := next(ctx, info.RawPayload) + log.Printf(ctx, "[API] Sending request: %v", info.RawPayload()) + resp, err := next(ctx, info.RawPayload()) if err != nil { log.Printf(ctx, "[API] Error: %v", err) return nil, err diff --git a/codegen/service/testdata/example_interceptors/api_interceptor_service_server.golden b/codegen/service/testdata/example_interceptors/api_interceptor_service_server.golden index ff86a4cee7..4be7b616b5 100644 --- a/codegen/service/testdata/example_interceptors/api_interceptor_service_server.golden +++ b/codegen/service/testdata/example_interceptors/api_interceptor_service_server.golden @@ -24,8 +24,8 @@ func NewAPIInterceptorServiceServerInterceptors() *APIInterceptorServiceServerIn return &APIInterceptorServiceServerInterceptors{} } func (i *APIInterceptorServiceServerInterceptors) API(ctx context.Context, info *interceptors.APIInfo, next goa.Endpoint) (any, error) { - log.Printf(ctx, "[API] Processing request: %v", info.RawPayload) - resp, err := next(ctx, info.RawPayload) + log.Printf(ctx, "[API] Processing request: %v", info.RawPayload()) + resp, err := next(ctx, info.RawPayload()) if err != nil { log.Printf(ctx, "[API] Error: %v", err) return nil, err diff --git a/codegen/service/testdata/example_interceptors/chained_interceptor_service_client.golden b/codegen/service/testdata/example_interceptors/chained_interceptor_service_client.golden index 4a1eeebce9..303c529a4c 100644 --- a/codegen/service/testdata/example_interceptors/chained_interceptor_service_client.golden +++ b/codegen/service/testdata/example_interceptors/chained_interceptor_service_client.golden @@ -24,8 +24,8 @@ func NewChainedInterceptorServiceClientInterceptors() *ChainedInterceptorService return &ChainedInterceptorServiceClientInterceptors{} } func (i *ChainedInterceptorServiceClientInterceptors) API(ctx context.Context, info *interceptors.APIInfo, next goa.Endpoint) (any, error) { - log.Printf(ctx, "[API] Sending request: %v", info.RawPayload) - resp, err := next(ctx, info.RawPayload) + log.Printf(ctx, "[API] Sending request: %v", info.RawPayload()) + resp, err := next(ctx, info.RawPayload()) if err != nil { log.Printf(ctx, "[API] Error: %v", err) return nil, err @@ -34,8 +34,8 @@ func (i *ChainedInterceptorServiceClientInterceptors) API(ctx context.Context, i return resp, nil } func (i *ChainedInterceptorServiceClientInterceptors) Method(ctx context.Context, info *interceptors.MethodInfo, next goa.Endpoint) (any, error) { - log.Printf(ctx, "[Method] Sending request: %v", info.RawPayload) - resp, err := next(ctx, info.RawPayload) + log.Printf(ctx, "[Method] Sending request: %v", info.RawPayload()) + resp, err := next(ctx, info.RawPayload()) if err != nil { log.Printf(ctx, "[Method] Error: %v", err) return nil, err @@ -44,8 +44,8 @@ func (i *ChainedInterceptorServiceClientInterceptors) Method(ctx context.Context return resp, nil } func (i *ChainedInterceptorServiceClientInterceptors) Service(ctx context.Context, info *interceptors.ServiceInfo, next goa.Endpoint) (any, error) { - log.Printf(ctx, "[Service] Sending request: %v", info.RawPayload) - resp, err := next(ctx, info.RawPayload) + log.Printf(ctx, "[Service] Sending request: %v", info.RawPayload()) + resp, err := next(ctx, info.RawPayload()) if err != nil { log.Printf(ctx, "[Service] Error: %v", err) return nil, err diff --git a/codegen/service/testdata/example_interceptors/chained_interceptor_service_server.golden b/codegen/service/testdata/example_interceptors/chained_interceptor_service_server.golden index 4027c3a597..cfec655426 100644 --- a/codegen/service/testdata/example_interceptors/chained_interceptor_service_server.golden +++ b/codegen/service/testdata/example_interceptors/chained_interceptor_service_server.golden @@ -24,8 +24,8 @@ func NewChainedInterceptorServiceServerInterceptors() *ChainedInterceptorService return &ChainedInterceptorServiceServerInterceptors{} } func (i *ChainedInterceptorServiceServerInterceptors) API(ctx context.Context, info *interceptors.APIInfo, next goa.Endpoint) (any, error) { - log.Printf(ctx, "[API] Processing request: %v", info.RawPayload) - resp, err := next(ctx, info.RawPayload) + log.Printf(ctx, "[API] Processing request: %v", info.RawPayload()) + resp, err := next(ctx, info.RawPayload()) if err != nil { log.Printf(ctx, "[API] Error: %v", err) return nil, err @@ -34,8 +34,8 @@ func (i *ChainedInterceptorServiceServerInterceptors) API(ctx context.Context, i return resp, nil } func (i *ChainedInterceptorServiceServerInterceptors) Method(ctx context.Context, info *interceptors.MethodInfo, next goa.Endpoint) (any, error) { - log.Printf(ctx, "[Method] Processing request: %v", info.RawPayload) - resp, err := next(ctx, info.RawPayload) + log.Printf(ctx, "[Method] Processing request: %v", info.RawPayload()) + resp, err := next(ctx, info.RawPayload()) if err != nil { log.Printf(ctx, "[Method] Error: %v", err) return nil, err @@ -44,8 +44,8 @@ func (i *ChainedInterceptorServiceServerInterceptors) Method(ctx context.Context return resp, nil } func (i *ChainedInterceptorServiceServerInterceptors) Service(ctx context.Context, info *interceptors.ServiceInfo, next goa.Endpoint) (any, error) { - log.Printf(ctx, "[Service] Processing request: %v", info.RawPayload) - resp, err := next(ctx, info.RawPayload) + log.Printf(ctx, "[Service] Processing request: %v", info.RawPayload()) + resp, err := next(ctx, info.RawPayload()) if err != nil { log.Printf(ctx, "[Service] Error: %v", err) return nil, err diff --git a/codegen/service/testdata/example_interceptors/client_interceptor_service_client.golden b/codegen/service/testdata/example_interceptors/client_interceptor_service_client.golden index f64ea4bd10..073621102b 100644 --- a/codegen/service/testdata/example_interceptors/client_interceptor_service_client.golden +++ b/codegen/service/testdata/example_interceptors/client_interceptor_service_client.golden @@ -24,8 +24,8 @@ func NewClientInterceptorServiceClientInterceptors() *ClientInterceptorServiceCl return &ClientInterceptorServiceClientInterceptors{} } func (i *ClientInterceptorServiceClientInterceptors) Test(ctx context.Context, info *interceptors.TestInfo, next goa.Endpoint) (any, error) { - log.Printf(ctx, "[Test] Sending request: %v", info.RawPayload) - resp, err := next(ctx, info.RawPayload) + log.Printf(ctx, "[Test] Sending request: %v", info.RawPayload()) + resp, err := next(ctx, info.RawPayload()) if err != nil { log.Printf(ctx, "[Test] Error: %v", err) return nil, err diff --git a/codegen/service/testdata/example_interceptors/multiple_interceptors_service_client.golden b/codegen/service/testdata/example_interceptors/multiple_interceptors_service_client.golden index 3086ebce99..37663e0c13 100644 --- a/codegen/service/testdata/example_interceptors/multiple_interceptors_service_client.golden +++ b/codegen/service/testdata/example_interceptors/multiple_interceptors_service_client.golden @@ -24,8 +24,8 @@ func NewMultipleInterceptorsServiceClientInterceptors() *MultipleInterceptorsSer return &MultipleInterceptorsServiceClientInterceptors{} } func (i *MultipleInterceptorsServiceClientInterceptors) Test2(ctx context.Context, info *interceptors.Test2Info, next goa.Endpoint) (any, error) { - log.Printf(ctx, "[Test2] Sending request: %v", info.RawPayload) - resp, err := next(ctx, info.RawPayload) + log.Printf(ctx, "[Test2] Sending request: %v", info.RawPayload()) + resp, err := next(ctx, info.RawPayload()) if err != nil { log.Printf(ctx, "[Test2] Error: %v", err) return nil, err @@ -34,8 +34,8 @@ func (i *MultipleInterceptorsServiceClientInterceptors) Test2(ctx context.Contex return resp, nil } func (i *MultipleInterceptorsServiceClientInterceptors) Test4(ctx context.Context, info *interceptors.Test4Info, next goa.Endpoint) (any, error) { - log.Printf(ctx, "[Test4] Sending request: %v", info.RawPayload) - resp, err := next(ctx, info.RawPayload) + log.Printf(ctx, "[Test4] Sending request: %v", info.RawPayload()) + resp, err := next(ctx, info.RawPayload()) if err != nil { log.Printf(ctx, "[Test4] Error: %v", err) return nil, err diff --git a/codegen/service/testdata/example_interceptors/multiple_interceptors_service_server.golden b/codegen/service/testdata/example_interceptors/multiple_interceptors_service_server.golden index 75f774ef53..3d51f2cbeb 100644 --- a/codegen/service/testdata/example_interceptors/multiple_interceptors_service_server.golden +++ b/codegen/service/testdata/example_interceptors/multiple_interceptors_service_server.golden @@ -24,8 +24,8 @@ func NewMultipleInterceptorsServiceServerInterceptors() *MultipleInterceptorsSer return &MultipleInterceptorsServiceServerInterceptors{} } func (i *MultipleInterceptorsServiceServerInterceptors) Test(ctx context.Context, info *interceptors.TestInfo, next goa.Endpoint) (any, error) { - log.Printf(ctx, "[Test] Processing request: %v", info.RawPayload) - resp, err := next(ctx, info.RawPayload) + log.Printf(ctx, "[Test] Processing request: %v", info.RawPayload()) + resp, err := next(ctx, info.RawPayload()) if err != nil { log.Printf(ctx, "[Test] Error: %v", err) return nil, err @@ -34,8 +34,8 @@ func (i *MultipleInterceptorsServiceServerInterceptors) Test(ctx context.Context return resp, nil } func (i *MultipleInterceptorsServiceServerInterceptors) Test3(ctx context.Context, info *interceptors.Test3Info, next goa.Endpoint) (any, error) { - log.Printf(ctx, "[Test3] Processing request: %v", info.RawPayload) - resp, err := next(ctx, info.RawPayload) + log.Printf(ctx, "[Test3] Processing request: %v", info.RawPayload()) + resp, err := next(ctx, info.RawPayload()) if err != nil { log.Printf(ctx, "[Test3] Error: %v", err) return nil, err diff --git a/codegen/service/testdata/example_interceptors/multiple_services_interceptors_service2_client.golden b/codegen/service/testdata/example_interceptors/multiple_services_interceptors_service2_client.golden index ff9d84033d..6c394d7ef0 100644 --- a/codegen/service/testdata/example_interceptors/multiple_services_interceptors_service2_client.golden +++ b/codegen/service/testdata/example_interceptors/multiple_services_interceptors_service2_client.golden @@ -24,8 +24,8 @@ func NewMultipleServicesInterceptorsService2ClientInterceptors() *MultipleServic return &MultipleServicesInterceptorsService2ClientInterceptors{} } func (i *MultipleServicesInterceptorsService2ClientInterceptors) Test2(ctx context.Context, info *interceptors.Test2Info, next goa.Endpoint) (any, error) { - log.Printf(ctx, "[Test2] Sending request: %v", info.RawPayload) - resp, err := next(ctx, info.RawPayload) + log.Printf(ctx, "[Test2] Sending request: %v", info.RawPayload()) + resp, err := next(ctx, info.RawPayload()) if err != nil { log.Printf(ctx, "[Test2] Error: %v", err) return nil, err @@ -34,8 +34,8 @@ func (i *MultipleServicesInterceptorsService2ClientInterceptors) Test2(ctx conte return resp, nil } func (i *MultipleServicesInterceptorsService2ClientInterceptors) Test4(ctx context.Context, info *interceptors.Test4Info, next goa.Endpoint) (any, error) { - log.Printf(ctx, "[Test4] Sending request: %v", info.RawPayload) - resp, err := next(ctx, info.RawPayload) + log.Printf(ctx, "[Test4] Sending request: %v", info.RawPayload()) + resp, err := next(ctx, info.RawPayload()) if err != nil { log.Printf(ctx, "[Test4] Error: %v", err) return nil, err diff --git a/codegen/service/testdata/example_interceptors/multiple_services_interceptors_service2_server.golden b/codegen/service/testdata/example_interceptors/multiple_services_interceptors_service2_server.golden index 173144f090..c17c39709b 100644 --- a/codegen/service/testdata/example_interceptors/multiple_services_interceptors_service2_server.golden +++ b/codegen/service/testdata/example_interceptors/multiple_services_interceptors_service2_server.golden @@ -24,8 +24,8 @@ func NewMultipleServicesInterceptorsService2ServerInterceptors() *MultipleServic return &MultipleServicesInterceptorsService2ServerInterceptors{} } func (i *MultipleServicesInterceptorsService2ServerInterceptors) Test(ctx context.Context, info *interceptors.TestInfo, next goa.Endpoint) (any, error) { - log.Printf(ctx, "[Test] Processing request: %v", info.RawPayload) - resp, err := next(ctx, info.RawPayload) + log.Printf(ctx, "[Test] Processing request: %v", info.RawPayload()) + resp, err := next(ctx, info.RawPayload()) if err != nil { log.Printf(ctx, "[Test] Error: %v", err) return nil, err @@ -34,8 +34,8 @@ func (i *MultipleServicesInterceptorsService2ServerInterceptors) Test(ctx contex return resp, nil } func (i *MultipleServicesInterceptorsService2ServerInterceptors) Test3(ctx context.Context, info *interceptors.Test3Info, next goa.Endpoint) (any, error) { - log.Printf(ctx, "[Test3] Processing request: %v", info.RawPayload) - resp, err := next(ctx, info.RawPayload) + log.Printf(ctx, "[Test3] Processing request: %v", info.RawPayload()) + resp, err := next(ctx, info.RawPayload()) if err != nil { log.Printf(ctx, "[Test3] Error: %v", err) return nil, err diff --git a/codegen/service/testdata/example_interceptors/multiple_services_interceptors_service_client.golden b/codegen/service/testdata/example_interceptors/multiple_services_interceptors_service_client.golden index 72c48c6bc8..f773c4ee6c 100644 --- a/codegen/service/testdata/example_interceptors/multiple_services_interceptors_service_client.golden +++ b/codegen/service/testdata/example_interceptors/multiple_services_interceptors_service_client.golden @@ -24,8 +24,8 @@ func NewMultipleServicesInterceptorsServiceClientInterceptors() *MultipleService return &MultipleServicesInterceptorsServiceClientInterceptors{} } func (i *MultipleServicesInterceptorsServiceClientInterceptors) Test2(ctx context.Context, info *interceptors.Test2Info, next goa.Endpoint) (any, error) { - log.Printf(ctx, "[Test2] Sending request: %v", info.RawPayload) - resp, err := next(ctx, info.RawPayload) + log.Printf(ctx, "[Test2] Sending request: %v", info.RawPayload()) + resp, err := next(ctx, info.RawPayload()) if err != nil { log.Printf(ctx, "[Test2] Error: %v", err) return nil, err @@ -34,8 +34,8 @@ func (i *MultipleServicesInterceptorsServiceClientInterceptors) Test2(ctx contex return resp, nil } func (i *MultipleServicesInterceptorsServiceClientInterceptors) Test4(ctx context.Context, info *interceptors.Test4Info, next goa.Endpoint) (any, error) { - log.Printf(ctx, "[Test4] Sending request: %v", info.RawPayload) - resp, err := next(ctx, info.RawPayload) + log.Printf(ctx, "[Test4] Sending request: %v", info.RawPayload()) + resp, err := next(ctx, info.RawPayload()) if err != nil { log.Printf(ctx, "[Test4] Error: %v", err) return nil, err diff --git a/codegen/service/testdata/example_interceptors/multiple_services_interceptors_service_server.golden b/codegen/service/testdata/example_interceptors/multiple_services_interceptors_service_server.golden index 4e780407ea..94c67c5d41 100644 --- a/codegen/service/testdata/example_interceptors/multiple_services_interceptors_service_server.golden +++ b/codegen/service/testdata/example_interceptors/multiple_services_interceptors_service_server.golden @@ -24,8 +24,8 @@ func NewMultipleServicesInterceptorsServiceServerInterceptors() *MultipleService return &MultipleServicesInterceptorsServiceServerInterceptors{} } func (i *MultipleServicesInterceptorsServiceServerInterceptors) Test(ctx context.Context, info *interceptors.TestInfo, next goa.Endpoint) (any, error) { - log.Printf(ctx, "[Test] Processing request: %v", info.RawPayload) - resp, err := next(ctx, info.RawPayload) + log.Printf(ctx, "[Test] Processing request: %v", info.RawPayload()) + resp, err := next(ctx, info.RawPayload()) if err != nil { log.Printf(ctx, "[Test] Error: %v", err) return nil, err @@ -34,8 +34,8 @@ func (i *MultipleServicesInterceptorsServiceServerInterceptors) Test(ctx context return resp, nil } func (i *MultipleServicesInterceptorsServiceServerInterceptors) Test3(ctx context.Context, info *interceptors.Test3Info, next goa.Endpoint) (any, error) { - log.Printf(ctx, "[Test3] Processing request: %v", info.RawPayload) - resp, err := next(ctx, info.RawPayload) + log.Printf(ctx, "[Test3] Processing request: %v", info.RawPayload()) + resp, err := next(ctx, info.RawPayload()) if err != nil { log.Printf(ctx, "[Test3] Error: %v", err) return nil, err diff --git a/codegen/service/testdata/example_interceptors/server_interceptor_by_name_service_server.golden b/codegen/service/testdata/example_interceptors/server_interceptor_by_name_service_server.golden index 2660f90abe..4136d5f9ec 100644 --- a/codegen/service/testdata/example_interceptors/server_interceptor_by_name_service_server.golden +++ b/codegen/service/testdata/example_interceptors/server_interceptor_by_name_service_server.golden @@ -24,8 +24,8 @@ func NewServerInterceptorByNameServiceServerInterceptors() *ServerInterceptorByN return &ServerInterceptorByNameServiceServerInterceptors{} } func (i *ServerInterceptorByNameServiceServerInterceptors) Test(ctx context.Context, info *interceptors.TestInfo, next goa.Endpoint) (any, error) { - log.Printf(ctx, "[Test] Processing request: %v", info.RawPayload) - resp, err := next(ctx, info.RawPayload) + log.Printf(ctx, "[Test] Processing request: %v", info.RawPayload()) + resp, err := next(ctx, info.RawPayload()) if err != nil { log.Printf(ctx, "[Test] Error: %v", err) return nil, err diff --git a/codegen/service/testdata/example_interceptors/server_interceptor_service_server.golden b/codegen/service/testdata/example_interceptors/server_interceptor_service_server.golden index 517fdbc27e..6f5d89a40d 100644 --- a/codegen/service/testdata/example_interceptors/server_interceptor_service_server.golden +++ b/codegen/service/testdata/example_interceptors/server_interceptor_service_server.golden @@ -24,8 +24,8 @@ func NewServerInterceptorServiceServerInterceptors() *ServerInterceptorServiceSe return &ServerInterceptorServiceServerInterceptors{} } func (i *ServerInterceptorServiceServerInterceptors) Test(ctx context.Context, info *interceptors.TestInfo, next goa.Endpoint) (any, error) { - log.Printf(ctx, "[Test] Processing request: %v", info.RawPayload) - resp, err := next(ctx, info.RawPayload) + log.Printf(ctx, "[Test] Processing request: %v", info.RawPayload()) + resp, err := next(ctx, info.RawPayload()) if err != nil { log.Printf(ctx, "[Test] Error: %v", err) return nil, err diff --git a/codegen/service/testdata/interceptors/interceptor-with-read-payload_interceptor_wrappers.go.golden b/codegen/service/testdata/interceptors/interceptor-with-read-payload_interceptor_wrappers.go.golden index 1f4ac6ebd3..0cde37225c 100644 --- a/codegen/service/testdata/interceptors/interceptor-with-read-payload_interceptor_wrappers.go.golden +++ b/codegen/service/testdata/interceptors/interceptor-with-read-payload_interceptor_wrappers.go.golden @@ -4,10 +4,10 @@ func wrapMethodValidation(endpoint goa.Endpoint, i ServerInterceptors) goa.Endpoint { return func(ctx context.Context, req any) (any, error) { info := &ValidationInfo{ - Service: "InterceptorWithReadPayload", - Method: "Method", - Endpoint: endpoint, - RawPayload: req, + service: "InterceptorWithReadPayload", + method: "Method", + callType: goa.InterceptorUnary, + rawPayload: req, } return i.Validation(ctx, info, endpoint) } @@ -18,12 +18,11 @@ func wrapMethodValidation(endpoint goa.Endpoint, i ServerInterceptors) goa.Endpo func wrapClientMethodValidation(endpoint goa.Endpoint, i ClientInterceptors) goa.Endpoint { return func(ctx context.Context, req any) (any, error) { info := &ValidationInfo{ - Service: "InterceptorWithReadPayload", - Method: "Method", - Endpoint: endpoint, - RawPayload: req, + service: "InterceptorWithReadPayload", + method: "Method", + callType: goa.InterceptorUnary, + rawPayload: req, } return i.Validation(ctx, info, endpoint) } } - diff --git a/codegen/service/testdata/interceptors/interceptor-with-read-payload_service_interceptors.go.golden b/codegen/service/testdata/interceptors/interceptor-with-read-payload_service_interceptors.go.golden index 7e616c9438..3acc1de99c 100644 --- a/codegen/service/testdata/interceptors/interceptor-with-read-payload_service_interceptors.go.golden +++ b/codegen/service/testdata/interceptors/interceptor-with-read-payload_service_interceptors.go.golden @@ -10,7 +10,12 @@ type ServerInterceptors interface { type ( // ValidationInfo provides metadata about the current interception. // It includes service name, method name, and access to the endpoint. - ValidationInfo goa.InterceptorInfo + ValidationInfo struct { + service string + method string + callType goa.InterceptorCallType + rawPayload any + } // ValidationPayload provides type-safe access to the method payload. // It allows reading and writing specific fields of the payload as defined @@ -36,9 +41,29 @@ func WrapMethodEndpoint(endpoint goa.Endpoint, i ServerInterceptors) goa.Endpoin // Public accessor methods for Info types +// Service returns the name of the service handling the request. +func (info *ValidationInfo) Service() string { + return info.service +} + +// Method returns the name of the method handling the request. +func (info *ValidationInfo) Method() string { + return info.method +} + +// CallType returns the type of call the interceptor is handling. +func (info *ValidationInfo) CallType() goa.InterceptorCallType { + return info.callType +} + +// RawPayload returns the raw payload of the request. +func (info *ValidationInfo) RawPayload() any { + return info.rawPayload +} + // Payload returns a type-safe accessor for the method payload. func (info *ValidationInfo) Payload() ValidationPayload { - return &validationMethodPayload{payload: info.RawPayload.(*MethodPayload)} + return &validationMethodPayload{payload: info.RawPayload().(*MethodPayload)} } // Private implementation methods diff --git a/codegen/service/testdata/interceptors/interceptor-with-read-result_interceptor_wrappers.go.golden b/codegen/service/testdata/interceptors/interceptor-with-read-result_interceptor_wrappers.go.golden index 5f86fe8455..431b0789ce 100644 --- a/codegen/service/testdata/interceptors/interceptor-with-read-result_interceptor_wrappers.go.golden +++ b/codegen/service/testdata/interceptors/interceptor-with-read-result_interceptor_wrappers.go.golden @@ -4,10 +4,10 @@ func wrapMethodCaching(endpoint goa.Endpoint, i ServerInterceptors) goa.Endpoint { return func(ctx context.Context, req any) (any, error) { info := &CachingInfo{ - Service: "InterceptorWithReadResult", - Method: "Method", - Endpoint: endpoint, - RawPayload: req, + service: "InterceptorWithReadResult", + method: "Method", + callType: goa.InterceptorUnary, + rawPayload: req, } return i.Caching(ctx, info, endpoint) } @@ -17,12 +17,11 @@ func wrapMethodCaching(endpoint goa.Endpoint, i ServerInterceptors) goa.Endpoint func wrapClientMethodCaching(endpoint goa.Endpoint, i ClientInterceptors) goa.Endpoint { return func(ctx context.Context, req any) (any, error) { info := &CachingInfo{ - Service: "InterceptorWithReadResult", - Method: "Method", - Endpoint: endpoint, - RawPayload: req, + service: "InterceptorWithReadResult", + method: "Method", + callType: goa.InterceptorUnary, + rawPayload: req, } return i.Caching(ctx, info, endpoint) } } - diff --git a/codegen/service/testdata/interceptors/interceptor-with-read-result_service_interceptors.go.golden b/codegen/service/testdata/interceptors/interceptor-with-read-result_service_interceptors.go.golden index a658f22d37..acbf42db74 100644 --- a/codegen/service/testdata/interceptors/interceptor-with-read-result_service_interceptors.go.golden +++ b/codegen/service/testdata/interceptors/interceptor-with-read-result_service_interceptors.go.golden @@ -10,7 +10,12 @@ type ServerInterceptors interface { type ( // CachingInfo provides metadata about the current interception. // It includes service name, method name, and access to the endpoint. - CachingInfo goa.InterceptorInfo + CachingInfo struct { + service string + method string + callType goa.InterceptorCallType + rawPayload any + } // CachingResult provides type-safe access to the method result. // It allows reading and writing specific fields of the result as defined @@ -35,6 +40,27 @@ func WrapMethodEndpoint(endpoint goa.Endpoint, i ServerInterceptors) goa.Endpoin } // Public accessor methods for Info types + +// Service returns the name of the service handling the request. +func (info *CachingInfo) Service() string { + return info.service +} + +// Method returns the name of the method handling the request. +func (info *CachingInfo) Method() string { + return info.method +} + +// CallType returns the type of call the interceptor is handling. +func (info *CachingInfo) CallType() goa.InterceptorCallType { + return info.callType +} + +// RawPayload returns the raw payload of the request. +func (info *CachingInfo) RawPayload() any { + return info.rawPayload +} + // Result returns a type-safe accessor for the method result. func (info *CachingInfo) Result(res any) CachingResult { return &cachingMethodResult{result: res.(*MethodResult)} diff --git a/codegen/service/testdata/interceptors/interceptor-with-read-write-payload_interceptor_wrappers.go.golden b/codegen/service/testdata/interceptors/interceptor-with-read-write-payload_interceptor_wrappers.go.golden index f628ed5e05..8a1d529196 100644 --- a/codegen/service/testdata/interceptors/interceptor-with-read-write-payload_interceptor_wrappers.go.golden +++ b/codegen/service/testdata/interceptors/interceptor-with-read-write-payload_interceptor_wrappers.go.golden @@ -4,10 +4,10 @@ func wrapMethodValidation(endpoint goa.Endpoint, i ServerInterceptors) goa.Endpoint { return func(ctx context.Context, req any) (any, error) { info := &ValidationInfo{ - Service: "InterceptorWithReadWritePayload", - Method: "Method", - Endpoint: endpoint, - RawPayload: req, + service: "InterceptorWithReadWritePayload", + method: "Method", + callType: goa.InterceptorUnary, + rawPayload: req, } return i.Validation(ctx, info, endpoint) } @@ -18,12 +18,11 @@ func wrapMethodValidation(endpoint goa.Endpoint, i ServerInterceptors) goa.Endpo func wrapClientMethodValidation(endpoint goa.Endpoint, i ClientInterceptors) goa.Endpoint { return func(ctx context.Context, req any) (any, error) { info := &ValidationInfo{ - Service: "InterceptorWithReadWritePayload", - Method: "Method", - Endpoint: endpoint, - RawPayload: req, + service: "InterceptorWithReadWritePayload", + method: "Method", + callType: goa.InterceptorUnary, + rawPayload: req, } return i.Validation(ctx, info, endpoint) } } - diff --git a/codegen/service/testdata/interceptors/interceptor-with-read-write-payload_service_interceptors.go.golden b/codegen/service/testdata/interceptors/interceptor-with-read-write-payload_service_interceptors.go.golden index 0f84e22320..424a697488 100644 --- a/codegen/service/testdata/interceptors/interceptor-with-read-write-payload_service_interceptors.go.golden +++ b/codegen/service/testdata/interceptors/interceptor-with-read-write-payload_service_interceptors.go.golden @@ -10,7 +10,12 @@ type ServerInterceptors interface { type ( // ValidationInfo provides metadata about the current interception. // It includes service name, method name, and access to the endpoint. - ValidationInfo goa.InterceptorInfo + ValidationInfo struct { + service string + method string + callType goa.InterceptorCallType + rawPayload any + } // ValidationPayload provides type-safe access to the method payload. // It allows reading and writing specific fields of the payload as defined @@ -37,9 +42,29 @@ func WrapMethodEndpoint(endpoint goa.Endpoint, i ServerInterceptors) goa.Endpoin // Public accessor methods for Info types +// Service returns the name of the service handling the request. +func (info *ValidationInfo) Service() string { + return info.service +} + +// Method returns the name of the method handling the request. +func (info *ValidationInfo) Method() string { + return info.method +} + +// CallType returns the type of call the interceptor is handling. +func (info *ValidationInfo) CallType() goa.InterceptorCallType { + return info.callType +} + +// RawPayload returns the raw payload of the request. +func (info *ValidationInfo) RawPayload() any { + return info.rawPayload +} + // Payload returns a type-safe accessor for the method payload. func (info *ValidationInfo) Payload() ValidationPayload { - return &validationMethodPayload{payload: info.RawPayload.(*MethodPayload)} + return &validationMethodPayload{payload: info.RawPayload().(*MethodPayload)} } // Private implementation methods diff --git a/codegen/service/testdata/interceptors/interceptor-with-read-write-result_interceptor_wrappers.go.golden b/codegen/service/testdata/interceptors/interceptor-with-read-write-result_interceptor_wrappers.go.golden index 1e5ab9536e..40be57c66d 100644 --- a/codegen/service/testdata/interceptors/interceptor-with-read-write-result_interceptor_wrappers.go.golden +++ b/codegen/service/testdata/interceptors/interceptor-with-read-write-result_interceptor_wrappers.go.golden @@ -4,10 +4,10 @@ func wrapMethodCaching(endpoint goa.Endpoint, i ServerInterceptors) goa.Endpoint { return func(ctx context.Context, req any) (any, error) { info := &CachingInfo{ - Service: "InterceptorWithReadWriteResult", - Method: "Method", - Endpoint: endpoint, - RawPayload: req, + service: "InterceptorWithReadWriteResult", + method: "Method", + callType: goa.InterceptorUnary, + rawPayload: req, } return i.Caching(ctx, info, endpoint) } @@ -17,12 +17,11 @@ func wrapMethodCaching(endpoint goa.Endpoint, i ServerInterceptors) goa.Endpoint func wrapClientMethodCaching(endpoint goa.Endpoint, i ClientInterceptors) goa.Endpoint { return func(ctx context.Context, req any) (any, error) { info := &CachingInfo{ - Service: "InterceptorWithReadWriteResult", - Method: "Method", - Endpoint: endpoint, - RawPayload: req, + service: "InterceptorWithReadWriteResult", + method: "Method", + callType: goa.InterceptorUnary, + rawPayload: req, } return i.Caching(ctx, info, endpoint) } } - diff --git a/codegen/service/testdata/interceptors/interceptor-with-read-write-result_service_interceptors.go.golden b/codegen/service/testdata/interceptors/interceptor-with-read-write-result_service_interceptors.go.golden index 96c934c24e..cebda374e6 100644 --- a/codegen/service/testdata/interceptors/interceptor-with-read-write-result_service_interceptors.go.golden +++ b/codegen/service/testdata/interceptors/interceptor-with-read-write-result_service_interceptors.go.golden @@ -10,7 +10,12 @@ type ServerInterceptors interface { type ( // CachingInfo provides metadata about the current interception. // It includes service name, method name, and access to the endpoint. - CachingInfo goa.InterceptorInfo + CachingInfo struct { + service string + method string + callType goa.InterceptorCallType + rawPayload any + } // CachingResult provides type-safe access to the method result. // It allows reading and writing specific fields of the result as defined @@ -36,6 +41,27 @@ func WrapMethodEndpoint(endpoint goa.Endpoint, i ServerInterceptors) goa.Endpoin } // Public accessor methods for Info types + +// Service returns the name of the service handling the request. +func (info *CachingInfo) Service() string { + return info.service +} + +// Method returns the name of the method handling the request. +func (info *CachingInfo) Method() string { + return info.method +} + +// CallType returns the type of call the interceptor is handling. +func (info *CachingInfo) CallType() goa.InterceptorCallType { + return info.callType +} + +// RawPayload returns the raw payload of the request. +func (info *CachingInfo) RawPayload() any { + return info.rawPayload +} + // Result returns a type-safe accessor for the method result. func (info *CachingInfo) Result(res any) CachingResult { return &cachingMethodResult{result: res.(*MethodResult)} diff --git a/codegen/service/testdata/interceptors/interceptor-with-write-payload_interceptor_wrappers.go.golden b/codegen/service/testdata/interceptors/interceptor-with-write-payload_interceptor_wrappers.go.golden index 70657d6eef..d7059393aa 100644 --- a/codegen/service/testdata/interceptors/interceptor-with-write-payload_interceptor_wrappers.go.golden +++ b/codegen/service/testdata/interceptors/interceptor-with-write-payload_interceptor_wrappers.go.golden @@ -4,10 +4,10 @@ func wrapMethodValidation(endpoint goa.Endpoint, i ServerInterceptors) goa.Endpoint { return func(ctx context.Context, req any) (any, error) { info := &ValidationInfo{ - Service: "InterceptorWithWritePayload", - Method: "Method", - Endpoint: endpoint, - RawPayload: req, + service: "InterceptorWithWritePayload", + method: "Method", + callType: goa.InterceptorUnary, + rawPayload: req, } return i.Validation(ctx, info, endpoint) } @@ -18,12 +18,11 @@ func wrapMethodValidation(endpoint goa.Endpoint, i ServerInterceptors) goa.Endpo func wrapClientMethodValidation(endpoint goa.Endpoint, i ClientInterceptors) goa.Endpoint { return func(ctx context.Context, req any) (any, error) { info := &ValidationInfo{ - Service: "InterceptorWithWritePayload", - Method: "Method", - Endpoint: endpoint, - RawPayload: req, + service: "InterceptorWithWritePayload", + method: "Method", + callType: goa.InterceptorUnary, + rawPayload: req, } return i.Validation(ctx, info, endpoint) } } - diff --git a/codegen/service/testdata/interceptors/interceptor-with-write-payload_service_interceptors.go.golden b/codegen/service/testdata/interceptors/interceptor-with-write-payload_service_interceptors.go.golden index c76eb125e0..e9b7d863fb 100644 --- a/codegen/service/testdata/interceptors/interceptor-with-write-payload_service_interceptors.go.golden +++ b/codegen/service/testdata/interceptors/interceptor-with-write-payload_service_interceptors.go.golden @@ -10,7 +10,12 @@ type ServerInterceptors interface { type ( // ValidationInfo provides metadata about the current interception. // It includes service name, method name, and access to the endpoint. - ValidationInfo goa.InterceptorInfo + ValidationInfo struct { + service string + method string + callType goa.InterceptorCallType + rawPayload any + } // ValidationPayload provides type-safe access to the method payload. // It allows reading and writing specific fields of the payload as defined @@ -36,9 +41,29 @@ func WrapMethodEndpoint(endpoint goa.Endpoint, i ServerInterceptors) goa.Endpoin // Public accessor methods for Info types +// Service returns the name of the service handling the request. +func (info *ValidationInfo) Service() string { + return info.service +} + +// Method returns the name of the method handling the request. +func (info *ValidationInfo) Method() string { + return info.method +} + +// CallType returns the type of call the interceptor is handling. +func (info *ValidationInfo) CallType() goa.InterceptorCallType { + return info.callType +} + +// RawPayload returns the raw payload of the request. +func (info *ValidationInfo) RawPayload() any { + return info.rawPayload +} + // Payload returns a type-safe accessor for the method payload. func (info *ValidationInfo) Payload() ValidationPayload { - return &validationMethodPayload{payload: info.RawPayload.(*MethodPayload)} + return &validationMethodPayload{payload: info.RawPayload().(*MethodPayload)} } // Private implementation methods diff --git a/codegen/service/testdata/interceptors/interceptor-with-write-result_interceptor_wrappers.go.golden b/codegen/service/testdata/interceptors/interceptor-with-write-result_interceptor_wrappers.go.golden index bfcca2ab0c..89854d6c95 100644 --- a/codegen/service/testdata/interceptors/interceptor-with-write-result_interceptor_wrappers.go.golden +++ b/codegen/service/testdata/interceptors/interceptor-with-write-result_interceptor_wrappers.go.golden @@ -4,10 +4,10 @@ func wrapMethodCaching(endpoint goa.Endpoint, i ServerInterceptors) goa.Endpoint { return func(ctx context.Context, req any) (any, error) { info := &CachingInfo{ - Service: "InterceptorWithWriteResult", - Method: "Method", - Endpoint: endpoint, - RawPayload: req, + service: "InterceptorWithWriteResult", + method: "Method", + callType: goa.InterceptorUnary, + rawPayload: req, } return i.Caching(ctx, info, endpoint) } @@ -17,12 +17,11 @@ func wrapMethodCaching(endpoint goa.Endpoint, i ServerInterceptors) goa.Endpoint func wrapClientMethodCaching(endpoint goa.Endpoint, i ClientInterceptors) goa.Endpoint { return func(ctx context.Context, req any) (any, error) { info := &CachingInfo{ - Service: "InterceptorWithWriteResult", - Method: "Method", - Endpoint: endpoint, - RawPayload: req, + service: "InterceptorWithWriteResult", + method: "Method", + callType: goa.InterceptorUnary, + rawPayload: req, } return i.Caching(ctx, info, endpoint) } } - diff --git a/codegen/service/testdata/interceptors/interceptor-with-write-result_service_interceptors.go.golden b/codegen/service/testdata/interceptors/interceptor-with-write-result_service_interceptors.go.golden index 26b2620a97..161c5e8a3a 100644 --- a/codegen/service/testdata/interceptors/interceptor-with-write-result_service_interceptors.go.golden +++ b/codegen/service/testdata/interceptors/interceptor-with-write-result_service_interceptors.go.golden @@ -10,7 +10,12 @@ type ServerInterceptors interface { type ( // CachingInfo provides metadata about the current interception. // It includes service name, method name, and access to the endpoint. - CachingInfo goa.InterceptorInfo + CachingInfo struct { + service string + method string + callType goa.InterceptorCallType + rawPayload any + } // CachingResult provides type-safe access to the method result. // It allows reading and writing specific fields of the result as defined @@ -35,6 +40,27 @@ func WrapMethodEndpoint(endpoint goa.Endpoint, i ServerInterceptors) goa.Endpoin } // Public accessor methods for Info types + +// Service returns the name of the service handling the request. +func (info *CachingInfo) Service() string { + return info.service +} + +// Method returns the name of the method handling the request. +func (info *CachingInfo) Method() string { + return info.method +} + +// CallType returns the type of call the interceptor is handling. +func (info *CachingInfo) CallType() goa.InterceptorCallType { + return info.callType +} + +// RawPayload returns the raw payload of the request. +func (info *CachingInfo) RawPayload() any { + return info.rawPayload +} + // Result returns a type-safe accessor for the method result. func (info *CachingInfo) Result(res any) CachingResult { return &cachingMethodResult{result: res.(*MethodResult)} diff --git a/codegen/service/testdata/interceptors/multiple-interceptors_client_interceptors.go.golden b/codegen/service/testdata/interceptors/multiple-interceptors_client_interceptors.go.golden index 00d3b74592..e99e5b6ed6 100644 --- a/codegen/service/testdata/interceptors/multiple-interceptors_client_interceptors.go.golden +++ b/codegen/service/testdata/interceptors/multiple-interceptors_client_interceptors.go.golden @@ -11,10 +11,20 @@ type ClientInterceptors interface { type ( // Test2Info provides metadata about the current interception. // It includes service name, method name, and access to the endpoint. - Test2Info goa.InterceptorInfo + Test2Info struct { + service string + method string + callType goa.InterceptorCallType + rawPayload any + } // Test4Info provides metadata about the current interception. // It includes service name, method name, and access to the endpoint. - Test4Info goa.InterceptorInfo + Test4Info struct { + service string + method string + callType goa.InterceptorCallType + rawPayload any + } ) // WrapMethodClientEndpoint wraps the Method endpoint with the client diff --git a/codegen/service/testdata/interceptors/multiple-interceptors_interceptor_wrappers.go.golden b/codegen/service/testdata/interceptors/multiple-interceptors_interceptor_wrappers.go.golden index f23c4d7171..cfabf2905f 100644 --- a/codegen/service/testdata/interceptors/multiple-interceptors_interceptor_wrappers.go.golden +++ b/codegen/service/testdata/interceptors/multiple-interceptors_interceptor_wrappers.go.golden @@ -4,10 +4,10 @@ func wrapMethodTest(endpoint goa.Endpoint, i ServerInterceptors) goa.Endpoint { return func(ctx context.Context, req any) (any, error) { info := &TestInfo{ - Service: "MultipleInterceptorsService", - Method: "Method", - Endpoint: endpoint, - RawPayload: req, + service: "MultipleInterceptorsService", + method: "Method", + callType: goa.InterceptorUnary, + rawPayload: req, } return i.Test(ctx, info, endpoint) } @@ -17,10 +17,10 @@ func wrapMethodTest(endpoint goa.Endpoint, i ServerInterceptors) goa.Endpoint { func wrapMethodTest3(endpoint goa.Endpoint, i ServerInterceptors) goa.Endpoint { return func(ctx context.Context, req any) (any, error) { info := &Test3Info{ - Service: "MultipleInterceptorsService", - Method: "Method", - Endpoint: endpoint, - RawPayload: req, + service: "MultipleInterceptorsService", + method: "Method", + callType: goa.InterceptorUnary, + rawPayload: req, } return i.Test3(ctx, info, endpoint) } @@ -30,10 +30,10 @@ func wrapMethodTest3(endpoint goa.Endpoint, i ServerInterceptors) goa.Endpoint { func wrapClientMethodTest2(endpoint goa.Endpoint, i ClientInterceptors) goa.Endpoint { return func(ctx context.Context, req any) (any, error) { info := &Test2Info{ - Service: "MultipleInterceptorsService", - Method: "Method", - Endpoint: endpoint, - RawPayload: req, + service: "MultipleInterceptorsService", + method: "Method", + callType: goa.InterceptorUnary, + rawPayload: req, } return i.Test2(ctx, info, endpoint) } @@ -43,12 +43,11 @@ func wrapClientMethodTest2(endpoint goa.Endpoint, i ClientInterceptors) goa.Endp func wrapClientMethodTest4(endpoint goa.Endpoint, i ClientInterceptors) goa.Endpoint { return func(ctx context.Context, req any) (any, error) { info := &Test4Info{ - Service: "MultipleInterceptorsService", - Method: "Method", - Endpoint: endpoint, - RawPayload: req, + service: "MultipleInterceptorsService", + method: "Method", + callType: goa.InterceptorUnary, + rawPayload: req, } return i.Test4(ctx, info, endpoint) } } - diff --git a/codegen/service/testdata/interceptors/multiple-interceptors_service_interceptors.go.golden b/codegen/service/testdata/interceptors/multiple-interceptors_service_interceptors.go.golden index 1df6e00cf8..c69d0297a0 100644 --- a/codegen/service/testdata/interceptors/multiple-interceptors_service_interceptors.go.golden +++ b/codegen/service/testdata/interceptors/multiple-interceptors_service_interceptors.go.golden @@ -11,10 +11,20 @@ type ServerInterceptors interface { type ( // TestInfo provides metadata about the current interception. // It includes service name, method name, and access to the endpoint. - TestInfo goa.InterceptorInfo + TestInfo struct { + service string + method string + callType goa.InterceptorCallType + rawPayload any + } // Test3Info provides metadata about the current interception. // It includes service name, method name, and access to the endpoint. - Test3Info goa.InterceptorInfo + Test3Info struct { + service string + method string + callType goa.InterceptorCallType + rawPayload any + } ) // WrapMethodEndpoint wraps the Method endpoint with the server-side diff --git a/codegen/service/testdata/interceptors/single-api-server-interceptor_interceptor_wrappers.go.golden b/codegen/service/testdata/interceptors/single-api-server-interceptor_interceptor_wrappers.go.golden index b7e0eebf4c..498cc404ca 100644 --- a/codegen/service/testdata/interceptors/single-api-server-interceptor_interceptor_wrappers.go.golden +++ b/codegen/service/testdata/interceptors/single-api-server-interceptor_interceptor_wrappers.go.golden @@ -4,10 +4,10 @@ func wrapMethodLogging(endpoint goa.Endpoint, i ServerInterceptors) goa.Endpoint { return func(ctx context.Context, req any) (any, error) { info := &LoggingInfo{ - Service: "SingleAPIServerInterceptor", - Method: "Method", - Endpoint: endpoint, - RawPayload: req, + service: "SingleAPIServerInterceptor", + method: "Method", + callType: goa.InterceptorUnary, + rawPayload: req, } return i.Logging(ctx, info, endpoint) } @@ -17,11 +17,11 @@ func wrapMethodLogging(endpoint goa.Endpoint, i ServerInterceptors) goa.Endpoint func wrapMethod2Logging(endpoint goa.Endpoint, i ServerInterceptors) goa.Endpoint { return func(ctx context.Context, req any) (any, error) { info := &LoggingInfo{ - Service: "SingleAPIServerInterceptor", - Method: "Method2", - Endpoint: endpoint, - RawPayload: req, + service: "SingleAPIServerInterceptor", + method: "Method2", + callType: goa.InterceptorUnary, + rawPayload: req, } return i.Logging(ctx, info, endpoint) } -} \ No newline at end of file +} diff --git a/codegen/service/testdata/interceptors/single-api-server-interceptor_service_interceptors.go.golden b/codegen/service/testdata/interceptors/single-api-server-interceptor_service_interceptors.go.golden index f4870a7eef..9ee4f5833c 100644 --- a/codegen/service/testdata/interceptors/single-api-server-interceptor_service_interceptors.go.golden +++ b/codegen/service/testdata/interceptors/single-api-server-interceptor_service_interceptors.go.golden @@ -10,7 +10,12 @@ type ServerInterceptors interface { type ( // LoggingInfo provides metadata about the current interception. // It includes service name, method name, and access to the endpoint. - LoggingInfo goa.InterceptorInfo + LoggingInfo struct { + service string + method string + callType goa.InterceptorCallType + rawPayload any + } ) // WrapMethodEndpoint wraps the Method endpoint with the server-side diff --git a/codegen/service/testdata/interceptors/single-client-interceptor_client_interceptors.go.golden b/codegen/service/testdata/interceptors/single-client-interceptor_client_interceptors.go.golden index 8f272d85e6..8ff2ec6478 100644 --- a/codegen/service/testdata/interceptors/single-client-interceptor_client_interceptors.go.golden +++ b/codegen/service/testdata/interceptors/single-client-interceptor_client_interceptors.go.golden @@ -10,7 +10,12 @@ type ClientInterceptors interface { type ( // TracingInfo provides metadata about the current interception. // It includes service name, method name, and access to the endpoint. - TracingInfo goa.InterceptorInfo + TracingInfo struct { + service string + method string + callType goa.InterceptorCallType + rawPayload any + } ) // WrapMethodClientEndpoint wraps the Method endpoint with the client diff --git a/codegen/service/testdata/interceptors/single-client-interceptor_interceptor_wrappers.go.golden b/codegen/service/testdata/interceptors/single-client-interceptor_interceptor_wrappers.go.golden index b05666e31d..b72e20a2e2 100644 --- a/codegen/service/testdata/interceptors/single-client-interceptor_interceptor_wrappers.go.golden +++ b/codegen/service/testdata/interceptors/single-client-interceptor_interceptor_wrappers.go.golden @@ -4,12 +4,11 @@ func wrapClientMethodTracing(endpoint goa.Endpoint, i ClientInterceptors) goa.Endpoint { return func(ctx context.Context, req any) (any, error) { info := &TracingInfo{ - Service: "SingleClientInterceptor", - Method: "Method", - Endpoint: endpoint, - RawPayload: req, + service: "SingleClientInterceptor", + method: "Method", + callType: goa.InterceptorUnary, + rawPayload: req, } return i.Tracing(ctx, info, endpoint) } } - diff --git a/codegen/service/testdata/interceptors/single-method-server-interceptor_interceptor_wrappers.go.golden b/codegen/service/testdata/interceptors/single-method-server-interceptor_interceptor_wrappers.go.golden index c06dbb3edd..58c5f96d45 100644 --- a/codegen/service/testdata/interceptors/single-method-server-interceptor_interceptor_wrappers.go.golden +++ b/codegen/service/testdata/interceptors/single-method-server-interceptor_interceptor_wrappers.go.golden @@ -4,11 +4,11 @@ func wrapMethodLogging(endpoint goa.Endpoint, i ServerInterceptors) goa.Endpoint { return func(ctx context.Context, req any) (any, error) { info := &LoggingInfo{ - Service: "SingleMethodServerInterceptor", - Method: "Method", - Endpoint: endpoint, - RawPayload: req, + service: "SingleMethodServerInterceptor", + method: "Method", + callType: goa.InterceptorUnary, + rawPayload: req, } return i.Logging(ctx, info, endpoint) } -} \ No newline at end of file +} diff --git a/codegen/service/testdata/interceptors/single-method-server-interceptor_service_interceptors.go.golden b/codegen/service/testdata/interceptors/single-method-server-interceptor_service_interceptors.go.golden index 58b647a34a..b533e544c0 100644 --- a/codegen/service/testdata/interceptors/single-method-server-interceptor_service_interceptors.go.golden +++ b/codegen/service/testdata/interceptors/single-method-server-interceptor_service_interceptors.go.golden @@ -10,7 +10,12 @@ type ServerInterceptors interface { type ( // LoggingInfo provides metadata about the current interception. // It includes service name, method name, and access to the endpoint. - LoggingInfo goa.InterceptorInfo + LoggingInfo struct { + service string + method string + callType goa.InterceptorCallType + rawPayload any + } ) // WrapMethodEndpoint wraps the Method endpoint with the server-side diff --git a/codegen/service/testdata/interceptors/single-service-server-interceptor_interceptor_wrappers.go.golden b/codegen/service/testdata/interceptors/single-service-server-interceptor_interceptor_wrappers.go.golden index c15ab43987..a73b41c30c 100644 --- a/codegen/service/testdata/interceptors/single-service-server-interceptor_interceptor_wrappers.go.golden +++ b/codegen/service/testdata/interceptors/single-service-server-interceptor_interceptor_wrappers.go.golden @@ -4,10 +4,10 @@ func wrapMethodLogging(endpoint goa.Endpoint, i ServerInterceptors) goa.Endpoint { return func(ctx context.Context, req any) (any, error) { info := &LoggingInfo{ - Service: "SingleServerInterceptor", - Method: "Method", - Endpoint: endpoint, - RawPayload: req, + service: "SingleServerInterceptor", + method: "Method", + callType: goa.InterceptorUnary, + rawPayload: req, } return i.Logging(ctx, info, endpoint) } @@ -17,11 +17,11 @@ func wrapMethodLogging(endpoint goa.Endpoint, i ServerInterceptors) goa.Endpoint func wrapMethod2Logging(endpoint goa.Endpoint, i ServerInterceptors) goa.Endpoint { return func(ctx context.Context, req any) (any, error) { info := &LoggingInfo{ - Service: "SingleServerInterceptor", - Method: "Method2", - Endpoint: endpoint, - RawPayload: req, + service: "SingleServerInterceptor", + method: "Method2", + callType: goa.InterceptorUnary, + rawPayload: req, } return i.Logging(ctx, info, endpoint) } -} \ No newline at end of file +} diff --git a/codegen/service/testdata/interceptors/single-service-server-interceptor_service_interceptors.go.golden b/codegen/service/testdata/interceptors/single-service-server-interceptor_service_interceptors.go.golden index f4870a7eef..9ee4f5833c 100644 --- a/codegen/service/testdata/interceptors/single-service-server-interceptor_service_interceptors.go.golden +++ b/codegen/service/testdata/interceptors/single-service-server-interceptor_service_interceptors.go.golden @@ -10,7 +10,12 @@ type ServerInterceptors interface { type ( // LoggingInfo provides metadata about the current interception. // It includes service name, method name, and access to the endpoint. - LoggingInfo goa.InterceptorInfo + LoggingInfo struct { + service string + method string + callType goa.InterceptorCallType + rawPayload any + } ) // WrapMethodEndpoint wraps the Method endpoint with the server-side diff --git a/codegen/service/testdata/interceptors/streaming-interceptors-with-read-payload-and-read-streaming-payload_client_interceptors.go.golden b/codegen/service/testdata/interceptors/streaming-interceptors-with-read-payload-and-read-streaming-payload_client_interceptors.go.golden new file mode 100644 index 0000000000..3790fd8cde --- /dev/null +++ b/codegen/service/testdata/interceptors/streaming-interceptors-with-read-payload-and-read-streaming-payload_client_interceptors.go.golden @@ -0,0 +1,14 @@ +// ClientInterceptors defines the interface for all client-side interceptors. +// Client interceptors execute after the payload is encoded and before the request +// is sent to the server. The implementation is responsible for calling next to +// complete the request. +type ClientInterceptors interface { + Logging(ctx context.Context, info *LoggingInfo, next goa.Endpoint) (any, error) +} + +// WrapMethodClientEndpoint wraps the Method endpoint with the client +// interceptors defined in the design. +func WrapMethodClientEndpoint(endpoint goa.Endpoint, i ClientInterceptors) goa.Endpoint { + endpoint = wrapClientMethodlogging(endpoint, i) + return endpoint +} diff --git a/codegen/service/testdata/interceptors/streaming-interceptors-with-read-payload-and-read-streaming-payload_interceptor_wrappers.go.golden b/codegen/service/testdata/interceptors/streaming-interceptors-with-read-payload-and-read-streaming-payload_interceptor_wrappers.go.golden new file mode 100644 index 0000000000..e7c93363c3 --- /dev/null +++ b/codegen/service/testdata/interceptors/streaming-interceptors-with-read-payload-and-read-streaming-payload_interceptor_wrappers.go.golden @@ -0,0 +1,124 @@ + + +// wrappedMethodServerStream is a server interceptor wrapper for the +// MethodServerStream stream. +type wrappedMethodServerStream struct { + ctx context.Context + recvWithContext func(context.Context) (*MethodStreamingPayload, error) + stream MethodServerStream +} + +// wrappedMethodClientStream is a client interceptor wrapper for the +// MethodClientStream stream. +type wrappedMethodClientStream struct { + ctx context.Context + sendWithContext func(context.Context, *MethodStreamingPayload) error + stream MethodClientStream +} + +// wrapLoggingMethod applies the logging server interceptor to endpoints. +func wrapMethodLogging(endpoint goa.Endpoint, i ServerInterceptors) goa.Endpoint { + return func(ctx context.Context, req any) (any, error) { + info := &LoggingInfo{ + service: "StreamingInterceptorsWithReadPayloadAndReadStreamingPayload", + method: "Method", + callType: goa.InterceptorUnary, + rawPayload: req, + } + res, err := i.Logging(ctx, info, endpoint) + if err != nil { + return res, err + } + stream := res.(MethodServerStream) + return &wrappedMethodServerStream{ + ctx: ctx, + recvWithContext: func(ctx context.Context) (*MethodStreamingPayload, error) { + info := &LoggingInfo{ + service: "StreamingInterceptorsWithReadPayloadAndReadStreamingPayload", + method: "Method", + callType: goa.InterceptorStreamingRecv, + } + res, err := i.Logging(ctx, info, func(ctx context.Context, _ any) (any, error) { + return stream.RecvWithContext(ctx) + }) + castRes, _ := res.(*MethodStreamingPayload) + return castRes, err + }, + stream: stream, + }, nil + } +} + +// wrapClientLoggingMethod applies the logging client interceptor to endpoints. +func wrapClientMethodLogging(endpoint goa.Endpoint, i ClientInterceptors) goa.Endpoint { + return func(ctx context.Context, req any) (any, error) { + info := &LoggingInfo{ + service: "StreamingInterceptorsWithReadPayloadAndReadStreamingPayload", + method: "Method", + callType: goa.InterceptorUnary, + rawPayload: req, + } + res, err := i.Logging(ctx, info, endpoint) + if err != nil { + return res, err + } + stream := res.(MethodClientStream) + return &wrappedMethodClientStream{ + ctx: ctx, + sendWithContext: func(ctx context.Context, req *MethodStreamingPayload) error { + info := &LoggingInfo{ + service: "StreamingInterceptorsWithReadPayloadAndReadStreamingPayload", + method: "Method", + callType: goa.InterceptorStreamingSend, + rawPayload: req, + } + _, err := i.Logging(ctx, info, func(ctx context.Context, req any) (any, error) { + castReq, _ := req.(*MethodStreamingPayload) + return nil, stream.SendWithContext(ctx, castReq) + }) + return err + }, + stream: stream, + }, nil + } +} + +// Recv reads instances of "MethodServerStream" from the stream after executing +// the applied interceptor. +func (w *wrappedMethodServerStream) Recv() (*MethodStreamingPayload, error) { + return w.RecvWithContext(w.ctx) +} + +// RecvWithContext reads instances of "MethodServerStream" from the stream +// after executing the applied interceptor with context. +func (w *wrappedMethodServerStream) RecvWithContext(ctx context.Context) (*MethodStreamingPayload, error) { + if w.recvWithContext == nil { + return w.stream.RecvWithContext(ctx) + } + return w.recvWithContext(ctx) +} + +// Close closes the stream. +func (w *wrappedMethodServerStream) Close() error { + return w.stream.Close() +} + +// Send streams instances of "MethodClientStream" after executing the applied +// interceptor. +func (w *wrappedMethodClientStream) Send(v *MethodStreamingPayload) error { + return w.SendWithContext(w.ctx, v) +} + +// SendWithContext streams instances of "MethodClientStream" after executing +// the applied interceptor with context. +func (w *wrappedMethodClientStream) SendWithContext(ctx context.Context, v *MethodStreamingPayload) error { + if w.sendWithContext == nil { + return w.stream.SendWithContext(ctx, v) + } + return w.sendWithContext(ctx, v) +} + +// Close closes the stream. +func (w *wrappedMethodClientStream) Close() error { + return w.stream.Close() +} diff --git a/codegen/service/testdata/interceptors/streaming-interceptors-with-read-payload-and-read-streaming-payload_service_interceptors.go.golden b/codegen/service/testdata/interceptors/streaming-interceptors-with-read-payload-and-read-streaming-payload_service_interceptors.go.golden new file mode 100644 index 0000000000..f9f66d5eac --- /dev/null +++ b/codegen/service/testdata/interceptors/streaming-interceptors-with-read-payload-and-read-streaming-payload_service_interceptors.go.golden @@ -0,0 +1,104 @@ +// ServerInterceptors defines the interface for all server-side interceptors. +// Server interceptors execute after the request is decoded and before the +// payload is sent to the service. The implementation is responsible for calling +// next to complete the request. +type ServerInterceptors interface { + Logging(ctx context.Context, info *LoggingInfo, next goa.Endpoint) (any, error) +} + +// Access interfaces for interceptor payloads and results +type ( + // LoggingInfo provides metadata about the current interception. + // It includes service name, method name, and access to the endpoint. + LoggingInfo struct { + service string + method string + callType goa.InterceptorCallType + rawPayload any + } + + // LoggingPayload provides type-safe access to the method payload. + // It allows reading and writing specific fields of the payload as defined + // in the design. + LoggingPayload interface { + Chunk() string + } + + // LoggingStreamingPayload provides type-safe access to the method streaming payload. + // It allows reading and writing specific fields of the streaming payload as defined + // in the design. + LoggingStreamingPayload interface { + Chunk() string + } +) + +// Private implementation types +type ( + loggingMethodPayload struct { + payload *MethodPayload + } + loggingMethodStreamingPayload struct { + payload *MethodStreamingPayload + } +) + +// WrapMethodEndpoint wraps the Method endpoint with the server-side +// interceptors defined in the design. +func WrapMethodEndpoint(endpoint goa.Endpoint, i ServerInterceptors) goa.Endpoint { + endpoint = wrapMethodlogging(endpoint, i) + return endpoint +} + +// Public accessor methods for Info types + +// Service returns the name of the service handling the request. +func (info *LoggingInfo) Service() string { + return info.service +} + +// Method returns the name of the method handling the request. +func (info *LoggingInfo) Method() string { + return info.method +} + +// CallType returns the type of call the interceptor is handling. +func (info *LoggingInfo) CallType() goa.InterceptorCallType { + return info.callType +} + +// RawPayload returns the raw payload of the request. +func (info *LoggingInfo) RawPayload() any { + return info.rawPayload +} + +// Payload returns a type-safe accessor for the method payload. +func (info *LoggingInfo) Payload() LoggingPayload { + return &loggingMethodPayload{payload: info.RawPayload().(*MethodPayload)} +} + +// ClientStreamingPayload returns a type-safe accessor for the method streaming payload for a client-side interceptor. +func (info *LoggingInfo) ClientStreamingPayload() LoggingStreamingPayload { + return &loggingMethodStreamingPayload{payload: info.RawPayload().(*MethodStreamingPayload)} +} + +// ServerStreamingPayload returns a type-safe accessor for the method streaming payload for a server-side interceptor. +func (info *LoggingInfo) ServerStreamingPayload(pay any) LoggingStreamingPayload { + return &loggingMethodStreamingPayload{payload: pay.(*MethodStreamingPayload)} +} + +// Private implementation methods + +func (p *loggingMethodPayload) Chunk() string { + if p.payload.Chunk == nil { + var zero string + return zero + } + return *p.payload.Chunk +} +func (p *loggingMethodStreamingPayload) Chunk() string { + if p.payload.Chunk == nil { + var zero string + return zero + } + return *p.payload.Chunk +} diff --git a/codegen/service/testdata/interceptors/streaming-interceptors-with-read-payload_interceptor_wrappers.go.golden b/codegen/service/testdata/interceptors/streaming-interceptors-with-read-payload_interceptor_wrappers.go.golden index 554dade015..b4f94826cd 100644 --- a/codegen/service/testdata/interceptors/streaming-interceptors-with-read-payload_interceptor_wrappers.go.golden +++ b/codegen/service/testdata/interceptors/streaming-interceptors-with-read-payload_interceptor_wrappers.go.golden @@ -4,11 +4,11 @@ func wrapMethodLogging(endpoint goa.Endpoint, i ServerInterceptors) goa.Endpoint { return func(ctx context.Context, req any) (any, error) { info := &LoggingInfo{ - Service: "StreamingInterceptorsWithReadPayload", - Method: "Method", - Endpoint: endpoint, - RawPayload: req.(*MethodServerStream).Payload, + service: "StreamingInterceptorsWithReadPayload", + method: "Method", + callType: goa.InterceptorUnary, + rawPayload: req, } return i.Logging(ctx, info, endpoint) } -} \ No newline at end of file +} diff --git a/codegen/service/testdata/interceptors/streaming-interceptors-with-read-payload_service_interceptors.go.golden b/codegen/service/testdata/interceptors/streaming-interceptors-with-read-payload_service_interceptors.go.golden index 4a173a3ce4..aeced16360 100644 --- a/codegen/service/testdata/interceptors/streaming-interceptors-with-read-payload_service_interceptors.go.golden +++ b/codegen/service/testdata/interceptors/streaming-interceptors-with-read-payload_service_interceptors.go.golden @@ -10,7 +10,12 @@ type ServerInterceptors interface { type ( // LoggingInfo provides metadata about the current interception. // It includes service name, method name, and access to the endpoint. - LoggingInfo goa.InterceptorInfo + LoggingInfo struct { + service string + method string + callType goa.InterceptorCallType + rawPayload any + } // LoggingPayload provides type-safe access to the method payload. // It allows reading and writing specific fields of the payload as defined @@ -36,9 +41,29 @@ func WrapMethodEndpoint(endpoint goa.Endpoint, i ServerInterceptors) goa.Endpoin // Public accessor methods for Info types +// Service returns the name of the service handling the request. +func (info *LoggingInfo) Service() string { + return info.service +} + +// Method returns the name of the method handling the request. +func (info *LoggingInfo) Method() string { + return info.method +} + +// CallType returns the type of call the interceptor is handling. +func (info *LoggingInfo) CallType() goa.InterceptorCallType { + return info.callType +} + +// RawPayload returns the raw payload of the request. +func (info *LoggingInfo) RawPayload() any { + return info.rawPayload +} + // Payload returns a type-safe accessor for the method payload. func (info *LoggingInfo) Payload() LoggingPayload { - return &loggingMethodPayload{payload: info.RawPayload.(*MethodPayload)} + return &loggingMethodPayload{payload: info.RawPayload().(*MethodPayload)} } // Private implementation methods diff --git a/codegen/service/testdata/interceptors/streaming-interceptors-with-read-result_interceptor_wrappers.go.golden b/codegen/service/testdata/interceptors/streaming-interceptors-with-read-result_interceptor_wrappers.go.golden index 2fc769d48b..b6e8f62cc2 100644 --- a/codegen/service/testdata/interceptors/streaming-interceptors-with-read-result_interceptor_wrappers.go.golden +++ b/codegen/service/testdata/interceptors/streaming-interceptors-with-read-result_interceptor_wrappers.go.golden @@ -4,11 +4,11 @@ func wrapMethodLogging(endpoint goa.Endpoint, i ServerInterceptors) goa.Endpoint { return func(ctx context.Context, req any) (any, error) { info := &LoggingInfo{ - Service: "StreamingInterceptorsWithReadResult", - Method: "Method", - Endpoint: endpoint, - RawPayload: req.(*MethodServerStream).Payload, + service: "StreamingInterceptorsWithReadResult", + method: "Method", + callType: goa.InterceptorUnary, + rawPayload: req, } return i.Logging(ctx, info, endpoint) } -} \ No newline at end of file +} diff --git a/codegen/service/testdata/interceptors/streaming-interceptors-with-read-result_service_interceptors.go.golden b/codegen/service/testdata/interceptors/streaming-interceptors-with-read-result_service_interceptors.go.golden index fc61ae626f..3bbb27f3db 100644 --- a/codegen/service/testdata/interceptors/streaming-interceptors-with-read-result_service_interceptors.go.golden +++ b/codegen/service/testdata/interceptors/streaming-interceptors-with-read-result_service_interceptors.go.golden @@ -10,7 +10,12 @@ type ServerInterceptors interface { type ( // LoggingInfo provides metadata about the current interception. // It includes service name, method name, and access to the endpoint. - LoggingInfo goa.InterceptorInfo + LoggingInfo struct { + service string + method string + callType goa.InterceptorCallType + rawPayload any + } // LoggingResult provides type-safe access to the method result. // It allows reading and writing specific fields of the result as defined @@ -35,6 +40,27 @@ func WrapMethodEndpoint(endpoint goa.Endpoint, i ServerInterceptors) goa.Endpoin } // Public accessor methods for Info types + +// Service returns the name of the service handling the request. +func (info *LoggingInfo) Service() string { + return info.service +} + +// Method returns the name of the method handling the request. +func (info *LoggingInfo) Method() string { + return info.method +} + +// CallType returns the type of call the interceptor is handling. +func (info *LoggingInfo) CallType() goa.InterceptorCallType { + return info.callType +} + +// RawPayload returns the raw payload of the request. +func (info *LoggingInfo) RawPayload() any { + return info.rawPayload +} + // Result returns a type-safe accessor for the method result. func (info *LoggingInfo) Result(res any) LoggingResult { return &loggingMethodResult{result: res.(*MethodResult)} diff --git a/codegen/service/testdata/interceptors/streaming-interceptors-with-read-streaming-result_client_interceptors.go.golden b/codegen/service/testdata/interceptors/streaming-interceptors-with-read-streaming-result_client_interceptors.go.golden new file mode 100644 index 0000000000..3790fd8cde --- /dev/null +++ b/codegen/service/testdata/interceptors/streaming-interceptors-with-read-streaming-result_client_interceptors.go.golden @@ -0,0 +1,14 @@ +// ClientInterceptors defines the interface for all client-side interceptors. +// Client interceptors execute after the payload is encoded and before the request +// is sent to the server. The implementation is responsible for calling next to +// complete the request. +type ClientInterceptors interface { + Logging(ctx context.Context, info *LoggingInfo, next goa.Endpoint) (any, error) +} + +// WrapMethodClientEndpoint wraps the Method endpoint with the client +// interceptors defined in the design. +func WrapMethodClientEndpoint(endpoint goa.Endpoint, i ClientInterceptors) goa.Endpoint { + endpoint = wrapClientMethodlogging(endpoint, i) + return endpoint +} diff --git a/codegen/service/testdata/interceptors/streaming-interceptors-with-read-streaming-result_interceptor_wrappers.go.golden b/codegen/service/testdata/interceptors/streaming-interceptors-with-read-streaming-result_interceptor_wrappers.go.golden new file mode 100644 index 0000000000..61210965f6 --- /dev/null +++ b/codegen/service/testdata/interceptors/streaming-interceptors-with-read-streaming-result_interceptor_wrappers.go.golden @@ -0,0 +1,107 @@ + + +// wrappedMethodServerStream is a server interceptor wrapper for the +// MethodServerStream stream. +type wrappedMethodServerStream struct { + ctx context.Context + sendWithContext func(context.Context, *MethodResult) error + stream MethodServerStream +} + +// wrappedMethodClientStream is a client interceptor wrapper for the +// MethodClientStream stream. +type wrappedMethodClientStream struct { + ctx context.Context + recvWithContext func(context.Context) (*MethodResult, error) + stream MethodClientStream +} + +// wrapLoggingMethod applies the logging server interceptor to endpoints. +func wrapMethodLogging(endpoint goa.Endpoint, i ServerInterceptors) goa.Endpoint { + return func(ctx context.Context, req any) (any, error) { + res, err := endpoint(ctx, req) + if err != nil { + return res, err + } + stream := res.(MethodServerStream) + return &wrappedMethodServerStream{ + ctx: ctx, + sendWithContext: func(ctx context.Context, req *MethodResult) error { + info := &LoggingInfo{ + service: "StreamingInterceptorsWithReadStreamingResult", + method: "Method", + callType: goa.InterceptorStreamingSend, + rawPayload: req, + } + _, err := i.Logging(ctx, info, func(ctx context.Context, req any) (any, error) { + castReq, _ := req.(*MethodResult) + return nil, stream.SendWithContext(ctx, castReq) + }) + return err + }, + stream: stream, + }, nil + } +} + +// wrapClientLoggingMethod applies the logging client interceptor to endpoints. +func wrapClientMethodLogging(endpoint goa.Endpoint, i ClientInterceptors) goa.Endpoint { + return func(ctx context.Context, req any) (any, error) { + res, err := endpoint(ctx, req) + if err != nil { + return res, err + } + stream := res.(MethodClientStream) + return &wrappedMethodClientStream{ + ctx: ctx, + recvWithContext: func(ctx context.Context) (*MethodResult, error) { + info := &LoggingInfo{ + service: "StreamingInterceptorsWithReadStreamingResult", + method: "Method", + callType: goa.InterceptorStreamingRecv, + } + res, err := i.Logging(ctx, info, func(ctx context.Context, _ any) (any, error) { + return stream.RecvWithContext(ctx) + }) + castRes, _ := res.(*MethodResult) + return castRes, err + }, + stream: stream, + }, nil + } +} + +// Send streams instances of "MethodServerStream" after executing the applied +// interceptor. +func (w *wrappedMethodServerStream) Send(v *MethodResult) error { + return w.SendWithContext(w.ctx, v) +} + +// SendWithContext streams instances of "MethodServerStream" after executing +// the applied interceptor with context. +func (w *wrappedMethodServerStream) SendWithContext(ctx context.Context, v *MethodResult) error { + if w.sendWithContext == nil { + return w.stream.SendWithContext(ctx, v) + } + return w.sendWithContext(ctx, v) +} + +// Close closes the stream. +func (w *wrappedMethodServerStream) Close() error { + return w.stream.Close() +} + +// Recv reads instances of "MethodClientStream" from the stream after executing +// the applied interceptor. +func (w *wrappedMethodClientStream) Recv() (*MethodResult, error) { + return w.RecvWithContext(w.ctx) +} + +// RecvWithContext reads instances of "MethodClientStream" from the stream +// after executing the applied interceptor with context. +func (w *wrappedMethodClientStream) RecvWithContext(ctx context.Context) (*MethodResult, error) { + if w.recvWithContext == nil { + return w.stream.RecvWithContext(ctx) + } + return w.recvWithContext(ctx) +} diff --git a/codegen/service/testdata/interceptors/streaming-interceptors-with-read-streaming-result_service_interceptors.go.golden b/codegen/service/testdata/interceptors/streaming-interceptors-with-read-streaming-result_service_interceptors.go.golden new file mode 100644 index 0000000000..c074c15cca --- /dev/null +++ b/codegen/service/testdata/interceptors/streaming-interceptors-with-read-streaming-result_service_interceptors.go.golden @@ -0,0 +1,82 @@ +// ServerInterceptors defines the interface for all server-side interceptors. +// Server interceptors execute after the request is decoded and before the +// payload is sent to the service. The implementation is responsible for calling +// next to complete the request. +type ServerInterceptors interface { + Logging(ctx context.Context, info *LoggingInfo, next goa.Endpoint) (any, error) +} + +// Access interfaces for interceptor payloads and results +type ( + // LoggingInfo provides metadata about the current interception. + // It includes service name, method name, and access to the endpoint. + LoggingInfo struct { + service string + method string + callType goa.InterceptorCallType + rawPayload any + } + + // LoggingStreamingResult provides type-safe access to the method streaming result. + // It allows reading and writing specific fields of the streaming result as defined + // in the design. + LoggingStreamingResult interface { + Data() string + } +) + +// Private implementation types +type ( + loggingMethodStreamingResult struct { + result *MethodResult + } +) + +// WrapMethodEndpoint wraps the Method endpoint with the server-side +// interceptors defined in the design. +func WrapMethodEndpoint(endpoint goa.Endpoint, i ServerInterceptors) goa.Endpoint { + endpoint = wrapMethodlogging(endpoint, i) + return endpoint +} + +// Public accessor methods for Info types + +// Service returns the name of the service handling the request. +func (info *LoggingInfo) Service() string { + return info.service +} + +// Method returns the name of the method handling the request. +func (info *LoggingInfo) Method() string { + return info.method +} + +// CallType returns the type of call the interceptor is handling. +func (info *LoggingInfo) CallType() goa.InterceptorCallType { + return info.callType +} + +// RawPayload returns the raw payload of the request. +func (info *LoggingInfo) RawPayload() any { + return info.rawPayload +} + +// ClientStreamingResult returns a type-safe accessor for the method streaming result for a client-side interceptor. +func (info *LoggingInfo) ClientStreamingResult(res any) LoggingStreamingResult { + return &loggingMethodStreamingResult{result: res.(*MethodResult)} +} + +// ServerStreamingResult returns a type-safe accessor for the method streaming result for a server-side interceptor. +func (info *LoggingInfo) ServerStreamingResult() LoggingStreamingResult { + return &loggingMethodStreamingResult{result: info.RawPayload().(*MethodResult)} +} + +// Private implementation methods + +func (r *loggingMethodStreamingResult) Data() string { + if r.result.Data == nil { + var zero string + return zero + } + return *r.result.Data +} diff --git a/codegen/service/testdata/interceptors/streaming-interceptors_client_interceptors.go.golden b/codegen/service/testdata/interceptors/streaming-interceptors_client_interceptors.go.golden new file mode 100644 index 0000000000..3790fd8cde --- /dev/null +++ b/codegen/service/testdata/interceptors/streaming-interceptors_client_interceptors.go.golden @@ -0,0 +1,14 @@ +// ClientInterceptors defines the interface for all client-side interceptors. +// Client interceptors execute after the payload is encoded and before the request +// is sent to the server. The implementation is responsible for calling next to +// complete the request. +type ClientInterceptors interface { + Logging(ctx context.Context, info *LoggingInfo, next goa.Endpoint) (any, error) +} + +// WrapMethodClientEndpoint wraps the Method endpoint with the client +// interceptors defined in the design. +func WrapMethodClientEndpoint(endpoint goa.Endpoint, i ClientInterceptors) goa.Endpoint { + endpoint = wrapClientMethodlogging(endpoint, i) + return endpoint +} diff --git a/codegen/service/testdata/interceptors/streaming-interceptors_interceptor_wrappers.go.golden b/codegen/service/testdata/interceptors/streaming-interceptors_interceptor_wrappers.go.golden index 0361aa2387..1e5bd18489 100644 --- a/codegen/service/testdata/interceptors/streaming-interceptors_interceptor_wrappers.go.golden +++ b/codegen/service/testdata/interceptors/streaming-interceptors_interceptor_wrappers.go.golden @@ -1,14 +1,169 @@ +// wrappedMethodServerStream is a server interceptor wrapper for the +// MethodServerStream stream. +type wrappedMethodServerStream struct { + ctx context.Context + sendWithContext func(context.Context, *MethodResult) error + recvWithContext func(context.Context) (*MethodStreamingPayload, error) + stream MethodServerStream +} + +// wrappedMethodClientStream is a client interceptor wrapper for the +// MethodClientStream stream. +type wrappedMethodClientStream struct { + ctx context.Context + sendWithContext func(context.Context, *MethodStreamingPayload) error + recvWithContext func(context.Context) (*MethodResult, error) + stream MethodClientStream +} + // wrapLoggingMethod applies the logging server interceptor to endpoints. func wrapMethodLogging(endpoint goa.Endpoint, i ServerInterceptors) goa.Endpoint { return func(ctx context.Context, req any) (any, error) { - info := &LoggingInfo{ - Service: "StreamingInterceptors", - Method: "Method", - Endpoint: endpoint, - RawPayload: req.(*MethodServerStream).Payload, + res, err := endpoint(ctx, req) + if err != nil { + return res, err + } + stream := res.(MethodServerStream) + return &wrappedMethodServerStream{ + ctx: ctx, + sendWithContext: func(ctx context.Context, req *MethodResult) error { + info := &LoggingInfo{ + service: "StreamingInterceptors", + method: "Method", + callType: goa.InterceptorStreamingSend, + rawPayload: req, + } + _, err := i.Logging(ctx, info, func(ctx context.Context, req any) (any, error) { + castReq, _ := req.(*MethodResult) + return nil, stream.SendWithContext(ctx, castReq) + }) + return err + }, + recvWithContext: func(ctx context.Context) (*MethodStreamingPayload, error) { + info := &LoggingInfo{ + service: "StreamingInterceptors", + method: "Method", + callType: goa.InterceptorStreamingRecv, + } + res, err := i.Logging(ctx, info, func(ctx context.Context, _ any) (any, error) { + return stream.RecvWithContext(ctx) + }) + castRes, _ := res.(*MethodStreamingPayload) + return castRes, err + }, + stream: stream, + }, nil + } +} + +// wrapClientLoggingMethod applies the logging client interceptor to endpoints. +func wrapClientMethodLogging(endpoint goa.Endpoint, i ClientInterceptors) goa.Endpoint { + return func(ctx context.Context, req any) (any, error) { + res, err := endpoint(ctx, req) + if err != nil { + return res, err } - return i.Logging(ctx, info, endpoint) + stream := res.(MethodClientStream) + return &wrappedMethodClientStream{ + ctx: ctx, + sendWithContext: func(ctx context.Context, req *MethodStreamingPayload) error { + info := &LoggingInfo{ + service: "StreamingInterceptors", + method: "Method", + callType: goa.InterceptorStreamingSend, + rawPayload: req, + } + _, err := i.Logging(ctx, info, func(ctx context.Context, req any) (any, error) { + castReq, _ := req.(*MethodStreamingPayload) + return nil, stream.SendWithContext(ctx, castReq) + }) + return err + }, + recvWithContext: func(ctx context.Context) (*MethodResult, error) { + info := &LoggingInfo{ + service: "StreamingInterceptors", + method: "Method", + callType: goa.InterceptorStreamingRecv, + } + res, err := i.Logging(ctx, info, func(ctx context.Context, _ any) (any, error) { + return stream.RecvWithContext(ctx) + }) + castRes, _ := res.(*MethodResult) + return castRes, err + }, + stream: stream, + }, nil + } +} + +// Send streams instances of "MethodServerStream" after executing the applied +// interceptor. +func (w *wrappedMethodServerStream) Send(v *MethodResult) error { + return w.SendWithContext(w.ctx, v) +} + +// SendWithContext streams instances of "MethodServerStream" after executing +// the applied interceptor with context. +func (w *wrappedMethodServerStream) SendWithContext(ctx context.Context, v *MethodResult) error { + if w.sendWithContext == nil { + return w.stream.SendWithContext(ctx, v) + } + return w.sendWithContext(ctx, v) +} + +// Recv reads instances of "MethodServerStream" from the stream after executing +// the applied interceptor. +func (w *wrappedMethodServerStream) Recv() (*MethodStreamingPayload, error) { + return w.RecvWithContext(w.ctx) +} + +// RecvWithContext reads instances of "MethodServerStream" from the stream +// after executing the applied interceptor with context. +func (w *wrappedMethodServerStream) RecvWithContext(ctx context.Context) (*MethodStreamingPayload, error) { + if w.recvWithContext == nil { + return w.stream.RecvWithContext(ctx) + } + return w.recvWithContext(ctx) +} + +// Close closes the stream. +func (w *wrappedMethodServerStream) Close() error { + return w.stream.Close() +} + +// Send streams instances of "MethodClientStream" after executing the applied +// interceptor. +func (w *wrappedMethodClientStream) Send(v *MethodStreamingPayload) error { + return w.SendWithContext(w.ctx, v) +} + +// SendWithContext streams instances of "MethodClientStream" after executing +// the applied interceptor with context. +func (w *wrappedMethodClientStream) SendWithContext(ctx context.Context, v *MethodStreamingPayload) error { + if w.sendWithContext == nil { + return w.stream.SendWithContext(ctx, v) } -} \ No newline at end of file + return w.sendWithContext(ctx, v) +} + +// Recv reads instances of "MethodClientStream" from the stream after executing +// the applied interceptor. +func (w *wrappedMethodClientStream) Recv() (*MethodResult, error) { + return w.RecvWithContext(w.ctx) +} + +// RecvWithContext reads instances of "MethodClientStream" from the stream +// after executing the applied interceptor with context. +func (w *wrappedMethodClientStream) RecvWithContext(ctx context.Context) (*MethodResult, error) { + if w.recvWithContext == nil { + return w.stream.RecvWithContext(ctx) + } + return w.recvWithContext(ctx) +} + +// Close closes the stream. +func (w *wrappedMethodClientStream) Close() error { + return w.stream.Close() +} diff --git a/codegen/service/testdata/interceptors/streaming-interceptors_service_interceptors.go.golden b/codegen/service/testdata/interceptors/streaming-interceptors_service_interceptors.go.golden index 58b647a34a..3424b0a6ba 100644 --- a/codegen/service/testdata/interceptors/streaming-interceptors_service_interceptors.go.golden +++ b/codegen/service/testdata/interceptors/streaming-interceptors_service_interceptors.go.golden @@ -10,7 +10,38 @@ type ServerInterceptors interface { type ( // LoggingInfo provides metadata about the current interception. // It includes service name, method name, and access to the endpoint. - LoggingInfo goa.InterceptorInfo + LoggingInfo struct { + service string + method string + callType goa.InterceptorCallType + rawPayload any + } + + // LoggingStreamingPayload provides type-safe access to the method streaming payload. + // It allows reading and writing specific fields of the streaming payload as defined + // in the design. + LoggingStreamingPayload interface { + Chunk() string + SetChunk(string) + } + + // LoggingStreamingResult provides type-safe access to the method streaming result. + // It allows reading and writing specific fields of the streaming result as defined + // in the design. + LoggingStreamingResult interface { + Data() string + SetData(string) + } +) + +// Private implementation types +type ( + loggingMethodStreamingPayload struct { + payload *MethodStreamingPayload + } + loggingMethodStreamingResult struct { + result *MethodResult + } ) // WrapMethodEndpoint wraps the Method endpoint with the server-side @@ -20,3 +51,67 @@ func WrapMethodEndpoint(endpoint goa.Endpoint, i ServerInterceptors) goa.Endpoin return endpoint } +// Public accessor methods for Info types + +// Service returns the name of the service handling the request. +func (info *LoggingInfo) Service() string { + return info.service +} + +// Method returns the name of the method handling the request. +func (info *LoggingInfo) Method() string { + return info.method +} + +// CallType returns the type of call the interceptor is handling. +func (info *LoggingInfo) CallType() goa.InterceptorCallType { + return info.callType +} + +// RawPayload returns the raw payload of the request. +func (info *LoggingInfo) RawPayload() any { + return info.rawPayload +} + +// ClientStreamingPayload returns a type-safe accessor for the method streaming payload for a client-side interceptor. +func (info *LoggingInfo) ClientStreamingPayload() LoggingStreamingPayload { + return &loggingMethodStreamingPayload{payload: info.RawPayload().(*MethodStreamingPayload)} +} + +// ClientStreamingResult returns a type-safe accessor for the method streaming result for a client-side interceptor. +func (info *LoggingInfo) ClientStreamingResult(res any) LoggingStreamingResult { + return &loggingMethodStreamingResult{result: res.(*MethodResult)} +} + +// ServerStreamingPayload returns a type-safe accessor for the method streaming payload for a server-side interceptor. +func (info *LoggingInfo) ServerStreamingPayload(pay any) LoggingStreamingPayload { + return &loggingMethodStreamingPayload{payload: pay.(*MethodStreamingPayload)} +} + +// ServerStreamingResult returns a type-safe accessor for the method streaming result for a server-side interceptor. +func (info *LoggingInfo) ServerStreamingResult() LoggingStreamingResult { + return &loggingMethodStreamingResult{result: info.RawPayload().(*MethodResult)} +} + +// Private implementation methods + +func (p *loggingMethodStreamingPayload) Chunk() string { + if p.payload.Chunk == nil { + var zero string + return zero + } + return *p.payload.Chunk +} +func (p *loggingMethodStreamingPayload) SetChunk(v string) { + p.payload.Chunk = &v +} +func (r *loggingMethodStreamingResult) Data() string { + if r.result.Data == nil { + var zero string + return zero + } + return *r.result.Data +} +func (r *loggingMethodStreamingResult) SetData(v string) { + r.result.Data = &v +} diff --git a/codegen/service/testdata/interceptors_dsls.go b/codegen/service/testdata/interceptors_dsls.go index dead879c9f..d901825e2c 100644 --- a/codegen/service/testdata/interceptors_dsls.go +++ b/codegen/service/testdata/interceptors_dsls.go @@ -214,9 +214,23 @@ var InterceptorWithReadWriteResultDSL = func() { } var StreamingInterceptorsDSL = func() { - Interceptor("logging") + Interceptor("logging", func() { + ReadStreamingPayload(func() { + Attribute("chunk") + }) + WriteStreamingPayload(func() { + Attribute("chunk") + }) + ReadStreamingResult(func() { + Attribute("data") + }) + WriteStreamingResult(func() { + Attribute("data") + }) + }) Service("StreamingInterceptors", func() { ServerInterceptor("logging") + ClientInterceptor("logging") Method("Method", func() { StreamingPayload(func() { Attribute("chunk", String) @@ -229,6 +243,48 @@ var StreamingInterceptorsDSL = func() { }) } +var StreamingInterceptorsWithReadPayloadAndReadStreamingPayloadDSL = func() { + Interceptor("logging", func() { + ReadPayload(func() { + Attribute("chunk") + }) + ReadStreamingPayload(func() { + Attribute("chunk") + }) + }) + Service("StreamingInterceptorsWithReadPayloadAndReadStreamingPayload", func() { + ServerInterceptor("logging") + ClientInterceptor("logging") + Method("Method", func() { + Payload(func() { + Field(1, "chunk", String) + }) + StreamingPayload(func() { + Field(1, "chunk", String) + }) + GRPC(func() {}) + }) + }) +} + +var StreamingInterceptorsWithReadStreamingResultDSL = func() { + Interceptor("logging", func() { + ReadStreamingResult(func() { + Attribute("data") + }) + }) + Service("StreamingInterceptorsWithReadStreamingResult", func() { + ServerInterceptor("logging") + ClientInterceptor("logging") + Method("Method", func() { + StreamingResult(func() { + Field(1, "data", String) + }) + GRPC(func() {}) + }) + }) +} + var StreamingInterceptorsWithReadPayloadDSL = func() { Interceptor("logging", func() { ReadPayload(func() { diff --git a/codegen/service/testdata/service_code.go b/codegen/service/testdata/service_code.go index f6a9b5bf9a..b2d92cdf43 100644 --- a/codegen/service/testdata/service_code.go +++ b/codegen/service/testdata/service_code.go @@ -1814,6 +1814,8 @@ var MethodNames = [1]string{"StreamingResultMethod"} type StreamingResultMethodServerStream interface { // Send streams instances of "AResult". Send(*AResult) error + // SendWithContext streams instances of "AResult" with context. + SendWithContext(context.Context, *AResult) error // Close closes the stream. Close() error } @@ -1823,6 +1825,8 @@ type StreamingResultMethodServerStream interface { type StreamingResultMethodClientStream interface { // Recv reads instances of "AResult" from the stream. Recv() (*AResult, error) + // RecvWithContext reads instances of "AResult" from the stream with context. + RecvWithContext(context.Context) (*AResult, error) } // APayload is the payload type of the StreamingResultService service @@ -1877,6 +1881,8 @@ var MethodNames = [1]string{"StreamingResultWithViewsMethod"} type StreamingResultWithViewsMethodServerStream interface { // Send streams instances of "MultipleViews". Send(*MultipleViews) error + // SendWithContext streams instances of "MultipleViews" with context. + SendWithContext(context.Context, *MultipleViews) error // Close closes the stream. Close() error // SetView sets the view used to render the result before streaming. @@ -1888,6 +1894,9 @@ type StreamingResultWithViewsMethodServerStream interface { type StreamingResultWithViewsMethodClientStream interface { // Recv reads instances of "MultipleViews" from the stream. Recv() (*MultipleViews, error) + // RecvWithContext reads instances of "MultipleViews" from the stream with + // context. + RecvWithContext(context.Context) (*MultipleViews, error) } // MultipleViews is the result type of the StreamingResultWithViewsService @@ -1993,6 +2002,8 @@ var MethodNames = [1]string{"StreamingResultWithExplicitViewMethod"} type StreamingResultWithExplicitViewMethodServerStream interface { // Send streams instances of "MultipleViews". Send(*MultipleViews) error + // SendWithContext streams instances of "MultipleViews" with context. + SendWithContext(context.Context, *MultipleViews) error // Close closes the stream. Close() error } @@ -2002,6 +2013,9 @@ type StreamingResultWithExplicitViewMethodServerStream interface { type StreamingResultWithExplicitViewMethodClientStream interface { // Recv reads instances of "MultipleViews" from the stream. Recv() (*MultipleViews, error) + // RecvWithContext reads instances of "MultipleViews" from the stream with + // context. + RecvWithContext(context.Context) (*MultipleViews, error) } // MultipleViews is the result type of the @@ -2107,6 +2121,8 @@ var MethodNames = [1]string{"StreamingResultNoPayloadMethod"} type StreamingResultNoPayloadMethodServerStream interface { // Send streams instances of "AResult". Send(*AResult) error + // SendWithContext streams instances of "AResult" with context. + SendWithContext(context.Context, *AResult) error // Close closes the stream. Close() error } @@ -2116,6 +2132,8 @@ type StreamingResultNoPayloadMethodServerStream interface { type StreamingResultNoPayloadMethodClientStream interface { // Recv reads instances of "AResult" from the stream. Recv() (*AResult, error) + // RecvWithContext reads instances of "AResult" from the stream with context. + RecvWithContext(context.Context) (*AResult, error) } // AResult is the result type of the StreamingResultNoPayloadService service @@ -2157,8 +2175,13 @@ var MethodNames = [1]string{"StreamingPayloadMethod"} type StreamingPayloadMethodServerStream interface { // SendAndClose streams instances of "AResult" and closes the stream. SendAndClose(*AResult) error + // SendAndCloseWithContext streams instances of "AResult" and closes the stream + // with context. + SendAndCloseWithContext(context.Context, *AResult) error // Recv reads instances of "APayload" from the stream. Recv() (*APayload, error) + // RecvWithContext reads instances of "APayload" from the stream with context. + RecvWithContext(context.Context) (*APayload, error) } // StreamingPayloadMethodClientStream is the interface a @@ -2166,9 +2189,14 @@ type StreamingPayloadMethodServerStream interface { type StreamingPayloadMethodClientStream interface { // Send streams instances of "APayload". Send(*APayload) error + // SendWithContext streams instances of "APayload" with context. + SendWithContext(context.Context, *APayload) error // CloseAndRecv stops sending messages to the stream and reads instances of // "AResult" from the stream. CloseAndRecv() (*AResult, error) + // CloseAndRecvWithContext stops sending messages to the stream and reads + // instances of "AResult" from the stream with context. + CloseAndRecvWithContext(context.Context) (*AResult, error) } // APayload is the streaming payload type of the StreamingPayloadService @@ -2240,8 +2268,13 @@ var MethodNames = [1]string{"StreamingPayloadNoPayloadMethod"} type StreamingPayloadNoPayloadMethodServerStream interface { // SendAndClose streams instances of "string" and closes the stream. SendAndClose(string) error + // SendAndCloseWithContext streams instances of "string" and closes the stream + // with context. + SendAndCloseWithContext(context.Context, string) error // Recv reads instances of "any" from the stream. Recv() (any, error) + // RecvWithContext reads instances of "any" from the stream with context. + RecvWithContext(context.Context) (any, error) } // StreamingPayloadNoPayloadMethodClientStream is the interface a @@ -2249,9 +2282,14 @@ type StreamingPayloadNoPayloadMethodServerStream interface { type StreamingPayloadNoPayloadMethodClientStream interface { // Send streams instances of "any". Send(any) error + // SendWithContext streams instances of "any" with context. + SendWithContext(context.Context, any) error // CloseAndRecv stops sending messages to the stream and reads instances of // "string" from the stream. CloseAndRecv() (string, error) + // CloseAndRecvWithContext stops sending messages to the stream and reads + // instances of "string" from the stream with context. + CloseAndRecvWithContext(context.Context) (string, error) } ` @@ -2283,6 +2321,8 @@ var MethodNames = [1]string{"StreamingPayloadNoResultMethod"} type StreamingPayloadNoResultMethodServerStream interface { // Recv reads instances of "int" from the stream. Recv() (int, error) + // RecvWithContext reads instances of "int" from the stream with context. + RecvWithContext(context.Context) (int, error) // Close closes the stream. Close() error } @@ -2292,6 +2332,8 @@ type StreamingPayloadNoResultMethodServerStream interface { type StreamingPayloadNoResultMethodClientStream interface { // Send streams instances of "int". Send(int) error + // SendWithContext streams instances of "int" with context. + SendWithContext(context.Context, int) error // Close closes the stream. Close() error } @@ -2329,8 +2371,13 @@ var MethodNames = [1]string{"StreamingPayloadResultWithViewsMethod"} type StreamingPayloadResultWithViewsMethodServerStream interface { // SendAndClose streams instances of "MultipleViews" and closes the stream. SendAndClose(*MultipleViews) error + // SendAndCloseWithContext streams instances of "MultipleViews" and closes the + // stream with context. + SendAndCloseWithContext(context.Context, *MultipleViews) error // Recv reads instances of "APayload" from the stream. Recv() (*APayload, error) + // RecvWithContext reads instances of "APayload" from the stream with context. + RecvWithContext(context.Context) (*APayload, error) // SetView sets the view used to render the result before streaming. SetView(view string) } @@ -2340,9 +2387,14 @@ type StreamingPayloadResultWithViewsMethodServerStream interface { type StreamingPayloadResultWithViewsMethodClientStream interface { // Send streams instances of "APayload". Send(*APayload) error + // SendWithContext streams instances of "APayload" with context. + SendWithContext(context.Context, *APayload) error // CloseAndRecv stops sending messages to the stream and reads instances of // "MultipleViews" from the stream. CloseAndRecv() (*MultipleViews, error) + // CloseAndRecvWithContext stops sending messages to the stream and reads + // instances of "MultipleViews" from the stream with context. + CloseAndRecvWithContext(context.Context) (*MultipleViews, error) } // APayload is the streaming payload type of the @@ -2462,8 +2514,13 @@ var MethodNames = [1]string{"StreamingPayloadResultWithExplicitViewMethod"} type StreamingPayloadResultWithExplicitViewMethodServerStream interface { // SendAndClose streams instances of "MultipleViews" and closes the stream. SendAndClose(*MultipleViews) error + // SendAndCloseWithContext streams instances of "MultipleViews" and closes the + // stream with context. + SendAndCloseWithContext(context.Context, *MultipleViews) error // Recv reads instances of "[]string" from the stream. Recv() ([]string, error) + // RecvWithContext reads instances of "[]string" from the stream with context. + RecvWithContext(context.Context) ([]string, error) } // StreamingPayloadResultWithExplicitViewMethodClientStream is the interface a @@ -2472,9 +2529,14 @@ type StreamingPayloadResultWithExplicitViewMethodServerStream interface { type StreamingPayloadResultWithExplicitViewMethodClientStream interface { // Send streams instances of "[]string". Send([]string) error + // SendWithContext streams instances of "[]string" with context. + SendWithContext(context.Context, []string) error // CloseAndRecv stops sending messages to the stream and reads instances of // "MultipleViews" from the stream. CloseAndRecv() (*MultipleViews, error) + // CloseAndRecvWithContext stops sending messages to the stream and reads + // instances of "MultipleViews" from the stream with context. + CloseAndRecvWithContext(context.Context) (*MultipleViews, error) } // MultipleViews is the result type of the @@ -2580,8 +2642,12 @@ var MethodNames = [1]string{"BidirectionalStreamingMethod"} type BidirectionalStreamingMethodServerStream interface { // Send streams instances of "AResult". Send(*AResult) error + // SendWithContext streams instances of "AResult" with context. + SendWithContext(context.Context, *AResult) error // Recv reads instances of "APayload" from the stream. Recv() (*APayload, error) + // RecvWithContext reads instances of "APayload" from the stream with context. + RecvWithContext(context.Context) (*APayload, error) // Close closes the stream. Close() error } @@ -2591,8 +2657,12 @@ type BidirectionalStreamingMethodServerStream interface { type BidirectionalStreamingMethodClientStream interface { // Send streams instances of "APayload". Send(*APayload) error + // SendWithContext streams instances of "APayload" with context. + SendWithContext(context.Context, *APayload) error // Recv reads instances of "AResult" from the stream. Recv() (*AResult, error) + // RecvWithContext reads instances of "AResult" from the stream with context. + RecvWithContext(context.Context) (*AResult, error) // Close closes the stream. Close() error } @@ -2667,8 +2737,12 @@ var MethodNames = [1]string{"BidirectionalStreamingNoPayloadMethod"} type BidirectionalStreamingNoPayloadMethodServerStream interface { // Send streams instances of "int". Send(int) error + // SendWithContext streams instances of "int" with context. + SendWithContext(context.Context, int) error // Recv reads instances of "string" from the stream. Recv() (string, error) + // RecvWithContext reads instances of "string" from the stream with context. + RecvWithContext(context.Context) (string, error) // Close closes the stream. Close() error } @@ -2678,8 +2752,12 @@ type BidirectionalStreamingNoPayloadMethodServerStream interface { type BidirectionalStreamingNoPayloadMethodClientStream interface { // Send streams instances of "string". Send(string) error + // SendWithContext streams instances of "string" with context. + SendWithContext(context.Context, string) error // Recv reads instances of "int" from the stream. Recv() (int, error) + // RecvWithContext reads instances of "int" from the stream with context. + RecvWithContext(context.Context) (int, error) // Close closes the stream. Close() error } @@ -2719,8 +2797,12 @@ var MethodNames = [1]string{"BidirectionalStreamingResultWithViewsMethod"} type BidirectionalStreamingResultWithViewsMethodServerStream interface { // Send streams instances of "MultipleViews". Send(*MultipleViews) error + // SendWithContext streams instances of "MultipleViews" with context. + SendWithContext(context.Context, *MultipleViews) error // Recv reads instances of "APayload" from the stream. Recv() (*APayload, error) + // RecvWithContext reads instances of "APayload" from the stream with context. + RecvWithContext(context.Context) (*APayload, error) // Close closes the stream. Close() error // SetView sets the view used to render the result before streaming. @@ -2733,8 +2815,13 @@ type BidirectionalStreamingResultWithViewsMethodServerStream interface { type BidirectionalStreamingResultWithViewsMethodClientStream interface { // Send streams instances of "APayload". Send(*APayload) error + // SendWithContext streams instances of "APayload" with context. + SendWithContext(context.Context, *APayload) error // Recv reads instances of "MultipleViews" from the stream. Recv() (*MultipleViews, error) + // RecvWithContext reads instances of "MultipleViews" from the stream with + // context. + RecvWithContext(context.Context) (*MultipleViews, error) // Close closes the stream. Close() error } @@ -2856,8 +2943,12 @@ var MethodNames = [1]string{"BidirectionalStreamingResultWithExplicitViewMethod" type BidirectionalStreamingResultWithExplicitViewMethodServerStream interface { // Send streams instances of "MultipleViews". Send(*MultipleViews) error + // SendWithContext streams instances of "MultipleViews" with context. + SendWithContext(context.Context, *MultipleViews) error // Recv reads instances of "[][]byte" from the stream. Recv() ([][]byte, error) + // RecvWithContext reads instances of "[][]byte" from the stream with context. + RecvWithContext(context.Context) ([][]byte, error) // Close closes the stream. Close() error } @@ -2868,8 +2959,13 @@ type BidirectionalStreamingResultWithExplicitViewMethodServerStream interface { type BidirectionalStreamingResultWithExplicitViewMethodClientStream interface { // Send streams instances of "[][]byte". Send([][]byte) error + // SendWithContext streams instances of "[][]byte" with context. + SendWithContext(context.Context, [][]byte) error // Recv reads instances of "MultipleViews" from the stream. Recv() (*MultipleViews, error) + // RecvWithContext reads instances of "MultipleViews" from the stream with + // context. + RecvWithContext(context.Context) (*MultipleViews, error) // Close closes the stream. Close() error } diff --git a/dsl/api.go b/dsl/api.go index e34a4326b5..1cc7b9afe2 100644 --- a/dsl/api.go +++ b/dsl/api.go @@ -56,7 +56,7 @@ func API(name string, fn func()) *expr.APIExpr { // Title sets the API title. It is used by the generated OpenAPI specification. // -// Title must appear in a API expression. +// Title must appear in an API expression. // // Title accepts a single string argument. // @@ -75,7 +75,7 @@ func Title(val string) { // Version specifies the API version. One design describes one version. // -// Version must appear in a API expression. +// Version must appear in an API expression. // // Version accepts a single string argument. // @@ -94,7 +94,7 @@ func Version(ver string) { // Contact sets the API contact information. // -// Contact must appear in a API expression. +// Contact must appear in an API expression. // // Contact takes a single argument which is the defining DSL. // @@ -121,7 +121,7 @@ func Contact(fn func()) { // License sets the API license information. // -// License must appear in a API expression. +// License must appear in an API expression. // // License takes a single argument which is the defining DSL. // @@ -147,7 +147,7 @@ func License(fn func()) { // Randomizer sets the API example randomizer. // -// Randomizer must appear in a API expression. +// Randomizer must appear in an API expression. // // Randomizer takes a single argument which is an implementation of // expr.Randomizer. @@ -215,7 +215,7 @@ func Docs(fn func()) { // TermsOfService describes the API terms of services or links to them. // -// TermsOfService must appear in a API expression. +// TermsOfService must appear in an API expression. // // TermsOfService takes a single argument which is the TOS text or URL. // diff --git a/dsl/http.go b/dsl/http.go index fe26072d87..826d6f5335 100644 --- a/dsl/http.go +++ b/dsl/http.go @@ -233,7 +233,7 @@ func Produces(args ...string) { // As a special case, if you want to generate a path with a trailing slash, you can use // GET("/./") to generate a path such as '/foo/'. // -// Path must appear in a API HTTP expression or a Service HTTP expression. +// Path must appear in an API HTTP expression or a Service HTTP expression. // // Path accepts one argument: the HTTP path prefix. func Path(val string) { @@ -1166,7 +1166,7 @@ func cookies(exp eval.Expression) *expr.MappedAttributeExpr { } // params returns the mapped attribute containing the path and query params for -// the given expression if it's either the root, a API server, a service or an +// the given expression if it's either the root, an API server, a service or an // endpoint - nil otherwise. func params(exp eval.Expression) *expr.MappedAttributeExpr { switch e := exp.(type) { diff --git a/dsl/interceptor.go b/dsl/interceptor.go index fdb42fa1b8..44de81370a 100644 --- a/dsl/interceptor.go +++ b/dsl/interceptor.go @@ -8,7 +8,7 @@ import ( // Interceptor defines a request interceptor. Interceptors provide a type-safe way // to read and write from and to the request and response. // -// Interceptor must appear in a API, Service or Method expression. +// Interceptor must appear in an API, Service or Method expression. // // Interceptor accepts two arguments: the name of the interceptor and the // defining DSL. @@ -143,10 +143,102 @@ func WriteResult(arg any) { }) } +// ReadStreamingPayload defines the streaming payload attributes read by the interceptor. +// +// ReadStreamingPayload must appear in an interceptor DSL. +// +// ReadStreamingPayload takes a function as argument which can use the Attribute DSL to +// define the attributes read by the interceptor. +// +// Example: +// +// ReadStreamingPayload(func() { +// Attribute("id") +// }) +// +// ReadStreamingPayload also accepts user defined types: +// +// // Interceptor can read any streaming payload field +// ReadStreamingPayload(MethodStreamingPayload) +func ReadStreamingPayload(arg any) { + setInterceptorAttribute(arg, func(i *expr.InterceptorExpr, attr *expr.AttributeExpr) { + i.ReadStreamingPayload = attr + }) +} + +// WriteStreamingPayload defines the streaming payload attributes written by the interceptor. +// +// WriteStreamingPayload must appear in an interceptor DSL. +// +// WriteStreamingPayload takes a function as argument which can use the Attribute DSL to +// define the attributes written by the interceptor. +// +// Example: +// +// WriteStreamingPayload(func() { +// Attribute("id") +// }) +// +// WriteStreamingPayload also accepts user defined types: +// +// // Interceptor can write any streaming payload field +// WriteStreamingPayload(MethodStreamingPayload) +func WriteStreamingPayload(arg any) { + setInterceptorAttribute(arg, func(i *expr.InterceptorExpr, attr *expr.AttributeExpr) { + i.WriteStreamingPayload = attr + }) +} + +// ReadStreamingResult defines the streaming result attributes read by the interceptor. +// +// ReadStreamingResult must appear in an interceptor DSL. +// +// ReadStreamingResult takes a function as argument which can use the Attribute DSL to +// define the attributes read by the interceptor. +// +// Example: +// +// ReadStreamingResult(func() { +// Attribute("cachedAt") +// }) +// +// ReadStreamingResult also accepts user defined types: +// +// // Interceptor can read any streaming result field +// ReadStreamingResult(MethodStreamingResult) +func ReadStreamingResult(arg any) { + setInterceptorAttribute(arg, func(i *expr.InterceptorExpr, attr *expr.AttributeExpr) { + i.ReadStreamingResult = attr + }) +} + +// WriteStreamingResult defines the streaming result attributes written by the interceptor. +// +// WriteStreamingResult must appear in an interceptor DSL. +// +// WriteStreamingResult takes a function as argument which can use the Attribute DSL to +// define the attributes written by the interceptor. +// +// Example: +// +// WriteStreamingResult(func() { +// Attribute("cachedAt") +// }) +// +// WriteStreamingResult also accepts user defined types: +// +// // Interceptor can write any streaming result field +// WriteStreamingResult(MethodStreamingResult) +func WriteStreamingResult(arg any) { + setInterceptorAttribute(arg, func(i *expr.InterceptorExpr, attr *expr.AttributeExpr) { + i.WriteStreamingResult = attr + }) +} + // ServerInterceptor lists the server-side interceptors that apply to all the // API endpoints, all the service endpoints or a specific endpoint. // -// ServerInterceptor must appear in a API, Service or Method expression. +// ServerInterceptor must appear in an API, Service or Method expression. // // ServerInterceptor accepts one or more interceptor or interceptor names as // arguments. ServerInterceptor can appear multiple times in the same DSL. @@ -176,7 +268,7 @@ func ServerInterceptor(interceptors ...any) { // ClientInterceptor lists the client-side interceptors that apply to all the // API endpoints, all the service endpoints or a specific endpoint. // -// ClientInterceptor must appear in a API, Service or Method expression. +// ClientInterceptor must appear in an API, Service or Method expression. // // ClientInterceptor accepts one or more interceptor or interceptor names as // arguments. ClientInterceptor can appear multiple times in the same DSL. @@ -207,7 +299,7 @@ func ClientInterceptor(interceptors ...any) { } // setInterceptorAttribute is a helper function that handles the common logic for -// setting interceptor attributes (ReadPayload, WritePayload, ReadResult, WriteResult). +// setting interceptor attributes (ReadPayload, WritePayload, ReadResult, WriteResult, ReadStreamingPayload, WriteStreamingPayload, ReadStreamingResult, WriteStreamingResult). func setInterceptorAttribute(arg any, setter func(i *expr.InterceptorExpr, attr *expr.AttributeExpr)) { i, ok := eval.Current().(*expr.InterceptorExpr) if !ok { diff --git a/dsl/interceptor_test.go b/dsl/interceptor_test.go index a96c4308e2..7b94d86011 100644 --- a/dsl/interceptor_test.go +++ b/dsl/interceptor_test.go @@ -69,6 +69,65 @@ func TestInterceptor(t *testing.T) { assert.NotNil(t, wr.Attribute("qux"), "WriteResult should have a qux attribute") }, }, + "valid-streaming": { + func() { + Interceptor("streaming", func() { + Description("test streaming interceptor") + ReadPayload(func() { + Attribute("foo", String) + }) + WritePayload(func() { + Attribute("bar", String) + }) + ReadStreamingPayload(func() { + Attribute("foo", String) + }) + WriteStreamingPayload(func() { + Attribute("bar", String) + }) + ReadStreamingResult(func() { + Attribute("baz", String) + }) + WriteStreamingResult(func() { + Attribute("qux", String) + }) + }) + }, + func(t *testing.T, intr *expr.InterceptorExpr) { + require.NotNil(t, intr, "interceptor should not be nil") + assert.Equal(t, "test streaming interceptor", intr.Description) + + require.NotNil(t, intr.ReadPayload, "ReadPayload should not be nil") + rp := expr.AsObject(intr.ReadPayload.Type) + require.NotNil(t, rp, "ReadPayload should be an object") + assert.NotNil(t, rp.Attribute("foo"), "ReadPayload should have a foo attribute") + + require.NotNil(t, intr.WritePayload, "WritePayload should not be nil") + wp := expr.AsObject(intr.WritePayload.Type) + require.NotNil(t, wp, "WritePayload should be an object") + assert.NotNil(t, wp.Attribute("bar"), "WritePayload should have a bar attribute") + + require.NotNil(t, intr.ReadStreamingPayload, "ReadStreamingPayload should not be nil") + rs := expr.AsObject(intr.ReadStreamingPayload.Type) + require.NotNil(t, rs, "ReadStreamingPayload should be an object") + assert.NotNil(t, rs.Attribute("foo"), "ReadStreamingPayload should have a foo attribute") + + require.NotNil(t, intr.WriteStreamingPayload, "WriteStreamingPayload should not be nil") + ws := expr.AsObject(intr.WriteStreamingPayload.Type) + require.NotNil(t, ws, "WriteStreamingPayload should be an object") + assert.NotNil(t, ws.Attribute("bar"), "WriteStreamingPayload should have a bar attribute") + + require.NotNil(t, intr.ReadStreamingResult, "ReadStreamingResult should not be nil") + rsr := expr.AsObject(intr.ReadStreamingResult.Type) + require.NotNil(t, rsr, "ReadStreamingResult should be an object") + assert.NotNil(t, rsr.Attribute("baz"), "ReadStreamingResult should have a baz attribute") + + require.NotNil(t, intr.WriteStreamingResult, "WriteStreamingResult should not be nil") + wsr := expr.AsObject(intr.WriteStreamingResult.Type) + require.NotNil(t, wsr, "WriteStreamingResult should be an object") + assert.NotNil(t, wsr.Attribute("qux"), "WriteStreamingResult should have a qux attribute") + }, + }, "empty-name": { func() { Interceptor("", func() {}) diff --git a/dsl/result_type.go b/dsl/result_type.go index d8e503b9e1..3bafe7c769 100644 --- a/dsl/result_type.go +++ b/dsl/result_type.go @@ -451,7 +451,7 @@ func Reference(t expr.DataType) { // }) // }) // -// var UpdateBottlePayload = Type("UpatePayload", func() { +// var UpdateBottlePayload = Type("UpdatePayload", func() { // Attribute("id", String, "ID of bottle to update") // Extend(CreateBottlePayload) // Adds attributes "name" and "vintage" // }) diff --git a/dsl/security.go b/dsl/security.go index 76aab1d8cb..0af951b22e 100644 --- a/dsl/security.go +++ b/dsl/security.go @@ -186,7 +186,7 @@ func JWTSecurity(name string, fn ...func()) *expr.SchemeExpr { // in the same scope in which case the client may validate any one of the // requirements for the request to be authorized. // -// Security must appear in a API, Service or Method expression. +// Security must appear in an API, Service or Method expression. // // Security accepts an arbitrary number of security schemes as argument // specified by name or by reference and an optional DSL function as last diff --git a/dsl/server.go b/dsl/server.go index dfb861ef7b..f2ffc42e90 100644 --- a/dsl/server.go +++ b/dsl/server.go @@ -18,7 +18,7 @@ import ( // the first host is used to set the OpenAPI v2 specification 'host' and // 'basePath' values. // -// Server must appear in a API expression. +// Server must appear in an API expression. // // Server takes two arguments: the name of the server and the defining DSL. // diff --git a/expr/api.go b/expr/api.go index 7d77fb975e..f5e4557a5c 100644 --- a/expr/api.go +++ b/expr/api.go @@ -7,7 +7,7 @@ import ( ) type ( - // APIExpr contains the global properties for a API expression. + // APIExpr contains the global properties for an API expression. APIExpr struct { // DSLFunc contains the DSL used to initialize the expression. eval.DSLFunc diff --git a/expr/http_endpoint.go b/expr/http_endpoint.go index 09107b9280..bc6c92a679 100644 --- a/expr/http_endpoint.go +++ b/expr/http_endpoint.go @@ -740,7 +740,7 @@ func (e *HTTPEndpointExpr) validateParams() *eval.ValidationErrors { // We have to figure out the actual type for the params because the actual // type is initialized only during the finalize phase. In the validation // phase, all param types are string type by default unless specified - // expliclty. + // explicitly. initAttr(pparams, e.MethodExpr.Payload) initAttr(qparams, e.MethodExpr.Payload) diff --git a/expr/interceptor.go b/expr/interceptor.go index 538d85463f..31a243351b 100644 --- a/expr/interceptor.go +++ b/expr/interceptor.go @@ -25,6 +25,14 @@ type ( ReadResult *AttributeExpr // WriteResult lists the result attribute names written by the interceptor WriteResult *AttributeExpr + // ReadStreamingPayload lists the streaming payload attribute names read by the interceptor + ReadStreamingPayload *AttributeExpr + // WriteStreamingPayload lists the streaming payload attribute names written by the interceptor + WriteStreamingPayload *AttributeExpr + // ReadStreamingResult lists the streaming result attribute names read by the interceptor + ReadStreamingResult *AttributeExpr + // WriteStreamingResult lists the streaming result attribute names written by the interceptor + WriteStreamingResult *AttributeExpr } ) @@ -66,6 +74,38 @@ func (i *InterceptorExpr) validate(m *MethodExpr) *eval.ValidationErrors { } } + if i.ReadStreamingPayload != nil || i.WriteStreamingPayload != nil { + if !m.IsPayloadStreaming() { + verr.Add(m, "interceptor %q cannot be applied because the method payload is not streaming", i.Name) + } + payloadObj := AsObject(m.StreamingPayload.Type) + if payloadObj == nil { + verr.Add(m, "interceptor %q cannot be applied because the method payload is not an object", i.Name) + } + if i.ReadStreamingPayload != nil { + i.validateAttributeAccess(m, "read streaming payload", verr, payloadObj, i.ReadStreamingPayload) + } + if i.WriteStreamingPayload != nil { + i.validateAttributeAccess(m, "write streaming payload", verr, payloadObj, i.WriteStreamingPayload) + } + } + + if i.ReadStreamingResult != nil || i.WriteStreamingResult != nil { + if !m.IsResultStreaming() { + verr.Add(m, "interceptor %q cannot be applied because the method result is not streaming", i.Name) + } + resultObj := AsObject(m.Result.Type) + if resultObj == nil { + verr.Add(m, "interceptor %q cannot be applied because the method result is not an object", i.Name) + } + if i.ReadStreamingResult != nil { + i.validateAttributeAccess(m, "read streaming result", verr, resultObj, i.ReadStreamingResult) + } + if i.WriteStreamingResult != nil { + i.validateAttributeAccess(m, "write streaming result", verr, resultObj, i.WriteStreamingResult) + } + } + return verr } diff --git a/grpc/codegen/client_cli.go b/grpc/codegen/client_cli.go index 8807818b9f..4f6c2b8df2 100644 --- a/grpc/codegen/client_cli.go +++ b/grpc/codegen/client_cli.go @@ -27,7 +27,7 @@ func ClientCLIFiles(genpkg string, root *expr.RootExpr) []*codegen.File { command := cli.BuildCommandData(sd.Service) for _, e := range sd.Endpoints { flags, buildFunction := buildFlags(e) - subcmd := cli.BuildSubcommandData(sd.Service.Name, e.Method, buildFunction, flags) + subcmd := cli.BuildSubcommandData(sd.Service, e.Method, buildFunction, flags) command.Subcommands = append(command.Subcommands, subcmd) } command.Example = command.Subcommands[0].Example diff --git a/grpc/codegen/service_data.go b/grpc/codegen/service_data.go index 16ac9f6977..442d8d0fd3 100644 --- a/grpc/codegen/service_data.go +++ b/grpc/codegen/service_data.go @@ -332,6 +332,10 @@ type ( SendName string // SendDesc is the description for the send function. SendDesc string + // SendWithContextName is the name of the send function with context. + SendWithContextName string + // SendWithContextDesc is the description for the send function with context. + SendWithContextDesc string // SendRef is the fully qualified reference to the type sent across the // stream. SendRef string @@ -347,6 +351,10 @@ type ( RecvName string // RecvDesc is the description for the recv function. RecvDesc string + // RecvWithContextName is the name of the receive function with context. + RecvWithContextName string + // RecvWithContextDesc is the description for the recv function with context. + RecvWithContextDesc string // RecvRef is the fully qualified reference to the type received from the // stream. RecvRef string @@ -393,7 +401,7 @@ func (d ServicesData) Get(name string) *ServiceData { return d[name] } -// Endpoint returns the endoint data for the endpoint with the given name, nil +// Endpoint returns the endpoint data for the endpoint with the given name, nil // if there isn't one. func (sd *ServiceData) Endpoint(name string) *EndpointData { for _, ed := range sd.Endpoints { @@ -427,16 +435,11 @@ func (sd *ServiceData) HasStreamingEndpoint() bool { // analyze creates the data necessary to render the code of the given service. func (ServicesData) analyze(gs *expr.GRPCServiceExpr) *ServiceData { - var ( - sd *ServiceData - seen, imported map[string]struct{} - svcVarN string - ) svc := service.Services.Get(gs.Name()) scope := codegen.NewNameScope() pkg := codegen.SnakeCase(codegen.Goify(svc.Name, false)) + pbPkgName - svcVarN = scope.HashedUnique(gs.ServiceExpr, codegen.Goify(svc.Name, true)) - sd = &ServiceData{ + svcVarN := scope.HashedUnique(gs.ServiceExpr, codegen.Goify(svc.Name, true)) + sd := &ServiceData{ Service: svc, Name: svcVarN, Description: svc.Description, @@ -450,7 +453,7 @@ func (ServicesData) analyze(gs *expr.GRPCServiceExpr) *ServiceData { ClientInterfaceInit: fmt.Sprintf("%s.New%sClient", pkg, svcVarN), Scope: scope, } - seen, imported = make(map[string]struct{}), make(map[string]struct{}) + seen, imported := make(map[string]struct{}), make(map[string]struct{}) for _, e := range gs.GRPCEndpoints { // convert request and response types to protocol buffer message types e.Request = makeProtoBufMessage(e.Request, protoBufify(e.Name()+"_request", true, true), sd) @@ -501,7 +504,6 @@ func (ServicesData) analyze(gs *expr.GRPCServiceExpr) *ServiceData { payloadRef string resultRef string viewedResultRef string - errors []*ErrorData ) md := svc.Method(e.Name()) if e.MethodExpr.Payload.Type != expr.Empty { @@ -515,7 +517,7 @@ func (ServicesData) analyze(gs *expr.GRPCServiceExpr) *ServiceData { if md.ViewedResult != nil { viewedResultRef = md.ViewedResult.FullRef } - errors = buildErrorsData(e, sd) + errors := buildErrorsData(e, sd) for _, er := range e.GRPCErrors { if er.ErrorExpr.Type == expr.ErrorResult || !expr.IsObject(er.ErrorExpr.Type) { continue @@ -524,9 +526,8 @@ func (ServicesData) analyze(gs *expr.GRPCServiceExpr) *ServiceData { } // build request data - var request *RequestData reqMD := extractMetadata(e.Metadata, e.MethodExpr.Payload, svc.Scope) - request = &RequestData{ + request := &RequestData{ Description: e.Request.Description, Metadata: reqMD, ServerConvert: buildRequestConvertData(e.Request, e.MethodExpr.Payload, reqMD, e, sd, true), @@ -566,14 +567,10 @@ func (ServicesData) analyze(gs *expr.GRPCServiceExpr) *ServiceData { } // build response data - var ( - response *ResponseData - trlrs []*MetadataData - ) result, svcCtx := resultContext(e, sd) hdrs := extractMetadata(e.Response.Headers, result, svc.Scope) - trlrs = extractMetadata(e.Response.Trailers, result, svc.Scope) - response = &ResponseData{ + trlrs := extractMetadata(e.Response.Trailers, result, svc.Scope) + response := &ResponseData{ StatusCode: statusCodeToGRPCConst(e.Response.StatusCode), Description: e.Response.Description, Headers: hdrs, @@ -762,7 +759,7 @@ func collectValidations(att *expr.AttributeExpr, attName string, ctx *codegen.At switch dt := att.Type.(type) { case expr.UserType: if expr.IsPrimitive(dt) { - // Alias type - validation is generatd inline in parent type validation code. + // Alias type - validation is generate inline in parent type validation code. return } vtx := protoBufTypeContext(sd.PkgName, sd.Scope, false) @@ -841,12 +838,9 @@ func buildRequestConvertData(request, payload *expr.AttributeExpr, md []*Metadat return nil } - var ( - svc = sd.Service - pkg = pkgWithDefault(svc.Method(e.MethodExpr.Name).PayloadLoc, svc.PkgName) - svcCtx = serviceTypeContext(pkg, svc.Scope) - ) - + svc := sd.Service + pkg := pkgWithDefault(svc.Method(e.MethodExpr.Name).PayloadLoc, svc.PkgName) + svcCtx := serviceTypeContext(pkg, svc.Scope) if svr { // server side data := buildInitData(request, payload, "message", "v", svcCtx, false, svr, false, sd) @@ -972,28 +966,16 @@ func buildResponseConvertData(response, result *expr.AttributeExpr, svcCtx *code // proto if true indicates the target type is a protocol buffer type // svr if true indicates the code is generated for conversion server side func buildInitData(source, target *expr.AttributeExpr, sourceVar, targetVar string, svcCtx *codegen.AttributeContext, proto, _, usesrc bool, sd *ServiceData) *InitData { - var ( - name string - isStruct bool - code string - helpers []*codegen.TransformFunctionData - args []*InitArgData - err error - srcCtx *codegen.AttributeContext - tgtCtx *codegen.AttributeContext - - // pbCtx = protoBufTypeContext(sd.PkgName, sd.Scope, proto && svr || !proto && !svr) - pbCtx = protoBufTypeContext(sd.PkgName, sd.Scope, false) - ) - name = "New" - srcCtx = pbCtx - tgtCtx = svcCtx + pbCtx := protoBufTypeContext(sd.PkgName, sd.Scope, false) + name := "New" + srcCtx := pbCtx + tgtCtx := svcCtx if proto { srcCtx = svcCtx tgtCtx = pbCtx name += "Proto" } - isStruct = expr.IsObject(target.Type) || expr.IsUnion(target.Type) + isStruct := expr.IsObject(target.Type) || expr.IsUnion(target.Type) if _, ok := source.Type.(expr.UserType); ok && usesrc { name += protoBufGoTypeName(source, sd.Scope) } @@ -1004,11 +986,12 @@ func buildInitData(source, target *expr.AttributeExpr, sourceVar, targetVar stri n = protoBufGoTypeName(source, sd.Scope) } name += n - code, helpers, err = protoBufTransform(source, target, sourceVar, targetVar, srcCtx, tgtCtx, proto, true) + code, helpers, err := protoBufTransform(source, target, sourceVar, targetVar, srcCtx, tgtCtx, proto, true) if err != nil { panic(err) // bug } sd.transformHelpers = codegen.AppendHelpers(sd.transformHelpers, helpers) + var args []*InitArgData if (!proto && !isEmpty(source.Type)) || (proto && !isEmpty(target.Type)) { args = []*InitArgData{{ Name: sourceVar, @@ -1033,9 +1016,8 @@ func buildInitData(source, target *expr.AttributeExpr, sourceVar, targetVar stri // endpoint expression. The response message for each error response are // inferred from the method's error expression if not specified explicitly. func buildErrorsData(e *expr.GRPCEndpointExpr, sd *ServiceData) []*ErrorData { - var errors []*ErrorData svc := sd.Service - errors = make([]*ErrorData, 0, len(e.GRPCErrors)) + errors := make([]*ErrorData, 0, len(e.GRPCErrors)) for _, v := range e.GRPCErrors { responseData := &ResponseData{ StatusCode: statusCodeToGRPCConst(v.Response.StatusCode), @@ -1094,26 +1076,29 @@ func buildErrorConvertData(ge *expr.GRPCErrorExpr, e *expr.GRPCEndpointExpr, sd // svr param indicates that the stream data is built for the server. func buildStreamData(e *expr.GRPCEndpointExpr, sd *ServiceData, svr bool) *StreamData { var ( - varn string - intName string - svcInt string - sendName string - sendDesc string - sendRef string - sendConvert *ConvertData - recvName string - recvDesc string - recvRef string - recvConvert *ConvertData - mustClose bool - typ string - - svc = sd.Service - ed = sd.Endpoint(e.Name()) - md = ed.Method - svcCtx = serviceTypeContext(svc.PkgName, svc.Scope) - result, resCtx = resultContext(e, sd) + varn string + intName string + svcInt string + sendName string + sendDesc string + sendWithContextName string + sendWithContextDesc string + sendRef string + sendConvert *ConvertData + recvName string + recvDesc string + recvWithContextName string + recvWithContextDesc string + recvRef string + recvConvert *ConvertData + mustClose bool + typ string ) + svc := sd.Service + ed := sd.Endpoint(e.Name()) + md := ed.Method + svcCtx := serviceTypeContext(svc.PkgName, svc.Scope) + result, resCtx := resultContext(e, sd) resVar := "result" if md.ViewedResult != nil { resVar = "vresult" @@ -1126,6 +1111,7 @@ func buildStreamData(e *expr.GRPCEndpointExpr, sd *ServiceData, svr bool) *Strea if e.MethodExpr.Result.Type != expr.Empty { sendName = md.ServerStream.SendName sendRef = ed.ResultRef + sendWithContextName = md.ServerStream.SendWithContextName sendConvert = &ConvertData{ SrcName: resCtx.Scope.Name(result, resCtx.Pkg(result), resCtx.Pointer, resCtx.UseDefault), SrcRef: resCtx.Scope.Ref(result, resCtx.Pkg(result)), @@ -1136,6 +1122,7 @@ func buildStreamData(e *expr.GRPCEndpointExpr, sd *ServiceData, svr bool) *Strea } if e.MethodExpr.StreamingPayload.Type != expr.Empty { recvName = md.ServerStream.RecvName + recvWithContextName = md.ServerStream.RecvWithContextName recvRef = svcCtx.Scope.Ref(e.MethodExpr.StreamingPayload, svcCtx.Pkg(e.MethodExpr.StreamingPayload)) recvConvert = &ConvertData{ SrcName: protoBufGoFullTypeName(e.StreamingRequest, sd.PkgName, sd.Scope), @@ -1154,6 +1141,7 @@ func buildStreamData(e *expr.GRPCEndpointExpr, sd *ServiceData, svr bool) *Strea svcInt = fmt.Sprintf("%s.%s", svc.PkgName, md.ClientStream.Interface) if e.MethodExpr.StreamingPayload.Type != expr.Empty { sendName = md.ClientStream.SendName + sendWithContextName = md.ClientStream.SendWithContextName sendRef = svcCtx.Scope.Ref(e.MethodExpr.StreamingPayload, svcCtx.Pkg(e.MethodExpr.StreamingPayload)) sendConvert = &ConvertData{ SrcName: svcCtx.Scope.Name(e.MethodExpr.StreamingPayload, svcCtx.Pkg(e.MethodExpr.StreamingPayload), svcCtx.Pointer, svcCtx.UseDefault), @@ -1165,6 +1153,7 @@ func buildStreamData(e *expr.GRPCEndpointExpr, sd *ServiceData, svr bool) *Strea } if e.MethodExpr.Result.Type != expr.Empty { recvName = md.ClientStream.RecvName + recvWithContextName = md.ClientStream.RecvWithContextName recvRef = ed.ResultRef recvConvert = &ConvertData{ SrcName: protoBufGoFullTypeName(e.Response.Message, sd.PkgName, sd.Scope), @@ -1179,25 +1168,31 @@ func buildStreamData(e *expr.GRPCEndpointExpr, sd *ServiceData, svr bool) *Strea } if sendConvert != nil { sendDesc = fmt.Sprintf("%s streams instances of %q to the %q endpoint gRPC stream.", sendName, sendConvert.TgtName, md.Name) + sendWithContextDesc = fmt.Sprintf("%s streams instances of %q to the %q endpoint gRPC stream with context.", sendWithContextName, sendConvert.TgtName, md.Name) } if recvConvert != nil { recvDesc = fmt.Sprintf("%s reads instances of %q from the %q endpoint gRPC stream.", recvName, recvConvert.SrcName, md.Name) + recvWithContextDesc = fmt.Sprintf("%s reads instances of %q from the %q endpoint gRPC stream with context.", recvWithContextName, recvConvert.SrcName, md.Name) } return &StreamData{ - VarName: varn, - Type: typ, - Interface: intName, - ServiceInterface: svcInt, - Endpoint: ed, - SendName: sendName, - SendDesc: sendDesc, - SendRef: sendRef, - SendConvert: sendConvert, - RecvName: recvName, - RecvDesc: recvDesc, - RecvRef: recvRef, - RecvConvert: recvConvert, - MustClose: mustClose, + VarName: varn, + Type: typ, + Interface: intName, + ServiceInterface: svcInt, + Endpoint: ed, + SendName: sendName, + SendDesc: sendDesc, + SendWithContextName: sendWithContextName, + SendWithContextDesc: sendWithContextDesc, + SendRef: sendRef, + SendConvert: sendConvert, + RecvName: recvName, + RecvDesc: recvDesc, + RecvWithContextName: recvWithContextName, + RecvWithContextDesc: recvWithContextDesc, + RecvRef: recvRef, + RecvConvert: recvConvert, + MustClose: mustClose, } } @@ -1207,18 +1202,13 @@ func extractMetadata(a *expr.MappedAttributeExpr, service *expr.AttributeExpr, s var metadata []*MetadataData ctx := serviceTypeContext("", scope) codegen.WalkMappedAttr(a, func(name, elem string, required bool, c *expr.AttributeExpr) error { // nolint: errcheck - var ( - varn string - fieldName string - pointer bool - - arr = expr.AsArray(c.Type) - mp = expr.AsMap(c.Type) - typeRef = scope.GoTypeRef(unalias(c)) - ft = service.Type - ) - varn = scope.Name(codegen.Goify(name, false)) - fieldName = codegen.Goify(name, true) + arr := expr.AsArray(c.Type) + mp := expr.AsMap(c.Type) + typeRef := scope.GoTypeRef(unalias(c)) + ft := service.Type + varn := scope.Name(codegen.Goify(name, false)) + fieldName := codegen.Goify(name, true) + var pointer bool if !expr.IsObject(service.Type) { fieldName = "" } else { diff --git a/grpc/codegen/templates/parse_endpoint.go.tpl b/grpc/codegen/templates/parse_endpoint.go.tpl index 43f98aec9f..538dad4768 100644 --- a/grpc/codegen/templates/parse_endpoint.go.tpl +++ b/grpc/codegen/templates/parse_endpoint.go.tpl @@ -22,12 +22,11 @@ func ParseEndpoint( c := {{ .PkgName }}.NewClient(cc, opts...) switch epn { {{- $pkgName := .PkgName }} - {{- $interceptors := .Interceptors }} {{ range .Subcommands }} case "{{ .Name }}": endpoint = c.{{ .MethodVarName }}() - {{- if $interceptors }} - endpoint = {{ $interceptors.PkgName }}.Wrap{{ .MethodVarName }}ClientEndpoint(endpoint, {{ $interceptors.VarName }}) + {{- if .Interceptors }} + endpoint = {{ .Interceptors.PkgName }}.Wrap{{ .MethodVarName }}ClientEndpoint(endpoint, {{ .Interceptors.VarName }}) {{- end }} {{- if .BuildFunction }} data, err = {{ $pkgName}}.{{ .BuildFunction.Name }}({{ range .BuildFunction.ActualParams }}*{{ . }}Flag, {{ end }}) @@ -44,4 +43,4 @@ func ParseEndpoint( } return endpoint, data, nil -} \ No newline at end of file +} diff --git a/grpc/codegen/templates/stream_recv.go.tpl b/grpc/codegen/templates/stream_recv.go.tpl index 593ce4de98..93215633a5 100644 --- a/grpc/codegen/templates/stream_recv.go.tpl +++ b/grpc/codegen/templates/stream_recv.go.tpl @@ -21,3 +21,8 @@ func (s *{{ .VarName }}) {{ .RecvName }}() ({{ .RecvRef }}, error) { return {{ .RecvConvert.Init.Name }}({{ range .RecvConvert.Init.Args }}{{ .Name }}, {{ end }}), nil {{- end }} } + +{{ comment .RecvWithContextDesc }} +func (s *{{ .VarName }}) {{ .RecvWithContextName }}(ctx context.Context) ({{ .RecvRef }}, error) { + return s.{{ .RecvName }}() +} diff --git a/grpc/codegen/templates/stream_send.go.tpl b/grpc/codegen/templates/stream_send.go.tpl index 7a66cea3d1..e873121a22 100644 --- a/grpc/codegen/templates/stream_send.go.tpl +++ b/grpc/codegen/templates/stream_send.go.tpl @@ -10,3 +10,8 @@ func (s *{{ .VarName }}) {{ .SendName }}(res {{ .SendRef }}) error { v := {{ .SendConvert.Init.Name }}({{ if and .Endpoint.Method.ViewedResult (eq .Type "server") }}vres.Projected{{ else }}res{{ end }}) return s.stream.{{ .SendName }}(v) } + +{{ comment .SendWithContextDesc }} +func (s *{{ .VarName }}) {{ .SendWithContextName }}(ctx context.Context, res {{ .SendRef }}) error { + return s.{{ .SendName }}(res) +} diff --git a/grpc/codegen/testdata/streaming_code.go b/grpc/codegen/testdata/streaming_code.go index ae871c393d..0a13907ff6 100644 --- a/grpc/codegen/testdata/streaming_code.go +++ b/grpc/codegen/testdata/streaming_code.go @@ -15,6 +15,13 @@ func (s *MethodServerStreamingUserTypeRPCServerStream) Send(res *serviceserverst v := NewProtoUserTypeMethodServerStreamingUserTypeRPCResponse(res) return s.stream.Send(v) } + +// SendWithContext streams instances of +// "service_server_streaming_user_type_rpcpb.MethodServerStreamingUserTypeRPCResponse" +// to the "MethodServerStreamingUserTypeRPC" endpoint gRPC stream with context. +func (s *MethodServerStreamingUserTypeRPCServerStream) SendWithContext(ctx context.Context, res *serviceserverstreamingusertyperpc.UserType) error { + return s.Send(res) +} ` var ServerStreamingServerCloseCode = `func (s *MethodServerStreamingUserTypeRPCServerStream) Close() error { @@ -42,6 +49,14 @@ func (s *MethodServerStreamingUserTypeRPCClientStream) Recv() (*serviceserverstr } return NewMethodServerStreamingUserTypeRPCResponseUserType(v), nil } + +// RecvWithContext reads instances of +// "service_server_streaming_user_type_rpcpb.MethodServerStreamingUserTypeRPCResponse" +// from the "MethodServerStreamingUserTypeRPC" endpoint gRPC stream with +// context. +func (s *MethodServerStreamingUserTypeRPCClientStream) RecvWithContext(ctx context.Context) (*serviceserverstreamingusertyperpc.UserType, error) { + return s.Recv() +} ` var ServerStreamingResultWithViewsServerStructCode = `// MethodServerStreamingUserTypeRPCServerStream implements the @@ -61,6 +76,13 @@ func (s *MethodServerStreamingUserTypeRPCServerStream) Send(res *serviceserverst v := NewProtoResultTypeViewMethodServerStreamingUserTypeRPCResponse(vres.Projected) return s.stream.Send(v) } + +// SendWithContext streams instances of +// "service_server_streaming_user_type_rpcpb.MethodServerStreamingUserTypeRPCResponse" +// to the "MethodServerStreamingUserTypeRPC" endpoint gRPC stream with context. +func (s *MethodServerStreamingUserTypeRPCServerStream) SendWithContext(ctx context.Context, res *serviceserverstreamingusertyperpc.ResultType) error { + return s.Send(res) +} ` var ServerStreamingResultWithViewsServerSetViewCode = `// SetView sets the view. @@ -94,6 +116,14 @@ func (s *MethodServerStreamingUserTypeRPCClientStream) Recv() (*serviceserverstr } return serviceserverstreamingusertyperpc.NewResultType(vres), nil } + +// RecvWithContext reads instances of +// "service_server_streaming_user_type_rpcpb.MethodServerStreamingUserTypeRPCResponse" +// from the "MethodServerStreamingUserTypeRPC" endpoint gRPC stream with +// context. +func (s *MethodServerStreamingUserTypeRPCClientStream) RecvWithContext(ctx context.Context) (*serviceserverstreamingusertyperpc.ResultType, error) { + return s.Recv() +} ` var ServerStreamingResultWithViewsClientSetViewCode = `// SetView sets the view. @@ -111,6 +141,14 @@ func (s *MethodServerStreamingResultTypeCollectionWithExplicitViewServerStream) v := NewProtoResultTypeCollectionViewResultTypeCollection(vres.Projected) return s.stream.Send(v) } + +// SendWithContext streams instances of +// "service_server_streaming_result_type_collection_with_explicit_viewpb.ResultTypeCollection" +// to the "MethodServerStreamingResultTypeCollectionWithExplicitView" endpoint +// gRPC stream with context. +func (s *MethodServerStreamingResultTypeCollectionWithExplicitViewServerStream) SendWithContext(ctx context.Context, res serviceserverstreamingresulttypecollectionwithexplicitview.ResultTypeCollection) error { + return s.Send(res) +} ` var ServerStreamingResultCollectionWithExplicitViewClientRecvCode = `// Recv reads instances of @@ -130,6 +168,14 @@ func (s *MethodServerStreamingResultTypeCollectionWithExplicitViewClientStream) } return serviceserverstreamingresulttypecollectionwithexplicitview.NewResultTypeCollection(vres), nil } + +// RecvWithContext reads instances of +// "service_server_streaming_result_type_collection_with_explicit_viewpb.ResultTypeCollection" +// from the "MethodServerStreamingResultTypeCollectionWithExplicitView" +// endpoint gRPC stream with context. +func (s *MethodServerStreamingResultTypeCollectionWithExplicitViewClientStream) RecvWithContext(ctx context.Context) (serviceserverstreamingresulttypecollectionwithexplicitview.ResultTypeCollection, error) { + return s.Recv() +} ` var ServerStreamingPrimitiveServerSendCode = `// Send streams instances of @@ -139,6 +185,13 @@ func (s *MethodServerStreamingRPCServerStream) Send(res string) error { v := NewProtoMethodServerStreamingRPCResponse(res) return s.stream.Send(v) } + +// SendWithContext streams instances of +// "service_server_streaming_rpcpb.MethodServerStreamingRPCResponse" to the +// "MethodServerStreamingRPC" endpoint gRPC stream with context. +func (s *MethodServerStreamingRPCServerStream) SendWithContext(ctx context.Context, res string) error { + return s.Send(res) +} ` var ServerStreamingPrimitiveClientRecvCode = `// Recv reads instances of @@ -152,6 +205,13 @@ func (s *MethodServerStreamingRPCClientStream) Recv() (string, error) { } return NewMethodServerStreamingRPCResponseMethodServerStreamingRPCResponse(v), nil } + +// RecvWithContext reads instances of +// "service_server_streaming_rpcpb.MethodServerStreamingRPCResponse" from the +// "MethodServerStreamingRPC" endpoint gRPC stream with context. +func (s *MethodServerStreamingRPCClientStream) RecvWithContext(ctx context.Context) (string, error) { + return s.Recv() +} ` var ServerStreamingArrayServerSendCode = `// Send streams instances of @@ -161,6 +221,13 @@ func (s *MethodServerStreamingArrayServerStream) Send(res []int) error { v := NewProtoMethodServerStreamingArrayResponse(res) return s.stream.Send(v) } + +// SendWithContext streams instances of +// "service_server_streaming_arraypb.MethodServerStreamingArrayResponse" to the +// "MethodServerStreamingArray" endpoint gRPC stream with context. +func (s *MethodServerStreamingArrayServerStream) SendWithContext(ctx context.Context, res []int) error { + return s.Send(res) +} ` var ServerStreamingArrayClientRecvCode = `// Recv reads instances of @@ -174,6 +241,13 @@ func (s *MethodServerStreamingArrayClientStream) Recv() ([]int, error) { } return NewMethodServerStreamingArrayResponseMethodServerStreamingArrayResponse(v), nil } + +// RecvWithContext reads instances of +// "service_server_streaming_arraypb.MethodServerStreamingArrayResponse" from +// the "MethodServerStreamingArray" endpoint gRPC stream with context. +func (s *MethodServerStreamingArrayClientStream) RecvWithContext(ctx context.Context) ([]int, error) { + return s.Recv() +} ` var ServerStreamingMapServerSendCode = `// Send streams instances of @@ -183,6 +257,13 @@ func (s *MethodServerStreamingMapServerStream) Send(res map[string]*serviceserve v := NewProtoMethodServerStreamingMapResponse(res) return s.stream.Send(v) } + +// SendWithContext streams instances of +// "service_server_streaming_mappb.MethodServerStreamingMapResponse" to the +// "MethodServerStreamingMap" endpoint gRPC stream with context. +func (s *MethodServerStreamingMapServerStream) SendWithContext(ctx context.Context, res map[string]*serviceserverstreamingmap.UserType) error { + return s.Send(res) +} ` var ServerStreamingMapClientRecvCode = `// Recv reads instances of @@ -196,6 +277,13 @@ func (s *MethodServerStreamingMapClientStream) Recv() (map[string]*serviceserver } return NewMethodServerStreamingMapResponseMethodServerStreamingMapResponse(v), nil } + +// RecvWithContext reads instances of +// "service_server_streaming_mappb.MethodServerStreamingMapResponse" from the +// "MethodServerStreamingMap" endpoint gRPC stream with context. +func (s *MethodServerStreamingMapClientStream) RecvWithContext(ctx context.Context) (map[string]*serviceserverstreamingmap.UserType, error) { + return s.Recv() +} ` var ServerStreamingServerRPCSharedResultRecvCode = `// Recv reads instances of @@ -210,6 +298,13 @@ func (s *MethodServerStreamingRPCClientStream) Recv() (*serviceserverstreamingrp return NewMethodServerStreamingRPCResponseUserType(v), nil } +// RecvWithContext reads instances of +// "service_server_streaming_rpcpb.MethodServerStreamingRPCResponse" from the +// "MethodServerStreamingRPC" endpoint gRPC stream with context. +func (s *MethodServerStreamingRPCClientStream) RecvWithContext(ctx context.Context) (*serviceserverstreamingrpc.UserType, error) { + return s.Recv() +} + // Recv reads instances of // "service_server_streaming_rpcpb.OtherMethodServerStreamingRPCResponse" from // the "OtherMethodServerStreamingRPC" endpoint gRPC stream. @@ -221,6 +316,13 @@ func (s *OtherMethodServerStreamingRPCClientStream) Recv() (*serviceserverstream } return NewOtherMethodServerStreamingRPCResponseUserType(v), nil } + +// RecvWithContext reads instances of +// "service_server_streaming_rpcpb.OtherMethodServerStreamingRPCResponse" from +// the "OtherMethodServerStreamingRPC" endpoint gRPC stream with context. +func (s *OtherMethodServerStreamingRPCClientStream) RecvWithContext(ctx context.Context) (*serviceserverstreamingrpc.UserType, error) { + return s.Recv() +} ` var ClientStreamingServerStructCode = `// MethodClientStreamingRPCServerStream implements the @@ -237,6 +339,13 @@ func (s *MethodClientStreamingRPCServerStream) SendAndClose(res string) error { v := NewProtoMethodClientStreamingRPCResponse(res) return s.stream.SendAndClose(v) } + +// SendAndCloseWithContext streams instances of +// "service_client_streaming_rpcpb.MethodClientStreamingRPCResponse" to the +// "MethodClientStreamingRPC" endpoint gRPC stream with context. +func (s *MethodClientStreamingRPCServerStream) SendAndCloseWithContext(ctx context.Context, res string) error { + return s.SendAndClose(res) +} ` var ClientStreamingServerRecvCode = `// Recv reads instances of @@ -250,6 +359,13 @@ func (s *MethodClientStreamingRPCServerStream) Recv() (int, error) { } return NewMethodClientStreamingRPCStreamingRequestMethodClientStreamingRPCStreamingRequest(v), nil } + +// RecvWithContext reads instances of +// "service_client_streaming_rpcpb.MethodClientStreamingRPCStreamingRequest" +// from the "MethodClientStreamingRPC" endpoint gRPC stream with context. +func (s *MethodClientStreamingRPCServerStream) RecvWithContext(ctx context.Context) (int, error) { + return s.Recv() +} ` var ClientStreamingClientStructCode = `// MethodClientStreamingRPCClientStream implements the @@ -266,6 +382,13 @@ func (s *MethodClientStreamingRPCClientStream) Send(res int) error { v := NewProtoMethodClientStreamingRPCStreamingRequest(res) return s.stream.Send(v) } + +// SendWithContext streams instances of +// "service_client_streaming_rpcpb.MethodClientStreamingRPCStreamingRequest" to +// the "MethodClientStreamingRPC" endpoint gRPC stream with context. +func (s *MethodClientStreamingRPCClientStream) SendWithContext(ctx context.Context, res int) error { + return s.Send(res) +} ` var ClientStreamingClientRecvCode = `// CloseAndRecv reads instances of @@ -279,6 +402,13 @@ func (s *MethodClientStreamingRPCClientStream) CloseAndRecv() (string, error) { } return NewMethodClientStreamingRPCResponseMethodClientStreamingRPCResponse(v), nil } + +// CloseAndRecvWithContext reads instances of +// "service_client_streaming_rpcpb.MethodClientStreamingRPCResponse" from the +// "MethodClientStreamingRPC" endpoint gRPC stream with context. +func (s *MethodClientStreamingRPCClientStream) CloseAndRecvWithContext(ctx context.Context) (string, error) { + return s.CloseAndRecv() +} ` var ClientStreamingServerNoResultCloseCode = `func (s *MethodClientStreamingNoResultServerStream) Close() error { @@ -311,6 +441,13 @@ func (s *MethodBidirectionalStreamingRPCServerStream) Send(res *servicebidirecti v := NewProtoIDViewMethodBidirectionalStreamingRPCResponse(vres.Projected) return s.stream.Send(v) } + +// SendWithContext streams instances of +// "service_bidirectional_streaming_rpcpb.MethodBidirectionalStreamingRPCResponse" +// to the "MethodBidirectionalStreamingRPC" endpoint gRPC stream with context. +func (s *MethodBidirectionalStreamingRPCServerStream) SendWithContext(ctx context.Context, res *servicebidirectionalstreamingrpc.ID) error { + return s.Send(res) +} ` var BidirectionalStreamingServerRecvCode = `// Recv reads instances of @@ -324,6 +461,13 @@ func (s *MethodBidirectionalStreamingRPCServerStream) Recv() (int, error) { } return NewMethodBidirectionalStreamingRPCStreamingRequestMethodBidirectionalStreamingRPCStreamingRequest(v), nil } + +// RecvWithContext reads instances of +// "service_bidirectional_streaming_rpcpb.MethodBidirectionalStreamingRPCStreamingRequest" +// from the "MethodBidirectionalStreamingRPC" endpoint gRPC stream with context. +func (s *MethodBidirectionalStreamingRPCServerStream) RecvWithContext(ctx context.Context) (int, error) { + return s.Recv() +} ` var BidirectionalStreamingServerCloseCode = `func (s *MethodBidirectionalStreamingRPCServerStream) Close() error { @@ -348,6 +492,13 @@ func (s *MethodBidirectionalStreamingRPCClientStream) Send(res int) error { v := NewProtoMethodBidirectionalStreamingRPCStreamingRequest(res) return s.stream.Send(v) } + +// SendWithContext streams instances of +// "service_bidirectional_streaming_rpcpb.MethodBidirectionalStreamingRPCStreamingRequest" +// to the "MethodBidirectionalStreamingRPC" endpoint gRPC stream with context. +func (s *MethodBidirectionalStreamingRPCClientStream) SendWithContext(ctx context.Context, res int) error { + return s.Send(res) +} ` var BidirectionalStreamingClientRecvCode = `// Recv reads instances of @@ -366,6 +517,13 @@ func (s *MethodBidirectionalStreamingRPCClientStream) Recv() (*servicebidirectio } return servicebidirectionalstreamingrpc.NewID(vres), nil } + +// RecvWithContext reads instances of +// "service_bidirectional_streaming_rpcpb.MethodBidirectionalStreamingRPCResponse" +// from the "MethodBidirectionalStreamingRPC" endpoint gRPC stream with context. +func (s *MethodBidirectionalStreamingRPCClientStream) RecvWithContext(ctx context.Context) (*servicebidirectionalstreamingrpc.ID, error) { + return s.Recv() +} ` var BidirectionalStreamingClientCloseCode = `func (s *MethodBidirectionalStreamingRPCClientStream) Close() error { diff --git a/http/codegen/client_cli.go b/http/codegen/client_cli.go index 9cf67f2888..da4fa238a8 100644 --- a/http/codegen/client_cli.go +++ b/http/codegen/client_cli.go @@ -24,7 +24,7 @@ type subcommandData struct { // MultipartFuncName is the name of the function used to render a multipart // request encoder. MultipartFuncName string - // MultipartFuncName is the name of the variabl used to render a multipart + // MultipartFuncName is the name of the variable used to render a multipart // request encoder. MultipartVarName string // StreamFlag is the flag used to identify the file to be streamed when @@ -87,7 +87,7 @@ func buildSubcommandData(sd *ServiceData, e *EndpointData) *subcommandData { flags, buildFunction := buildFlags(sd, e) sub := &subcommandData{ - SubcommandData: cli.BuildSubcommandData(sd.Service.Name, e.Method, buildFunction, flags), + SubcommandData: cli.BuildSubcommandData(sd.Service, e.Method, buildFunction, flags), } if e.MultipartRequestEncoder != nil { sub.MultipartVarName = e.MultipartRequestEncoder.VarName diff --git a/http/codegen/templates/parse_endpoint.go.tpl b/http/codegen/templates/parse_endpoint.go.tpl index fc55279552..55ef173574 100644 --- a/http/codegen/templates/parse_endpoint.go.tpl +++ b/http/codegen/templates/parse_endpoint.go.tpl @@ -38,12 +38,11 @@ func ParseEndpoint( c := {{ .PkgName }}.NewClient(scheme, host, doer, enc, dec, restore{{ if .NeedStream }}, dialer, {{ .VarName }}Configurer{{ end }}) switch epn { {{- $pkgName := .PkgName }} - {{- $interceptors := .Interceptors }} {{- range .Subcommands }} case "{{ .Name }}": endpoint = c.{{ .MethodVarName }}({{ if .MultipartVarName }}{{ .MultipartVarName }}{{ end }}) - {{- if $interceptors }} - endpoint = {{ $interceptors.PkgName }}.Wrap{{ .MethodVarName }}ClientEndpoint(endpoint, {{ $interceptors.VarName }}) + {{- if .Interceptors }} + endpoint = {{ .Interceptors.PkgName }}.Wrap{{ .MethodVarName }}ClientEndpoint(endpoint, {{ .Interceptors.VarName }}) {{- end }} {{- if .BuildFunction }} data, err = {{ $pkgName }}.{{ .BuildFunction.Name }}({{ range .BuildFunction.ActualParams }}*{{ . }}Flag, {{ end }}) diff --git a/http/codegen/templates/websocket_recv.go.tpl b/http/codegen/templates/websocket_recv.go.tpl index ee9e732b72..f6c1a8067c 100644 --- a/http/codegen/templates/websocket_recv.go.tpl +++ b/http/codegen/templates/websocket_recv.go.tpl @@ -83,3 +83,8 @@ func (s *{{ .VarName }}) {{ .RecvName }}() ({{ .RecvTypeRef }}, error) { {{- end }} {{- end }} } + +{{ comment .RecvWithContextDesc }} +func (s *{{ .VarName }}) {{ .RecvWithContextName }}(ctx context.Context) ({{ .RecvTypeRef }}, error) { + return s.{{ .RecvName }}() +} diff --git a/http/codegen/templates/websocket_send.go.tpl b/http/codegen/templates/websocket_send.go.tpl index d47846bc95..11f2f02b22 100644 --- a/http/codegen/templates/websocket_send.go.tpl +++ b/http/codegen/templates/websocket_send.go.tpl @@ -52,3 +52,8 @@ func (s *{{ .VarName }}) {{ .SendName }}(v {{ .SendTypeRef }}) error { {{- end }} {{- end }} } + +{{ comment .SendWithContextDesc }} +func (s *{{ .VarName }}) {{ .SendWithContextName }}(ctx context.Context, v {{ .SendTypeRef }}) error { + return s.{{ .SendName }}(v) +} diff --git a/http/codegen/testdata/streaming_code.go b/http/codegen/testdata/streaming_code.go index e31536f882..8feb4abaa5 100644 --- a/http/codegen/testdata/streaming_code.go +++ b/http/codegen/testdata/streaming_code.go @@ -97,6 +97,12 @@ func (s *StreamingResultMethodServerStream) Send(v *streamingresultservice.UserT body := NewStreamingResultMethodResponseBody(res) return s.conn.WriteJSON(body) } + +// SendWithContext streams instances of "streamingresultservice.UserType" to +// the "StreamingResultMethod" endpoint websocket connection with context. +func (s *StreamingResultMethodServerStream) SendWithContext(ctx context.Context, v *streamingresultservice.UserType) error { + return s.Send(v) +} ` var StreamingResultServerStreamCloseCode = `// Close closes the "StreamingResultMethod" endpoint websocket connection. @@ -151,6 +157,13 @@ func (s *StreamingResultWithViewsMethodServerStream) Send(v *streamingresultwith } return s.conn.WriteJSON(body) } + +// SendWithContext streams instances of +// "streamingresultwithviewsservice.Usertype" to the +// "StreamingResultWithViewsMethod" endpoint websocket connection with context. +func (s *StreamingResultWithViewsMethodServerStream) SendWithContext(ctx context.Context, v *streamingresultwithviewsservice.Usertype) error { + return s.Send(v) +} ` var StreamingResultWithViewsServerStreamSetViewCode = `// SetView sets the view to render the streamingresultwithviewsservice.Usertype @@ -284,6 +297,12 @@ func (s *StreamingResultMethodClientStream) Recv() (*streamingresultservice.User res := NewStreamingResultMethodUserTypeOK(&body) return res, nil } + +// RecvWithContext reads instances of "streamingresultservice.UserType" from +// the "StreamingResultMethod" endpoint websocket connection with context. +func (s *StreamingResultMethodClientStream) RecvWithContext(ctx context.Context) (*streamingresultservice.UserType, error) { + return s.Recv() +} ` var StreamingResultWithViewsClientEndpointCode = `// StreamingResultWithViewsMethod returns an endpoint that makes HTTP requests @@ -350,6 +369,13 @@ func (s *StreamingResultWithViewsMethodClientStream) Recv() (*streamingresultwit } return streamingresultwithviewsservice.NewUsertype(vres), nil } + +// RecvWithContext reads instances of +// "streamingresultwithviewsservice.Usertype" from the +// "StreamingResultWithViewsMethod" endpoint websocket connection with context. +func (s *StreamingResultWithViewsMethodClientStream) RecvWithContext(ctx context.Context) (*streamingresultwithviewsservice.Usertype, error) { + return s.Recv() +} ` var StreamingResultWithViewsClientStreamSetViewCode = `// SetView sets the view to render the type before sending to the @@ -422,6 +448,14 @@ func (s *StreamingResultWithExplicitViewMethodClientStream) Recv() (*streamingre } return streamingresultwithexplicitviewservice.NewUsertype(vres), nil } + +// RecvWithContext reads instances of +// "streamingresultwithexplicitviewservice.Usertype" from the +// "StreamingResultWithExplicitViewMethod" endpoint websocket connection with +// context. +func (s *StreamingResultWithExplicitViewMethodClientStream) RecvWithContext(ctx context.Context) (*streamingresultwithexplicitviewservice.Usertype, error) { + return s.Recv() +} ` var StreamingResultWithExplicitViewServerStreamSendCode = `// Send streams instances of "streamingresultwithexplicitviewservice.Usertype" @@ -449,6 +483,14 @@ func (s *StreamingResultWithExplicitViewMethodServerStream) Send(v *streamingres body := NewStreamingResultWithExplicitViewMethodResponseBodyExtended(res.Projected) return s.conn.WriteJSON(body) } + +// SendWithContext streams instances of +// "streamingresultwithexplicitviewservice.Usertype" to the +// "StreamingResultWithExplicitViewMethod" endpoint websocket connection with +// context. +func (s *StreamingResultWithExplicitViewMethodServerStream) SendWithContext(ctx context.Context, v *streamingresultwithexplicitviewservice.Usertype) error { + return s.Send(v) +} ` var StreamingResultCollectionWithViewsServerStreamSendCode = `// Send streams instances of @@ -487,6 +529,14 @@ func (s *StreamingResultCollectionWithViewsMethodServerStream) Send(v streamingr } return s.conn.WriteJSON(body) } + +// SendWithContext streams instances of +// "streamingresultcollectionwithviewsservice.UsertypeCollection" to the +// "StreamingResultCollectionWithViewsMethod" endpoint websocket connection +// with context. +func (s *StreamingResultCollectionWithViewsMethodServerStream) SendWithContext(ctx context.Context, v streamingresultcollectionwithviewsservice.UsertypeCollection) error { + return s.Send(v) +} ` var StreamingResultCollectionWithViewsServerStreamSetViewCode = `// SetView sets the view to render the @@ -522,6 +572,14 @@ func (s *StreamingResultCollectionWithViewsMethodClientStream) Recv() (streaming } return streamingresultcollectionwithviewsservice.NewUsertypeCollection(vres), nil } + +// RecvWithContext reads instances of +// "streamingresultcollectionwithviewsservice.UsertypeCollection" from the +// "StreamingResultCollectionWithViewsMethod" endpoint websocket connection +// with context. +func (s *StreamingResultCollectionWithViewsMethodClientStream) RecvWithContext(ctx context.Context) (streamingresultcollectionwithviewsservice.UsertypeCollection, error) { + return s.Recv() +} ` var StreamingResultCollectionWithViewsClientStreamSetViewCode = `// SetView sets the view to render the type before sending to the @@ -558,8 +616,15 @@ func (s *StreamingResultCollectionWithExplicitViewMethodServerStream) Send(v str body := NewUsertypeResponseTinyCollection(res.Projected) return s.conn.WriteJSON(body) } -` +// SendWithContext streams instances of +// "streamingresultcollectionwithexplicitviewservice.UsertypeCollection" to the +// "StreamingResultCollectionWithExplicitViewMethod" endpoint websocket +// connection with context. +func (s *StreamingResultCollectionWithExplicitViewMethodServerStream) SendWithContext(ctx context.Context, v streamingresultcollectionwithexplicitviewservice.UsertypeCollection) error { + return s.Send(v) +} +` var StreamingResultCollectionWithExplicitViewClientEndpointCode = `// StreamingResultCollectionWithExplicitViewMethod returns an endpoint that // makes HTTP requests to the StreamingResultCollectionWithExplicitViewService // service StreamingResultCollectionWithExplicitViewMethod server. @@ -624,6 +689,14 @@ func (s *StreamingResultCollectionWithExplicitViewMethodClientStream) Recv() (st } return streamingresultcollectionwithexplicitviewservice.NewUsertypeCollection(vres), nil } + +// RecvWithContext reads instances of +// "streamingresultcollectionwithexplicitviewservice.UsertypeCollection" from +// the "StreamingResultCollectionWithExplicitViewMethod" endpoint websocket +// connection with context. +func (s *StreamingResultCollectionWithExplicitViewMethodClientStream) RecvWithContext(ctx context.Context) (streamingresultcollectionwithexplicitviewservice.UsertypeCollection, error) { + return s.Recv() +} ` var StreamingResultPrimitiveServerStreamSendCode = `// Send streams instances of "string" to the "StreamingResultPrimitiveMethod" @@ -650,6 +723,12 @@ func (s *StreamingResultPrimitiveMethodServerStream) Send(v string) error { res := v return s.conn.WriteJSON(res) } + +// SendWithContext streams instances of "string" to the +// "StreamingResultPrimitiveMethod" endpoint websocket connection with context. +func (s *StreamingResultPrimitiveMethodServerStream) SendWithContext(ctx context.Context, v string) error { + return s.Send(v) +} ` var StreamingResultPrimitiveClientStreamRecvCode = `// Recv reads instances of "string" from the "StreamingResultPrimitiveMethod" @@ -670,6 +749,12 @@ func (s *StreamingResultPrimitiveMethodClientStream) Recv() (string, error) { } return body, nil } + +// RecvWithContext reads instances of "string" from the +// "StreamingResultPrimitiveMethod" endpoint websocket connection with context. +func (s *StreamingResultPrimitiveMethodClientStream) RecvWithContext(ctx context.Context) (string, error) { + return s.Recv() +} ` var StreamingResultPrimitiveArrayServerStreamSendCode = `// Send streams instances of "[]int32" to the @@ -696,6 +781,13 @@ func (s *StreamingResultPrimitiveArrayMethodServerStream) Send(v []int32) error res := v return s.conn.WriteJSON(res) } + +// SendWithContext streams instances of "[]int32" to the +// "StreamingResultPrimitiveArrayMethod" endpoint websocket connection with +// context. +func (s *StreamingResultPrimitiveArrayMethodServerStream) SendWithContext(ctx context.Context, v []int32) error { + return s.Send(v) +} ` var StreamingResultPrimitiveArrayClientStreamRecvCode = `// Recv reads instances of "[]int32" from the @@ -716,6 +808,13 @@ func (s *StreamingResultPrimitiveArrayMethodClientStream) Recv() ([]int32, error } return body, nil } + +// RecvWithContext reads instances of "[]int32" from the +// "StreamingResultPrimitiveArrayMethod" endpoint websocket connection with +// context. +func (s *StreamingResultPrimitiveArrayMethodClientStream) RecvWithContext(ctx context.Context) ([]int32, error) { + return s.Recv() +} ` var StreamingResultPrimitiveMapServerStreamSendCode = `// Send streams instances of "map[int32]string" to the @@ -742,6 +841,13 @@ func (s *StreamingResultPrimitiveMapMethodServerStream) Send(v map[int32]string) res := v return s.conn.WriteJSON(res) } + +// SendWithContext streams instances of "map[int32]string" to the +// "StreamingResultPrimitiveMapMethod" endpoint websocket connection with +// context. +func (s *StreamingResultPrimitiveMapMethodServerStream) SendWithContext(ctx context.Context, v map[int32]string) error { + return s.Send(v) +} ` var StreamingResultPrimitiveMapClientStreamRecvCode = `// Recv reads instances of "map[int32]string" from the @@ -762,6 +868,13 @@ func (s *StreamingResultPrimitiveMapMethodClientStream) Recv() (map[int32]string } return body, nil } + +// RecvWithContext reads instances of "map[int32]string" from the +// "StreamingResultPrimitiveMapMethod" endpoint websocket connection with +// context. +func (s *StreamingResultPrimitiveMapMethodClientStream) RecvWithContext(ctx context.Context) (map[int32]string, error) { + return s.Recv() +} ` var StreamingResultUserTypeArrayServerStreamSendCode = `// Send streams instances of "[]*streamingresultusertypearrayservice.UserType" @@ -789,6 +902,14 @@ func (s *StreamingResultUserTypeArrayMethodServerStream) Send(v []*streamingresu body := NewStreamingResultUserTypeArrayMethodResponseBody(res) return s.conn.WriteJSON(body) } + +// SendWithContext streams instances of +// "[]*streamingresultusertypearrayservice.UserType" to the +// "StreamingResultUserTypeArrayMethod" endpoint websocket connection with +// context. +func (s *StreamingResultUserTypeArrayMethodServerStream) SendWithContext(ctx context.Context, v []*streamingresultusertypearrayservice.UserType) error { + return s.Send(v) +} ` var StreamingResultUserTypeArrayClientStreamRecvCode = `// Recv reads instances of "[]*streamingresultusertypearrayservice.UserType" @@ -810,6 +931,14 @@ func (s *StreamingResultUserTypeArrayMethodClientStream) Recv() ([]*streamingres res := NewStreamingResultUserTypeArrayMethodUserTypeOK(body) return res, nil } + +// RecvWithContext reads instances of +// "[]*streamingresultusertypearrayservice.UserType" from the +// "StreamingResultUserTypeArrayMethod" endpoint websocket connection with +// context. +func (s *StreamingResultUserTypeArrayMethodClientStream) RecvWithContext(ctx context.Context) ([]*streamingresultusertypearrayservice.UserType, error) { + return s.Recv() +} ` var StreamingResultUserTypeMapServerStreamSendCode = `// Send streams instances of @@ -838,6 +967,14 @@ func (s *StreamingResultUserTypeMapMethodServerStream) Send(v map[string]*stream body := NewStreamingResultUserTypeMapMethodResponseBody(res) return s.conn.WriteJSON(body) } + +// SendWithContext streams instances of +// "map[string]*streamingresultusertypemapservice.UserType" to the +// "StreamingResultUserTypeMapMethod" endpoint websocket connection with +// context. +func (s *StreamingResultUserTypeMapMethodServerStream) SendWithContext(ctx context.Context, v map[string]*streamingresultusertypemapservice.UserType) error { + return s.Send(v) +} ` var StreamingResultUserTypeMapClientStreamRecvCode = `// Recv reads instances of @@ -860,6 +997,14 @@ func (s *StreamingResultUserTypeMapMethodClientStream) Recv() (map[string]*strea res := NewStreamingResultUserTypeMapMethodMapStringUserTypeOK(body) return res, nil } + +// RecvWithContext reads instances of +// "map[string]*streamingresultusertypemapservice.UserType" from the +// "StreamingResultUserTypeMapMethod" endpoint websocket connection with +// context. +func (s *StreamingResultUserTypeMapMethodClientStream) RecvWithContext(ctx context.Context) (map[string]*streamingresultusertypemapservice.UserType, error) { + return s.Recv() +} ` var StreamingResultNoPayloadClientEndpointCode = `// StreamingResultNoPayloadMethod returns an endpoint that makes HTTP requests @@ -966,6 +1111,13 @@ func (s *StreamingPayloadMethodServerStream) SendAndClose(v *streamingpayloadser body := NewStreamingPayloadMethodResponseBody(res) return s.conn.WriteJSON(body) } + +// SendAndCloseWithContext streams instances of +// "streamingpayloadservice.UserType" to the "StreamingPayloadMethod" endpoint +// websocket connection with context and closes the connection. +func (s *StreamingPayloadMethodServerStream) SendAndCloseWithContext(ctx context.Context, v *streamingpayloadservice.UserType) error { + return s.SendAndClose(v) +} ` var StreamingPayloadServerStreamRecvCode = `// Recv reads instances of "streamingpayloadservice.Request" from the @@ -1001,6 +1153,12 @@ func (s *StreamingPayloadMethodServerStream) Recv() (*streamingpayloadservice.Re } return NewStreamingPayloadMethodStreamingBody(msg), nil } + +// RecvWithContext reads instances of "streamingpayloadservice.Request" from +// the "StreamingPayloadMethod" endpoint websocket connection with context. +func (s *StreamingPayloadMethodServerStream) RecvWithContext(ctx context.Context) (*streamingpayloadservice.Request, error) { + return s.Recv() +} ` var StreamingPayloadClientEndpointCode = `// StreamingPayloadMethod returns an endpoint that makes HTTP requests to the @@ -1041,6 +1199,12 @@ func (s *StreamingPayloadMethodClientStream) Send(v *streamingpayloadservice.Req body := NewStreamingPayloadMethodStreamingBody(v) return s.conn.WriteJSON(body) } + +// SendWithContext streams instances of "streamingpayloadservice.Request" to +// the "StreamingPayloadMethod" endpoint websocket connection with context. +func (s *StreamingPayloadMethodClientStream) SendWithContext(ctx context.Context, v *streamingpayloadservice.Request) error { + return s.Send(v) +} ` var StreamingPayloadClientStreamRecvCode = `// CloseAndRecv stops sending messages to the "StreamingPayloadMethod" endpoint @@ -1068,6 +1232,13 @@ func (s *StreamingPayloadMethodClientStream) CloseAndRecv() (*streamingpayloadse res := NewStreamingPayloadMethodUserTypeOK(&body) return res, nil } + +// CloseAndRecvWithContext stops sending messages to the +// "StreamingPayloadMethod" endpoint websocket connection and reads instances +// of "streamingpayloadservice.UserType" from the connection with context. +func (s *StreamingPayloadMethodClientStream) CloseAndRecvWithContext(ctx context.Context) (*streamingpayloadservice.UserType, error) { + return s.CloseAndRecv() +} ` var StreamingPayloadNoPayloadServerHandlerInitCode = `// NewStreamingPayloadNoPayloadMethodHandler creates a HTTP handler which loads @@ -1152,6 +1323,13 @@ func (s *StreamingPayloadNoPayloadMethodClientStream) Send(v *streamingpayloadno body := NewStreamingPayloadNoPayloadMethodStreamingBody(v) return s.conn.WriteJSON(body) } + +// SendWithContext streams instances of +// "streamingpayloadnopayloadservice.Request" to the +// "StreamingPayloadNoPayloadMethod" endpoint websocket connection with context. +func (s *StreamingPayloadNoPayloadMethodClientStream) SendWithContext(ctx context.Context, v *streamingpayloadnopayloadservice.Request) error { + return s.Send(v) +} ` var StreamingPayloadNoPayloadClientStreamRecvCode = `// CloseAndRecv stops sending messages to the "StreamingPayloadNoPayloadMethod" @@ -1179,6 +1357,14 @@ func (s *StreamingPayloadNoPayloadMethodClientStream) CloseAndRecv() (*streaming res := NewStreamingPayloadNoPayloadMethodUserTypeOK(&body) return res, nil } + +// CloseAndRecvWithContext stops sending messages to the +// "StreamingPayloadNoPayloadMethod" endpoint websocket connection and reads +// instances of "streamingpayloadnopayloadservice.UserType" from the connection +// with context. +func (s *StreamingPayloadNoPayloadMethodClientStream) CloseAndRecvWithContext(ctx context.Context) (*streamingpayloadnopayloadservice.UserType, error) { + return s.CloseAndRecv() +} ` var StreamingPayloadNoResultServerStreamRecvCode = `// Recv reads instances of "string" from the "StreamingPayloadNoResultMethod" @@ -1214,6 +1400,12 @@ func (s *StreamingPayloadNoResultMethodServerStream) Recv() (string, error) { } return *msg, nil } + +// RecvWithContext reads instances of "string" from the +// "StreamingPayloadNoResultMethod" endpoint websocket connection with context. +func (s *StreamingPayloadNoResultMethodServerStream) RecvWithContext(ctx context.Context) (string, error) { + return s.Recv() +} ` var StreamingPayloadNoResultServerStreamCloseCode = `// Close closes the "StreamingPayloadNoResultMethod" endpoint websocket @@ -1239,6 +1431,12 @@ var StreamingPayloadNoResultClientStreamSendCode = `// Send streams instances of func (s *StreamingPayloadNoResultMethodClientStream) Send(v string) error { return s.conn.WriteJSON(v) } + +// SendWithContext streams instances of "string" to the +// "StreamingPayloadNoResultMethod" endpoint websocket connection with context. +func (s *StreamingPayloadNoResultMethodClientStream) SendWithContext(ctx context.Context, v string) error { + return s.Send(v) +} ` var StreamingPayloadNoResultClientStreamCloseCode = `// Close closes the "StreamingPayloadNoResultMethod" endpoint websocket @@ -1271,6 +1469,14 @@ func (s *StreamingPayloadResultWithViewsMethodServerStream) SendAndClose(v *stre } return s.conn.WriteJSON(body) } + +// SendAndCloseWithContext streams instances of +// "streamingpayloadresultwithviewsservice.Usertype" to the +// "StreamingPayloadResultWithViewsMethod" endpoint websocket connection with +// context and closes the connection. +func (s *StreamingPayloadResultWithViewsMethodServerStream) SendAndCloseWithContext(ctx context.Context, v *streamingpayloadresultwithviewsservice.Usertype) error { + return s.SendAndClose(v) +} ` var StreamingPayloadResultWithViewsServerStreamRecvCode = `// Recv reads instances of "float32" from the @@ -1306,6 +1512,13 @@ func (s *StreamingPayloadResultWithViewsMethodServerStream) Recv() (float32, err } return *msg, nil } + +// RecvWithContext reads instances of "float32" from the +// "StreamingPayloadResultWithViewsMethod" endpoint websocket connection with +// context. +func (s *StreamingPayloadResultWithViewsMethodServerStream) RecvWithContext(ctx context.Context) (float32, error) { + return s.Recv() +} ` var StreamingPayloadResultWithViewsServerStreamSetViewCode = `// SetView sets the view to render the @@ -1321,6 +1534,13 @@ var StreamingPayloadResultWithViewsClientStreamSendCode = `// Send streams insta func (s *StreamingPayloadResultWithViewsMethodClientStream) Send(v float32) error { return s.conn.WriteJSON(v) } + +// SendWithContext streams instances of "float32" to the +// "StreamingPayloadResultWithViewsMethod" endpoint websocket connection with +// context. +func (s *StreamingPayloadResultWithViewsMethodClientStream) SendWithContext(ctx context.Context, v float32) error { + return s.Send(v) +} ` var StreamingPayloadResultWithViewsClientStreamRecvCode = `// CloseAndRecv stops sending messages to the @@ -1353,6 +1573,14 @@ func (s *StreamingPayloadResultWithViewsMethodClientStream) CloseAndRecv() (*str } return streamingpayloadresultwithviewsservice.NewUsertype(vres), nil } + +// CloseAndRecvWithContext stops sending messages to the +// "StreamingPayloadResultWithViewsMethod" endpoint websocket connection and +// reads instances of "streamingpayloadresultwithviewsservice.Usertype" from +// the connection with context. +func (s *StreamingPayloadResultWithViewsMethodClientStream) CloseAndRecvWithContext(ctx context.Context) (*streamingpayloadresultwithviewsservice.Usertype, error) { + return s.CloseAndRecv() +} ` var StreamingPayloadResultWithViewsClientStreamSetViewCode = `// SetView sets the view to render the float32 type before sending to the @@ -1372,6 +1600,14 @@ func (s *StreamingPayloadResultWithExplicitViewMethodServerStream) SendAndClose( body := NewStreamingPayloadResultWithExplicitViewMethodResponseBodyExtended(res.Projected) return s.conn.WriteJSON(body) } + +// SendAndCloseWithContext streams instances of +// "streamingpayloadresultwithexplicitviewservice.Usertype" to the +// "StreamingPayloadResultWithExplicitViewMethod" endpoint websocket connection +// with context and closes the connection. +func (s *StreamingPayloadResultWithExplicitViewMethodServerStream) SendAndCloseWithContext(ctx context.Context, v *streamingpayloadresultwithexplicitviewservice.Usertype) error { + return s.SendAndClose(v) +} ` var StreamingPayloadResultWithExplicitViewServerStreamRecvCode = `// Recv reads instances of "float32" from the @@ -1407,6 +1643,13 @@ func (s *StreamingPayloadResultWithExplicitViewMethodServerStream) Recv() (float } return *msg, nil } + +// RecvWithContext reads instances of "float32" from the +// "StreamingPayloadResultWithExplicitViewMethod" endpoint websocket connection +// with context. +func (s *StreamingPayloadResultWithExplicitViewMethodServerStream) RecvWithContext(ctx context.Context) (float32, error) { + return s.Recv() +} ` var StreamingPayloadResultWithExplicitViewClientStreamSendCode = `// Send streams instances of "float32" to the @@ -1414,6 +1657,13 @@ var StreamingPayloadResultWithExplicitViewClientStreamSendCode = `// Send stream func (s *StreamingPayloadResultWithExplicitViewMethodClientStream) Send(v float32) error { return s.conn.WriteJSON(v) } + +// SendWithContext streams instances of "float32" to the +// "StreamingPayloadResultWithExplicitViewMethod" endpoint websocket connection +// with context. +func (s *StreamingPayloadResultWithExplicitViewMethodClientStream) SendWithContext(ctx context.Context, v float32) error { + return s.Send(v) +} ` var StreamingPayloadResultWithExplicitViewClientStreamRecvCode = `// CloseAndRecv stops sending messages to the @@ -1446,6 +1696,15 @@ func (s *StreamingPayloadResultWithExplicitViewMethodClientStream) CloseAndRecv( } return streamingpayloadresultwithexplicitviewservice.NewUsertype(vres), nil } + +// CloseAndRecvWithContext stops sending messages to the +// "StreamingPayloadResultWithExplicitViewMethod" endpoint websocket connection +// and reads instances of +// "streamingpayloadresultwithexplicitviewservice.Usertype" from the connection +// with context. +func (s *StreamingPayloadResultWithExplicitViewMethodClientStream) CloseAndRecvWithContext(ctx context.Context) (*streamingpayloadresultwithexplicitviewservice.Usertype, error) { + return s.CloseAndRecv() +} ` var StreamingPayloadResultCollectionWithViewsServerStreamSendCode = `// SendAndClose streams instances of @@ -1466,6 +1725,14 @@ func (s *StreamingPayloadResultCollectionWithViewsMethodServerStream) SendAndClo } return s.conn.WriteJSON(body) } + +// SendAndCloseWithContext streams instances of +// "streamingpayloadresultcollectionwithviewsservice.UsertypeCollection" to the +// "StreamingPayloadResultCollectionWithViewsMethod" endpoint websocket +// connection with context and closes the connection. +func (s *StreamingPayloadResultCollectionWithViewsMethodServerStream) SendAndCloseWithContext(ctx context.Context, v streamingpayloadresultcollectionwithviewsservice.UsertypeCollection) error { + return s.SendAndClose(v) +} ` var StreamingPayloadResultCollectionWithViewsServerStreamRecvCode = `// Recv reads instances of "any" from the @@ -1502,6 +1769,13 @@ func (s *StreamingPayloadResultCollectionWithViewsMethodServerStream) Recv() (an } return *msg, nil } + +// RecvWithContext reads instances of "any" from the +// "StreamingPayloadResultCollectionWithViewsMethod" endpoint websocket +// connection with context. +func (s *StreamingPayloadResultCollectionWithViewsMethodServerStream) RecvWithContext(ctx context.Context) (any, error) { + return s.Recv() +} ` var StreamingPayloadResultCollectionWithViewsServerStreamSetViewCode = `// SetView sets the view to render the @@ -1519,6 +1793,13 @@ var StreamingPayloadResultCollectionWithViewsClientStreamSendCode = `// Send str func (s *StreamingPayloadResultCollectionWithViewsMethodClientStream) Send(v any) error { return s.conn.WriteJSON(v) } + +// SendWithContext streams instances of "any" to the +// "StreamingPayloadResultCollectionWithViewsMethod" endpoint websocket +// connection with context. +func (s *StreamingPayloadResultCollectionWithViewsMethodClientStream) SendWithContext(ctx context.Context, v any) error { + return s.Send(v) +} ` var StreamingPayloadResultCollectionWithViewsClientStreamRecvCode = `// CloseAndRecv stops sending messages to the @@ -1552,6 +1833,15 @@ func (s *StreamingPayloadResultCollectionWithViewsMethodClientStream) CloseAndRe } return streamingpayloadresultcollectionwithviewsservice.NewUsertypeCollection(vres), nil } + +// CloseAndRecvWithContext stops sending messages to the +// "StreamingPayloadResultCollectionWithViewsMethod" endpoint websocket +// connection and reads instances of +// "streamingpayloadresultcollectionwithviewsservice.UsertypeCollection" from +// the connection with context. +func (s *StreamingPayloadResultCollectionWithViewsMethodClientStream) CloseAndRecvWithContext(ctx context.Context) (streamingpayloadresultcollectionwithviewsservice.UsertypeCollection, error) { + return s.CloseAndRecv() +} ` var StreamingPayloadResultCollectionWithViewsClientStreamSetViewCode = `// SetView sets the view to render the any type before sending to the @@ -1572,6 +1862,14 @@ func (s *StreamingPayloadResultCollectionWithExplicitViewMethodServerStream) Sen body := NewUsertypeResponseTinyCollection(res.Projected) return s.conn.WriteJSON(body) } + +// SendAndCloseWithContext streams instances of +// "streamingpayloadresultcollectionwithexplicitviewservice.UsertypeCollection" +// to the "StreamingPayloadResultCollectionWithExplicitViewMethod" endpoint +// websocket connection with context and closes the connection. +func (s *StreamingPayloadResultCollectionWithExplicitViewMethodServerStream) SendAndCloseWithContext(ctx context.Context, v streamingpayloadresultcollectionwithexplicitviewservice.UsertypeCollection) error { + return s.SendAndClose(v) +} ` var StreamingPayloadResultCollectionWithExplicitViewServerStreamRecvCode = `// Recv reads instances of "any" from the @@ -1608,6 +1906,13 @@ func (s *StreamingPayloadResultCollectionWithExplicitViewMethodServerStream) Rec } return *msg, nil } + +// RecvWithContext reads instances of "any" from the +// "StreamingPayloadResultCollectionWithExplicitViewMethod" endpoint websocket +// connection with context. +func (s *StreamingPayloadResultCollectionWithExplicitViewMethodServerStream) RecvWithContext(ctx context.Context) (any, error) { + return s.Recv() +} ` var StreamingPayloadResultCollectionWithExplicitViewClientStreamSendCode = `// Send streams instances of "any" to the @@ -1616,6 +1921,13 @@ var StreamingPayloadResultCollectionWithExplicitViewClientStreamSendCode = `// S func (s *StreamingPayloadResultCollectionWithExplicitViewMethodClientStream) Send(v any) error { return s.conn.WriteJSON(v) } + +// SendWithContext streams instances of "any" to the +// "StreamingPayloadResultCollectionWithExplicitViewMethod" endpoint websocket +// connection with context. +func (s *StreamingPayloadResultCollectionWithExplicitViewMethodClientStream) SendWithContext(ctx context.Context, v any) error { + return s.Send(v) +} ` var StreamingPayloadResultCollectionWithExplicitViewClientStreamRecvCode = `// CloseAndRecv stops sending messages to the @@ -1649,6 +1961,15 @@ func (s *StreamingPayloadResultCollectionWithExplicitViewMethodClientStream) Clo } return streamingpayloadresultcollectionwithexplicitviewservice.NewUsertypeCollection(vres), nil } + +// CloseAndRecvWithContext stops sending messages to the +// "StreamingPayloadResultCollectionWithExplicitViewMethod" endpoint websocket +// connection and reads instances of +// "streamingpayloadresultcollectionwithexplicitviewservice.UsertypeCollection" +// from the connection with context. +func (s *StreamingPayloadResultCollectionWithExplicitViewMethodClientStream) CloseAndRecvWithContext(ctx context.Context) (streamingpayloadresultcollectionwithexplicitviewservice.UsertypeCollection, error) { + return s.CloseAndRecv() +} ` var StreamingPayloadPrimitiveServerStreamSendCode = `// SendAndClose streams instances of "string" to the @@ -1659,6 +1980,13 @@ func (s *StreamingPayloadPrimitiveMethodServerStream) SendAndClose(v string) err res := v return s.conn.WriteJSON(res) } + +// SendAndCloseWithContext streams instances of "string" to the +// "StreamingPayloadPrimitiveMethod" endpoint websocket connection with context +// and closes the connection. +func (s *StreamingPayloadPrimitiveMethodServerStream) SendAndCloseWithContext(ctx context.Context, v string) error { + return s.SendAndClose(v) +} ` var StreamingPayloadPrimitiveServerStreamRecvCode = `// Recv reads instances of "string" from the "StreamingPayloadPrimitiveMethod" @@ -1694,6 +2022,12 @@ func (s *StreamingPayloadPrimitiveMethodServerStream) Recv() (string, error) { } return *msg, nil } + +// RecvWithContext reads instances of "string" from the +// "StreamingPayloadPrimitiveMethod" endpoint websocket connection with context. +func (s *StreamingPayloadPrimitiveMethodServerStream) RecvWithContext(ctx context.Context) (string, error) { + return s.Recv() +} ` var StreamingPayloadPrimitiveClientStreamSendCode = `// Send streams instances of "string" to the "StreamingPayloadPrimitiveMethod" @@ -1701,6 +2035,12 @@ var StreamingPayloadPrimitiveClientStreamSendCode = `// Send streams instances o func (s *StreamingPayloadPrimitiveMethodClientStream) Send(v string) error { return s.conn.WriteJSON(v) } + +// SendWithContext streams instances of "string" to the +// "StreamingPayloadPrimitiveMethod" endpoint websocket connection with context. +func (s *StreamingPayloadPrimitiveMethodClientStream) SendWithContext(ctx context.Context, v string) error { + return s.Send(v) +} ` var StreamingPayloadPrimitiveClientStreamRecvCode = `// CloseAndRecv stops sending messages to the "StreamingPayloadPrimitiveMethod" @@ -1727,6 +2067,13 @@ func (s *StreamingPayloadPrimitiveMethodClientStream) CloseAndRecv() (string, er } return body, nil } + +// CloseAndRecvWithContext stops sending messages to the +// "StreamingPayloadPrimitiveMethod" endpoint websocket connection and reads +// instances of "string" from the connection with context. +func (s *StreamingPayloadPrimitiveMethodClientStream) CloseAndRecvWithContext(ctx context.Context) (string, error) { + return s.CloseAndRecv() +} ` var StreamingPayloadPrimitiveArrayServerStreamSendCode = `// SendAndClose streams instances of "[]string" to the @@ -1737,6 +2084,13 @@ func (s *StreamingPayloadPrimitiveArrayMethodServerStream) SendAndClose(v []stri res := v return s.conn.WriteJSON(res) } + +// SendAndCloseWithContext streams instances of "[]string" to the +// "StreamingPayloadPrimitiveArrayMethod" endpoint websocket connection with +// context and closes the connection. +func (s *StreamingPayloadPrimitiveArrayMethodServerStream) SendAndCloseWithContext(ctx context.Context, v []string) error { + return s.SendAndClose(v) +} ` var StreamingPayloadPrimitiveArrayServerStreamRecvCode = `// Recv reads instances of "[]int32" from the @@ -1772,6 +2126,13 @@ func (s *StreamingPayloadPrimitiveArrayMethodServerStream) Recv() ([]int32, erro } return body, nil } + +// RecvWithContext reads instances of "[]int32" from the +// "StreamingPayloadPrimitiveArrayMethod" endpoint websocket connection with +// context. +func (s *StreamingPayloadPrimitiveArrayMethodServerStream) RecvWithContext(ctx context.Context) ([]int32, error) { + return s.Recv() +} ` var StreamingPayloadPrimitiveArrayClientStreamSendCode = `// Send streams instances of "[]int32" to the @@ -1779,6 +2140,13 @@ var StreamingPayloadPrimitiveArrayClientStreamSendCode = `// Send streams instan func (s *StreamingPayloadPrimitiveArrayMethodClientStream) Send(v []int32) error { return s.conn.WriteJSON(v) } + +// SendWithContext streams instances of "[]int32" to the +// "StreamingPayloadPrimitiveArrayMethod" endpoint websocket connection with +// context. +func (s *StreamingPayloadPrimitiveArrayMethodClientStream) SendWithContext(ctx context.Context, v []int32) error { + return s.Send(v) +} ` var StreamingPayloadPrimitiveArrayClientStreamRecvCode = `// CloseAndRecv stops sending messages to the @@ -1805,6 +2173,13 @@ func (s *StreamingPayloadPrimitiveArrayMethodClientStream) CloseAndRecv() ([]str } return body, nil } + +// CloseAndRecvWithContext stops sending messages to the +// "StreamingPayloadPrimitiveArrayMethod" endpoint websocket connection and +// reads instances of "[]string" from the connection with context. +func (s *StreamingPayloadPrimitiveArrayMethodClientStream) CloseAndRecvWithContext(ctx context.Context) ([]string, error) { + return s.CloseAndRecv() +} ` var StreamingPayloadPrimitiveMapServerStreamSendCode = `// SendAndClose streams instances of "map[int]int" to the @@ -1815,6 +2190,13 @@ func (s *StreamingPayloadPrimitiveMapMethodServerStream) SendAndClose(v map[int] res := v return s.conn.WriteJSON(res) } + +// SendAndCloseWithContext streams instances of "map[int]int" to the +// "StreamingPayloadPrimitiveMapMethod" endpoint websocket connection with +// context and closes the connection. +func (s *StreamingPayloadPrimitiveMapMethodServerStream) SendAndCloseWithContext(ctx context.Context, v map[int]int) error { + return s.SendAndClose(v) +} ` var StreamingPayloadPrimitiveMapServerStreamRecvCode = `// Recv reads instances of "map[string]int32" from the @@ -1850,6 +2232,13 @@ func (s *StreamingPayloadPrimitiveMapMethodServerStream) Recv() (map[string]int3 } return body, nil } + +// RecvWithContext reads instances of "map[string]int32" from the +// "StreamingPayloadPrimitiveMapMethod" endpoint websocket connection with +// context. +func (s *StreamingPayloadPrimitiveMapMethodServerStream) RecvWithContext(ctx context.Context) (map[string]int32, error) { + return s.Recv() +} ` var StreamingPayloadPrimitiveMapClientStreamSendCode = `// Send streams instances of "map[string]int32" to the @@ -1857,6 +2246,13 @@ var StreamingPayloadPrimitiveMapClientStreamSendCode = `// Send streams instance func (s *StreamingPayloadPrimitiveMapMethodClientStream) Send(v map[string]int32) error { return s.conn.WriteJSON(v) } + +// SendWithContext streams instances of "map[string]int32" to the +// "StreamingPayloadPrimitiveMapMethod" endpoint websocket connection with +// context. +func (s *StreamingPayloadPrimitiveMapMethodClientStream) SendWithContext(ctx context.Context, v map[string]int32) error { + return s.Send(v) +} ` var StreamingPayloadPrimitiveMapClientStreamRecvCode = `// CloseAndRecv stops sending messages to the @@ -1883,6 +2279,13 @@ func (s *StreamingPayloadPrimitiveMapMethodClientStream) CloseAndRecv() (map[int } return body, nil } + +// CloseAndRecvWithContext stops sending messages to the +// "StreamingPayloadPrimitiveMapMethod" endpoint websocket connection and reads +// instances of "map[int]int" from the connection with context. +func (s *StreamingPayloadPrimitiveMapMethodClientStream) CloseAndRecvWithContext(ctx context.Context) (map[int]int, error) { + return s.CloseAndRecv() +} ` var StreamingPayloadUserTypeArrayServerStreamSendCode = `// SendAndClose streams instances of "string" to the @@ -1893,6 +2296,13 @@ func (s *StreamingPayloadUserTypeArrayMethodServerStream) SendAndClose(v string) res := v return s.conn.WriteJSON(res) } + +// SendAndCloseWithContext streams instances of "string" to the +// "StreamingPayloadUserTypeArrayMethod" endpoint websocket connection with +// context and closes the connection. +func (s *StreamingPayloadUserTypeArrayMethodServerStream) SendAndCloseWithContext(ctx context.Context, v string) error { + return s.SendAndClose(v) +} ` var StreamingPayloadUserTypeArrayServerStreamRecvCode = `// Recv reads instances of @@ -1929,6 +2339,14 @@ func (s *StreamingPayloadUserTypeArrayMethodServerStream) Recv() ([]*streamingpa } return NewStreamingPayloadUserTypeArrayMethodArray(body), nil } + +// RecvWithContext reads instances of +// "[]*streamingpayloadusertypearrayservice.RequestType" from the +// "StreamingPayloadUserTypeArrayMethod" endpoint websocket connection with +// context. +func (s *StreamingPayloadUserTypeArrayMethodServerStream) RecvWithContext(ctx context.Context) ([]*streamingpayloadusertypearrayservice.RequestType, error) { + return s.Recv() +} ` var StreamingPayloadUserTypeArrayClientStreamSendCode = `// Send streams instances of @@ -1938,6 +2356,14 @@ func (s *StreamingPayloadUserTypeArrayMethodClientStream) Send(v []*streamingpay body := NewRequestType(v) return s.conn.WriteJSON(body) } + +// SendWithContext streams instances of +// "[]*streamingpayloadusertypearrayservice.RequestType" to the +// "StreamingPayloadUserTypeArrayMethod" endpoint websocket connection with +// context. +func (s *StreamingPayloadUserTypeArrayMethodClientStream) SendWithContext(ctx context.Context, v []*streamingpayloadusertypearrayservice.RequestType) error { + return s.Send(v) +} ` var StreamingPayloadUserTypeArrayClientStreamRecvCode = `// CloseAndRecv stops sending messages to the @@ -1964,6 +2390,13 @@ func (s *StreamingPayloadUserTypeArrayMethodClientStream) CloseAndRecv() (string } return body, nil } + +// CloseAndRecvWithContext stops sending messages to the +// "StreamingPayloadUserTypeArrayMethod" endpoint websocket connection and +// reads instances of "string" from the connection with context. +func (s *StreamingPayloadUserTypeArrayMethodClientStream) CloseAndRecvWithContext(ctx context.Context) (string, error) { + return s.CloseAndRecv() +} ` var StreamingPayloadUserTypeMapServerStreamSendCode = `// SendAndClose streams instances of "[]string" to the @@ -1974,6 +2407,13 @@ func (s *StreamingPayloadUserTypeMapMethodServerStream) SendAndClose(v []string) res := v return s.conn.WriteJSON(res) } + +// SendAndCloseWithContext streams instances of "[]string" to the +// "StreamingPayloadUserTypeMapMethod" endpoint websocket connection with +// context and closes the connection. +func (s *StreamingPayloadUserTypeMapMethodServerStream) SendAndCloseWithContext(ctx context.Context, v []string) error { + return s.SendAndClose(v) +} ` var StreamingPayloadUserTypeMapServerStreamRecvCode = `// Recv reads instances of @@ -2010,6 +2450,14 @@ func (s *StreamingPayloadUserTypeMapMethodServerStream) Recv() (map[string]*stre } return NewStreamingPayloadUserTypeMapMethodMap(body), nil } + +// RecvWithContext reads instances of +// "map[string]*streamingpayloadusertypemapservice.RequestType" from the +// "StreamingPayloadUserTypeMapMethod" endpoint websocket connection with +// context. +func (s *StreamingPayloadUserTypeMapMethodServerStream) RecvWithContext(ctx context.Context) (map[string]*streamingpayloadusertypemapservice.RequestType, error) { + return s.Recv() +} ` var StreamingPayloadUserTypeMapClientStreamSendCode = `// Send streams instances of @@ -2019,6 +2467,14 @@ func (s *StreamingPayloadUserTypeMapMethodClientStream) Send(v map[string]*strea body := NewMapStringRequestType(v) return s.conn.WriteJSON(body) } + +// SendWithContext streams instances of +// "map[string]*streamingpayloadusertypemapservice.RequestType" to the +// "StreamingPayloadUserTypeMapMethod" endpoint websocket connection with +// context. +func (s *StreamingPayloadUserTypeMapMethodClientStream) SendWithContext(ctx context.Context, v map[string]*streamingpayloadusertypemapservice.RequestType) error { + return s.Send(v) +} ` var StreamingPayloadUserTypeMapClientStreamRecvCode = `// CloseAndRecv stops sending messages to the @@ -2045,6 +2501,13 @@ func (s *StreamingPayloadUserTypeMapMethodClientStream) CloseAndRecv() ([]string } return body, nil } + +// CloseAndRecvWithContext stops sending messages to the +// "StreamingPayloadUserTypeMapMethod" endpoint websocket connection and reads +// instances of "[]string" from the connection with context. +func (s *StreamingPayloadUserTypeMapMethodClientStream) CloseAndRecvWithContext(ctx context.Context) ([]string, error) { + return s.CloseAndRecv() +} ` var BidirectionalStreamingServerHandlerInitCode = `// NewBidirectionalStreamingMethodHandler creates a HTTP handler which loads @@ -2128,6 +2591,13 @@ func (s *BidirectionalStreamingMethodServerStream) Send(v *bidirectionalstreamin body := NewBidirectionalStreamingMethodResponseBody(res) return s.conn.WriteJSON(body) } + +// SendWithContext streams instances of +// "bidirectionalstreamingservice.UserType" to the +// "BidirectionalStreamingMethod" endpoint websocket connection with context. +func (s *BidirectionalStreamingMethodServerStream) SendWithContext(ctx context.Context, v *bidirectionalstreamingservice.UserType) error { + return s.Send(v) +} ` var BidirectionalStreamingServerStreamRecvCode = `// Recv reads instances of "bidirectionalstreamingservice.Request" from the @@ -2163,6 +2633,13 @@ func (s *BidirectionalStreamingMethodServerStream) Recv() (*bidirectionalstreami } return NewBidirectionalStreamingMethodStreamingBody(msg), nil } + +// RecvWithContext reads instances of "bidirectionalstreamingservice.Request" +// from the "BidirectionalStreamingMethod" endpoint websocket connection with +// context. +func (s *BidirectionalStreamingMethodServerStream) RecvWithContext(ctx context.Context) (*bidirectionalstreamingservice.Request, error) { + return s.Recv() +} ` var BidirectionalStreamingServerStreamCloseCode = `// Close closes the "BidirectionalStreamingMethod" endpoint websocket @@ -2222,6 +2699,13 @@ func (s *BidirectionalStreamingMethodClientStream) Send(v *bidirectionalstreamin body := NewBidirectionalStreamingMethodStreamingBody(v) return s.conn.WriteJSON(body) } + +// SendWithContext streams instances of "bidirectionalstreamingservice.Request" +// to the "BidirectionalStreamingMethod" endpoint websocket connection with +// context. +func (s *BidirectionalStreamingMethodClientStream) SendWithContext(ctx context.Context, v *bidirectionalstreamingservice.Request) error { + return s.Send(v) +} ` var BidirectionalStreamingClientStreamRecvCode = `// Recv reads instances of "bidirectionalstreamingservice.UserType" from the @@ -2242,6 +2726,13 @@ func (s *BidirectionalStreamingMethodClientStream) Recv() (*bidirectionalstreami res := NewBidirectionalStreamingMethodUserTypeOK(&body) return res, nil } + +// RecvWithContext reads instances of "bidirectionalstreamingservice.UserType" +// from the "BidirectionalStreamingMethod" endpoint websocket connection with +// context. +func (s *BidirectionalStreamingMethodClientStream) RecvWithContext(ctx context.Context) (*bidirectionalstreamingservice.UserType, error) { + return s.Recv() +} ` var BidirectionalStreamingClientStreamCloseCode = `// Close closes the "BidirectionalStreamingMethod" endpoint websocket @@ -2357,6 +2848,14 @@ func (s *BidirectionalStreamingNoPayloadMethodClientStream) Send(v *bidirectiona body := NewBidirectionalStreamingNoPayloadMethodStreamingBody(v) return s.conn.WriteJSON(body) } + +// SendWithContext streams instances of +// "bidirectionalstreamingnopayloadservice.Request" to the +// "BidirectionalStreamingNoPayloadMethod" endpoint websocket connection with +// context. +func (s *BidirectionalStreamingNoPayloadMethodClientStream) SendWithContext(ctx context.Context, v *bidirectionalstreamingnopayloadservice.Request) error { + return s.Send(v) +} ` var BidirectionalStreamingNoPayloadClientStreamRecvCode = `// Recv reads instances of "bidirectionalstreamingnopayloadservice.UserType" @@ -2378,6 +2877,14 @@ func (s *BidirectionalStreamingNoPayloadMethodClientStream) Recv() (*bidirection res := NewBidirectionalStreamingNoPayloadMethodUserTypeOK(&body) return res, nil } + +// RecvWithContext reads instances of +// "bidirectionalstreamingnopayloadservice.UserType" from the +// "BidirectionalStreamingNoPayloadMethod" endpoint websocket connection with +// context. +func (s *BidirectionalStreamingNoPayloadMethodClientStream) RecvWithContext(ctx context.Context) (*bidirectionalstreamingnopayloadservice.UserType, error) { + return s.Recv() +} ` var BidirectionalStreamingNoPayloadClientStreamCloseCode = `// Close closes the "BidirectionalStreamingNoPayloadMethod" endpoint websocket @@ -2428,6 +2935,14 @@ func (s *BidirectionalStreamingResultWithViewsMethodServerStream) Send(v *bidire } return s.conn.WriteJSON(body) } + +// SendWithContext streams instances of +// "bidirectionalstreamingresultwithviewsservice.Usertype" to the +// "BidirectionalStreamingResultWithViewsMethod" endpoint websocket connection +// with context. +func (s *BidirectionalStreamingResultWithViewsMethodServerStream) SendWithContext(ctx context.Context, v *bidirectionalstreamingresultwithviewsservice.Usertype) error { + return s.Send(v) +} ` var BidirectionalStreamingResultWithViewsServerStreamRecvCode = `// Recv reads instances of "float32" from the @@ -2463,6 +2978,13 @@ func (s *BidirectionalStreamingResultWithViewsMethodServerStream) Recv() (float3 } return *msg, nil } + +// RecvWithContext reads instances of "float32" from the +// "BidirectionalStreamingResultWithViewsMethod" endpoint websocket connection +// with context. +func (s *BidirectionalStreamingResultWithViewsMethodServerStream) RecvWithContext(ctx context.Context) (float32, error) { + return s.Recv() +} ` var BidirectionalStreamingResultWithViewsServerStreamCloseCode = `// Close closes the "BidirectionalStreamingResultWithViewsMethod" endpoint @@ -2497,6 +3019,13 @@ var BidirectionalStreamingResultWithViewsClientStreamSendCode = `// Send streams func (s *BidirectionalStreamingResultWithViewsMethodClientStream) Send(v float32) error { return s.conn.WriteJSON(v) } + +// SendWithContext streams instances of "float32" to the +// "BidirectionalStreamingResultWithViewsMethod" endpoint websocket connection +// with context. +func (s *BidirectionalStreamingResultWithViewsMethodClientStream) SendWithContext(ctx context.Context, v float32) error { + return s.Send(v) +} ` var BidirectionalStreamingResultWithViewsClientStreamRecvCode = `// Recv reads instances of @@ -2522,6 +3051,14 @@ func (s *BidirectionalStreamingResultWithViewsMethodClientStream) Recv() (*bidir } return bidirectionalstreamingresultwithviewsservice.NewUsertype(vres), nil } + +// RecvWithContext reads instances of +// "bidirectionalstreamingresultwithviewsservice.Usertype" from the +// "BidirectionalStreamingResultWithViewsMethod" endpoint websocket connection +// with context. +func (s *BidirectionalStreamingResultWithViewsMethodClientStream) RecvWithContext(ctx context.Context) (*bidirectionalstreamingresultwithviewsservice.Usertype, error) { + return s.Recv() +} ` var BidirectionalStreamingResultWithViewsClientStreamCloseCode = `// Close closes the "BidirectionalStreamingResultWithViewsMethod" endpoint @@ -2570,6 +3107,14 @@ func (s *BidirectionalStreamingResultWithExplicitViewMethodServerStream) Send(v body := NewBidirectionalStreamingResultWithExplicitViewMethodResponseBodyExtended(res.Projected) return s.conn.WriteJSON(body) } + +// SendWithContext streams instances of +// "bidirectionalstreamingresultwithexplicitviewservice.Usertype" to the +// "BidirectionalStreamingResultWithExplicitViewMethod" endpoint websocket +// connection with context. +func (s *BidirectionalStreamingResultWithExplicitViewMethodServerStream) SendWithContext(ctx context.Context, v *bidirectionalstreamingresultwithexplicitviewservice.Usertype) error { + return s.Send(v) +} ` var BidirectionalStreamingResultWithExplicitViewServerStreamRecvCode = `// Recv reads instances of "float32" from the @@ -2606,6 +3151,13 @@ func (s *BidirectionalStreamingResultWithExplicitViewMethodServerStream) Recv() } return *msg, nil } + +// RecvWithContext reads instances of "float32" from the +// "BidirectionalStreamingResultWithExplicitViewMethod" endpoint websocket +// connection with context. +func (s *BidirectionalStreamingResultWithExplicitViewMethodServerStream) RecvWithContext(ctx context.Context) (float32, error) { + return s.Recv() +} ` var BidirectionalStreamingResultWithExplicitViewClientStreamSendCode = `// Send streams instances of "float32" to the @@ -2614,6 +3166,13 @@ var BidirectionalStreamingResultWithExplicitViewClientStreamSendCode = `// Send func (s *BidirectionalStreamingResultWithExplicitViewMethodClientStream) Send(v float32) error { return s.conn.WriteJSON(v) } + +// SendWithContext streams instances of "float32" to the +// "BidirectionalStreamingResultWithExplicitViewMethod" endpoint websocket +// connection with context. +func (s *BidirectionalStreamingResultWithExplicitViewMethodClientStream) SendWithContext(ctx context.Context, v float32) error { + return s.Send(v) +} ` var BidirectionalStreamingResultWithExplicitViewClientStreamRecvCode = `// Recv reads instances of @@ -2640,6 +3199,14 @@ func (s *BidirectionalStreamingResultWithExplicitViewMethodClientStream) Recv() } return bidirectionalstreamingresultwithexplicitviewservice.NewUsertype(vres), nil } + +// RecvWithContext reads instances of +// "bidirectionalstreamingresultwithexplicitviewservice.Usertype" from the +// "BidirectionalStreamingResultWithExplicitViewMethod" endpoint websocket +// connection with context. +func (s *BidirectionalStreamingResultWithExplicitViewMethodClientStream) RecvWithContext(ctx context.Context) (*bidirectionalstreamingresultwithexplicitviewservice.Usertype, error) { + return s.Recv() +} ` var BidirectionalStreamingResultCollectionWithViewsServerStreamSendCode = `// Send streams instances of @@ -2679,6 +3246,14 @@ func (s *BidirectionalStreamingResultCollectionWithViewsMethodServerStream) Send } return s.conn.WriteJSON(body) } + +// SendWithContext streams instances of +// "bidirectionalstreamingresultcollectionwithviewsservice.UsertypeCollection" +// to the "BidirectionalStreamingResultCollectionWithViewsMethod" endpoint +// websocket connection with context. +func (s *BidirectionalStreamingResultCollectionWithViewsMethodServerStream) SendWithContext(ctx context.Context, v bidirectionalstreamingresultcollectionwithviewsservice.UsertypeCollection) error { + return s.Send(v) +} ` var BidirectionalStreamingResultCollectionWithViewsServerStreamRecvCode = `// Recv reads instances of "any" from the @@ -2715,6 +3290,13 @@ func (s *BidirectionalStreamingResultCollectionWithViewsMethodServerStream) Recv } return *msg, nil } + +// RecvWithContext reads instances of "any" from the +// "BidirectionalStreamingResultCollectionWithViewsMethod" endpoint websocket +// connection with context. +func (s *BidirectionalStreamingResultCollectionWithViewsMethodServerStream) RecvWithContext(ctx context.Context) (any, error) { + return s.Recv() +} ` var BidirectionalStreamingResultCollectionWithViewsServerStreamSetViewCode = `// SetView sets the view to render the @@ -2733,6 +3315,13 @@ var BidirectionalStreamingResultCollectionWithViewsClientStreamSendCode = `// Se func (s *BidirectionalStreamingResultCollectionWithViewsMethodClientStream) Send(v any) error { return s.conn.WriteJSON(v) } + +// SendWithContext streams instances of "any" to the +// "BidirectionalStreamingResultCollectionWithViewsMethod" endpoint websocket +// connection with context. +func (s *BidirectionalStreamingResultCollectionWithViewsMethodClientStream) SendWithContext(ctx context.Context, v any) error { + return s.Send(v) +} ` var BidirectionalStreamingResultCollectionWithViewsClientStreamRecvCode = `// Recv reads instances of @@ -2759,6 +3348,14 @@ func (s *BidirectionalStreamingResultCollectionWithViewsMethodClientStream) Recv } return bidirectionalstreamingresultcollectionwithviewsservice.NewUsertypeCollection(vres), nil } + +// RecvWithContext reads instances of +// "bidirectionalstreamingresultcollectionwithviewsservice.UsertypeCollection" +// from the "BidirectionalStreamingResultCollectionWithViewsMethod" endpoint +// websocket connection with context. +func (s *BidirectionalStreamingResultCollectionWithViewsMethodClientStream) RecvWithContext(ctx context.Context) (bidirectionalstreamingresultcollectionwithviewsservice.UsertypeCollection, error) { + return s.Recv() +} ` var BidirectionalStreamingResultCollectionWithViewsClientStreamSetViewCode = `// SetView sets the view to render the any type before sending to the @@ -2796,6 +3393,14 @@ func (s *BidirectionalStreamingResultCollectionWithExplicitViewMethodServerStrea body := NewUsertypeResponseTinyCollection(res.Projected) return s.conn.WriteJSON(body) } + +// SendWithContext streams instances of +// "bidirectionalstreamingresultcollectionwithexplicitviewservice.UsertypeCollection" +// to the "BidirectionalStreamingResultCollectionWithExplicitViewMethod" +// endpoint websocket connection with context. +func (s *BidirectionalStreamingResultCollectionWithExplicitViewMethodServerStream) SendWithContext(ctx context.Context, v bidirectionalstreamingresultcollectionwithexplicitviewservice.UsertypeCollection) error { + return s.Send(v) +} ` var BidirectionalStreamingResultCollectionWithExplicitViewServerStreamRecvCode = `// Recv reads instances of "any" from the @@ -2832,6 +3437,13 @@ func (s *BidirectionalStreamingResultCollectionWithExplicitViewMethodServerStrea } return *msg, nil } + +// RecvWithContext reads instances of "any" from the +// "BidirectionalStreamingResultCollectionWithExplicitViewMethod" endpoint +// websocket connection with context. +func (s *BidirectionalStreamingResultCollectionWithExplicitViewMethodServerStream) RecvWithContext(ctx context.Context) (any, error) { + return s.Recv() +} ` var BidirectionalStreamingResultCollectionWithExplicitViewClientStreamSendCode = `// Send streams instances of "any" to the @@ -2840,6 +3452,13 @@ var BidirectionalStreamingResultCollectionWithExplicitViewClientStreamSendCode = func (s *BidirectionalStreamingResultCollectionWithExplicitViewMethodClientStream) Send(v any) error { return s.conn.WriteJSON(v) } + +// SendWithContext streams instances of "any" to the +// "BidirectionalStreamingResultCollectionWithExplicitViewMethod" endpoint +// websocket connection with context. +func (s *BidirectionalStreamingResultCollectionWithExplicitViewMethodClientStream) SendWithContext(ctx context.Context, v any) error { + return s.Send(v) +} ` var BidirectionalStreamingResultCollectionWithExplicitViewClientStreamRecvCode = `// Recv reads instances of @@ -2866,6 +3485,14 @@ func (s *BidirectionalStreamingResultCollectionWithExplicitViewMethodClientStrea } return bidirectionalstreamingresultcollectionwithexplicitviewservice.NewUsertypeCollection(vres), nil } + +// RecvWithContext reads instances of +// "bidirectionalstreamingresultcollectionwithexplicitviewservice.UsertypeCollection" +// from the "BidirectionalStreamingResultCollectionWithExplicitViewMethod" +// endpoint websocket connection with context. +func (s *BidirectionalStreamingResultCollectionWithExplicitViewMethodClientStream) RecvWithContext(ctx context.Context) (bidirectionalstreamingresultcollectionwithexplicitviewservice.UsertypeCollection, error) { + return s.Recv() +} ` var BidirectionalStreamingPrimitiveServerStreamSendCode = `// Send streams instances of "string" to the @@ -2892,6 +3519,13 @@ func (s *BidirectionalStreamingPrimitiveMethodServerStream) Send(v string) error res := v return s.conn.WriteJSON(res) } + +// SendWithContext streams instances of "string" to the +// "BidirectionalStreamingPrimitiveMethod" endpoint websocket connection with +// context. +func (s *BidirectionalStreamingPrimitiveMethodServerStream) SendWithContext(ctx context.Context, v string) error { + return s.Send(v) +} ` var BidirectionalStreamingPrimitiveServerStreamRecvCode = `// Recv reads instances of "string" from the @@ -2927,6 +3561,13 @@ func (s *BidirectionalStreamingPrimitiveMethodServerStream) Recv() (string, erro } return *msg, nil } + +// RecvWithContext reads instances of "string" from the +// "BidirectionalStreamingPrimitiveMethod" endpoint websocket connection with +// context. +func (s *BidirectionalStreamingPrimitiveMethodServerStream) RecvWithContext(ctx context.Context) (string, error) { + return s.Recv() +} ` var BidirectionalStreamingPrimitiveClientStreamSendCode = `// Send streams instances of "string" to the @@ -2934,6 +3575,13 @@ var BidirectionalStreamingPrimitiveClientStreamSendCode = `// Send streams insta func (s *BidirectionalStreamingPrimitiveMethodClientStream) Send(v string) error { return s.conn.WriteJSON(v) } + +// SendWithContext streams instances of "string" to the +// "BidirectionalStreamingPrimitiveMethod" endpoint websocket connection with +// context. +func (s *BidirectionalStreamingPrimitiveMethodClientStream) SendWithContext(ctx context.Context, v string) error { + return s.Send(v) +} ` var BidirectionalStreamingPrimitiveClientStreamRecvCode = `// Recv reads instances of "string" from the @@ -2953,6 +3601,13 @@ func (s *BidirectionalStreamingPrimitiveMethodClientStream) Recv() (string, erro } return body, nil } + +// RecvWithContext reads instances of "string" from the +// "BidirectionalStreamingPrimitiveMethod" endpoint websocket connection with +// context. +func (s *BidirectionalStreamingPrimitiveMethodClientStream) RecvWithContext(ctx context.Context) (string, error) { + return s.Recv() +} ` var BidirectionalStreamingPrimitiveArrayServerStreamSendCode = `// Send streams instances of "[]string" to the @@ -2979,6 +3634,13 @@ func (s *BidirectionalStreamingPrimitiveArrayMethodServerStream) Send(v []string res := v return s.conn.WriteJSON(res) } + +// SendWithContext streams instances of "[]string" to the +// "BidirectionalStreamingPrimitiveArrayMethod" endpoint websocket connection +// with context. +func (s *BidirectionalStreamingPrimitiveArrayMethodServerStream) SendWithContext(ctx context.Context, v []string) error { + return s.Send(v) +} ` var BidirectionalStreamingPrimitiveArrayServerStreamRecvCode = `// Recv reads instances of "[]int32" from the @@ -3014,6 +3676,13 @@ func (s *BidirectionalStreamingPrimitiveArrayMethodServerStream) Recv() ([]int32 } return body, nil } + +// RecvWithContext reads instances of "[]int32" from the +// "BidirectionalStreamingPrimitiveArrayMethod" endpoint websocket connection +// with context. +func (s *BidirectionalStreamingPrimitiveArrayMethodServerStream) RecvWithContext(ctx context.Context) ([]int32, error) { + return s.Recv() +} ` var BidirectionalStreamingPrimitiveArrayClientStreamSendCode = `// Send streams instances of "[]int32" to the @@ -3021,6 +3690,13 @@ var BidirectionalStreamingPrimitiveArrayClientStreamSendCode = `// Send streams func (s *BidirectionalStreamingPrimitiveArrayMethodClientStream) Send(v []int32) error { return s.conn.WriteJSON(v) } + +// SendWithContext streams instances of "[]int32" to the +// "BidirectionalStreamingPrimitiveArrayMethod" endpoint websocket connection +// with context. +func (s *BidirectionalStreamingPrimitiveArrayMethodClientStream) SendWithContext(ctx context.Context, v []int32) error { + return s.Send(v) +} ` var BidirectionalStreamingPrimitiveArrayClientStreamRecvCode = `// Recv reads instances of "[]string" from the @@ -3040,6 +3716,13 @@ func (s *BidirectionalStreamingPrimitiveArrayMethodClientStream) Recv() ([]strin } return body, nil } + +// RecvWithContext reads instances of "[]string" from the +// "BidirectionalStreamingPrimitiveArrayMethod" endpoint websocket connection +// with context. +func (s *BidirectionalStreamingPrimitiveArrayMethodClientStream) RecvWithContext(ctx context.Context) ([]string, error) { + return s.Recv() +} ` var BidirectionalStreamingPrimitiveMapServerStreamSendCode = `// Send streams instances of "map[int]int" to the @@ -3066,6 +3749,13 @@ func (s *BidirectionalStreamingPrimitiveMapMethodServerStream) Send(v map[int]in res := v return s.conn.WriteJSON(res) } + +// SendWithContext streams instances of "map[int]int" to the +// "BidirectionalStreamingPrimitiveMapMethod" endpoint websocket connection +// with context. +func (s *BidirectionalStreamingPrimitiveMapMethodServerStream) SendWithContext(ctx context.Context, v map[int]int) error { + return s.Send(v) +} ` var BidirectionalStreamingPrimitiveMapServerStreamRecvCode = `// Recv reads instances of "map[string]int32" from the @@ -3101,6 +3791,13 @@ func (s *BidirectionalStreamingPrimitiveMapMethodServerStream) Recv() (map[strin } return body, nil } + +// RecvWithContext reads instances of "map[string]int32" from the +// "BidirectionalStreamingPrimitiveMapMethod" endpoint websocket connection +// with context. +func (s *BidirectionalStreamingPrimitiveMapMethodServerStream) RecvWithContext(ctx context.Context) (map[string]int32, error) { + return s.Recv() +} ` var BidirectionalStreamingPrimitiveMapClientStreamSendCode = `// Send streams instances of "map[string]int32" to the @@ -3108,6 +3805,13 @@ var BidirectionalStreamingPrimitiveMapClientStreamSendCode = `// Send streams in func (s *BidirectionalStreamingPrimitiveMapMethodClientStream) Send(v map[string]int32) error { return s.conn.WriteJSON(v) } + +// SendWithContext streams instances of "map[string]int32" to the +// "BidirectionalStreamingPrimitiveMapMethod" endpoint websocket connection +// with context. +func (s *BidirectionalStreamingPrimitiveMapMethodClientStream) SendWithContext(ctx context.Context, v map[string]int32) error { + return s.Send(v) +} ` var BidirectionalStreamingPrimitiveMapClientStreamRecvCode = `// Recv reads instances of "map[int]int" from the @@ -3127,6 +3831,13 @@ func (s *BidirectionalStreamingPrimitiveMapMethodClientStream) Recv() (map[int]i } return body, nil } + +// RecvWithContext reads instances of "map[int]int" from the +// "BidirectionalStreamingPrimitiveMapMethod" endpoint websocket connection +// with context. +func (s *BidirectionalStreamingPrimitiveMapMethodClientStream) RecvWithContext(ctx context.Context) (map[int]int, error) { + return s.Recv() +} ` var BidirectionalStreamingUserTypeArrayServerStreamSendCode = `// Send streams instances of @@ -3155,6 +3866,14 @@ func (s *BidirectionalStreamingUserTypeArrayMethodServerStream) Send(v []*bidire body := NewBidirectionalStreamingUserTypeArrayMethodResponseBody(res) return s.conn.WriteJSON(body) } + +// SendWithContext streams instances of +// "[]*bidirectionalstreamingusertypearrayservice.ResultType" to the +// "BidirectionalStreamingUserTypeArrayMethod" endpoint websocket connection +// with context. +func (s *BidirectionalStreamingUserTypeArrayMethodServerStream) SendWithContext(ctx context.Context, v []*bidirectionalstreamingusertypearrayservice.ResultType) error { + return s.Send(v) +} ` var BidirectionalStreamingUserTypeArrayServerStreamRecvCode = `// Recv reads instances of @@ -3191,6 +3910,14 @@ func (s *BidirectionalStreamingUserTypeArrayMethodServerStream) Recv() ([]*bidir } return NewBidirectionalStreamingUserTypeArrayMethodArray(body), nil } + +// RecvWithContext reads instances of +// "[]*bidirectionalstreamingusertypearrayservice.RequestType" from the +// "BidirectionalStreamingUserTypeArrayMethod" endpoint websocket connection +// with context. +func (s *BidirectionalStreamingUserTypeArrayMethodServerStream) RecvWithContext(ctx context.Context) ([]*bidirectionalstreamingusertypearrayservice.RequestType, error) { + return s.Recv() +} ` var BidirectionalStreamingUserTypeArrayClientStreamSendCode = `// Send streams instances of @@ -3200,6 +3927,14 @@ func (s *BidirectionalStreamingUserTypeArrayMethodClientStream) Send(v []*bidire body := NewRequestType(v) return s.conn.WriteJSON(body) } + +// SendWithContext streams instances of +// "[]*bidirectionalstreamingusertypearrayservice.RequestType" to the +// "BidirectionalStreamingUserTypeArrayMethod" endpoint websocket connection +// with context. +func (s *BidirectionalStreamingUserTypeArrayMethodClientStream) SendWithContext(ctx context.Context, v []*bidirectionalstreamingusertypearrayservice.RequestType) error { + return s.Send(v) +} ` var BidirectionalStreamingUserTypeArrayClientStreamRecvCode = `// Recv reads instances of @@ -3221,6 +3956,14 @@ func (s *BidirectionalStreamingUserTypeArrayMethodClientStream) Recv() ([]*bidir res := NewBidirectionalStreamingUserTypeArrayMethodResultTypeOK(body) return res, nil } + +// RecvWithContext reads instances of +// "[]*bidirectionalstreamingusertypearrayservice.ResultType" from the +// "BidirectionalStreamingUserTypeArrayMethod" endpoint websocket connection +// with context. +func (s *BidirectionalStreamingUserTypeArrayMethodClientStream) RecvWithContext(ctx context.Context) ([]*bidirectionalstreamingusertypearrayservice.ResultType, error) { + return s.Recv() +} ` var BidirectionalStreamingUserTypeMapServerStreamSendCode = `// Send streams instances of @@ -3249,6 +3992,14 @@ func (s *BidirectionalStreamingUserTypeMapMethodServerStream) Send(v map[string] body := NewBidirectionalStreamingUserTypeMapMethodResponseBody(res) return s.conn.WriteJSON(body) } + +// SendWithContext streams instances of +// "map[string]*bidirectionalstreamingusertypemapservice.ResultType" to the +// "BidirectionalStreamingUserTypeMapMethod" endpoint websocket connection with +// context. +func (s *BidirectionalStreamingUserTypeMapMethodServerStream) SendWithContext(ctx context.Context, v map[string]*bidirectionalstreamingusertypemapservice.ResultType) error { + return s.Send(v) +} ` var BidirectionalStreamingUserTypeMapServerStreamRecvCode = `// Recv reads instances of @@ -3285,6 +4036,14 @@ func (s *BidirectionalStreamingUserTypeMapMethodServerStream) Recv() (map[string } return NewBidirectionalStreamingUserTypeMapMethodMap(body), nil } + +// RecvWithContext reads instances of +// "map[string]*bidirectionalstreamingusertypemapservice.RequestType" from the +// "BidirectionalStreamingUserTypeMapMethod" endpoint websocket connection with +// context. +func (s *BidirectionalStreamingUserTypeMapMethodServerStream) RecvWithContext(ctx context.Context) (map[string]*bidirectionalstreamingusertypemapservice.RequestType, error) { + return s.Recv() +} ` var BidirectionalStreamingUserTypeMapClientStreamSendCode = `// Send streams instances of @@ -3294,6 +4053,14 @@ func (s *BidirectionalStreamingUserTypeMapMethodClientStream) Send(v map[string] body := NewMapStringRequestType(v) return s.conn.WriteJSON(body) } + +// SendWithContext streams instances of +// "map[string]*bidirectionalstreamingusertypemapservice.RequestType" to the +// "BidirectionalStreamingUserTypeMapMethod" endpoint websocket connection with +// context. +func (s *BidirectionalStreamingUserTypeMapMethodClientStream) SendWithContext(ctx context.Context, v map[string]*bidirectionalstreamingusertypemapservice.RequestType) error { + return s.Send(v) +} ` var BidirectionalStreamingUserTypeMapClientStreamRecvCode = `// Recv reads instances of @@ -3315,4 +4082,12 @@ func (s *BidirectionalStreamingUserTypeMapMethodClientStream) Recv() (map[string res := NewBidirectionalStreamingUserTypeMapMethodMapStringResultTypeOK(body) return res, nil } + +// RecvWithContext reads instances of +// "map[string]*bidirectionalstreamingusertypemapservice.ResultType" from the +// "BidirectionalStreamingUserTypeMapMethod" endpoint websocket connection with +// context. +func (s *BidirectionalStreamingUserTypeMapMethodClientStream) RecvWithContext(ctx context.Context) (map[string]*bidirectionalstreamingusertypemapservice.ResultType, error) { + return s.Recv() +} ` diff --git a/http/codegen/websocket.go b/http/codegen/websocket.go index 1b62af8787..b0df17604a 100644 --- a/http/codegen/websocket.go +++ b/http/codegen/websocket.go @@ -32,6 +32,10 @@ type ( SendName string // SendDesc is the description for the send function. SendDesc string + // SendWithContextName is the name of the send function with context. + SendWithContextName string + // SendWithContextDesc is the description for the send function with context. + SendWithContextDesc string // SendTypeName is the fully qualified type name sent through // the stream. SendTypeName string @@ -42,6 +46,10 @@ type ( RecvName string // RecvDesc is the description for the recv function. RecvDesc string + // RecvWithContextName is the name of the receive function with context. + RecvWithContextName string + // RecvWithContextDesc is the description for the recv function with context. + RecvWithContextDesc string // RecvTypeName is the fully qualified type name received from // the stream. RecvTypeName string @@ -67,25 +75,24 @@ type ( // initWebSocketData initializes the WebSocket related data in ed. func initWebSocketData(ed *EndpointData, e *expr.HTTPEndpointExpr, sd *ServiceData) { var ( - svrSendTypeName string - svrSendTypeRef string - svrRecvTypeName string - svrRecvTypeRef string - svrSendDesc string - svrRecvDesc string - svrPayload *TypeData - cliSendDesc string - cliRecvDesc string - cliPayload *TypeData - - md = ed.Method - svc = sd.Service - svcctx = serviceContext(sd.Service.PkgName, sd.Service.Scope) + svrRecvTypeName string + svrRecvTypeRef string + svrRecvDesc string + svrRecvWithContextDesc string + svrPayload *TypeData + cliSendDesc string + cliSendWithContextDesc string + cliPayload *TypeData ) - svrSendTypeName = ed.Result.Name - svrSendTypeRef = ed.Result.Ref - svrSendDesc = fmt.Sprintf("%s streams instances of %q to the %q endpoint websocket connection.", md.ServerStream.SendName, svrSendTypeName, md.Name) - cliRecvDesc = fmt.Sprintf("%s reads instances of %q from the %q endpoint websocket connection.", md.ClientStream.RecvName, svrSendTypeName, md.Name) + md := ed.Method + svc := sd.Service + svcctx := serviceContext(sd.Service.PkgName, sd.Service.Scope) + svrSendTypeName := ed.Result.Name + svrSendTypeRef := ed.Result.Ref + svrSendDesc := fmt.Sprintf("%s streams instances of %q to the %q endpoint websocket connection.", md.ServerStream.SendName, svrSendTypeName, md.Name) + svrSendWithContextDesc := fmt.Sprintf("%s streams instances of %q to the %q endpoint websocket connection with context.", md.ServerStream.SendWithContextName, svrSendTypeName, md.Name) + cliRecvDesc := fmt.Sprintf("%s reads instances of %q from the %q endpoint websocket connection.", md.ClientStream.RecvName, svrSendTypeName, md.Name) + cliRecvWithContextDesc := fmt.Sprintf("%s reads instances of %q from the %q endpoint websocket connection with context.", md.ClientStream.RecvWithContextName, svrSendTypeName, md.Name) if e.MethodExpr.Stream == expr.ClientStreamKind || e.MethodExpr.Stream == expr.BidirectionalStreamKind { svrRecvTypeName = sd.Scope.GoFullTypeName(e.MethodExpr.StreamingPayload, svc.PkgName) svrRecvTypeRef = sd.Scope.GoFullTypeRef(e.MethodExpr.StreamingPayload, svc.PkgName) @@ -102,58 +109,53 @@ func initWebSocketData(ed *EndpointData, e *expr.HTTPEndpointExpr, sd *ServiceDa serverCode string err error ) - { - n := codegen.Goify(e.MethodExpr.Name, true) - p := codegen.Goify(svrPayload.Name, true) - // Raw payload object has type name prefixed with endpoint name. No need to - // prefix the type name again. - if strings.HasPrefix(p, n) { - name = fmt.Sprintf("New%s", p) - } else { - name = fmt.Sprintf("New%s%s", n, p) - } - desc = fmt.Sprintf("%s builds a %s service %s endpoint payload.", name, svc.Name, e.MethodExpr.Name) - if body != expr.Empty { - var ( - ref string - svcode string - ) - ref = "body" - if expr.IsObject(body) { - ref = "&body" - } - if ut, ok := body.(expr.UserType); ok { - if val := ut.Attribute().Validation; val != nil { - httpctx := httpContext("", sd.Scope, true, true) - svcode = codegen.ValidationCode(ut.Attribute(), ut, httpctx, true, expr.IsAlias(ut), false, "body") - } - } - serverArgs = []*InitArgData{{ - Ref: ref, - AttributeData: &AttributeData{ - Name: "payload", - VarName: "body", - TypeName: sd.Scope.GoTypeName(e.StreamingBody), - TypeRef: sd.Scope.GoTypeRef(e.StreamingBody), - Type: e.StreamingBody.Type, - Required: true, - Example: e.Body.Example(expr.Root.API.ExampleGenerator), - Validate: svcode, - }, - }} + n := codegen.Goify(e.MethodExpr.Name, true) + p := codegen.Goify(svrPayload.Name, true) + // Raw payload object has type name prefixed with endpoint name. No need to + // prefix the type name again. + if strings.HasPrefix(p, n) { + name = fmt.Sprintf("New%s", p) + } else { + name = fmt.Sprintf("New%s%s", n, p) + } + desc = fmt.Sprintf("%s builds a %s service %s endpoint payload.", name, svc.Name, e.MethodExpr.Name) + if body != expr.Empty { + ref := "body" + if expr.IsObject(body) { + ref = "&body" } - if body != expr.Empty { - var helpers []*codegen.TransformFunctionData - httpctx := httpContext("", sd.Scope, true, true) - serverCode, helpers, err = marshal(e.StreamingBody, e.MethodExpr.StreamingPayload, "body", "v", httpctx, svcctx) - if err == nil { - sd.ServerTransformHelpers = codegen.AppendHelpers(sd.ServerTransformHelpers, helpers) + var svcode string + if ut, ok := body.(expr.UserType); ok { + if val := ut.Attribute().Validation; val != nil { + httpctx := httpContext("", sd.Scope, true, true) + svcode = codegen.ValidationCode(ut.Attribute(), ut, httpctx, true, expr.IsAlias(ut), false, "body") } } - if err != nil { - fmt.Println(err.Error()) // TBD validate DSL so errors are not possible + serverArgs = []*InitArgData{{ + Ref: ref, + AttributeData: &AttributeData{ + Name: "payload", + VarName: "body", + TypeName: sd.Scope.GoTypeName(e.StreamingBody), + TypeRef: sd.Scope.GoTypeRef(e.StreamingBody), + Type: e.StreamingBody.Type, + Required: true, + Example: e.Body.Example(expr.Root.API.ExampleGenerator), + Validate: svcode, + }, + }} + } + if body != expr.Empty { + var helpers []*codegen.TransformFunctionData + httpctx := httpContext("", sd.Scope, true, true) + serverCode, helpers, err = marshal(e.StreamingBody, e.MethodExpr.StreamingPayload, "body", "v", httpctx, svcctx) + if err == nil { + sd.ServerTransformHelpers = codegen.AppendHelpers(sd.ServerTransformHelpers, helpers) } } + if err != nil { + fmt.Println(err.Error()) // TBD validate DSL so errors are not possible + } svrPayload.Init = &InitData{ Name: name, Description: desc, @@ -172,49 +174,61 @@ func initWebSocketData(ed *EndpointData, e *expr.HTTPEndpointExpr, sd *ServiceDa } if e.MethodExpr.Stream == expr.ClientStreamKind { svrSendDesc = fmt.Sprintf("%s streams instances of %q to the %q endpoint websocket connection and closes the connection.", md.ServerStream.SendName, svrSendTypeName, md.Name) + svrSendWithContextDesc = fmt.Sprintf("%s streams instances of %q to the %q endpoint websocket connection with context and closes the connection.", md.ServerStream.SendWithContextName, svrSendTypeName, md.Name) cliRecvDesc = fmt.Sprintf("%s stops sending messages to the %q endpoint websocket connection and reads instances of %q from the connection.", md.ClientStream.RecvName, md.Name, svrSendTypeName) + cliRecvWithContextDesc = fmt.Sprintf("%s stops sending messages to the %q endpoint websocket connection and reads instances of %q from the connection with context.", md.ClientStream.RecvWithContextName, md.Name, svrSendTypeName) } svrRecvDesc = fmt.Sprintf("%s reads instances of %q from the %q endpoint websocket connection.", md.ServerStream.RecvName, svrRecvTypeName, md.Name) + svrRecvWithContextDesc = fmt.Sprintf("%s reads instances of %q from the %q endpoint websocket connection with context.", md.ServerStream.RecvWithContextName, svrRecvTypeName, md.Name) cliSendDesc = fmt.Sprintf("%s streams instances of %q to the %q endpoint websocket connection.", md.ClientStream.SendName, svrRecvTypeName, md.Name) + cliSendWithContextDesc = fmt.Sprintf("%s streams instances of %q to the %q endpoint websocket connection with context.", md.ClientStream.SendWithContextName, svrRecvTypeName, md.Name) } ed.ServerWebSocket = &WebSocketData{ - VarName: md.ServerStream.VarName, - Interface: fmt.Sprintf("%s.%s", svc.PkgName, md.ServerStream.Interface), - Endpoint: ed, - Payload: svrPayload, - Response: ed.Result.Responses[0], - PkgName: svc.PkgName, - Type: "server", - Kind: md.ServerStream.Kind, - SendName: md.ServerStream.SendName, - SendDesc: svrSendDesc, - SendTypeName: svrSendTypeName, - SendTypeRef: svrSendTypeRef, - RecvName: md.ServerStream.RecvName, - RecvDesc: svrRecvDesc, - RecvTypeName: svrRecvTypeName, - RecvTypeRef: svrRecvTypeRef, - RecvTypeIsPointer: expr.IsArray(e.MethodExpr.StreamingPayload.Type) || expr.IsMap(e.MethodExpr.StreamingPayload.Type), - MustClose: md.ServerStream.MustClose, + VarName: md.ServerStream.VarName, + Interface: fmt.Sprintf("%s.%s", svc.PkgName, md.ServerStream.Interface), + Endpoint: ed, + Payload: svrPayload, + Response: ed.Result.Responses[0], + PkgName: svc.PkgName, + Type: "server", + Kind: md.ServerStream.Kind, + SendName: md.ServerStream.SendName, + SendDesc: svrSendDesc, + SendWithContextName: md.ServerStream.SendWithContextName, + SendWithContextDesc: svrSendWithContextDesc, + SendTypeName: svrSendTypeName, + SendTypeRef: svrSendTypeRef, + RecvName: md.ServerStream.RecvName, + RecvDesc: svrRecvDesc, + RecvWithContextName: md.ServerStream.RecvWithContextName, + RecvWithContextDesc: svrRecvWithContextDesc, + RecvTypeName: svrRecvTypeName, + RecvTypeRef: svrRecvTypeRef, + RecvTypeIsPointer: expr.IsArray(e.MethodExpr.StreamingPayload.Type) || expr.IsMap(e.MethodExpr.StreamingPayload.Type), + MustClose: md.ServerStream.MustClose, } ed.ClientWebSocket = &WebSocketData{ - VarName: md.ClientStream.VarName, - Interface: fmt.Sprintf("%s.%s", svc.PkgName, md.ClientStream.Interface), - Endpoint: ed, - Payload: cliPayload, - Response: ed.Result.Responses[0], - PkgName: svc.PkgName, - Type: "client", - Kind: md.ClientStream.Kind, - SendName: md.ClientStream.SendName, - SendDesc: cliSendDesc, - SendTypeName: svrRecvTypeName, - SendTypeRef: svrRecvTypeRef, - RecvName: md.ClientStream.RecvName, - RecvDesc: cliRecvDesc, - RecvTypeName: svrSendTypeName, - RecvTypeRef: svrSendTypeRef, - MustClose: md.ClientStream.MustClose, + VarName: md.ClientStream.VarName, + Interface: fmt.Sprintf("%s.%s", svc.PkgName, md.ClientStream.Interface), + Endpoint: ed, + Payload: cliPayload, + Response: ed.Result.Responses[0], + PkgName: svc.PkgName, + Type: "client", + Kind: md.ClientStream.Kind, + SendName: md.ClientStream.SendName, + SendDesc: cliSendDesc, + SendWithContextName: md.ClientStream.SendWithContextName, + SendWithContextDesc: cliSendWithContextDesc, + SendTypeName: svrRecvTypeName, + SendTypeRef: svrRecvTypeRef, + RecvName: md.ClientStream.RecvName, + RecvDesc: cliRecvDesc, + RecvWithContextName: md.ClientStream.RecvWithContextName, + RecvWithContextDesc: cliRecvWithContextDesc, + RecvTypeName: svrSendTypeName, + RecvTypeRef: svrSendTypeRef, + MustClose: md.ClientStream.MustClose, } } diff --git a/pkg/interceptor.go b/pkg/interceptor.go index c784f14b88..1c3abd1313 100644 --- a/pkg/interceptor.go +++ b/pkg/interceptor.go @@ -3,15 +3,28 @@ package goa type ( // InterceptorInfo contains information about the request shared between // all interceptors in the service chain. It provides access to the service name, - // method name, endpoint function, and request payload. - InterceptorInfo struct { - // Name of service handling request - Service string - // Name of method handling request - Method string - // Endpoint of request, can be used for retrying - Endpoint Endpoint - // Payload of request - RawPayload any + // method name, the type of call the interceptor is handling (unary, streaming send, + // or streaming receive), and the request payload. + InterceptorInfo interface { + // Service returns the name of the service handling the request. + Service() string + // Method returns the name of the method handling the request. + Method() string + // CallType returns the type of call the interceptor is handling. + CallType() InterceptorCallType + // RawPayload returns the raw payload of the request. + RawPayload() any } + + // InterceptorCallType is the type of call the interceptor is handling + InterceptorCallType int +) + +const ( + // InterceptorUnary indicates the interceptor is handling a unary call + InterceptorUnary InterceptorCallType = iota + // InterceptorStreamingSend indicates the interceptor is handling a streaming Send + InterceptorStreamingSend + // InterceptorStreamingRecv indicates the interceptor is handling a streaming Recv + InterceptorStreamingRecv )