2121import software .amazon .smithy .rulesengine .language .syntax .parameters .Parameter ;
2222import software .amazon .smithy .rulesengine .language .syntax .parameters .Parameters ;
2323import software .amazon .smithy .rulesengine .language .syntax .rule .Condition ;
24+ import software .amazon .smithy .rulesengine .language .syntax .rule .EndpointRule ;
25+ import software .amazon .smithy .rulesengine .language .syntax .rule .ErrorRule ;
2426import software .amazon .smithy .rulesengine .language .syntax .rule .Rule ;
2527import software .amazon .smithy .rulesengine .language .syntax .rule .RuleValueVisitor ;
28+ import software .amazon .smithy .rulesengine .logic .RuleBasedConditionEvaluator ;
29+ import software .amazon .smithy .rulesengine .logic .bdd .Bdd ;
30+ import software .amazon .smithy .rulesengine .logic .bdd .BddEvaluator ;
2631import software .amazon .smithy .utils .SmithyUnstableApi ;
2732
2833/**
@@ -45,6 +50,44 @@ public static Value evaluate(EndpointRuleSet ruleset, Map<Identifier, Value> par
4550 return new RuleEvaluator ().evaluateRuleSet (ruleset , parameterArguments );
4651 }
4752
53+ /**
54+ * Initializes a new {@link RuleEvaluator} instances, and evaluates the provided BDD and parameter arguments.
55+ *
56+ * @param bdd The endpoint bdd.
57+ * @param parameterArguments The rule-set parameter identifiers and values to evaluate the BDD against.
58+ * @return The resulting value from the final matched rule.
59+ */
60+ public static Value evaluate (Bdd bdd , Map <Identifier , Value > parameterArguments ) {
61+ return new RuleEvaluator ().evaluateBdd (bdd , parameterArguments );
62+ }
63+
64+ private Value evaluateBdd (Bdd bdd , Map <Identifier , Value > parameterArguments ) {
65+ return scope .inScope (() -> {
66+ for (Parameter parameter : bdd .getParameters ()) {
67+ parameter .getDefault ().ifPresent (value -> scope .insert (parameter .getName (), value ));
68+ }
69+
70+ parameterArguments .forEach (scope ::insert );
71+ BddEvaluator evaluator = BddEvaluator .from (bdd );
72+ Condition [] conds = bdd .getConditions ().toArray (new Condition [0 ]);
73+ RuleBasedConditionEvaluator conditionEvaluator = new RuleBasedConditionEvaluator (this , conds );
74+ int result = evaluator .evaluate (conditionEvaluator );
75+
76+ if (result <= 0 ) {
77+ throw new RuntimeException ("No BDD result matched" );
78+ }
79+
80+ Rule rule = bdd .getResults ().get (result );
81+ if (rule instanceof EndpointRule ) {
82+ return resolveEndpoint (this , ((EndpointRule ) rule ).getEndpoint ());
83+ } else if (rule instanceof ErrorRule ) {
84+ return resolveError (this , ((ErrorRule ) rule ).getError ());
85+ } else {
86+ throw new RuntimeException ("Invalid BDD rule result: " + rule );
87+ }
88+ });
89+ }
90+
4891 /**
4992 * Evaluate the provided ruleset and parameter arguments.
5093 *
@@ -175,32 +218,40 @@ public Value visitTreeRule(List<Rule> rules) {
175218
176219 @ Override
177220 public Value visitErrorRule (Expression error ) {
178- return error . accept (self );
221+ return resolveError (self , error );
179222 }
180223
181224 @ Override
182225 public Value visitEndpointRule (Endpoint endpoint ) {
183- EndpointValue .Builder builder = EndpointValue .builder ()
184- .sourceLocation (endpoint )
185- .url (endpoint .getUrl ()
186- .accept (RuleEvaluator .this )
187- .expectStringValue ()
188- .getValue ());
189-
190- for (Map .Entry <Identifier , Literal > entry : endpoint .getProperties ().entrySet ()) {
191- builder .putProperty (entry .getKey ().toString (), entry .getValue ().accept (RuleEvaluator .this ));
192- }
193-
194- for (Map .Entry <String , List <Expression >> entry : endpoint .getHeaders ().entrySet ()) {
195- List <String > values = new ArrayList <>();
196- for (Expression expression : entry .getValue ()) {
197- values .add (expression .accept (RuleEvaluator .this ).expectStringValue ().getValue ());
198- }
199- builder .putHeader (entry .getKey (), values );
200- }
201- return builder .build ();
226+ return resolveEndpoint (self , endpoint );
202227 }
203228 });
204229 });
205230 }
231+
232+ private static Value resolveEndpoint (RuleEvaluator self , Endpoint endpoint ) {
233+ EndpointValue .Builder builder = EndpointValue .builder ()
234+ .sourceLocation (endpoint )
235+ .url (endpoint .getUrl ()
236+ .accept (self )
237+ .expectStringValue ()
238+ .getValue ());
239+
240+ for (Map .Entry <Identifier , Literal > entry : endpoint .getProperties ().entrySet ()) {
241+ builder .putProperty (entry .getKey ().toString (), entry .getValue ().accept (self ));
242+ }
243+
244+ for (Map .Entry <String , List <Expression >> entry : endpoint .getHeaders ().entrySet ()) {
245+ List <String > values = new ArrayList <>();
246+ for (Expression expression : entry .getValue ()) {
247+ values .add (expression .accept (self ).expectStringValue ().getValue ());
248+ }
249+ builder .putHeader (entry .getKey (), values );
250+ }
251+ return builder .build ();
252+ }
253+
254+ private static Value resolveError (RuleEvaluator self , Expression error ) {
255+ return error .accept (self );
256+ }
206257}
0 commit comments