void postProcessShapes()

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);
                }
            }
        }
    }