private static void writeMiddleware()

in codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/integration/EndpointHostPrefixMiddleware.java [100:171]


    private static void writeMiddleware(
            GoWriter writer,
            Model model,
            SymbolProvider symbolProvider,
            OperationShape operation,
            SmithyPattern pattern
    ) {
        GoStackStepMiddlewareGenerator middlewareGenerator =
                GoStackStepMiddlewareGenerator.createFinalizeStepMiddleware(
                        getMiddlewareName(operation),
                        MIDDLEWARE_ID
                );

        middlewareGenerator.writeMiddleware(writer, (generator, w) -> {
            writer.addUseImports(SmithyGoDependency.SMITHY_HTTP_TRANSPORT);
            writer.addUseImports(SmithyGoDependency.FMT);

            w.openBlock("if smithyhttp.GetHostnameImmutable(ctx) || "
                    + "smithyhttp.IsEndpointHostPrefixDisabled(ctx) {", "}", () -> {
                w.write("return next.$L(ctx, in)", generator.getHandleMethodName());
            }).write("");

            w.write("req, ok := in.Request.(*smithyhttp.Request)");
            w.openBlock("if !ok {", "}", () -> {
                writer.write("return out, metadata, fmt.Errorf(\"unknown transport type %T\", in.Request)");
            }).write("");

            if (pattern.getLabels().isEmpty()) {
                w.write("req.URL.Host = $S + req.URL.Host", pattern.toString());
            } else {
                // If the pattern has labels, we need to build up the host prefix using a string builder.
                writer.addUseImports(SmithyGoDependency.STRINGS);
                writer.addUseImports(SmithyGoDependency.SMITHY);
                StructureShape input = ProtocolUtils.expectInput(model, operation);
                writer.write("opaqueInput := getOperationInput(ctx)");
                writer.write("input, ok := opaqueInput.($P)", symbolProvider.toSymbol(input));
                w.openBlock("if !ok {", "}", () -> {
                    writer.write("return out, metadata, fmt.Errorf(\"unknown input type %T\", opaqueInput)");
                }).write("");

                w.write("var prefix strings.Builder");
                for (SmithyPattern.Segment segment : pattern.getSegments()) {
                    if (!segment.isLabel()) {
                        w.write("prefix.WriteString($S)", segment.toString());
                    } else {
                        MemberShape member = input.getMember(segment.getContent()).get();
                        String memberName = symbolProvider.toMemberName(member);
                        String memberReference = "input." + memberName;

                        // Theoretically this should never be nil or empty by this point unless validation has
                        // been disabled.
                        w.write("if $L == nil {", memberReference).indent();
                        w.write("return out, metadata, &smithy.SerializationError{Err: "
                                        + "fmt.Errorf(\"$L forms part of the endpoint host and so may not be nil\")}",
                                memberName);
                        w.dedent().write("} else if !smithyhttp.ValidHostLabel(*$L) {", memberReference).indent();
                        w.write("return out, metadata, &smithy.SerializationError{Err: "
                                + "fmt.Errorf(\"$L forms part of the endpoint host and so must match "
                                + "\\\"[a-zA-Z0-9-]{1,63}\\\""
                                + ", but was \\\"%s\\\"\", *$L)}", memberName, memberReference);
                        w.dedent().openBlock("} else {", "}", () -> {
                            w.write("prefix.WriteString(*$L)", memberReference);
                        });
                    }
                }
                w.write("req.URL.Host = prefix.String() + req.URL.Host");
            }
            w.write("");

            w.write("return next.$L(ctx, in)", generator.getHandleMethodName());
        });
    }