protected abstract void generateEventStreamSerializers()

in codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/integration/HttpRpcProtocolGenerator.java [110:231]


    protected abstract void generateEventStreamSerializers(
            GenerationContext context,
            UnionShape eventUnion,
            Set<EventStreamInfo> eventStreamInfos
    );

    /**
     * Generate the event stream deserializers for the given event stream target and asscioated operations.
     *
     * @param context          the generation context
     * @param eventUnion       the event stream union
     * @param eventStreamInfos the event stream infos
     */
    protected abstract void generateEventStreamDeserializers(
            GenerationContext context,
            UnionShape eventUnion,
            Set<EventStreamInfo> eventStreamInfos
    );

    private void generateOperationSerializer(GenerationContext context, OperationShape operation) {
        SymbolProvider symbolProvider = context.getSymbolProvider();
        Model model = context.getModel();
        ServiceShape service = context.getService();
        Shape inputShape = ProtocolUtils.expectInput(model, operation);
        Symbol inputSymbol = symbolProvider.toSymbol(inputShape);
        ApplicationProtocol applicationProtocol = getApplicationProtocol();
        Symbol requestType = applicationProtocol.getRequestType();
        GoWriter writer = context.getWriter().get();

        writer.pushState();

        GoStackStepMiddlewareGenerator middleware = GoStackStepMiddlewareGenerator.createSerializeStepMiddleware(
                ProtocolGenerator.getSerializeMiddlewareName(operation.getId(), service, getProtocolName()),
                ProtocolUtils.OPERATION_SERIALIZER_MIDDLEWARE_ID);

        middleware.writeMiddleware(context.getWriter().get(), (generator, w) -> {
            writer.addUseImports(SmithyGoDependency.SMITHY);
            writer.addUseImports(SmithyGoDependency.FMT);
            writer.addUseImports(SmithyGoDependency.SMITHY_HTTP_BINDING);

            writer.write(goTemplate("""
                    _, span := $T(ctx, "OperationSerializer")
                    endTimer := startMetricTimer(ctx, "client.call.serialization_duration")
                    defer endTimer()
                    defer span.End()
                    """, SMITHY_TRACING.func("StartSpan")));

            // TODO: refactor the http binding encoder to be split up into its component parts
            // This would allow most of this shared code to be split off into its own function
            // to reduce duplication, and potentially allowing it to be a static function.
            // For example, a HeaderBag type could handle all the headers.
            // Cast the input request to the transport request type and check for errors.
            writer.write("request, ok := in.Request.($P)", requestType);
            writer.openBlock("if !ok {", "}", () -> {
                writer.write("return out, metadata, "
                             + "&smithy.SerializationError{Err: fmt.Errorf(\"unknown transport type %T\", in.Request)}"
                );
            }).write("");

            // Cast the input parameters to the operation request type and check for errors.
            writer.write("input, ok := in.Parameters.($P)", inputSymbol);
            writer.write("_ = input");
            writer.openBlock("if !ok {", "}", () -> {
                writer.write("return out, metadata, "
                             + "&smithy.SerializationError{Err: fmt.Errorf(\"unknown input parameters type %T\","
                             + " in.Parameters)}");
            }).write("");

            writer.putContext("opPath", getOperationPath(context, operation));
            writer.putContext("pathJoin", SymbolUtils.createValueSymbolBuilder("Join",
                    SmithyGoDependency.PATH).build());
            writer.write("""
                         operationPath := $opPath:S
                         if len(request.Request.URL.Path) == 0 {
                             request.Request.URL.Path = operationPath
                         } else {
                             request.Request.URL.Path = $pathJoin:T(request.Request.URL.Path, operationPath)
                             if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' {
                                 request.Request.URL.Path += "/"
                             }
                         }""");
            writer.write("request.Request.Method = \"POST\"");
            writer.write("httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, "
                         + "request.URL.RawQuery, request.Header)");
            writer.openBlock("if err != nil {", "}", () -> {
                writer.write("return out, metadata, &smithy.SerializationError{Err: err}");
            });

            Optional<EventStreamInfo> optionalEventStreamInfo = EventStreamIndex.of(model).getInputInfo(operation);
            // Skip and Handle Input Event Stream Setup Separately
            if (optionalEventStreamInfo.isEmpty()) {
                writeRequestHeaders(context, operation, writer);
                writer.write("");
                // delegate the setup and usage of the document serializer function for the protocol
                serializeInputDocument(context, operation);
                // Skipping calling serializer method for the input shape is responsibility of the
                // serializeInputDocument implementation.
                if (!CodegenUtils.isStubSynthetic(ProtocolUtils.expectInput(context.getModel(), operation))) {
                    serializingDocumentShapes.add(ProtocolUtils.expectInput(model, operation));
                }
            } else {
                writeDefaultHeaders(context, operation, writer);
                writeOperationSerializerMiddlewareEventStreamSetup(context, optionalEventStreamInfo.get());
            }

            writer.write("");

            writer.openBlock("if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil {",
                    "}", () -> {
                        writer.write("return out, metadata, &smithy.SerializationError{Err: err}");
                    });
            // Ensure the request value is updated if modified for a document.
            writer.write("in.Request = request");

            writer.write("");
            writer.write("endTimer()");
            writer.write("span.End()");
            writer.write("return next.$L(ctx, in)", generator.getHandleMethodName());
        });

        writer.popState();
    }