public void run()

in codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/OperationGenerator.java [72:170]


    public void run() {
        OperationIndex operationIndex = OperationIndex.of(model);
        Symbol serviceSymbol = symbolProvider.toSymbol(service);

        if (!operationIndex.getInput(operation).isPresent()) {
            // Theoretically this shouldn't ever get hit since we automatically insert synthetic inputs / outputs.
            throw new CodegenException(
                    "Operations are required to have input shapes in order to allow for future evolution.");
        }
        StructureShape inputShape = operationIndex.getInput(operation).get();
        Symbol inputSymbol = symbolProvider.toSymbol(inputShape);

        if (!operationIndex.getOutput(operation).isPresent()) {
            throw new CodegenException(
                    "Operations are required to have output shapes in order to allow for future evolution.");
        }
        StructureShape outputShape = operationIndex.getOutput(operation).get();
        Symbol outputSymbol = symbolProvider.toSymbol(outputShape);

        // Generate operation method
        final boolean hasDocs = writer.writeShapeDocs(operation);
        operation.getTrait(DeprecatedTrait.class)
                .ifPresent(trait -> {
                    if (hasDocs) {
                        writer.writeDocs("");
                    }
                    final String defaultMessage = "This operation has been deprecated.";
                    writer.writeDocs("Deprecated: " + trait.getMessage().map(s -> {
                        if (s.length() == 0) {
                            return defaultMessage;
                        }
                        return s;
                    }).orElse(defaultMessage));
                });
        Symbol contextSymbol = SymbolUtils.createValueSymbolBuilder("Context", SmithyGoDependency.CONTEXT).build();
        writer.openBlock("func (c $P) $T(ctx $T, params $P, optFns ...func(*Options)) ($P, error) {", "}",
                serviceSymbol, operationSymbol, contextSymbol, inputSymbol, outputSymbol, () -> {
                    writer.write("if params == nil { params = &$T{} }", inputSymbol);
                    writer.write("");

                    writer.write("result, metadata, err := c.invokeOperation(ctx, $S, params, optFns, c.$L)",
                            operationSymbol.getName(), getAddOperationMiddlewareFuncName(operationSymbol));
                    writer.write("if err != nil { return nil, err }");
                    writer.write("");

                    writer.write("out := result.($P)", outputSymbol);
                    writer.write("out.ResultMetadata = metadata");
                    writer.write("return out, nil");
                }).write("");

        // Write out the input and output structures. These are written out here to prevent naming conflicts with other
        // shapes in the model.
        new StructureGenerator(model, symbolProvider, writer, service, inputShape, inputSymbol, protocolGenerator)
                .renderStructure(() -> {
                }, true);

        var rulesTrait = service.getTrait(EndpointRuleSetTrait.class);
        if (rulesTrait.isPresent()) {
            writer.write(new EndpointParameterOperationBindingsGenerator(ctx, operation, inputShape)
                    .generate());
        }

        // The output structure gets a metadata member added.
        Symbol metadataSymbol = SymbolUtils.createValueSymbolBuilder("Metadata", SmithyGoDependency.SMITHY_MIDDLEWARE)
                .build();

        boolean hasEventStream = Stream.concat(inputShape.members().stream(),
                        outputShape.members().stream())
                .anyMatch(memberShape -> StreamingTrait.isEventStream(model, memberShape));

        new StructureGenerator(model, symbolProvider, writer, service, outputShape, outputSymbol, protocolGenerator)
                .renderStructure(() -> {
                    if (outputShape.getMemberNames().size() != 0) {
                        writer.write("");
                    }

                    if (hasEventStream) {
                        writer.write("eventStream $P",
                                        EventStreamGenerator.getEventStreamOperationStructureSymbol(service, operation))
                                .write("");
                    }

                    writer.writeDocs("Metadata pertaining to the operation's result.");
                    writer.write("ResultMetadata $T", metadataSymbol);
                });

        if (hasEventStream) {
            writer.write("""
                         // GetStream returns the type to interact with the event stream.
                         func (o $P) GetStream() $P {
                             return o.eventStream
                         }
                         """, outputSymbol, EventStreamGenerator.getEventStreamOperationStructureSymbol(
                    service, operation));
        }

        // Generate operation protocol middleware helper function
        generateAddOperationMiddleware();
    }