diff --git a/smithy-model/src/main/java/software/amazon/smithy/model/shapes/ModelSerializer.java b/smithy-model/src/main/java/software/amazon/smithy/model/shapes/ModelSerializer.java index eac5684e94c..49c32ac9599 100644 --- a/smithy-model/src/main/java/software/amazon/smithy/model/shapes/ModelSerializer.java +++ b/smithy-model/src/main/java/software/amazon/smithy/model/shapes/ModelSerializer.java @@ -54,7 +54,11 @@ public final class ModelSerializer { private ModelSerializer(Builder builder) { metadataFilter = builder.metadataFilter; - shapeFilter = builder.shapeFilter.and(FunctionalUtils.not(Prelude::isPreludeShape)); + if (!builder.includePrelude) { + shapeFilter = builder.shapeFilter.and(FunctionalUtils.not(Prelude::isPreludeShape)); + } else { + shapeFilter = builder.shapeFilter; + } traitFilter = builder.traitFilter; } @@ -97,6 +101,7 @@ public static Builder builder() { public static final class Builder implements SmithyBuilder { private Predicate metadataFilter = FunctionalUtils.alwaysTrue(); private Predicate shapeFilter = FunctionalUtils.alwaysTrue(); + private boolean includePrelude = false; private Predicate traitFilter = FunctionalUtils.alwaysTrue(); private Builder() {} @@ -121,6 +126,25 @@ public Builder shapeFilter(Predicate shapeFilter) { return this; } + /** + * Enables or disables including the prelude in the serialized model. + * + *

By default, the prelude is not included. + * + *

This should nearly always be left at default, as per the spec the prelude is + * inherently part of every model, and so any Smithy implementation must build in + * an understanding of the prelude. Disabling this filter can be useful for those + * implementations to allow them to build their understanding of it from a JSON + * version of the prelude. + * + * @param includePrelude boolean indicating whether the prelude should be included or not. + * @return Returns the builder. + */ + public Builder includePrelude(boolean includePrelude) { + this.includePrelude = includePrelude; + return this; + } + /** * Sets a predicate that can be used to filter trait values from * appearing in the serialized model. diff --git a/smithy-model/src/test/java/software/amazon/smithy/model/shapes/ModelSerializerTest.java b/smithy-model/src/test/java/software/amazon/smithy/model/shapes/ModelSerializerTest.java index fcc68bc862d..801cc8bb75e 100644 --- a/smithy-model/src/test/java/software/amazon/smithy/model/shapes/ModelSerializerTest.java +++ b/smithy-model/src/test/java/software/amazon/smithy/model/shapes/ModelSerializerTest.java @@ -21,7 +21,8 @@ import static org.hamcrest.Matchers.hasKey; import static org.hamcrest.Matchers.is; import static org.hamcrest.Matchers.not; -import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.hamcrest.Matchers.startsWith; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.Optional; import org.junit.jupiter.api.Test; @@ -141,7 +142,23 @@ public void doesNotSerializePreludeTraitsOrShapes() { ModelSerializer serializer = ModelSerializer.builder().build(); ObjectNode serialized = serializer.serialize(model); - assertFalse(serialized.getMember("smithy.api").isPresent()); + ObjectNode shapes = serialized.expectObjectMember("shapes"); + shapes.getMembers().forEach((key, value) -> { + assertThat(key.getValue(), not(startsWith("smithy.api#"))); + }); + } + + @Test + public void allowsDisablingPreludeFilter() { + Model model = Model.assembler().assemble().unwrap(); + ModelSerializer serializer = ModelSerializer.builder().includePrelude(true).build(); + ObjectNode serialized = serializer.serialize(model); + + ObjectNode shapes = serialized.expectObjectMember("shapes"); + assertTrue(shapes.getMembers().size() > 1); + shapes.getMembers().forEach((key, value) -> { + assertThat(key.getValue(), startsWith("smithy.api#")); + }); } @Test