Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

generate protocol-specific event payload #554

Merged
merged 3 commits into from
Jun 13, 2022
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1350,6 +1350,29 @@ protected abstract void serializeInputDocumentBody(
List<HttpBinding> documentBindings
);

/**
* Writes the code needed to serialize an event payload as a protocol-specific document.
*
* <p>Implementations of this method are expected to set a value to the ${@code message.body} property.
* The value set is expected to by a JavaScript ${@code Uint8Array} type and is to be encoded as the
* event payload.
*
* <p>Three parameters will be available in scope:
* <ul>
* <li>{@code body}: The serialized event payload object that needs to be transformed to binary data</li>
* <li>{@code message: <T>}: The partially constructed event message.</li>
* <li>{@code context: SerdeContext}: a TypeScript type containing context and tools for type serde.</li>
* </ul>
*
* <p>For example:
*
* <pre>{@code
* message.body = context.utf8Decoder(JSON.stringify(body));
* }</pre>
* @param context The generation context.
*/
protected abstract void serializeInputEventDocumentPayload(GenerationContext context);

/**
* Writes the code needed to serialize a protocol output document.
*
Expand Down Expand Up @@ -1611,25 +1634,34 @@ private void writeEventBody(GenerationContext context, StructureShape event) {
TypeScriptWriter writer = context.getWriter();
Model model = context.getModel();
List<MemberShape> payloadMembers = event.getAllMembers().values().stream()
.filter(member -> member.hasTrait(EventPayloadTrait.class)).collect(Collectors.toList());
List<MemberShape> documentMembers = event.getAllMembers().values().stream()
.filter(member -> !member.hasTrait(EventHeaderTrait.class)
&& !member.hasTrait(EventPayloadTrait.class))
.filter(member -> member.hasTrait(EventPayloadTrait.class))
.collect(Collectors.toList());
if (!payloadMembers.isEmpty()) {
// Write event payload if exists. There is at most 1 payload member.
Shape payloadShape = payloadMembers.isEmpty()
? event // implicit payload
: model.expectShape(payloadMembers.get(0).getTarget());
if (payloadShape instanceof BlobShape || payloadShape instanceof StringShape) {
// Since event itself must be a structure shape, so string or blob payload member must has eventPayload
// trait explicitly.
MemberShape payloadMember = payloadMembers.get(0);
String memberName = payloadMember.getMemberName();
String payloadMemberName = payloadMember.getMemberName();
writer.write("message.body = $L || message.body;",
getInputValue(context, Location.PAYLOAD, "input." + memberName, payloadMember,
getInputValue(context, Location.PAYLOAD, "input." + payloadMemberName, payloadMember,
model.expectShape(payloadMember.getTarget())));
} else if (!documentMembers.isEmpty()) {
// Write event document bindings if exist.
} else if (payloadShape instanceof StructureShape || payloadShape instanceof UnionShape) {
// handle implicit event payload by removing members with eventHeader trait.
for (MemberShape memberShape : event.members()) {
if (memberShape.hasTrait(EventHeaderTrait.class)) {
writer.write("delete input[$S]", memberShape.getMemberName());
}
}
SymbolProvider symbolProvider = context.getSymbolProvider();
Symbol symbol = symbolProvider.toSymbol(event);
// Use normal structure serializer instead of event serializer to serialize document body.
Symbol symbol = symbolProvider.toSymbol(payloadShape);
String serFunctionName = ProtocolGenerator.getSerFunctionName(symbol, context.getProtocolName());
writer.write("message.body = $L(input, context);", serFunctionName);
writer.write("const body = $L(input, context);", serFunctionName);
serializeInputEventDocumentPayload(context);
} else {
throw new CodegenException(String.format("Unexpected shape type bound to event payload: `%s`",
payloadShape.getType()));
}
}

Expand Down