in tools/code-generation/generator/src/main/java/com/amazonaws/util/awsclientgenerator/transform/C2jModelToGeneratorModelTransformer.java [316:380]
void postProcessShapes() {
for(Map.Entry<String, Shape> entry : shapes.entrySet()) {
Shape shape = entry.getValue();
/*
If this shape ends up deriving from AmazonStreamingWebServiceRequest, then we already have implemented accessors for ContentType and the
header insertion there. So strip this out of the model (affects S3's PutObjectRequest).
*/
if (shape.hasStreamMembers() && shape.isRequest()) {
shape.RemoveMember("contentType");
shape.RemoveMember("ContentType");
}
/**
* Decide event payload type, should be one of them: "blob" | "string" | "structure" | null
*/
if (shape.isEvent()) {
if (!shape.getMembers().values().stream().anyMatch(member -> !member.isEventHeader())) {
// Header only event
shape.setEventPayloadType(null);
} else if (shape.hasEventPayloadMembers() || shape.getMembers().size() == 1) {
if (shape.getMembers().size() == 1) {
shape.getMembers().entrySet().stream().forEach(memberEntry -> {
/**
* Note: this is complicated and potentially not completely correct.
* So touch at your own risk until we have protocol tests supported.
* In summary:
* - we need to determine how to serialize events in eventstream
* - to specify payload there is an eventpayload trait
* - but what happens if that trait is not specified
* - if there is one field and its a string or struct then we assume that field is event payload
* - if there is one field and its a blob within structure and not explicitly marked as eventpayload then parent shape is eventpayload
* - if that one field is of any other type then treat parent shape as eventpayload
* - if there is more than one field then parent shape is the payload
*/
Shape memberShape = memberEntry.getValue().getShape();
if (memberShape.isString() ||
memberShape.isBlob() && !shape.isStructure() ||
memberShape.isBlob() && memberEntry.getValue().isEventPayload() ||
memberShape.isStructure()) {
memberEntry.getValue().setEventPayload(true);
shape.setEventPayloadMemberName(memberEntry.getKey());
shape.setEventPayloadType(memberShape.getType());
} else {
if (!shape.getType().equals("structure")) {
throw new RuntimeException("Event shape should always has \"structure\" type if single member cannot be event payload.");
}
shape.setEventPayloadType(shape.getType());
}
});
} else {
throw new RuntimeException("Event shape used in Event Stream should only has one member if it has event payload member.");
}
} else if (shape.getMembers().size() > 1) {
if (!shape.getType().equals("structure")) {
throw new RuntimeException("Event shape should always has \"structure\" type if has multiple members.");
}
shape.setEventPayloadType(shape.getType());
} else {
shape.setEventPayloadType(null);
}
}
}
}