private void serializeKeyValuePairs(ObjectNode node, Shape shape) {
            if (node.isEmpty()) {
                return;
            }

            // If we're looking at a structure or union shape, we'll need to get the member shape based on the
            // node key. Here we pre-compute a mapping, so we don't have to traverse the member list every time.
            Map<String, MemberShape> members;
            if (shape == null) {
                members = Collections.emptyMap();
            } else {
                members = shape.members()
                        .stream()
                        .collect(Collectors.toMap(MemberShape::getMemberName, Function.identity()));
            }

            node.getMembers().forEach((name, value) -> {
                // Try to find the member shape.
                Shape member;
                if (shape != null && shape.isMapShape()) {
                    // For maps the value member will always be the same.
                    member = shape.asMapShape().get().getValue();
                } else if (shape instanceof StructureShape || shape instanceof UnionShape) {
                    member = members.get(name.getValue());
                } else {
                    // At this point the shape is either null or a document shape.
                    member = shape;
                }

                codeWriter.writeInline("\n$K: ", name.getValue());
                serialize(value, member);
            });
            codeWriter.write("");
        }
Serialize an object node without the surrounding brackets.

<p>This is mainly useful for serializing trait value nodes.

@param node The node to serialize.
@param shape The shape of the node.
smithy-model/src/main/java/software/amazon/smithy/model/shapes/SmithyIdlModelSerializer.java