Model transform(ModelTransformer transformer, Model model) {
        return transformer.replaceShapes(model,
                model.shapes()
                        .flatMap(shape -> {
                            Shape mapped =
                                    Objects.requireNonNull(mapper.apply(shape), "Shape mapper must not return null");
                            if (mapped.equals(shape)) {
                                return Stream.empty();
                            } else if (!mapped.getId().equals(shape.getId())) {
                                throw new ModelTransformException(String.format(
                                        "Mapped shapes must have the same shape ID. Expected %s, but found %s",
                                        shape.getId(),
                                        mapped.getId()));
                            } else {
                                return Stream.of(mapped);
                            }
                        })
                        .collect(Collectors.toSet()));
    }
Maps over shapes in the model using a mapping function.

<p>Only shapes that have changed cause the shape the be replaced in
the Model. The mapping function MUST return a shape with the same
ID and the same type (e.g., a string cannot become an integer).

@see ModelTransformer#mapShapes
smithy-model/src/main/java/software/amazon/smithy/model/transform/MapShapes.java