From 06ee3c6f9e2c73f488ecc016876503f9120dbb5c Mon Sep 17 00:00:00 2001 From: Joe Wu Date: Fri, 30 Jan 2026 15:12:48 -0800 Subject: [PATCH 1/5] Add new build transform CompileBddFromEndpointRuleSet --- .../rules-engine/specification.rst | 9 +- docs/source-2.0/guides/smithy-build-json.rst | 23 +++++ smithy-build/build.gradle.kts | 2 + .../CompileBddFromEndpointRuleSet.java | 84 +++++++++++++++++++ ....amazon.smithy.build.ProjectionTransformer | 1 + .../CompileBddFromEndpointRuleSetTest.java | 34 ++++++++ .../compile-bdd-from-endpoint-ruleset.smithy | 50 +++++++++++ 7 files changed, 200 insertions(+), 3 deletions(-) create mode 100644 smithy-build/src/main/java/software/amazon/smithy/build/transforms/CompileBddFromEndpointRuleSet.java create mode 100644 smithy-build/src/test/java/software/amazon/smithy/build/transforms/CompileBddFromEndpointRuleSetTest.java create mode 100644 smithy-build/src/test/resources/software/amazon/smithy/build/transforms/compile-bdd-from-endpoint-ruleset.smithy diff --git a/docs/source-2.0/additional-specs/rules-engine/specification.rst b/docs/source-2.0/additional-specs/rules-engine/specification.rst index 01ce02bef77..affd201fa74 100644 --- a/docs/source-2.0/additional-specs/rules-engine/specification.rst +++ b/docs/source-2.0/additional-specs/rules-engine/specification.rst @@ -94,7 +94,7 @@ on the scenario. This trait is experimental and subject to change. Summary - A Binary `Decision Diagram (BDD) `_ representation of + A `Binary Decision Diagram (BDD) `_ representation of endpoint rules that is more compact and efficient at runtime than the decision-tree-based EndpointRuleSet trait. Trait selector ``service`` @@ -108,8 +108,11 @@ runtime performance and reduced artifact sizes. .. note:: - The ``endpointBdd`` trait can be generated from an ``endpointRuleSet`` trait through compilation. Services may - provide either trait, with ``endpointBdd`` preferred for production use due to its performance characteristics. + The ``endpointBdd`` trait can be generated from an ``endpointRuleSet`` trait through compilation. + To generate the ``endpointBdd`` trait for a service, add the + :ref:`compileBddFromEndpointRuleSet ` transform to the + ``smithy-build.json`` file. Services may provide either trait, with ``endpointBdd`` preferred for + production use due to its performance characteristics. The ``endpointBdd`` structure has the following properties: diff --git a/docs/source-2.0/guides/smithy-build-json.rst b/docs/source-2.0/guides/smithy-build-json.rst index 543fe18b075..344a466bbcb 100644 --- a/docs/source-2.0/guides/smithy-build-json.rst +++ b/docs/source-2.0/guides/smithy-build-json.rst @@ -654,6 +654,29 @@ Only the following shape type changes are supported: .. seealso:: :ref:`changeStringEnumsToEnumShapes` +.. _compileBddFromEndpointRuleSet-transform: + +compileBddFromEndpointRuleSet +----------------------------- + +This transform compiles `Binary Decision Diagram (BDD) `_ +from service shape's :ref:`@endpointRuleSet ` trait and attaches +the compiled :ref:`@endpointBdd ` trait to the service shape. + +.. code-block:: json + + { + "version": "1.0", + "projections": { + "exampleProjection": { + "transforms": [ + { + "name": "compileBddFromEndpointRuleSet" + } + ] + } + } + } .. _excludeShapesBySelector-transform: diff --git a/smithy-build/build.gradle.kts b/smithy-build/build.gradle.kts index a44ae728dd9..1afad8bf9da 100644 --- a/smithy-build/build.gradle.kts +++ b/smithy-build/build.gradle.kts @@ -15,6 +15,8 @@ extra["moduleName"] = "software.amazon.smithy.build" dependencies { api(project(":smithy-utils")) api(project(":smithy-model")) + api(project(":smithy-rules-engine")) + api(project(":smithy-aws-endpoints")) // Allows testing of annotation processor testImplementation(libs.compile.testing) diff --git a/smithy-build/src/main/java/software/amazon/smithy/build/transforms/CompileBddFromEndpointRuleSet.java b/smithy-build/src/main/java/software/amazon/smithy/build/transforms/CompileBddFromEndpointRuleSet.java new file mode 100644 index 00000000000..4db01b7040b --- /dev/null +++ b/smithy-build/src/main/java/software/amazon/smithy/build/transforms/CompileBddFromEndpointRuleSet.java @@ -0,0 +1,84 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ +package software.amazon.smithy.build.transforms; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; +import software.amazon.smithy.build.ProjectionTransformer; +import software.amazon.smithy.build.TransformContext; +import software.amazon.smithy.model.Model; +import software.amazon.smithy.model.shapes.ServiceShape; +import software.amazon.smithy.model.shapes.Shape; +import software.amazon.smithy.model.shapes.ShapeId; +import software.amazon.smithy.model.transform.ModelTransformer; +import software.amazon.smithy.rulesengine.aws.s3.S3TreeRewriter; +import software.amazon.smithy.rulesengine.language.EndpointRuleSet; +import software.amazon.smithy.rulesengine.language.evaluation.TestEvaluator; +import software.amazon.smithy.rulesengine.logic.bdd.CostOptimization; +import software.amazon.smithy.rulesengine.logic.bdd.SiftingOptimization; +import software.amazon.smithy.rulesengine.logic.cfg.Cfg; +import software.amazon.smithy.rulesengine.traits.EndpointBddTrait; +import software.amazon.smithy.rulesengine.traits.EndpointRuleSetTrait; +import software.amazon.smithy.rulesengine.traits.EndpointTestCase; +import software.amazon.smithy.rulesengine.traits.EndpointTestsTrait; + +/** + * Compiles a Binary Decision Diagram (BDD) from a service's {@code @endpointRuleSet} + * trait and attaches the compiled {@code @endpointBdd} trait to the service shape. + */ +public final class CompileBddFromEndpointRuleSet implements ProjectionTransformer { + private static final ShapeId S3_SERVICE_ID = ShapeId.from("com.amazonaws.s3#AmazonS3"); + + @Override + public String getName() { + return "compileBddFromEndpointRuleSet"; + } + + @Override + public Model transform(TransformContext transformContext) { + Model model = transformContext.getModel(); + Collection shapes = new HashSet<>(); + Set serviceShapes = model.getServiceShapes(); + for (ServiceShape serviceShape : serviceShapes) { + if (serviceShape.hasTrait(EndpointRuleSetTrait.ID)) { + EndpointRuleSetTrait endpointRuleSetTrait = serviceShape.expectTrait(EndpointRuleSetTrait.class); + EndpointRuleSet rules = endpointRuleSetTrait.getEndpointRuleSet(); + // S3 has special tree transformations that dramatically improve the BDD compiled result + // both in size and performance + if (serviceShape.getId().equals(S3_SERVICE_ID)) { + rules = transformRulesetForS3(rules, serviceShape.expectTrait(EndpointTestsTrait.class)); + } + EndpointBddTrait bdd = compileBdd(rules); + shapes.add(serviceShape.toBuilder().addTrait(bdd).build()); + } + } + return ModelTransformer.create().replaceShapes(model, shapes); + } + + private EndpointRuleSet transformRulesetForS3(EndpointRuleSet rules, EndpointTestsTrait testsTrait) { + EndpointRuleSet transformedRules = S3TreeRewriter.transform(rules); + // Verify transforms preserve semantics by running all test cases + for (EndpointTestCase testCase : testsTrait.getTestCases()) { + TestEvaluator.evaluate(transformedRules, testCase); + } + return transformedRules; + } + + private EndpointBddTrait compileBdd(EndpointRuleSet rules) { + // Create the CFG to start BDD compilation process. + Cfg cfg = Cfg.from(rules); + EndpointBddTrait unoptimizedTrait = EndpointBddTrait.from(cfg); + + // Sift the BDD to shorten paths and reduce the BDD size. + EndpointBddTrait siftedTrait = SiftingOptimization.builder().cfg(cfg).build().apply(unoptimizedTrait); + + // "cost optimize" the BDD to ensure cheap conditions come first with up to 10% size impact. + EndpointBddTrait costOptimizedTrait = CostOptimization.builder().cfg(cfg).build().apply(siftedTrait); + + // Remove unreferenced conditions. This is destructive and further optimizations cannot be applied after this. + return costOptimizedTrait.removeUnreferencedConditions(); + } +} diff --git a/smithy-build/src/main/resources/META-INF/services/software.amazon.smithy.build.ProjectionTransformer b/smithy-build/src/main/resources/META-INF/services/software.amazon.smithy.build.ProjectionTransformer index 9a9afd233d3..fe2329d51d7 100644 --- a/smithy-build/src/main/resources/META-INF/services/software.amazon.smithy.build.ProjectionTransformer +++ b/smithy-build/src/main/resources/META-INF/services/software.amazon.smithy.build.ProjectionTransformer @@ -1,6 +1,7 @@ software.amazon.smithy.build.transforms.Apply software.amazon.smithy.build.transforms.ChangeStringEnumsToEnumShapes software.amazon.smithy.build.transforms.ChangeTypes +software.amazon.smithy.build.transforms.CompileBddFromEndpointRuleSet software.amazon.smithy.build.transforms.ExcludeMetadata software.amazon.smithy.build.transforms.ExcludeShapesBySelector software.amazon.smithy.build.transforms.ExcludeShapesByTag diff --git a/smithy-build/src/test/java/software/amazon/smithy/build/transforms/CompileBddFromEndpointRuleSetTest.java b/smithy-build/src/test/java/software/amazon/smithy/build/transforms/CompileBddFromEndpointRuleSetTest.java new file mode 100644 index 00000000000..0dd971340fb --- /dev/null +++ b/smithy-build/src/test/java/software/amazon/smithy/build/transforms/CompileBddFromEndpointRuleSetTest.java @@ -0,0 +1,34 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ +package software.amazon.smithy.build.transforms; + +import static org.junit.Assert.assertTrue; + +import java.nio.file.Paths; +import org.junit.jupiter.api.Test; +import software.amazon.smithy.build.TransformContext; +import software.amazon.smithy.model.Model; +import software.amazon.smithy.model.shapes.Shape; +import software.amazon.smithy.model.shapes.ShapeId; +import software.amazon.smithy.rulesengine.traits.EndpointBddTrait; + +public class CompileBddFromEndpointRuleSetTest { + + @Test + public void compilesAndAttachesBddTrait() throws Exception { + ShapeId serviceId = ShapeId.from("smithy.example#ExampleService"); + Model model = Model.assembler() + .discoverModels() + .addImport(Paths.get(getClass().getResource("compile-bdd-from-endpoint-ruleset.smithy").toURI())) + .assemble() + .unwrap(); + TransformContext context = TransformContext.builder() + .model(model) + .build(); + Model result = new CompileBddFromEndpointRuleSet().transform(context); + Shape serviceShape = result.expectShape(serviceId); + assertTrue(serviceShape.hasTrait(EndpointBddTrait.ID)); + } +} diff --git a/smithy-build/src/test/resources/software/amazon/smithy/build/transforms/compile-bdd-from-endpoint-ruleset.smithy b/smithy-build/src/test/resources/software/amazon/smithy/build/transforms/compile-bdd-from-endpoint-ruleset.smithy new file mode 100644 index 00000000000..e0af1af4ad7 --- /dev/null +++ b/smithy-build/src/test/resources/software/amazon/smithy/build/transforms/compile-bdd-from-endpoint-ruleset.smithy @@ -0,0 +1,50 @@ +$version: "2.0" + +namespace smithy.example + +use smithy.rules#clientContextParams +use smithy.rules#endpointRuleSet +use smithy.rules#endpointTests + +@clientContextParams( + Region: {type: "string", documentation: "docs"} +) +@endpointRuleSet({ + "version": "1.1" + "parameters": { + "Region": { + "required": true + "type": "String" + "documentation": "docs" + } + } + "rules": [ + { + "conditions": [] + "documentation": "base rule" + "endpoint": { + "url": "https://{Region}.amazonaws.com" + "properties": {} + "headers": {} + } + "type": "endpoint" + } + ] +}) +@endpointTests({ + "version": "1.0" + "testCases": [ + { + "documentation": "example endpoint test" + "expect": { + "endpoint": { + "url": "https://example-region.amazonaws.com" + } + } + "params": { + Region: "example-region" + } + } + ] +}) +service ExampleService {} From 6a84423d1a451a7f1c0e06027a4ccf6b58ecc765 Mon Sep 17 00:00:00 2001 From: Joe Wu Date: Fri, 30 Jan 2026 15:18:07 -0800 Subject: [PATCH 2/5] Add changelog --- .../feature-e8b0c9d42596402804ac70a348da0fd38622a0e4.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .changes/next-release/feature-e8b0c9d42596402804ac70a348da0fd38622a0e4.json diff --git a/.changes/next-release/feature-e8b0c9d42596402804ac70a348da0fd38622a0e4.json b/.changes/next-release/feature-e8b0c9d42596402804ac70a348da0fd38622a0e4.json new file mode 100644 index 00000000000..120bf2dd919 --- /dev/null +++ b/.changes/next-release/feature-e8b0c9d42596402804ac70a348da0fd38622a0e4.json @@ -0,0 +1,7 @@ +{ + "type": "feature", + "description": "Add new build transform CompileBddFromEndpointRuleSet", + "pull_requests": [ + "[#2953](https://github.com/smithy-lang/smithy/pull/2953)" + ] +} From e365f44aff43f59ec944a9cc2f6f1ca167e8d87a Mon Sep 17 00:00:00 2001 From: Joe Wu Date: Mon, 2 Feb 2026 13:56:30 -0800 Subject: [PATCH 3/5] Split transform into two and move to different packages --- .../rules-engine/specification.rst | 5 +- docs/source-2.0/guides/smithy-build-json.rst | 16 ++++- .../aws/language/functions/S3BddTest.java | 15 +++++ .../rulesengine/aws/s3/CompileBddForS3.java | 30 +++------ ....amazon.smithy.build.ProjectionTransformer | 1 + smithy-build/build.gradle.kts | 2 - ....amazon.smithy.build.ProjectionTransformer | 1 - smithy-rules-engine/build.gradle.kts | 1 + .../rulesengine/transforms/CompileBdd.java | 64 +++++++++++++++++++ ....amazon.smithy.build.ProjectionTransformer | 1 + .../transforms/CompileBddTest.java | 10 +-- .../rulesengine/transforms/compile-bdd.smithy | 0 12 files changed, 112 insertions(+), 34 deletions(-) rename smithy-build/src/main/java/software/amazon/smithy/build/transforms/CompileBddFromEndpointRuleSet.java => smithy-aws-endpoints/src/main/java/software/amazon/smithy/rulesengine/aws/s3/CompileBddForS3.java (68%) create mode 100644 smithy-aws-endpoints/src/main/resources/META-INF/services/software.amazon.smithy.build.ProjectionTransformer create mode 100644 smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/transforms/CompileBdd.java create mode 100644 smithy-rules-engine/src/main/resources/META-INF/services/software.amazon.smithy.build.ProjectionTransformer rename smithy-build/src/test/java/software/amazon/smithy/build/transforms/CompileBddFromEndpointRuleSetTest.java => smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/transforms/CompileBddTest.java (79%) rename smithy-build/src/test/resources/software/amazon/smithy/build/transforms/compile-bdd-from-endpoint-ruleset.smithy => smithy-rules-engine/src/test/resources/software/amazon/smithy/rulesengine/transforms/compile-bdd.smithy (100%) diff --git a/docs/source-2.0/additional-specs/rules-engine/specification.rst b/docs/source-2.0/additional-specs/rules-engine/specification.rst index affd201fa74..9561260d2f1 100644 --- a/docs/source-2.0/additional-specs/rules-engine/specification.rst +++ b/docs/source-2.0/additional-specs/rules-engine/specification.rst @@ -109,9 +109,8 @@ runtime performance and reduced artifact sizes. .. note:: The ``endpointBdd`` trait can be generated from an ``endpointRuleSet`` trait through compilation. - To generate the ``endpointBdd`` trait for a service, add the - :ref:`compileBddFromEndpointRuleSet ` transform to the - ``smithy-build.json`` file. Services may provide either trait, with ``endpointBdd`` preferred for + To generate the ``endpointBdd`` trait for a service, add the :ref:`compileBdd ` transform + to the ``smithy-build.json`` file. Services may provide either trait, with ``endpointBdd`` preferred for production use due to its performance characteristics. The ``endpointBdd`` structure has the following properties: diff --git a/docs/source-2.0/guides/smithy-build-json.rst b/docs/source-2.0/guides/smithy-build-json.rst index 344a466bbcb..76d435c00bb 100644 --- a/docs/source-2.0/guides/smithy-build-json.rst +++ b/docs/source-2.0/guides/smithy-build-json.rst @@ -654,9 +654,9 @@ Only the following shape type changes are supported: .. seealso:: :ref:`changeStringEnumsToEnumShapes` -.. _compileBddFromEndpointRuleSet-transform: +.. _compileBdd-transform: -compileBddFromEndpointRuleSet +compileBdd ----------------------------- This transform compiles `Binary Decision Diagram (BDD) `_ @@ -671,13 +671,23 @@ the compiled :ref:`@endpointBdd ` trait to the s "exampleProjection": { "transforms": [ { - "name": "compileBddFromEndpointRuleSet" + "name": "compileBdd" } ] } + }, + "maven": { + "dependencies": [ + "software.amazon.smithy:smithy-rules-engine:__smithy_version__" + ] } } +.. note:: + ``S3`` has special tree transformations that dramatically improve the BDD compiled result both in size and + performance BDD compilation transform. To use it, please use the dedicated transform ``compileBddForS3`` and + include the dependency of ``software.amazon.smithy:smithy-aws-endpoints:__smithy_version__``. + .. _excludeShapesBySelector-transform: excludeShapesBySelector diff --git a/smithy-aws-endpoints/src/it/java/software/amazon/smithy/rulesengine/aws/language/functions/S3BddTest.java b/smithy-aws-endpoints/src/it/java/software/amazon/smithy/rulesengine/aws/language/functions/S3BddTest.java index fccf607f251..c3854d5139b 100644 --- a/smithy-aws-endpoints/src/it/java/software/amazon/smithy/rulesengine/aws/language/functions/S3BddTest.java +++ b/smithy-aws-endpoints/src/it/java/software/amazon/smithy/rulesengine/aws/language/functions/S3BddTest.java @@ -4,6 +4,8 @@ */ package software.amazon.smithy.rulesengine.aws.language.functions; +import static org.junit.jupiter.api.Assertions.assertTrue; + import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; @@ -11,12 +13,15 @@ import java.util.List; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; +import software.amazon.smithy.build.TransformContext; import software.amazon.smithy.model.Model; import software.amazon.smithy.model.node.Node; import software.amazon.smithy.model.shapes.ModelSerializer; import software.amazon.smithy.model.shapes.ServiceShape; +import software.amazon.smithy.model.shapes.Shape; import software.amazon.smithy.model.shapes.ShapeId; import software.amazon.smithy.rulesengine.analysis.BddCoverageChecker; +import software.amazon.smithy.rulesengine.aws.s3.CompileBddForS3; import software.amazon.smithy.rulesengine.aws.s3.S3TreeRewriter; import software.amazon.smithy.rulesengine.language.EndpointRuleSet; import software.amazon.smithy.rulesengine.language.evaluation.TestEvaluator; @@ -154,4 +159,14 @@ private void writeModelWithBddTrait(EndpointBddTrait bddTrait) { throw new RuntimeException("Failed to write S3 BDD model", e); } } + + @Test + void compileBddForS3AddedTrait() { + TransformContext context = TransformContext.builder() + .model(model) + .build(); + Model result = new CompileBddForS3().transform(context); + Shape serviceShape = result.expectShape(S3_SERVICE_ID); + assertTrue(serviceShape.hasTrait(EndpointBddTrait.ID)); + } } diff --git a/smithy-build/src/main/java/software/amazon/smithy/build/transforms/CompileBddFromEndpointRuleSet.java b/smithy-aws-endpoints/src/main/java/software/amazon/smithy/rulesengine/aws/s3/CompileBddForS3.java similarity index 68% rename from smithy-build/src/main/java/software/amazon/smithy/build/transforms/CompileBddFromEndpointRuleSet.java rename to smithy-aws-endpoints/src/main/java/software/amazon/smithy/rulesengine/aws/s3/CompileBddForS3.java index 4db01b7040b..fa2c1bb973e 100644 --- a/smithy-build/src/main/java/software/amazon/smithy/build/transforms/CompileBddFromEndpointRuleSet.java +++ b/smithy-aws-endpoints/src/main/java/software/amazon/smithy/rulesengine/aws/s3/CompileBddForS3.java @@ -2,7 +2,7 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0 */ -package software.amazon.smithy.build.transforms; +package software.amazon.smithy.rulesengine.aws.s3; import java.util.Collection; import java.util.HashSet; @@ -12,9 +12,7 @@ import software.amazon.smithy.model.Model; import software.amazon.smithy.model.shapes.ServiceShape; import software.amazon.smithy.model.shapes.Shape; -import software.amazon.smithy.model.shapes.ShapeId; import software.amazon.smithy.model.transform.ModelTransformer; -import software.amazon.smithy.rulesengine.aws.s3.S3TreeRewriter; import software.amazon.smithy.rulesengine.language.EndpointRuleSet; import software.amazon.smithy.rulesengine.language.evaluation.TestEvaluator; import software.amazon.smithy.rulesengine.logic.bdd.CostOptimization; @@ -26,15 +24,12 @@ import software.amazon.smithy.rulesengine.traits.EndpointTestsTrait; /** - * Compiles a Binary Decision Diagram (BDD) from a service's {@code @endpointRuleSet} - * trait and attaches the compiled {@code @endpointBdd} trait to the service shape. + * A dedicated transform to compile Binary Decision Diagram (BDD) from S3. */ -public final class CompileBddFromEndpointRuleSet implements ProjectionTransformer { - private static final ShapeId S3_SERVICE_ID = ShapeId.from("com.amazonaws.s3#AmazonS3"); - +public class CompileBddForS3 implements ProjectionTransformer { @Override public String getName() { - return "compileBddFromEndpointRuleSet"; + return "compileBddForS3"; } @Override @@ -43,17 +38,12 @@ public Model transform(TransformContext transformContext) { Collection shapes = new HashSet<>(); Set serviceShapes = model.getServiceShapes(); for (ServiceShape serviceShape : serviceShapes) { - if (serviceShape.hasTrait(EndpointRuleSetTrait.ID)) { - EndpointRuleSetTrait endpointRuleSetTrait = serviceShape.expectTrait(EndpointRuleSetTrait.class); - EndpointRuleSet rules = endpointRuleSetTrait.getEndpointRuleSet(); - // S3 has special tree transformations that dramatically improve the BDD compiled result - // both in size and performance - if (serviceShape.getId().equals(S3_SERVICE_ID)) { - rules = transformRulesetForS3(rules, serviceShape.expectTrait(EndpointTestsTrait.class)); - } - EndpointBddTrait bdd = compileBdd(rules); - shapes.add(serviceShape.toBuilder().addTrait(bdd).build()); - } + EndpointRuleSetTrait endpointRuleSetTrait = serviceShape.expectTrait(EndpointRuleSetTrait.class); + EndpointRuleSet rules = endpointRuleSetTrait.getEndpointRuleSet(); + EndpointRuleSet transformedRules = transformRulesetForS3(rules, + serviceShape.expectTrait(EndpointTestsTrait.class)); + EndpointBddTrait bdd = compileBdd(transformedRules); + shapes.add(serviceShape.toBuilder().addTrait(bdd).build()); } return ModelTransformer.create().replaceShapes(model, shapes); } diff --git a/smithy-aws-endpoints/src/main/resources/META-INF/services/software.amazon.smithy.build.ProjectionTransformer b/smithy-aws-endpoints/src/main/resources/META-INF/services/software.amazon.smithy.build.ProjectionTransformer new file mode 100644 index 00000000000..5d595ebe04a --- /dev/null +++ b/smithy-aws-endpoints/src/main/resources/META-INF/services/software.amazon.smithy.build.ProjectionTransformer @@ -0,0 +1 @@ +software.amazon.smithy.rulesengine.aws.s3.CompileBddForS3 \ No newline at end of file diff --git a/smithy-build/build.gradle.kts b/smithy-build/build.gradle.kts index 1afad8bf9da..a44ae728dd9 100644 --- a/smithy-build/build.gradle.kts +++ b/smithy-build/build.gradle.kts @@ -15,8 +15,6 @@ extra["moduleName"] = "software.amazon.smithy.build" dependencies { api(project(":smithy-utils")) api(project(":smithy-model")) - api(project(":smithy-rules-engine")) - api(project(":smithy-aws-endpoints")) // Allows testing of annotation processor testImplementation(libs.compile.testing) diff --git a/smithy-build/src/main/resources/META-INF/services/software.amazon.smithy.build.ProjectionTransformer b/smithy-build/src/main/resources/META-INF/services/software.amazon.smithy.build.ProjectionTransformer index fe2329d51d7..9a9afd233d3 100644 --- a/smithy-build/src/main/resources/META-INF/services/software.amazon.smithy.build.ProjectionTransformer +++ b/smithy-build/src/main/resources/META-INF/services/software.amazon.smithy.build.ProjectionTransformer @@ -1,7 +1,6 @@ software.amazon.smithy.build.transforms.Apply software.amazon.smithy.build.transforms.ChangeStringEnumsToEnumShapes software.amazon.smithy.build.transforms.ChangeTypes -software.amazon.smithy.build.transforms.CompileBddFromEndpointRuleSet software.amazon.smithy.build.transforms.ExcludeMetadata software.amazon.smithy.build.transforms.ExcludeShapesBySelector software.amazon.smithy.build.transforms.ExcludeShapesByTag diff --git a/smithy-rules-engine/build.gradle.kts b/smithy-rules-engine/build.gradle.kts index 8bf1bdd248d..0db26a1b1f2 100644 --- a/smithy-rules-engine/build.gradle.kts +++ b/smithy-rules-engine/build.gradle.kts @@ -13,6 +13,7 @@ extra["moduleName"] = "software.amazon.smithy.rulesengine" dependencies { api(project(":smithy-model")) + api(project(":smithy-build")) api(project(":smithy-utils")) api(project(":smithy-jmespath")) } diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/transforms/CompileBdd.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/transforms/CompileBdd.java new file mode 100644 index 00000000000..fc0935245f3 --- /dev/null +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/transforms/CompileBdd.java @@ -0,0 +1,64 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ +package software.amazon.smithy.rulesengine.transforms; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; +import software.amazon.smithy.build.ProjectionTransformer; +import software.amazon.smithy.build.TransformContext; +import software.amazon.smithy.model.Model; +import software.amazon.smithy.model.shapes.ServiceShape; +import software.amazon.smithy.model.shapes.Shape; +import software.amazon.smithy.model.transform.ModelTransformer; +import software.amazon.smithy.rulesengine.language.EndpointRuleSet; +import software.amazon.smithy.rulesengine.logic.bdd.CostOptimization; +import software.amazon.smithy.rulesengine.logic.bdd.SiftingOptimization; +import software.amazon.smithy.rulesengine.logic.cfg.Cfg; +import software.amazon.smithy.rulesengine.traits.EndpointBddTrait; +import software.amazon.smithy.rulesengine.traits.EndpointRuleSetTrait; + +/** + * Compiles a Binary Decision Diagram (BDD) from a service's {@code @endpointRuleSet} + * trait and attaches the compiled {@code @endpointBdd} trait to the service shape. + */ +public final class CompileBdd implements ProjectionTransformer { + + @Override + public String getName() { + return "compileBdd"; + } + + @Override + public Model transform(TransformContext transformContext) { + Model model = transformContext.getModel(); + Collection shapes = new HashSet<>(); + Set serviceShapes = model.getServiceShapes(); + for (ServiceShape serviceShape : serviceShapes) { + if (serviceShape.hasTrait(EndpointRuleSetTrait.ID)) { + EndpointRuleSetTrait endpointRuleSetTrait = serviceShape.expectTrait(EndpointRuleSetTrait.class); + EndpointRuleSet rules = endpointRuleSetTrait.getEndpointRuleSet(); + EndpointBddTrait bdd = compileBdd(rules); + shapes.add(serviceShape.toBuilder().addTrait(bdd).build()); + } + } + return ModelTransformer.create().replaceShapes(model, shapes); + } + + private EndpointBddTrait compileBdd(EndpointRuleSet rules) { + // Create the CFG to start BDD compilation process. + Cfg cfg = Cfg.from(rules); + EndpointBddTrait unoptimizedTrait = EndpointBddTrait.from(cfg); + + // Sift the BDD to shorten paths and reduce the BDD size. + EndpointBddTrait siftedTrait = SiftingOptimization.builder().cfg(cfg).build().apply(unoptimizedTrait); + + // "cost optimize" the BDD to ensure cheap conditions come first with up to 10% size impact. + EndpointBddTrait costOptimizedTrait = CostOptimization.builder().cfg(cfg).build().apply(siftedTrait); + + // Remove unreferenced conditions. This is destructive and further optimizations cannot be applied after this. + return costOptimizedTrait.removeUnreferencedConditions(); + } +} diff --git a/smithy-rules-engine/src/main/resources/META-INF/services/software.amazon.smithy.build.ProjectionTransformer b/smithy-rules-engine/src/main/resources/META-INF/services/software.amazon.smithy.build.ProjectionTransformer new file mode 100644 index 00000000000..e53a5b7644f --- /dev/null +++ b/smithy-rules-engine/src/main/resources/META-INF/services/software.amazon.smithy.build.ProjectionTransformer @@ -0,0 +1 @@ +software.amazon.smithy.rulesengine.transforms.CompileBdd \ No newline at end of file diff --git a/smithy-build/src/test/java/software/amazon/smithy/build/transforms/CompileBddFromEndpointRuleSetTest.java b/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/transforms/CompileBddTest.java similarity index 79% rename from smithy-build/src/test/java/software/amazon/smithy/build/transforms/CompileBddFromEndpointRuleSetTest.java rename to smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/transforms/CompileBddTest.java index 0dd971340fb..dd6a57462fc 100644 --- a/smithy-build/src/test/java/software/amazon/smithy/build/transforms/CompileBddFromEndpointRuleSetTest.java +++ b/smithy-rules-engine/src/test/java/software/amazon/smithy/rulesengine/transforms/CompileBddTest.java @@ -2,9 +2,9 @@ * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. * SPDX-License-Identifier: Apache-2.0 */ -package software.amazon.smithy.build.transforms; +package software.amazon.smithy.rulesengine.transforms; -import static org.junit.Assert.assertTrue; +import static org.junit.jupiter.api.Assertions.assertTrue; import java.nio.file.Paths; import org.junit.jupiter.api.Test; @@ -14,20 +14,20 @@ import software.amazon.smithy.model.shapes.ShapeId; import software.amazon.smithy.rulesengine.traits.EndpointBddTrait; -public class CompileBddFromEndpointRuleSetTest { +public class CompileBddTest { @Test public void compilesAndAttachesBddTrait() throws Exception { ShapeId serviceId = ShapeId.from("smithy.example#ExampleService"); Model model = Model.assembler() .discoverModels() - .addImport(Paths.get(getClass().getResource("compile-bdd-from-endpoint-ruleset.smithy").toURI())) + .addImport(Paths.get(getClass().getResource("compile-bdd.smithy").toURI())) .assemble() .unwrap(); TransformContext context = TransformContext.builder() .model(model) .build(); - Model result = new CompileBddFromEndpointRuleSet().transform(context); + Model result = new CompileBdd().transform(context); Shape serviceShape = result.expectShape(serviceId); assertTrue(serviceShape.hasTrait(EndpointBddTrait.ID)); } diff --git a/smithy-build/src/test/resources/software/amazon/smithy/build/transforms/compile-bdd-from-endpoint-ruleset.smithy b/smithy-rules-engine/src/test/resources/software/amazon/smithy/rulesengine/transforms/compile-bdd.smithy similarity index 100% rename from smithy-build/src/test/resources/software/amazon/smithy/build/transforms/compile-bdd-from-endpoint-ruleset.smithy rename to smithy-rules-engine/src/test/resources/software/amazon/smithy/rulesengine/transforms/compile-bdd.smithy From 8214d76451af259b8012c6c712930de570b07428 Mon Sep 17 00:00:00 2001 From: Joe Wu Date: Tue, 3 Feb 2026 09:48:50 -0800 Subject: [PATCH 4/5] update changelog --- .../feature-e8b0c9d42596402804ac70a348da0fd38622a0e4.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changes/next-release/feature-e8b0c9d42596402804ac70a348da0fd38622a0e4.json b/.changes/next-release/feature-e8b0c9d42596402804ac70a348da0fd38622a0e4.json index 120bf2dd919..1792a3283d3 100644 --- a/.changes/next-release/feature-e8b0c9d42596402804ac70a348da0fd38622a0e4.json +++ b/.changes/next-release/feature-e8b0c9d42596402804ac70a348da0fd38622a0e4.json @@ -1,6 +1,6 @@ { "type": "feature", - "description": "Add new build transform CompileBddFromEndpointRuleSet", + "description": "Add new transform compileBdd and compileBddForS3", "pull_requests": [ "[#2953](https://github.com/smithy-lang/smithy/pull/2953)" ] From 3ee8880be1ab259336f4fe306daa967e1ff121aa Mon Sep 17 00:00:00 2001 From: Joe Wu Date: Tue, 3 Feb 2026 14:33:57 -0800 Subject: [PATCH 5/5] make compileBddForS3 aws generic --- ...0c9d42596402804ac70a348da0fd38622a0e4.json | 2 +- .../rules-engine/specification.rst | 5 +- docs/source-2.0/guides/smithy-build-json.rst | 4 +- .../aws/language/functions/S3BddTest.java | 4 +- .../rulesengine/aws/s3/CompileBddForS3.java | 74 ------------------- .../aws/transforms/CompileBddForAws.java | 70 ++++++++++++++++++ ....amazon.smithy.build.ProjectionTransformer | 2 +- .../rulesengine/transforms/CompileBdd.java | 19 +++-- ....amazon.smithy.build.ProjectionTransformer | 2 +- 9 files changed, 91 insertions(+), 91 deletions(-) delete mode 100644 smithy-aws-endpoints/src/main/java/software/amazon/smithy/rulesengine/aws/s3/CompileBddForS3.java create mode 100644 smithy-aws-endpoints/src/main/java/software/amazon/smithy/rulesengine/aws/transforms/CompileBddForAws.java diff --git a/.changes/next-release/feature-e8b0c9d42596402804ac70a348da0fd38622a0e4.json b/.changes/next-release/feature-e8b0c9d42596402804ac70a348da0fd38622a0e4.json index 1792a3283d3..92d6212b5c3 100644 --- a/.changes/next-release/feature-e8b0c9d42596402804ac70a348da0fd38622a0e4.json +++ b/.changes/next-release/feature-e8b0c9d42596402804ac70a348da0fd38622a0e4.json @@ -1,6 +1,6 @@ { "type": "feature", - "description": "Add new transform compileBdd and compileBddForS3", + "description": "Add new transform compileBdd and compileBddForAws", "pull_requests": [ "[#2953](https://github.com/smithy-lang/smithy/pull/2953)" ] diff --git a/docs/source-2.0/additional-specs/rules-engine/specification.rst b/docs/source-2.0/additional-specs/rules-engine/specification.rst index 9561260d2f1..22abb1e9f46 100644 --- a/docs/source-2.0/additional-specs/rules-engine/specification.rst +++ b/docs/source-2.0/additional-specs/rules-engine/specification.rst @@ -110,8 +110,9 @@ runtime performance and reduced artifact sizes. The ``endpointBdd`` trait can be generated from an ``endpointRuleSet`` trait through compilation. To generate the ``endpointBdd`` trait for a service, add the :ref:`compileBdd ` transform - to the ``smithy-build.json`` file. Services may provide either trait, with ``endpointBdd`` preferred for - production use due to its performance characteristics. + to the ``smithy-build.json`` file. + Services may provide either trait, with ``endpointBdd`` preferred for production use due to + its performance characteristics. The ``endpointBdd`` structure has the following properties: diff --git a/docs/source-2.0/guides/smithy-build-json.rst b/docs/source-2.0/guides/smithy-build-json.rst index 76d435c00bb..c1c7f0203c1 100644 --- a/docs/source-2.0/guides/smithy-build-json.rst +++ b/docs/source-2.0/guides/smithy-build-json.rst @@ -684,8 +684,8 @@ the compiled :ref:`@endpointBdd ` trait to the s } .. note:: - ``S3`` has special tree transformations that dramatically improve the BDD compiled result both in size and - performance BDD compilation transform. To use it, please use the dedicated transform ``compileBddForS3`` and + AWS services like ``S3`` can have special tree transformations that dramatically improve the BDD compiled result + both in size and performance. To use them, please use the dedicated transform ``compileBddForAws`` and include the dependency of ``software.amazon.smithy:smithy-aws-endpoints:__smithy_version__``. .. _excludeShapesBySelector-transform: diff --git a/smithy-aws-endpoints/src/it/java/software/amazon/smithy/rulesengine/aws/language/functions/S3BddTest.java b/smithy-aws-endpoints/src/it/java/software/amazon/smithy/rulesengine/aws/language/functions/S3BddTest.java index c3854d5139b..ca7a35a1af2 100644 --- a/smithy-aws-endpoints/src/it/java/software/amazon/smithy/rulesengine/aws/language/functions/S3BddTest.java +++ b/smithy-aws-endpoints/src/it/java/software/amazon/smithy/rulesengine/aws/language/functions/S3BddTest.java @@ -21,8 +21,8 @@ import software.amazon.smithy.model.shapes.Shape; import software.amazon.smithy.model.shapes.ShapeId; import software.amazon.smithy.rulesengine.analysis.BddCoverageChecker; -import software.amazon.smithy.rulesengine.aws.s3.CompileBddForS3; import software.amazon.smithy.rulesengine.aws.s3.S3TreeRewriter; +import software.amazon.smithy.rulesengine.aws.transforms.CompileBddForAws; import software.amazon.smithy.rulesengine.language.EndpointRuleSet; import software.amazon.smithy.rulesengine.language.evaluation.TestEvaluator; import software.amazon.smithy.rulesengine.logic.bdd.CostOptimization; @@ -165,7 +165,7 @@ void compileBddForS3AddedTrait() { TransformContext context = TransformContext.builder() .model(model) .build(); - Model result = new CompileBddForS3().transform(context); + Model result = new CompileBddForAws().transform(context); Shape serviceShape = result.expectShape(S3_SERVICE_ID); assertTrue(serviceShape.hasTrait(EndpointBddTrait.ID)); } diff --git a/smithy-aws-endpoints/src/main/java/software/amazon/smithy/rulesengine/aws/s3/CompileBddForS3.java b/smithy-aws-endpoints/src/main/java/software/amazon/smithy/rulesengine/aws/s3/CompileBddForS3.java deleted file mode 100644 index fa2c1bb973e..00000000000 --- a/smithy-aws-endpoints/src/main/java/software/amazon/smithy/rulesengine/aws/s3/CompileBddForS3.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0 - */ -package software.amazon.smithy.rulesengine.aws.s3; - -import java.util.Collection; -import java.util.HashSet; -import java.util.Set; -import software.amazon.smithy.build.ProjectionTransformer; -import software.amazon.smithy.build.TransformContext; -import software.amazon.smithy.model.Model; -import software.amazon.smithy.model.shapes.ServiceShape; -import software.amazon.smithy.model.shapes.Shape; -import software.amazon.smithy.model.transform.ModelTransformer; -import software.amazon.smithy.rulesengine.language.EndpointRuleSet; -import software.amazon.smithy.rulesengine.language.evaluation.TestEvaluator; -import software.amazon.smithy.rulesengine.logic.bdd.CostOptimization; -import software.amazon.smithy.rulesengine.logic.bdd.SiftingOptimization; -import software.amazon.smithy.rulesengine.logic.cfg.Cfg; -import software.amazon.smithy.rulesengine.traits.EndpointBddTrait; -import software.amazon.smithy.rulesengine.traits.EndpointRuleSetTrait; -import software.amazon.smithy.rulesengine.traits.EndpointTestCase; -import software.amazon.smithy.rulesengine.traits.EndpointTestsTrait; - -/** - * A dedicated transform to compile Binary Decision Diagram (BDD) from S3. - */ -public class CompileBddForS3 implements ProjectionTransformer { - @Override - public String getName() { - return "compileBddForS3"; - } - - @Override - public Model transform(TransformContext transformContext) { - Model model = transformContext.getModel(); - Collection shapes = new HashSet<>(); - Set serviceShapes = model.getServiceShapes(); - for (ServiceShape serviceShape : serviceShapes) { - EndpointRuleSetTrait endpointRuleSetTrait = serviceShape.expectTrait(EndpointRuleSetTrait.class); - EndpointRuleSet rules = endpointRuleSetTrait.getEndpointRuleSet(); - EndpointRuleSet transformedRules = transformRulesetForS3(rules, - serviceShape.expectTrait(EndpointTestsTrait.class)); - EndpointBddTrait bdd = compileBdd(transformedRules); - shapes.add(serviceShape.toBuilder().addTrait(bdd).build()); - } - return ModelTransformer.create().replaceShapes(model, shapes); - } - - private EndpointRuleSet transformRulesetForS3(EndpointRuleSet rules, EndpointTestsTrait testsTrait) { - EndpointRuleSet transformedRules = S3TreeRewriter.transform(rules); - // Verify transforms preserve semantics by running all test cases - for (EndpointTestCase testCase : testsTrait.getTestCases()) { - TestEvaluator.evaluate(transformedRules, testCase); - } - return transformedRules; - } - - private EndpointBddTrait compileBdd(EndpointRuleSet rules) { - // Create the CFG to start BDD compilation process. - Cfg cfg = Cfg.from(rules); - EndpointBddTrait unoptimizedTrait = EndpointBddTrait.from(cfg); - - // Sift the BDD to shorten paths and reduce the BDD size. - EndpointBddTrait siftedTrait = SiftingOptimization.builder().cfg(cfg).build().apply(unoptimizedTrait); - - // "cost optimize" the BDD to ensure cheap conditions come first with up to 10% size impact. - EndpointBddTrait costOptimizedTrait = CostOptimization.builder().cfg(cfg).build().apply(siftedTrait); - - // Remove unreferenced conditions. This is destructive and further optimizations cannot be applied after this. - return costOptimizedTrait.removeUnreferencedConditions(); - } -} diff --git a/smithy-aws-endpoints/src/main/java/software/amazon/smithy/rulesengine/aws/transforms/CompileBddForAws.java b/smithy-aws-endpoints/src/main/java/software/amazon/smithy/rulesengine/aws/transforms/CompileBddForAws.java new file mode 100644 index 00000000000..1b44bef2788 --- /dev/null +++ b/smithy-aws-endpoints/src/main/java/software/amazon/smithy/rulesengine/aws/transforms/CompileBddForAws.java @@ -0,0 +1,70 @@ +/* + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ +package software.amazon.smithy.rulesengine.aws.transforms; + +import static software.amazon.smithy.rulesengine.transforms.CompileBdd.compileBdd; + +import java.util.HashSet; +import java.util.Set; +import software.amazon.smithy.build.ProjectionTransformer; +import software.amazon.smithy.build.TransformContext; +import software.amazon.smithy.model.Model; +import software.amazon.smithy.model.shapes.ServiceShape; +import software.amazon.smithy.model.shapes.Shape; +import software.amazon.smithy.model.shapes.ShapeId; +import software.amazon.smithy.model.transform.ModelTransformer; +import software.amazon.smithy.rulesengine.aws.s3.S3TreeRewriter; +import software.amazon.smithy.rulesengine.language.EndpointRuleSet; +import software.amazon.smithy.rulesengine.language.evaluation.TestEvaluator; +import software.amazon.smithy.rulesengine.traits.EndpointBddTrait; +import software.amazon.smithy.rulesengine.traits.EndpointRuleSetTrait; +import software.amazon.smithy.rulesengine.traits.EndpointTestCase; +import software.amazon.smithy.rulesengine.traits.EndpointTestsTrait; + +/** + * A dedicated transform to compile Binary Decision Diagram (BDD) from AWS services. + */ +public final class CompileBddForAws implements ProjectionTransformer { + + private static final ShapeId S3_SERVICE_ID = ShapeId.from("com.amazonaws.s3#AmazonS3"); + + @Override + public String getName() { + return "compileBddForAws"; + } + + @Override + public Model transform(TransformContext transformContext) { + Model model = transformContext.getModel(); + Set shapes = new HashSet<>(); + for (ServiceShape serviceShape : model.getServiceShapes()) { + if (serviceShape.hasTrait(EndpointRuleSetTrait.ID) + && !serviceShape.hasTrait(EndpointBddTrait.ID)) { + EndpointRuleSet rules = getEndpointRuleSet(serviceShape); + EndpointBddTrait bdd = compileBdd(rules); + shapes.add(serviceShape.toBuilder().addTrait(bdd).build()); + } + } + return ModelTransformer.create().replaceShapes(model, shapes); + } + + private EndpointRuleSet getEndpointRuleSet(ServiceShape serviceShape) { + EndpointRuleSet rules = serviceShape.expectTrait(EndpointRuleSetTrait.class).getEndpointRuleSet(); + if (serviceShape.getId().equals(S3_SERVICE_ID)) { + return applyS3Transform(rules, serviceShape); + } + return rules; + } + + private EndpointRuleSet applyS3Transform(EndpointRuleSet rules, ServiceShape serviceShape) { + EndpointRuleSet transformedRules = S3TreeRewriter.transform(rules); + serviceShape.getTrait(EndpointTestsTrait.class).ifPresent(testsTrait -> { + for (EndpointTestCase testCase : testsTrait.getTestCases()) { + TestEvaluator.evaluate(transformedRules, testCase); + } + }); + return transformedRules; + } +} diff --git a/smithy-aws-endpoints/src/main/resources/META-INF/services/software.amazon.smithy.build.ProjectionTransformer b/smithy-aws-endpoints/src/main/resources/META-INF/services/software.amazon.smithy.build.ProjectionTransformer index 5d595ebe04a..1ecd1ba6db5 100644 --- a/smithy-aws-endpoints/src/main/resources/META-INF/services/software.amazon.smithy.build.ProjectionTransformer +++ b/smithy-aws-endpoints/src/main/resources/META-INF/services/software.amazon.smithy.build.ProjectionTransformer @@ -1 +1 @@ -software.amazon.smithy.rulesengine.aws.s3.CompileBddForS3 \ No newline at end of file +software.amazon.smithy.rulesengine.aws.transforms.CompileBddForAws diff --git a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/transforms/CompileBdd.java b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/transforms/CompileBdd.java index fc0935245f3..bb9b7451dfd 100644 --- a/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/transforms/CompileBdd.java +++ b/smithy-rules-engine/src/main/java/software/amazon/smithy/rulesengine/transforms/CompileBdd.java @@ -4,7 +4,6 @@ */ package software.amazon.smithy.rulesengine.transforms; -import java.util.Collection; import java.util.HashSet; import java.util.Set; import software.amazon.smithy.build.ProjectionTransformer; @@ -34,20 +33,24 @@ public String getName() { @Override public Model transform(TransformContext transformContext) { Model model = transformContext.getModel(); - Collection shapes = new HashSet<>(); - Set serviceShapes = model.getServiceShapes(); - for (ServiceShape serviceShape : serviceShapes) { - if (serviceShape.hasTrait(EndpointRuleSetTrait.ID)) { + Set shapes = new HashSet<>(); + for (ServiceShape serviceShape : model.getServiceShapes()) { + if (serviceShape.hasTrait(EndpointRuleSetTrait.ID) + && !serviceShape.hasTrait(EndpointBddTrait.ID)) { EndpointRuleSetTrait endpointRuleSetTrait = serviceShape.expectTrait(EndpointRuleSetTrait.class); - EndpointRuleSet rules = endpointRuleSetTrait.getEndpointRuleSet(); - EndpointBddTrait bdd = compileBdd(rules); + EndpointBddTrait bdd = compileBdd(endpointRuleSetTrait.getEndpointRuleSet()); shapes.add(serviceShape.toBuilder().addTrait(bdd).build()); } } return ModelTransformer.create().replaceShapes(model, shapes); } - private EndpointBddTrait compileBdd(EndpointRuleSet rules) { + /** + * Compile endpointBdd trait from endpoint ruleset and return the optimized version. + * + * @param rules Endpoint ruleset from service shape. + */ + public static EndpointBddTrait compileBdd(EndpointRuleSet rules) { // Create the CFG to start BDD compilation process. Cfg cfg = Cfg.from(rules); EndpointBddTrait unoptimizedTrait = EndpointBddTrait.from(cfg); diff --git a/smithy-rules-engine/src/main/resources/META-INF/services/software.amazon.smithy.build.ProjectionTransformer b/smithy-rules-engine/src/main/resources/META-INF/services/software.amazon.smithy.build.ProjectionTransformer index e53a5b7644f..3e2e71004a5 100644 --- a/smithy-rules-engine/src/main/resources/META-INF/services/software.amazon.smithy.build.ProjectionTransformer +++ b/smithy-rules-engine/src/main/resources/META-INF/services/software.amazon.smithy.build.ProjectionTransformer @@ -1 +1 @@ -software.amazon.smithy.rulesengine.transforms.CompileBdd \ No newline at end of file +software.amazon.smithy.rulesengine.transforms.CompileBdd