Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable custom inline suffixes in IDL serializer #2121

Merged
merged 1 commit into from
Jan 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,17 @@
* Serializes a {@link Model} into a set of Smithy IDL files.
*/
public final class SmithyIdlModelSerializer {
private static final String DEFAULT_INLINE_INPUT_SUFFIX = "Input";
private static final String DEFAULT_INLINE_OUTPUT_SUFFIX = "Output";

private final Predicate<String> metadataFilter;
private final Predicate<Shape> shapeFilter;
private final Predicate<Trait> traitFilter;
private final Function<Shape, Path> shapePlacer;
private final Path basePath;
private final SmithyIdlComponentOrder componentOrder;
private final String inlineInputSuffix;
private final String inlineOutputSuffix;

/**
* Trait serialization features.
Expand Down Expand Up @@ -113,6 +118,8 @@ private SmithyIdlModelSerializer(Builder builder) {
this.shapePlacer = builder.shapePlacer;
}
this.componentOrder = builder.componentOrder;
this.inlineInputSuffix = builder.inlineInputSuffix;
this.inlineOutputSuffix = builder.inlineOutputSuffix;
}

/**
Expand Down Expand Up @@ -182,14 +189,14 @@ private Set<ShapeId> getInlineableShapes(Model fullModel, Collection<Shape> shap
if (!operation.getInputShape().equals(UnitTypeTrait.UNIT)) {
Shape inputShape = fullModel.expectShape(operation.getInputShape());
if (shapes.contains(inputShape) && inputShape.hasTrait(InputTrait.ID)
&& operation.getInputShape().getName().equals(operation.getId().getName() + "Input")) {
&& inputShape.getId().getName().equals(operation.getId().getName() + inlineInputSuffix)) {
inlineableShapes.add(operation.getInputShape());
}
}
if (!operation.getOutputShape().equals(UnitTypeTrait.UNIT)) {
Shape outputShape = fullModel.expectShape(operation.getOutputShape());
if (shapes.contains(outputShape) && outputShape.hasTrait(OutputTrait.ID)
&& operation.getOutputShape().getName().equals(operation.getId().getName() + "Output")) {
&& outputShape.getId().getName().equals(operation.getId().getName() + inlineOutputSuffix)) {
inlineableShapes.add(operation.getOutputShape());
}
}
Expand All @@ -201,7 +208,17 @@ private String serializeHeader(Model fullModel, String namespace) {
SmithyCodeWriter codeWriter = new SmithyCodeWriter(null, fullModel);
NodeSerializer nodeSerializer = new NodeSerializer(codeWriter, fullModel);

codeWriter.write("$$version: \"$L\"", Model.MODEL_VERSION).write("");
codeWriter.write("$$version: \"$L\"", Model.MODEL_VERSION);

if (!inlineInputSuffix.equals(DEFAULT_INLINE_INPUT_SUFFIX)) {
codeWriter.write("$$operationInputSuffix: $S", inlineInputSuffix);
}

if (!inlineOutputSuffix.equals(DEFAULT_INLINE_OUTPUT_SUFFIX)) {
codeWriter.write("$$operationOutputSuffix: $S", inlineOutputSuffix);
}

codeWriter.write("");

Comparator<Map.Entry<String, Node>> comparator = componentOrder.metadataComparator();

Expand Down Expand Up @@ -260,6 +277,8 @@ public static final class Builder implements SmithyBuilder<SmithyIdlModelSeriali
private Path basePath = null;
private boolean serializePrelude = false;
private SmithyIdlComponentOrder componentOrder = SmithyIdlComponentOrder.PREFERRED;
private String inlineInputSuffix = DEFAULT_INLINE_INPUT_SUFFIX;
private String inlineOutputSuffix = DEFAULT_INLINE_OUTPUT_SUFFIX;

public Builder() {}

Expand Down Expand Up @@ -350,6 +369,34 @@ public Builder componentOrder(SmithyIdlComponentOrder componentOrder) {
return this;
}

/**
* Defines what suffixes are checked on operation input shapes to determine whether
* inline syntax should be used.
*
* <p>This will also set the "operationInputSuffix" control statement.
*
* @param inlineInputSuffix The suffix to use for inline operation input.
* @return Returns the builder.
*/
public Builder inlineInputSuffix(String inlineInputSuffix) {
this.inlineInputSuffix = inlineInputSuffix;
return this;
}

/**
* Defines what suffixes are checked on operation output shapes to determine whether
* inline syntax should be used.
*
* <p>This will also set the "operationOutputSuffix" control statement.
*
* @param inlineOutputSuffix The suffix to use for inline operation output.
* @return Returns the builder.
*/
public Builder inlineOutputSuffix(String inlineOutputSuffix) {
this.inlineOutputSuffix = inlineOutputSuffix;
return this;
}

@Override
public SmithyIdlModelSerializer build() {
return new SmithyIdlModelSerializer(this);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -259,4 +259,22 @@ public void handlesEnumMixins() {
String serializedString = serialized.entrySet().iterator().next().getValue();
Assertions.assertEquals(expectedOutput, serializedString);
}

@Test
public void handlesCustomInlineSuffixes() {
URL resource = getClass().getResource("idl-serialization/custom-inline-io.smithy");
Model model = Model.assembler().addImport(resource).assemble().unwrap();

Assertions.assertTrue(model.getShape(ShapeId.from("com.example#InlineOperationRequest")).isPresent());
Assertions.assertTrue(model.getShape(ShapeId.from("com.example#InlineOperationResponse")).isPresent());

Map<Path, String> reserialized = SmithyIdlModelSerializer.builder()
.inlineInputSuffix("Request")
.inlineOutputSuffix("Response")
.build()
.serialize(model);
String modelResult = reserialized.values().iterator().next().replace("\r\n", "\n");

assertThat(modelResult, equalTo(IoUtils.readUtf8Url(resource).replace("\r\n", "\n")));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
$version: "2.0"
$operationInputSuffix: "Request"
$operationOutputSuffix: "Response"

namespace com.example

service InlineService {
operations: [
InlineOperation
]
}

operation InlineOperation {
input := {}
output := {}
}
Loading