private void generateOperationDeserializer()

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


    private void generateOperationDeserializer(GenerationContext context, OperationShape operation) {
        SymbolProvider symbolProvider = context.getSymbolProvider();
        Model model = context.getModel();
        GoWriter writer = context.getWriter().get();
        ServiceShape service = context.getService();
        StructureShape outputShape = ProtocolUtils.expectOutput(context.getModel(), operation);
        Symbol outputSymbol = symbolProvider.toSymbol(outputShape);
        ApplicationProtocol applicationProtocol = getApplicationProtocol();
        Symbol responseType = applicationProtocol.getResponseType();
        String errorFunctionName = ProtocolGenerator.getOperationErrorDeserFunctionName(
                operation, context.getService(), context.getProtocolName());

        GoStackStepMiddlewareGenerator middleware = GoStackStepMiddlewareGenerator.createDeserializeStepMiddleware(
                ProtocolGenerator.getDeserializeMiddlewareName(operation.getId(), service, getProtocolName()),
                ProtocolUtils.OPERATION_DESERIALIZER_MIDDLEWARE_ID);

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

            writer.write("out, metadata, err = next.$L(ctx, in)", generator.getHandleMethodName());
            writer.write("if err != nil { return out, metadata, err }");
            writer.write("");

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

            writer.write("response, ok := out.RawResponse.($P)", responseType);
            writer.openBlock("if !ok {", "}", () -> {
                writer.write(String.format("return out, metadata, &smithy.DeserializationError{Err: %s}",
                        "fmt.Errorf(\"unknown transport type %T\", out.RawResponse)"));
            });
            writer.write("");

            writer.openBlock("if response.StatusCode < 200 || response.StatusCode >= 300 {", "}", () -> {
                writer.write("return out, metadata, $L(response, &metadata)", errorFunctionName);
            });

            writer.write("output := &$T{}", outputSymbol);
            writer.write("out.Result = output");
            writer.write("");

            Optional<EventStreamInfo> streamInfoOptional = EventStreamIndex.of(model).getOutputInfo(operation);

            // Discard without deserializing the response if the input shape is a stubbed synthetic clone
            // without an archetype.
            if (CodegenUtils.isStubSynthetic(ProtocolUtils.expectOutput(model, operation))
                && streamInfoOptional.isEmpty()) {
                writer.addUseImports(SmithyGoDependency.IOUTIL);
                writer.openBlock("if _, err = io.Copy(ioutil.Discard, response.Body); err != nil {", "}",
                        () -> {
                            writer.openBlock("return out, metadata, &smithy.DeserializationError{", "}", () -> {
                                writer.write("Err: fmt.Errorf(\"failed to discard response body, %w\", err),");
                            });
                        });
            } else if (streamInfoOptional.isEmpty()) {
                deserializeOutputDocument(context, operation);
                deserializingDocumentShapes.add(ProtocolUtils.expectOutput(model, operation));
            }
            writer.write("");

            writer.write("return out, metadata, err");
        });
        writer.write("");

        Set<StructureShape> errorShapes = generateErrorShapes(context, operation, responseType);
        deserializingErrorShapes.addAll(errorShapes);
        deserializingDocumentShapes.addAll(errorShapes);
    }