in codegen/smithy-go-codegen/src/main/java/software/amazon/smithy/go/codegen/integration/HttpRpcProtocolGenerator.java [107:218]
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);
// 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}");
});
writeRequestHeaders(context, operation, writer);
writer.write("");
Optional<EventStreamInfo> inputInfo = EventStreamIndex.of(model).getInputInfo(operation);
// Skip and Handle Input Event Stream Setup Separately
if (inputInfo.isEmpty()) {
// 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.isStubSyntheticClone(ProtocolUtils.expectInput(context.getModel(), operation))) {
serializingDocumentShapes.add(ProtocolUtils.expectInput(model, operation));
}
} else {
writeOperationSerializerMiddlewareEventStreamSetup(context, inputInfo.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("return next.$L(ctx, in)", generator.getHandleMethodName());
});
writer.popState();
}