From aa2ac9f969ba0bd8e0bd42aa601140b0e109227b Mon Sep 17 00:00:00 2001 From: Bert Blommers Date: Sat, 14 Dec 2024 12:19:14 -0100 Subject: [PATCH] StepFunctions: Various upgrades --- moto/core/versions.py | 1 + moto/stepfunctions/models.py | 11 +- moto/stepfunctions/parser/README.md | 2 +- moto/stepfunctions/parser/api.py | 289 +- .../parser/asl/antlr/ASLIntrinsicLexer.g4 | 3 + .../parser/asl/antlr/ASLIntrinsicParser.g4 | 1 + .../parser/asl/antlr/ASLLexer.g4 | 42 +- .../parser/asl/antlr/ASLParser.g4 | 291 +- .../antlr/runtime/ASLIntrinsicLexer.interp | 148 - .../asl/antlr/runtime/ASLIntrinsicLexer.py | 1671 +- .../antlr/runtime/ASLIntrinsicLexer.tokens | 79 - .../antlr/runtime/ASLIntrinsicParser.interp | 108 - .../asl/antlr/runtime/ASLIntrinsicParser.py | 199 +- .../antlr/runtime/ASLIntrinsicParser.tokens | 79 - .../runtime/ASLIntrinsicParserListener.py | 10 +- .../runtime/ASLIntrinsicParserVisitor.py | 6 +- .../parser/asl/antlr/runtime/ASLLexer.interp | 421 - .../parser/asl/antlr/runtime/ASLLexer.py | 19019 +++++++------ .../parser/asl/antlr/runtime/ASLLexer.tokens | 259 - .../parser/asl/antlr/runtime/ASLParser.interp | 364 - .../parser/asl/antlr/runtime/ASLParser.py | 22860 +++++++++++----- .../parser/asl/antlr/runtime/ASLParser.tokens | 259 - .../asl/antlr/runtime/ASLParserListener.py | 1010 +- .../asl/antlr/runtime/ASLParserVisitor.py | 506 +- .../common/assign}/__init__.py | 0 .../component/common/assign/assign_decl.py | 24 + .../common/assign/assign_decl_binding.py | 17 + .../common/assign/assign_template_binding.py | 106 + .../common/assign/assign_template_value.py | 6 + .../assign/assign_template_value_array.py | 20 + .../assign/assign_template_value_object.py | 21 + .../assign/assign_template_value_terminal.py | 94 + .../component/common/catch/catcher_decl.py | 71 +- .../common/error_name/custom_error_name.py | 12 +- .../component/common/error_name/error_name.py | 10 +- .../common/error_name/failure_event.py | 55 +- .../error_name/states_error_name_type.py | 2 + .../asl/component/common/jsonata/__init__.py | 0 .../jsonata/jsonata_template_binding.py | 23 + .../common/jsonata/jsonata_template_value.py | 6 + .../jsonata/jsonata_template_value_array.py | 20 + .../jsonata/jsonata_template_value_object.py | 21 + .../jsonata_template_value_terminal.py | 87 + .../parser/asl/component/common/outputdecl.py | 17 + .../parser/asl/component/common/parameters.py | 15 - .../parser/asl/component/common/parargs.py | 30 + .../asl/component/common/path/input_path.py | 49 +- .../asl/component/common/path/items_path.py | 42 +- .../asl/component/common/path/output_path.py | 48 +- .../asl/component/common/path/result_path.py | 2 +- .../payload_binding_intrinsic_func.py | 4 +- .../payloadbinding/payload_binding_path.py | 5 +- .../payload_binding_path_context_obj.py | 13 +- .../payloadbinding/payload_binding_var.py | 27 + .../payload_value_variable_sample.py | 18 + .../asl/component/common/query_language.py | 29 + .../asl/component/common/result_selector.py | 4 +- .../common/retry/interval_seconds_decl.py | 4 +- .../component/common/retry/retrier_decl.py | 5 +- .../component/common/timeouts/heartbeat.py | 48 +- .../asl/component/common/timeouts/timeout.py | 51 +- .../asl/component/common/variable_sample.py | 55 + .../parser/asl/component/eval_component.py | 18 +- .../function_argument_context_path.py | 6 +- .../argument/function_argument_json_path.py | 4 +- .../argument/function_argument_var.py | 20 + .../function/statesfunction/factory.py | 1 + .../statesfunction/generic/string_format.py | 11 +- .../string_operations/string_split.py | 5 +- .../parser/asl/component/intrinsic/jsonata.py | 85 + .../parser/asl/component/program/program.py | 47 +- .../asl/component/{ => program}/states.py | 0 .../component/{common => program}/version.py | 0 .../asl/component/state/choice/choice_rule.py | 10 +- .../state/choice/comparison/comparison.py | 138 +- .../choice/comparison/comparison_composite.py | 101 - .../choice/comparison/comparison_func.py | 55 +- .../choice/comparison/comparison_type.py | 8 + .../choice/comparison/comparison_variable.py | 6 +- .../choice/comparison/operator/factory.py | 2 +- .../implementations/boolean_equals.py | 4 +- .../operator/implementations/is_operator.py | 4 +- .../operator/implementations/numeric.py | 12 +- .../implementations/string_operators.py | 12 +- .../implementations/timestamp_operators.py | 12 +- .../state/choice/comparison/variable.py | 38 +- .../component/state/choice/state_choice.py | 11 +- .../asl/component/state/exec/execute_state.py | 64 +- .../transformer_csv.py | 1 + .../transformer_json.py | 1 + .../state_map/item_reader/item_reader_decl.py | 13 +- .../reader_config/max_items_decl.py | 45 +- .../reader_config/reader_config_props.py | 4 +- .../state/exec/state_map/items/__init__.py | 0 .../state/exec/state_map/items/items.py | 98 + .../distributed_iteration_component.py | 127 +- .../iteration/inline_iteration_component.py | 45 +- .../distributed_item_processor.py | 42 +- .../distributed_item_processor_worker.py | 61 +- .../itemprocessor/inline_item_processor.py | 40 +- .../inline_item_processor_worker.py | 22 +- .../itemprocessor/item_processor_decl.py | 20 +- .../itemprocessor/item_processor_factory.py | 4 +- .../iteration/itemprocessor/map_run_record.py | 66 +- .../iteration/iteration_component.py | 16 +- .../iteration/iteration_declaration.py | 14 +- .../state_map/iteration/iteration_worker.py | 59 +- .../iterator/distributed_iterator.py | 59 + .../iterator/distributed_iterator_worker.py | 133 + .../iteration/iterator/inline_iterator.py | 45 + .../iterator/inline_iterator_worker.py | 48 + .../state_map/iteration/iterator/iterator.py | 61 - .../iteration/iterator/iterator_factory.py | 38 + .../iteration/iterator/iterator_worker.py | 37 - .../state/exec/state_map/iteration/job.py | 10 +- .../state/exec/state_map/max_concurrency.py | 60 +- .../exec/state_map/result_writer/__init__.py | 0 .../result_writer/resource_eval/__init__.py | 0 .../resource_eval/resource_eval.py | 15 + .../resource_eval/resource_eval_factory.py | 19 + .../resource_eval/resource_eval_s3.py | 75 + .../result_writer/result_writer_decl.py | 44 + .../state/exec/state_map/state_map.py | 226 +- .../state/exec/state_map/tolerated_failure.py | 109 +- .../exec/state_parallel/branch_worker.py | 8 +- .../exec/state_parallel/branches_decl.py | 14 +- .../exec/state_parallel/state_parallel.py | 40 +- .../state/exec/state_task/credentials.py | 104 + .../exec/state_task/lambda_eval_utils.py | 6 +- .../state_task/service/state_task_service.py | 136 +- .../service/state_task_service_api_gateway.py | 9 + .../service/state_task_service_aws_sdk.py | 14 +- .../service/state_task_service_batch.py | 207 + .../service/state_task_service_callback.py | 340 +- .../service/state_task_service_dynamodb.py | 117 +- .../service/state_task_service_ecs.py | 130 + .../service/state_task_service_events.py | 39 +- .../service/state_task_service_factory.py | 40 +- .../service/state_task_service_glue.py | 233 + .../service/state_task_service_lambda.py | 76 +- .../service/state_task_service_sfn.py | 215 +- .../service/state_task_service_sns.py | 41 +- .../service/state_task_service_sqs.py | 52 +- .../service/state_task_service_unsupported.py | 60 + .../state/exec/state_task/state_task.py | 37 +- .../exec/state_task/state_task_activitiy.py | 223 + .../exec/state_task/state_task_factory.py | 12 +- .../exec/state_task/state_task_lambda.py | 85 +- .../asl/component/state/fail/cause_decl.py | 91 +- .../asl/component/state/fail/cause_path.py | 50 - .../asl/component/state/fail/error_decl.py | 91 +- .../asl/component/state/fail/error_path.py | 50 - .../asl/component/state/fail/state_fail.py | 7 +- .../parser/asl/component/state/state.py | 184 +- .../asl/component/state/state_pass/result.py | 12 +- .../component/state/state_pass/state_pass.py | 39 +- .../parser/asl/component/state/state_props.py | 30 +- .../component/state/state_succeed/__init__.py | 0 .../{ => state_succeed}/state_succeed.py | 0 .../asl/component/state/wait/state_wait.py | 2 + .../state/wait/wait_function/seconds.py | 26 +- .../state/wait/wait_function/seconds_path.py | 65 +- .../state/wait/wait_function/timestamp.py | 44 +- .../wait/wait_function/timestamp_path.py | 83 +- .../state/wait/wait_function/wait_function.py | 9 +- .../asl/component/test_state/__init__.py | 0 .../component/test_state/program/__init__.py | 0 .../test_state/program/test_state_program.py | 64 + .../component/test_state/state/__init__.py | 0 .../state/test_state_state_props.py | 29 + .../parser/asl/eval/aws_execution_details.py | 12 - .../parser/asl/eval/callback/callback.py | 123 +- .../parser/asl/eval/contex_object.py | 0 .../asl/eval/contextobject/contex_object.py | 62 - .../parser/asl/eval/environment.py | 136 +- .../parser/asl/eval/evaluation_details.py | 65 + .../parser/asl/eval/event/event_detail.py | 2 + .../parser/asl/eval/event/event_history.py | 88 - .../parser/asl/eval/event/event_manager.py | 216 + .../parser/asl/eval/event/logging.py | 271 + moto/stepfunctions/parser/asl/eval/states.py | 157 + .../parser/asl/eval/test_state/__init__.py | 0 .../parser/asl/eval/test_state/environment.py | 83 + .../asl/eval/test_state/program_state.py | 9 + .../parser/asl/eval/variable_store.py | 129 + .../parser/asl/jsonata/__init__.py | 0 .../parser/asl/jsonata/jsonata.py | 129 + .../parser/asl/jsonata/validations.py | 93 + .../parser/asl/parse/asl_parser.py | 24 +- .../asl/parse/intrinsic/intrinsic_parser.py | 6 +- .../asl/parse/intrinsic/preprocessor.py | 18 + .../parser/asl/parse/preprocessor.py | 1202 +- .../parser/asl/parse/test_state/__init__.py | 0 .../parser/asl/parse/test_state/asl_parser.py | 41 + .../asl/parse/test_state/preprocessor.py | 161 + .../parser/asl/static_analyser/__init__.py | 0 .../express_static_analyser.py | 34 + .../asl/static_analyser/intrinsic/__init__.py | 0 .../intrinsic/intrinsic_static_analyser.py | 14 + ...ariable_names_intrinsic_static_analyser.py | 43 + .../asl/static_analyser/static_analyser.py | 12 + .../static_analyser/test_state/__init__.py | 0 .../test_state/test_state_analyser.py | 51 + .../usage_metrics_static_analyser.py | 53 + .../variable_references_static_analyser.py | 110 + .../parser/asl/utils/boto_client.py | 6 +- .../parser/asl/utils/json_path.py | 50 +- moto/stepfunctions/parser/backend/activity.py | 51 + .../stepfunctions/parser/backend/execution.py | 316 +- .../parser/backend/execution_worker.py | 120 +- .../parser/backend/execution_worker_comm.py | 2 +- .../parser/backend/state_machine.py | 87 +- moto/stepfunctions/parser/backend/store.py | 22 + .../parser/backend/test_state/__init__.py | 0 .../parser/backend/test_state/execution.py | 145 + .../backend/test_state/execution_worker.py | 50 + moto/stepfunctions/parser/models.py | 17 +- moto/stepfunctions/parser/provider.py | 1401 + moto/stepfunctions/parser/quotas.py | 12 + ...aws_stepfunctions_statemachine.schema.json | 2 +- .../parser/stepfunctions_utils.py | 47 + moto/stepfunctions/parser/usage.py | 20 + moto/stepfunctions/parser/utils.py | 15 +- moto/stepfunctions/responses.py | 50 +- moto/utilities/collections.py | 28 + scripts/import_sfn_parser.sh | 110 + .../parser/templates/credentials.json | 14 + .../parser/test_parallel_states.py | 6 +- .../parser/test_stepfunctions.py | 14 +- 229 files changed, 39780 insertions(+), 20293 deletions(-) delete mode 100644 moto/stepfunctions/parser/asl/antlr/runtime/ASLIntrinsicLexer.interp delete mode 100644 moto/stepfunctions/parser/asl/antlr/runtime/ASLIntrinsicLexer.tokens delete mode 100644 moto/stepfunctions/parser/asl/antlr/runtime/ASLIntrinsicParser.interp delete mode 100644 moto/stepfunctions/parser/asl/antlr/runtime/ASLIntrinsicParser.tokens delete mode 100644 moto/stepfunctions/parser/asl/antlr/runtime/ASLLexer.interp delete mode 100644 moto/stepfunctions/parser/asl/antlr/runtime/ASLLexer.tokens delete mode 100644 moto/stepfunctions/parser/asl/antlr/runtime/ASLParser.interp delete mode 100644 moto/stepfunctions/parser/asl/antlr/runtime/ASLParser.tokens rename moto/stepfunctions/parser/asl/{eval/contextobject => component/common/assign}/__init__.py (100%) create mode 100644 moto/stepfunctions/parser/asl/component/common/assign/assign_decl.py create mode 100644 moto/stepfunctions/parser/asl/component/common/assign/assign_decl_binding.py create mode 100644 moto/stepfunctions/parser/asl/component/common/assign/assign_template_binding.py create mode 100644 moto/stepfunctions/parser/asl/component/common/assign/assign_template_value.py create mode 100644 moto/stepfunctions/parser/asl/component/common/assign/assign_template_value_array.py create mode 100644 moto/stepfunctions/parser/asl/component/common/assign/assign_template_value_object.py create mode 100644 moto/stepfunctions/parser/asl/component/common/assign/assign_template_value_terminal.py create mode 100644 moto/stepfunctions/parser/asl/component/common/jsonata/__init__.py create mode 100644 moto/stepfunctions/parser/asl/component/common/jsonata/jsonata_template_binding.py create mode 100644 moto/stepfunctions/parser/asl/component/common/jsonata/jsonata_template_value.py create mode 100644 moto/stepfunctions/parser/asl/component/common/jsonata/jsonata_template_value_array.py create mode 100644 moto/stepfunctions/parser/asl/component/common/jsonata/jsonata_template_value_object.py create mode 100644 moto/stepfunctions/parser/asl/component/common/jsonata/jsonata_template_value_terminal.py create mode 100644 moto/stepfunctions/parser/asl/component/common/outputdecl.py delete mode 100644 moto/stepfunctions/parser/asl/component/common/parameters.py create mode 100644 moto/stepfunctions/parser/asl/component/common/parargs.py create mode 100644 moto/stepfunctions/parser/asl/component/common/payload/payloadvalue/payloadbinding/payload_binding_var.py create mode 100644 moto/stepfunctions/parser/asl/component/common/payload/payloadvalue/payloadvaluelit/payload_value_variable_sample.py create mode 100644 moto/stepfunctions/parser/asl/component/common/query_language.py create mode 100644 moto/stepfunctions/parser/asl/component/common/variable_sample.py create mode 100644 moto/stepfunctions/parser/asl/component/intrinsic/argument/function_argument_var.py create mode 100644 moto/stepfunctions/parser/asl/component/intrinsic/jsonata.py rename moto/stepfunctions/parser/asl/component/{ => program}/states.py (100%) rename moto/stepfunctions/parser/asl/component/{common => program}/version.py (100%) delete mode 100644 moto/stepfunctions/parser/asl/component/state/choice/comparison/comparison_composite.py create mode 100644 moto/stepfunctions/parser/asl/component/state/choice/comparison/comparison_type.py create mode 100644 moto/stepfunctions/parser/asl/component/state/exec/state_map/items/__init__.py create mode 100644 moto/stepfunctions/parser/asl/component/state/exec/state_map/items/items.py create mode 100644 moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/iterator/distributed_iterator.py create mode 100644 moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/iterator/distributed_iterator_worker.py create mode 100644 moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/iterator/inline_iterator.py create mode 100644 moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/iterator/inline_iterator_worker.py delete mode 100644 moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/iterator/iterator.py create mode 100644 moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/iterator/iterator_factory.py delete mode 100644 moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/iterator/iterator_worker.py create mode 100644 moto/stepfunctions/parser/asl/component/state/exec/state_map/result_writer/__init__.py create mode 100644 moto/stepfunctions/parser/asl/component/state/exec/state_map/result_writer/resource_eval/__init__.py create mode 100644 moto/stepfunctions/parser/asl/component/state/exec/state_map/result_writer/resource_eval/resource_eval.py create mode 100644 moto/stepfunctions/parser/asl/component/state/exec/state_map/result_writer/resource_eval/resource_eval_factory.py create mode 100644 moto/stepfunctions/parser/asl/component/state/exec/state_map/result_writer/resource_eval/resource_eval_s3.py create mode 100644 moto/stepfunctions/parser/asl/component/state/exec/state_map/result_writer/result_writer_decl.py create mode 100644 moto/stepfunctions/parser/asl/component/state/exec/state_task/credentials.py create mode 100644 moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service_batch.py create mode 100644 moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service_ecs.py create mode 100644 moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service_glue.py create mode 100644 moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service_unsupported.py create mode 100644 moto/stepfunctions/parser/asl/component/state/exec/state_task/state_task_activitiy.py delete mode 100644 moto/stepfunctions/parser/asl/component/state/fail/cause_path.py delete mode 100644 moto/stepfunctions/parser/asl/component/state/fail/error_path.py create mode 100644 moto/stepfunctions/parser/asl/component/state/state_succeed/__init__.py rename moto/stepfunctions/parser/asl/component/state/{ => state_succeed}/state_succeed.py (100%) create mode 100644 moto/stepfunctions/parser/asl/component/test_state/__init__.py create mode 100644 moto/stepfunctions/parser/asl/component/test_state/program/__init__.py create mode 100644 moto/stepfunctions/parser/asl/component/test_state/program/test_state_program.py create mode 100644 moto/stepfunctions/parser/asl/component/test_state/state/__init__.py create mode 100644 moto/stepfunctions/parser/asl/component/test_state/state/test_state_state_props.py delete mode 100644 moto/stepfunctions/parser/asl/eval/aws_execution_details.py create mode 100644 moto/stepfunctions/parser/asl/eval/contex_object.py delete mode 100644 moto/stepfunctions/parser/asl/eval/contextobject/contex_object.py create mode 100644 moto/stepfunctions/parser/asl/eval/evaluation_details.py delete mode 100644 moto/stepfunctions/parser/asl/eval/event/event_history.py create mode 100644 moto/stepfunctions/parser/asl/eval/event/event_manager.py create mode 100644 moto/stepfunctions/parser/asl/eval/event/logging.py create mode 100644 moto/stepfunctions/parser/asl/eval/states.py create mode 100644 moto/stepfunctions/parser/asl/eval/test_state/__init__.py create mode 100644 moto/stepfunctions/parser/asl/eval/test_state/environment.py create mode 100644 moto/stepfunctions/parser/asl/eval/test_state/program_state.py create mode 100644 moto/stepfunctions/parser/asl/eval/variable_store.py create mode 100644 moto/stepfunctions/parser/asl/jsonata/__init__.py create mode 100644 moto/stepfunctions/parser/asl/jsonata/jsonata.py create mode 100644 moto/stepfunctions/parser/asl/jsonata/validations.py create mode 100644 moto/stepfunctions/parser/asl/parse/test_state/__init__.py create mode 100644 moto/stepfunctions/parser/asl/parse/test_state/asl_parser.py create mode 100644 moto/stepfunctions/parser/asl/parse/test_state/preprocessor.py create mode 100644 moto/stepfunctions/parser/asl/static_analyser/__init__.py create mode 100644 moto/stepfunctions/parser/asl/static_analyser/express_static_analyser.py create mode 100644 moto/stepfunctions/parser/asl/static_analyser/intrinsic/__init__.py create mode 100644 moto/stepfunctions/parser/asl/static_analyser/intrinsic/intrinsic_static_analyser.py create mode 100644 moto/stepfunctions/parser/asl/static_analyser/intrinsic/variable_names_intrinsic_static_analyser.py create mode 100644 moto/stepfunctions/parser/asl/static_analyser/static_analyser.py create mode 100644 moto/stepfunctions/parser/asl/static_analyser/test_state/__init__.py create mode 100644 moto/stepfunctions/parser/asl/static_analyser/test_state/test_state_analyser.py create mode 100644 moto/stepfunctions/parser/asl/static_analyser/usage_metrics_static_analyser.py create mode 100644 moto/stepfunctions/parser/asl/static_analyser/variable_references_static_analyser.py create mode 100644 moto/stepfunctions/parser/backend/activity.py create mode 100644 moto/stepfunctions/parser/backend/store.py create mode 100644 moto/stepfunctions/parser/backend/test_state/__init__.py create mode 100644 moto/stepfunctions/parser/backend/test_state/execution.py create mode 100644 moto/stepfunctions/parser/backend/test_state/execution_worker.py create mode 100644 moto/stepfunctions/parser/provider.py create mode 100644 moto/stepfunctions/parser/quotas.py create mode 100644 moto/stepfunctions/parser/stepfunctions_utils.py create mode 100644 moto/stepfunctions/parser/usage.py create mode 100644 moto/utilities/collections.py create mode 100755 scripts/import_sfn_parser.sh create mode 100644 tests/test_stepfunctions/parser/templates/credentials.json diff --git a/moto/core/versions.py b/moto/core/versions.py index cc2a6dba61ca..4b0d97ec1124 100644 --- a/moto/core/versions.py +++ b/moto/core/versions.py @@ -4,6 +4,7 @@ from moto.utilities.distutils_version import LooseVersion PYTHON_VERSION_INFO = sys.version_info +PYTHON_39 = sys.version_info >= (3, 9) PYTHON_311 = sys.version_info >= (3, 11) RESPONSES_VERSION = version("responses") WERKZEUG_VERSION = version("werkzeug") diff --git a/moto/stepfunctions/models.py b/moto/stepfunctions/models.py index f4726fed1d76..5a0ee9a1a4de 100644 --- a/moto/stepfunctions/models.py +++ b/moto/stepfunctions/models.py @@ -55,6 +55,7 @@ def __init__( } self.loggingConfiguration = loggingConfiguration or {"level": "OFF"} self.tracingConfiguration = tracingConfiguration or {"enabled": False} + self.sm_type = "STANDARD" # or express def start_execution( self, @@ -271,7 +272,7 @@ def __init__( ) self.execution_arn = execution_arn self.name = execution_name - self.start_date = iso_8601_datetime_with_milliseconds() + self.start_date = datetime.now() self.state_machine_arn = state_machine_arn self.execution_input = execution_input self.status = ( @@ -279,7 +280,7 @@ def __init__( if settings.get_sf_execution_history_type() == "SUCCESS" else "FAILED" ) - self.stop_date: Optional[str] = None + self.stop_date: Optional[datetime] = None self.account_id = account_id self.region_name = region_name self.output: Optional[str] = None @@ -388,7 +389,7 @@ def get_execution_history(self, roleArn: str) -> List[Dict[str, Any]]: def stop(self, *args: Any, **kwargs: Any) -> None: self.status = "ABORTED" - self.stop_date = iso_8601_datetime_with_milliseconds() + self.stop_date = datetime.now() class StepFunctionBackend(BaseBackend): @@ -644,7 +645,7 @@ def describe_execution(self, execution_arn: str) -> Execution: ) return exctn - def get_execution_history(self, execution_arn: str) -> List[Dict[str, Any]]: + def get_execution_history(self, execution_arn: str) -> Dict[str, Any]: self._validate_execution_arn(execution_arn) state_machine = self._get_state_machine_for_execution(execution_arn) execution = next( @@ -655,7 +656,7 @@ def get_execution_history(self, execution_arn: str) -> List[Dict[str, Any]]: raise ExecutionDoesNotExist( "Execution Does Not Exist: '" + execution_arn + "'" ) - return execution.get_execution_history(state_machine.roleArn) + return {"events": execution.get_execution_history(state_machine.roleArn)} def describe_state_machine_for_execution(self, execution_arn: str) -> StateMachine: for sm in self.state_machines: diff --git a/moto/stepfunctions/parser/README.md b/moto/stepfunctions/parser/README.md index af786b0a70f6..5f1b345f6345 100644 --- a/moto/stepfunctions/parser/README.md +++ b/moto/stepfunctions/parser/README.md @@ -1,3 +1,3 @@ In-memory ASL (Amazon StepFunctions Language) parser. -Created for Localstack by @mepalma (https://github.com/MEPalma) \ No newline at end of file +Created for Localstack by @mepalma (https://github.com/MEPalma). Latest commit: 235a06a07ee04a84e02e656f0924a8f4ea2e96a8 \ No newline at end of file diff --git a/moto/stepfunctions/parser/api.py b/moto/stepfunctions/parser/api.py index 436912ed3de3..8b8d11ba9f3e 100644 --- a/moto/stepfunctions/parser/api.py +++ b/moto/stepfunctions/parser/api.py @@ -1,15 +1,18 @@ from datetime import datetime -from typing import List, Optional, TypedDict +from enum import Enum +from typing import Dict, List, Optional, TypedDict from ..exceptions import AWSError as ServiceException AliasDescription = str +Arn = str CharacterRestrictedName = str ClientToken = str ConnectorParameters = str Definition = str Enabled = bool ErrorMessage = str +EvaluationFailureLocation = str HTTPBody = str HTTPHeaders = str HTTPMethod = str @@ -19,7 +22,10 @@ Identity = str IncludeExecutionData = bool IncludeExecutionDataGetExecutionHistory = bool +KmsDataKeyReusePeriodSeconds = int +KmsKeyId = str ListExecutionsPageToken = str +LongArn = str MapRunLabel = str MaxConcurrency = int Name = str @@ -42,24 +48,36 @@ TraceHeader = str URL = str UnsignedInteger = int +ValidateStateMachineDefinitionCode = str +ValidateStateMachineDefinitionLocation = str +ValidateStateMachineDefinitionMaxResult = int +ValidateStateMachineDefinitionMessage = str +ValidateStateMachineDefinitionTruncated = bool +VariableName = str +VariableValue = str VersionDescription = str VersionWeight = int includedDetails = bool truncated = bool -class ExecutionRedriveFilter(str): +class EncryptionType(str, Enum): + AWS_OWNED_KEY = "AWS_OWNED_KEY" + CUSTOMER_MANAGED_KMS_KEY = "CUSTOMER_MANAGED_KMS_KEY" + + +class ExecutionRedriveFilter(str, Enum): REDRIVEN = "REDRIVEN" NOT_REDRIVEN = "NOT_REDRIVEN" -class ExecutionRedriveStatus(str): +class ExecutionRedriveStatus(str, Enum): REDRIVABLE = "REDRIVABLE" NOT_REDRIVABLE = "NOT_REDRIVABLE" REDRIVABLE_BY_MAP_RUN = "REDRIVABLE_BY_MAP_RUN" -class ExecutionStatus(str): +class ExecutionStatus(str, Enum): RUNNING = "RUNNING" SUCCEEDED = "SUCCEEDED" FAILED = "FAILED" @@ -68,7 +86,7 @@ class ExecutionStatus(str): PENDING_REDRIVE = "PENDING_REDRIVE" -class HistoryEventType(str): +class HistoryEventType(str, Enum): ActivityFailed = "ActivityFailed" ActivityScheduled = "ActivityScheduled" ActivityScheduleFailed = "ActivityScheduleFailed" @@ -130,58 +148,88 @@ class HistoryEventType(str): MapRunSucceeded = "MapRunSucceeded" ExecutionRedriven = "ExecutionRedriven" MapRunRedriven = "MapRunRedriven" + EvaluationFailed = "EvaluationFailed" + +class IncludedData(str, Enum): + ALL_DATA = "ALL_DATA" + METADATA_ONLY = "METADATA_ONLY" -class InspectionLevel(str): + +class InspectionLevel(str, Enum): INFO = "INFO" DEBUG = "DEBUG" TRACE = "TRACE" -class LogLevel(str): +class KmsKeyState(str, Enum): + DISABLED = "DISABLED" + PENDING_DELETION = "PENDING_DELETION" + PENDING_IMPORT = "PENDING_IMPORT" + UNAVAILABLE = "UNAVAILABLE" + CREATING = "CREATING" + + +class LogLevel(str, Enum): ALL = "ALL" ERROR = "ERROR" FATAL = "FATAL" OFF = "OFF" -class MapRunStatus(str): +class MapRunStatus(str, Enum): RUNNING = "RUNNING" SUCCEEDED = "SUCCEEDED" FAILED = "FAILED" ABORTED = "ABORTED" -class StateMachineStatus(str): +class StateMachineStatus(str, Enum): ACTIVE = "ACTIVE" DELETING = "DELETING" -class StateMachineType(str): +class StateMachineType(str, Enum): STANDARD = "STANDARD" EXPRESS = "EXPRESS" -class SyncExecutionStatus(str): +class SyncExecutionStatus(str, Enum): SUCCEEDED = "SUCCEEDED" FAILED = "FAILED" TIMED_OUT = "TIMED_OUT" -class TestExecutionStatus(str): +class TestExecutionStatus(str, Enum): SUCCEEDED = "SUCCEEDED" FAILED = "FAILED" RETRIABLE = "RETRIABLE" CAUGHT_ERROR = "CAUGHT_ERROR" -class ValidationExceptionReason(str): +class ValidateStateMachineDefinitionResultCode(str, Enum): + OK = "OK" + FAIL = "FAIL" + + +class ValidateStateMachineDefinitionSeverity(str, Enum): + ERROR = "ERROR" + WARNING = "WARNING" + + +class ValidationExceptionReason(str, Enum): API_DOES_NOT_SUPPORT_LABELED_ARNS = "API_DOES_NOT_SUPPORT_LABELED_ARNS" MISSING_REQUIRED_PARAMETER = "MISSING_REQUIRED_PARAMETER" CANNOT_UPDATE_COMPLETED_MAP_RUN = "CANNOT_UPDATE_COMPLETED_MAP_RUN" INVALID_ROUTING_CONFIGURATION = "INVALID_ROUTING_CONFIGURATION" +class ActivityAlreadyExists(ServiceException): + code: str = "ActivityAlreadyExists" + sender_fault: bool = False + status_code: int = 400 + + class ActivityDoesNotExist(ServiceException): code: str = "ActivityDoesNotExist" sender_fault: bool = False @@ -242,6 +290,12 @@ class InvalidDefinition(ServiceException): status_code: int = 400 +class InvalidEncryptionConfiguration(ServiceException): + code: str = "InvalidEncryptionConfiguration" + sender_fault: bool = False + status_code: int = 400 + + class InvalidExecutionInput(ServiceException): code: str = "InvalidExecutionInput" sender_fault: bool = False @@ -283,6 +337,25 @@ class InvalidTracingConfiguration(ServiceException): status_code: int = 400 +class KmsAccessDeniedException(ServiceException): + code: str = "KmsAccessDeniedException" + sender_fault: bool = False + status_code: int = 400 + + +class KmsInvalidStateException(ServiceException): + code: str = "KmsInvalidStateException" + sender_fault: bool = False + status_code: int = 400 + kmsKeyState: Optional[KmsKeyState] + + +class KmsThrottlingException(ServiceException): + code: str = "KmsThrottlingException" + sender_fault: bool = False + status_code: int = 400 + + class MissingRequiredParameter(ServiceException): code: str = "MissingRequiredParameter" sender_fault: bool = False @@ -293,7 +366,7 @@ class ResourceNotFound(ServiceException): code: str = "ResourceNotFound" sender_fault: bool = False status_code: int = 400 - resourceName: Optional[str] + resourceName: Optional[Arn] class ServiceQuotaExceededException(ServiceException): @@ -344,6 +417,13 @@ class TaskTimedOut(ServiceException): status_code: int = 400 +class TooManyTags(ServiceException): + code: str = "TooManyTags" + sender_fault: bool = False + status_code: int = 400 + resourceName: Optional[Arn] + + class ValidationException(ServiceException): code: str = "ValidationException" sender_fault: bool = False @@ -360,7 +440,7 @@ class ActivityFailedEventDetails(TypedDict, total=False): class ActivityListItem(TypedDict, total=False): - activityArn: str + activityArn: Arn name: Name creationDate: Timestamp @@ -381,7 +461,7 @@ class HistoryEventExecutionDataDetails(TypedDict, total=False): class ActivityScheduledEventDetails(TypedDict, total=False): - resource: str + resource: Arn input: Optional[SensitiveData] inputDetails: Optional[HistoryEventExecutionDataDetails] timeoutInSeconds: Optional[TimeoutInSeconds] @@ -402,6 +482,13 @@ class ActivityTimedOutEventDetails(TypedDict, total=False): cause: Optional[SensitiveCause] +AssignedVariables = Dict[VariableName, VariableValue] + + +class AssignedVariablesDetails(TypedDict, total=False): + truncated: Optional[truncated] + + BilledDuration = int BilledMemoryUsed = int @@ -416,7 +503,18 @@ class CloudWatchEventsExecutionDataDetails(TypedDict, total=False): class CloudWatchLogsLogGroup(TypedDict, total=False): - logGroupArn: Optional[str] + logGroupArn: Optional[Arn] + + +EncryptionConfiguration = TypedDict( + "EncryptionConfiguration", + { + "kmsKeyId": Optional[KmsKeyId], + "kmsDataKeyReusePeriodSeconds": Optional[KmsDataKeyReusePeriodSeconds], + "type": EncryptionType, + }, + total=False, +) class Tag(TypedDict, total=False): @@ -428,12 +526,12 @@ class Tag(TypedDict, total=False): class CreateActivityOutput(TypedDict, total=False): - activityArn: str + activityArn: Arn creationDate: Timestamp class RoutingConfigurationListItem(TypedDict, total=False): - stateMachineVersionArn: str + stateMachineVersionArn: Arn weight: VersionWeight @@ -441,16 +539,10 @@ class RoutingConfigurationListItem(TypedDict, total=False): class CreateStateMachineAliasOutput(TypedDict, total=False): - stateMachineAliasArn: str + stateMachineAliasArn: Arn creationDate: Timestamp -class EncryptionConfiguration(TypedDict, total=False): - type: str - kmsDataKeyReusePeriodSeconds: Optional[int] - kmsKeyId: Optional[str] - - class TracingConfiguration(TypedDict, total=False): enabled: Optional[Enabled] @@ -473,23 +565,23 @@ class LoggingConfiguration(TypedDict, total=False): { "name": Name, "definition": Definition, - "roleArn": str, + "roleArn": Arn, "type": Optional[StateMachineType], "loggingConfiguration": Optional[LoggingConfiguration], "tags": Optional[TagList], "tracingConfiguration": Optional[TracingConfiguration], - "encryptionConfiguration": Optional[EncryptionConfiguration], "publish": Optional[Publish], "versionDescription": Optional[VersionDescription], + "encryptionConfiguration": Optional[EncryptionConfiguration], }, total=False, ) class CreateStateMachineOutput(TypedDict, total=False): - stateMachineArn: str + stateMachineArn: Arn creationDate: Timestamp - stateMachineVersionArn: Optional[str] + stateMachineVersionArn: Optional[Arn] class DeleteActivityOutput(TypedDict, total=False): @@ -509,14 +601,15 @@ class DeleteStateMachineVersionOutput(TypedDict, total=False): class DescribeActivityOutput(TypedDict, total=False): - activityArn: str + activityArn: Arn name: Name creationDate: Timestamp + encryptionConfiguration: Optional[EncryptionConfiguration] class DescribeExecutionOutput(TypedDict, total=False): - executionArn: str - stateMachineArn: str + executionArn: Arn + stateMachineArn: Arn name: Optional[Name] status: ExecutionStatus startDate: Timestamp @@ -526,11 +619,11 @@ class DescribeExecutionOutput(TypedDict, total=False): output: Optional[SensitiveData] outputDetails: Optional[CloudWatchEventsExecutionDataDetails] traceHeader: Optional[TraceHeader] - mapRunArn: Optional[str] + mapRunArn: Optional[LongArn] error: Optional[SensitiveError] cause: Optional[SensitiveCause] - stateMachineVersionArn: Optional[str] - stateMachineAliasArn: Optional[str] + stateMachineVersionArn: Optional[Arn] + stateMachineAliasArn: Optional[Arn] redriveCount: Optional[RedriveCount] redriveDate: Optional[Timestamp] redriveStatus: Optional[ExecutionRedriveStatus] @@ -571,8 +664,8 @@ class MapRunItemCounts(TypedDict, total=False): class DescribeMapRunOutput(TypedDict, total=False): - mapRunArn: str - executionArn: str + mapRunArn: LongArn + executionArn: Arn status: MapRunStatus startDate: Timestamp stopDate: Optional[Timestamp] @@ -586,7 +679,7 @@ class DescribeMapRunOutput(TypedDict, total=False): class DescribeStateMachineAliasOutput(TypedDict, total=False): - stateMachineAliasArn: Optional[str] + stateMachineAliasArn: Optional[Arn] name: Optional[Name] description: Optional[AliasDescription] routingConfiguration: Optional[RoutingConfigurationList] @@ -594,39 +687,54 @@ class DescribeStateMachineAliasOutput(TypedDict, total=False): updateDate: Optional[Timestamp] +VariableNameList = List[VariableName] +VariableReferences = Dict[StateName, VariableNameList] + + class DescribeStateMachineForExecutionOutput(TypedDict, total=False): - stateMachineArn: str + stateMachineArn: Arn name: Name definition: Definition - roleArn: str + roleArn: Arn updateDate: Timestamp loggingConfiguration: Optional[LoggingConfiguration] tracingConfiguration: Optional[TracingConfiguration] - encryptionConfiguration: Optional[EncryptionConfiguration] - mapRunArn: Optional[str] + mapRunArn: Optional[LongArn] label: Optional[MapRunLabel] revisionId: Optional[RevisionId] + encryptionConfiguration: Optional[EncryptionConfiguration] + variableReferences: Optional[VariableReferences] DescribeStateMachineOutput = TypedDict( "DescribeStateMachineOutput", { - "stateMachineArn": str, + "stateMachineArn": Arn, "name": Name, "status": Optional[StateMachineStatus], "definition": Definition, - "roleArn": str, + "roleArn": Arn, "type": StateMachineType, "creationDate": Timestamp, "loggingConfiguration": Optional[LoggingConfiguration], "tracingConfiguration": Optional[TracingConfiguration], - "encryptionConfiguration": Optional[EncryptionConfiguration], "label": Optional[MapRunLabel], "revisionId": Optional[RevisionId], "description": Optional[VersionDescription], + "encryptionConfiguration": Optional[EncryptionConfiguration], + "variableReferences": Optional[VariableReferences], }, total=False, ) + + +class EvaluationFailedEventDetails(TypedDict, total=False): + error: Optional[SensitiveError] + cause: Optional[SensitiveCause] + location: Optional[EvaluationFailureLocation] + state: StateName + + EventId = int @@ -641,16 +749,16 @@ class ExecutionFailedEventDetails(TypedDict, total=False): class ExecutionListItem(TypedDict, total=False): - executionArn: str - stateMachineArn: str + executionArn: Arn + stateMachineArn: Arn name: Name status: ExecutionStatus startDate: Timestamp stopDate: Optional[Timestamp] - mapRunArn: Optional[str] + mapRunArn: Optional[LongArn] itemCount: Optional[UnsignedInteger] - stateMachineVersionArn: Optional[str] - stateMachineAliasArn: Optional[str] + stateMachineVersionArn: Optional[Arn] + stateMachineAliasArn: Optional[Arn] redriveCount: Optional[RedriveCount] redriveDate: Optional[Timestamp] @@ -665,9 +773,9 @@ class ExecutionRedrivenEventDetails(TypedDict, total=False): class ExecutionStartedEventDetails(TypedDict, total=False): input: Optional[SensitiveData] inputDetails: Optional[HistoryEventExecutionDataDetails] - roleArn: Optional[str] - stateMachineAliasArn: Optional[str] - stateMachineVersionArn: Optional[str] + roleArn: Optional[Arn] + stateMachineAliasArn: Optional[Arn] + stateMachineVersionArn: Optional[Arn] class ExecutionSucceededEventDetails(TypedDict, total=False): @@ -686,7 +794,7 @@ class GetActivityTaskOutput(TypedDict, total=False): class MapRunRedrivenEventDetails(TypedDict, total=False): - mapRunArn: Optional[str] + mapRunArn: Optional[LongArn] redriveCount: Optional[RedriveCount] @@ -696,13 +804,15 @@ class MapRunFailedEventDetails(TypedDict, total=False): class MapRunStartedEventDetails(TypedDict, total=False): - mapRunArn: Optional[str] + mapRunArn: Optional[LongArn] class StateExitedEventDetails(TypedDict, total=False): name: Name output: Optional[SensitiveData] outputDetails: Optional[HistoryEventExecutionDataDetails] + assignedVariables: Optional[AssignedVariables] + assignedVariablesDetails: Optional[AssignedVariablesDetails] class StateEnteredEventDetails(TypedDict, total=False): @@ -727,11 +837,11 @@ class LambdaFunctionStartFailedEventDetails(TypedDict, total=False): class TaskCredentials(TypedDict, total=False): - roleArn: Optional[str] + roleArn: Optional[LongArn] class LambdaFunctionScheduledEventDetails(TypedDict, total=False): - resource: str + resource: Arn input: Optional[SensitiveData] inputDetails: Optional[HistoryEventExecutionDataDetails] timeoutInSeconds: Optional[TimeoutInSeconds] @@ -869,6 +979,7 @@ class TaskFailedEventDetails(TypedDict, total=False): "mapRunStartedEventDetails": Optional[MapRunStartedEventDetails], "mapRunFailedEventDetails": Optional[MapRunFailedEventDetails], "mapRunRedrivenEventDetails": Optional[MapRunRedrivenEventDetails], + "evaluationFailedEventDetails": Optional[EvaluationFailedEventDetails], }, total=False, ) @@ -898,6 +1009,7 @@ class InspectionDataRequest(TypedDict, total=False): class InspectionData(TypedDict, total=False): input: Optional[SensitiveData] + afterArguments: Optional[SensitiveData] afterInputPath: Optional[SensitiveData] afterParameters: Optional[SensitiveData] result: Optional[SensitiveData] @@ -905,22 +1017,13 @@ class InspectionData(TypedDict, total=False): afterResultPath: Optional[SensitiveData] request: Optional[InspectionDataRequest] response: Optional[InspectionDataResponse] - - -class ListActivitiesOutput(TypedDict, total=False): - activities: ActivityList - nextToken: Optional[PageToken] - - -class ListExecutionsOutput(TypedDict, total=False): - executions: ExecutionList - nextToken: Optional[ListExecutionsPageToken] + variables: Optional[SensitiveData] class MapRunListItem(TypedDict, total=False): - executionArn: str - mapRunArn: str - stateMachineArn: str + executionArn: Arn + mapRunArn: LongArn + stateMachineArn: Arn startDate: Timestamp stopDate: Optional[Timestamp] @@ -934,7 +1037,7 @@ class ListMapRunsOutput(TypedDict, total=False): class StateMachineAliasListItem(TypedDict, total=False): - stateMachineAliasArn: str + stateMachineAliasArn: LongArn creationDate: Timestamp @@ -947,7 +1050,7 @@ class ListStateMachineAliasesOutput(TypedDict, total=False): class StateMachineVersionListItem(TypedDict, total=False): - stateMachineVersionArn: str + stateMachineVersionArn: LongArn creationDate: Timestamp @@ -962,7 +1065,7 @@ class ListStateMachineVersionsOutput(TypedDict, total=False): StateMachineListItem = TypedDict( "StateMachineListItem", { - "stateMachineArn": str, + "stateMachineArn": Arn, "name": Name, "type": StateMachineType, "creationDate": Timestamp, @@ -983,7 +1086,7 @@ class ListTagsForResourceOutput(TypedDict, total=False): class PublishStateMachineVersionOutput(TypedDict, total=False): creationDate: Timestamp - stateMachineVersionArn: str + stateMachineVersionArn: Arn class RedriveExecutionOutput(TypedDict, total=False): @@ -1003,13 +1106,13 @@ class SendTaskSuccessOutput(TypedDict, total=False): class StartExecutionOutput(TypedDict, total=False): - executionArn: str + executionArn: Arn startDate: Timestamp class StartSyncExecutionOutput(TypedDict, total=False): - executionArn: str - stateMachineArn: Optional[str] + executionArn: Arn + stateMachineArn: Optional[Arn] name: Optional[Name] startDate: Timestamp stopDate: Timestamp @@ -1059,4 +1162,32 @@ class UpdateStateMachineAliasOutput(TypedDict, total=False): class UpdateStateMachineOutput(TypedDict, total=False): updateDate: Timestamp revisionId: Optional[RevisionId] - stateMachineVersionArn: Optional[str] + stateMachineVersionArn: Optional[Arn] + + +class ValidateStateMachineDefinitionDiagnostic(TypedDict, total=False): + severity: ValidateStateMachineDefinitionSeverity + code: ValidateStateMachineDefinitionCode + message: ValidateStateMachineDefinitionMessage + location: Optional[ValidateStateMachineDefinitionLocation] + + +ValidateStateMachineDefinitionDiagnosticList = List[ + ValidateStateMachineDefinitionDiagnostic +] +ValidateStateMachineDefinitionInput = TypedDict( + "ValidateStateMachineDefinitionInput", + { + "definition": Definition, + "type": Optional[StateMachineType], + "severity": Optional[ValidateStateMachineDefinitionSeverity], + "maxResults": Optional[ValidateStateMachineDefinitionMaxResult], + }, + total=False, +) + + +class ValidateStateMachineDefinitionOutput(TypedDict, total=False): + result: ValidateStateMachineDefinitionResultCode + diagnostics: ValidateStateMachineDefinitionDiagnosticList + truncated: Optional[ValidateStateMachineDefinitionTruncated] diff --git a/moto/stepfunctions/parser/asl/antlr/ASLIntrinsicLexer.g4 b/moto/stepfunctions/parser/asl/antlr/ASLIntrinsicLexer.g4 index 4e5fdcb56be9..437122207065 100644 --- a/moto/stepfunctions/parser/asl/antlr/ASLIntrinsicLexer.g4 +++ b/moto/stepfunctions/parser/asl/antlr/ASLIntrinsicLexer.g4 @@ -8,6 +8,9 @@ CONTEXT_PATH_STRING: DOLLAR DOLLAR JSON_PATH_BODY; JSON_PATH_STRING: DOLLAR JSON_PATH_BODY; +STRING_VARIABLE: DOLLAR IDENTIFIER JSON_PATH_BODY; + +// TODO: JSONPath body composition may need strenghening to support features such as filtering conditions. fragment JSON_PATH_BODY: JSON_PATH_BRACK? (DOT IDENTIFIER? JSON_PATH_BRACK?)*; fragment JSON_PATH_BRACK: '[' (JSON_PATH_BRACK | ~[\]])* ']'; diff --git a/moto/stepfunctions/parser/asl/antlr/ASLIntrinsicParser.g4 b/moto/stepfunctions/parser/asl/antlr/ASLIntrinsicParser.g4 index 76e03a7d7b55..be0cac2a9379 100644 --- a/moto/stepfunctions/parser/asl/antlr/ASLIntrinsicParser.g4 +++ b/moto/stepfunctions/parser/asl/antlr/ASLIntrinsicParser.g4 @@ -42,5 +42,6 @@ func_arg: | (TRUE | FALSE) # func_arg_bool | CONTEXT_PATH_STRING # func_arg_context_path | JSON_PATH_STRING # func_arg_json_path + | STRING_VARIABLE # func_arg_var | states_func_decl # func_arg_func_decl ; \ No newline at end of file diff --git a/moto/stepfunctions/parser/asl/antlr/ASLLexer.g4 b/moto/stepfunctions/parser/asl/antlr/ASLLexer.g4 index 21f5efae54c4..aa79ba245f38 100644 --- a/moto/stepfunctions/parser/asl/antlr/ASLLexer.g4 +++ b/moto/stepfunctions/parser/asl/antlr/ASLLexer.g4 @@ -55,6 +55,8 @@ MAP: '"Map"'; CHOICES: '"Choices"'; +CONDITION: '"Condition"'; + VARIABLE: '"Variable"'; DEFAULT: '"Default"'; @@ -189,6 +191,8 @@ INPUTPATH: '"InputPath"'; OUTPUTPATH: '"OutputPath"'; +ITEMS: '"Items"'; + ITEMSPATH: '"ItemsPath"'; RESULTPATH: '"ResultPath"'; @@ -197,6 +201,12 @@ RESULT: '"Result"'; PARAMETERS: '"Parameters"'; +CREDENTIALS: '"Credentials"'; + +ROLEARN: '"RoleArn"'; + +ROLEARNPATH: '"RoleArn.$"'; + RESULTSELECTOR: '"ResultSelector"'; ITEMREADER: '"ItemReader"'; @@ -223,6 +233,8 @@ TOLERATEDFAILUREPERCENTAGEPATH: '"ToleratedFailurePercentagePath"'; LABEL: '"Label"'; +RESULTWRITER: '"ResultWriter"'; + NEXT: '"Next"'; END: '"End"'; @@ -257,6 +269,22 @@ NONE: '"NONE"'; // Catch. CATCH: '"Catch"'; +// Query Language. +QUERYLANGUAGE: '"QueryLanguage"'; + +JSONPATH: '"JSONPath"'; + +JSONATA: '"JSONata"'; + +// Assign. +ASSIGN: '"Assign"'; + +// Output. +OUTPUT: '"Output"'; + +// Arguments. +ARGUMENTS: '"Arguments"'; + // ErrorNames ERRORNAMEStatesALL: '"States.ALL"'; @@ -286,6 +314,8 @@ ERRORNAMEStatesItemReaderFailed: '"States.ItemReaderFailed"'; ERRORNAMEStatesResultWriterFailed: '"States.ResultWriterFailed"'; +ERRORNAMEStatesQueryEvaluationError: '"States.QueryEvaluationError"'; + // Read-only: ERRORNAMEStatesRuntime: '"States.Runtime"'; @@ -294,7 +324,13 @@ STRINGDOLLAR: '"' (ESC | SAFECODEPOINT)* '.$"'; STRINGPATHCONTEXTOBJ: '"$$' (ESC | SAFECODEPOINT)* '"'; -STRINGPATH: '"$' (ESC | SAFECODEPOINT)* '"'; +STRINGPATH: '"$"' | '"$' ('.' | '[') (ESC | SAFECODEPOINT)* '"'; + +STRINGVAR: '"$' [a-zA-Z_] (ESC | SAFECODEPOINT)* '"'; + +STRINGINTRINSICFUNC: '"States.' (ESC | SAFECODEPOINT)+ '(' (ESC | SAFECODEPOINT)* ')"'; + +STRINGJSONATA: LJSONATA (ESC | SAFECODEPOINT)* RJSONATA; STRING: '"' (ESC | SAFECODEPOINT)* '"'; @@ -306,6 +342,10 @@ fragment HEX: [0-9a-fA-F]; fragment SAFECODEPOINT: ~ ["\\\u0000-\u001F]; +fragment LJSONATA: '"{%'; + +fragment RJSONATA: '%}"'; + // Numbers. INT: '0' | [1-9] [0-9]*; diff --git a/moto/stepfunctions/parser/asl/antlr/ASLParser.g4 b/moto/stepfunctions/parser/asl/antlr/ASLParser.g4 index 5634bfc7250f..62e6d283d565 100644 --- a/moto/stepfunctions/parser/asl/antlr/ASLParser.g4 +++ b/moto/stepfunctions/parser/asl/antlr/ASLParser.g4 @@ -12,7 +12,14 @@ state_machine: program_decl EOF; program_decl: LBRACE top_layer_stmt (COMMA top_layer_stmt)* RBRACE; -top_layer_stmt: comment_decl | version_decl | startat_decl | states_decl | timeout_seconds_decl; +top_layer_stmt: + comment_decl + | version_decl + | query_language_decl + | startat_decl + | states_decl + | timeout_seconds_decl +; startat_decl: STARTAT COLON keyword_or_string; @@ -20,8 +27,11 @@ comment_decl: COMMENT COLON keyword_or_string; version_decl: VERSION COLON keyword_or_string; +query_language_decl: QUERYLANGUAGE COLON (JSONPATH | JSONATA); + state_stmt: comment_decl + | query_language_decl | type_decl | input_path_decl | resource_decl @@ -40,6 +50,7 @@ state_stmt: | seconds_path_decl | timestamp_decl | timestamp_path_decl + | items_decl | items_path_decl | item_processor_decl | iterator_decl @@ -61,6 +72,11 @@ state_stmt: | tolerated_failure_percentage_decl | tolerated_failure_percentage_path_decl | label_decl + | result_writer_decl + | assign_decl + | arguments_decl + | output_decl + | credentials_decl ; states_decl: STATES COLON LBRACE state_decl (COMMA state_decl)* RBRACE; @@ -78,70 +94,136 @@ next_decl: NEXT COLON keyword_or_string; resource_decl: RESOURCE COLON keyword_or_string; -input_path_decl: INPUTPATH COLON (NULL | keyword_or_string); +input_path_decl: + INPUTPATH COLON variable_sample # input_path_decl_var + | INPUTPATH COLON STRINGPATHCONTEXTOBJ # input_path_decl_path_context_object + | INPUTPATH COLON (NULL | keyword_or_string) # input_path_decl_path +; result_decl: RESULT COLON json_value_decl; result_path_decl: RESULTPATH COLON (NULL | keyword_or_string); -output_path_decl: OUTPUTPATH COLON (NULL | keyword_or_string); +output_path_decl: + OUTPUTPATH COLON variable_sample # output_path_decl_var + | OUTPUTPATH COLON STRINGPATHCONTEXTOBJ # output_path_decl_path_context_object + | OUTPUTPATH COLON (NULL | keyword_or_string) # output_path_decl_path +; end_decl: END COLON (TRUE | FALSE); default_decl: DEFAULT COLON keyword_or_string; -error_decl: ERROR COLON keyword_or_string; +error_decl: + ERROR COLON STRINGJSONATA # error_jsonata + | ERROR COLON keyword_or_string # error_string +; error_path_decl: - ERRORPATH COLON STRINGPATH # error_path_decl_path - | ERRORPATH COLON intrinsic_func # error_path_decl_intrinsic + ERRORPATH COLON variable_sample # error_path_decl_var + | ERRORPATH COLON STRINGPATH # error_path_decl_path + | ERRORPATH COLON STRINGPATHCONTEXTOBJ # error_path_decl_context + | ERRORPATH COLON STRINGINTRINSICFUNC # error_path_decl_intrinsic ; -cause_decl: CAUSE COLON keyword_or_string; +cause_decl: + CAUSE COLON STRINGJSONATA # cause_jsonata + | CAUSE COLON keyword_or_string # cause_string +; cause_path_decl: - CAUSEPATH COLON STRINGPATH # cause_path_decl_path - | CAUSEPATH COLON intrinsic_func # cause_path_decl_intrinsic + CAUSEPATH COLON variable_sample # cause_path_decl_var + | CAUSEPATH COLON STRINGPATH # cause_path_decl_path + | CAUSEPATH COLON STRINGPATHCONTEXTOBJ # cause_path_decl_context + | CAUSEPATH COLON STRINGINTRINSICFUNC # cause_path_decl_intrinsic ; -seconds_decl: SECONDS COLON INT; +seconds_decl: SECONDS COLON STRINGJSONATA # seconds_jsonata | SECONDS COLON INT # seconds_int; + +seconds_path_decl: + SECONDSPATH COLON variable_sample # seconds_path_decl_var + | SECONDSPATH COLON keyword_or_string # seconds_path_decl_value +; -seconds_path_decl: SECONDSPATH COLON keyword_or_string; +timestamp_decl: + TIMESTAMP COLON STRINGJSONATA # timestamp_jsonata + | TIMESTAMP COLON keyword_or_string # timestamp_string +; -timestamp_decl: TIMESTAMP COLON keyword_or_string; +timestamp_path_decl: + TIMESTAMPPATH COLON variable_sample # timestamp_path_decl_var + | TIMESTAMPPATH COLON keyword_or_string # timestamp_path_decl_value +; -timestamp_path_decl: TIMESTAMPPATH COLON keyword_or_string; +items_decl: + ITEMS COLON jsonata_template_value_array # items_array + | ITEMS COLON STRINGJSONATA # items_jsonata +; -items_path_decl: ITEMSPATH COLON keyword_or_string; +items_path_decl: + ITEMSPATH COLON STRINGPATHCONTEXTOBJ # items_path_decl_path_context_object + | ITEMSPATH COLON variable_sample # items_path_decl_path_var + | ITEMSPATH COLON keyword_or_string # items_path_decl_path +; -max_concurrency_decl: MAXCONCURRENCY COLON INT; +max_concurrency_decl: + MAXCONCURRENCY COLON STRINGJSONATA # max_concurrency_jsonata + | MAXCONCURRENCY COLON INT # max_concurrency_int +; -max_concurrency_path_decl: MAXCONCURRENCYPATH COLON STRINGPATH; +max_concurrency_path_decl: + MAXCONCURRENCYPATH COLON variable_sample # max_concurrency_path_var + | MAXCONCURRENCYPATH COLON STRINGPATH # max_concurrency_path +; parameters_decl: PARAMETERS COLON payload_tmpl_decl; -timeout_seconds_decl: TIMEOUTSECONDS COLON INT; +credentials_decl: CREDENTIALS COLON LBRACE role_arn_decl RBRACE; -timeout_seconds_path_decl: TIMEOUTSECONDSPATH COLON STRINGPATH; +role_arn_decl: + ROLEARN COLON STRINGJSONATA # role_arn_jsonata + | ROLEARNPATH COLON STRINGPATH # role_arn_path + | ROLEARNPATH COLON STRINGPATHCONTEXTOBJ # role_arn_path_context_obj + | ROLEARNPATH COLON STRINGINTRINSICFUNC # role_arn_intrinsic_func + | ROLEARNPATH COLON variable_sample # role_arn_var + | ROLEARN COLON keyword_or_string # role_arn_str +; -heartbeat_seconds_decl: HEARTBEATSECONDS COLON INT; +timeout_seconds_decl: + TIMEOUTSECONDS COLON STRINGJSONATA # timeout_seconds_jsonata + | TIMEOUTSECONDS COLON INT # timeout_seconds_int +; -heartbeat_seconds_path_decl: HEARTBEATSECONDSPATH COLON STRINGPATH; +timeout_seconds_path_decl: + TIMEOUTSECONDSPATH COLON variable_sample # timeout_seconds_path_decl_var + | TIMEOUTSECONDSPATH COLON STRINGPATH # timeout_seconds_path_decl_path +; + +heartbeat_seconds_decl: + HEARTBEATSECONDS COLON STRINGJSONATA # heartbeat_seconds_jsonata + | HEARTBEATSECONDS COLON INT # heartbeat_seconds_int +; + +heartbeat_seconds_path_decl: + HEARTBEATSECONDSPATH COLON variable_sample # heartbeat_seconds_path_decl_var + | HEARTBEATSECONDSPATH COLON STRINGPATH # heartbeat_seconds_path_decl_path +; + +variable_sample: STRINGVAR; payload_tmpl_decl: LBRACE payload_binding (COMMA payload_binding)* RBRACE | LBRACE RBRACE; payload_binding: STRINGDOLLAR COLON STRINGPATH # payload_binding_path | STRINGDOLLAR COLON STRINGPATHCONTEXTOBJ # payload_binding_path_context_obj - | STRINGDOLLAR COLON intrinsic_func # payload_binding_intrinsic_func + | STRINGDOLLAR COLON STRINGINTRINSICFUNC # payload_binding_intrinsic_func + | STRINGDOLLAR COLON variable_sample # payload_binding_var | keyword_or_string COLON payload_value_decl # payload_binding_value ; -intrinsic_func: STRING; - payload_arr_decl: LBRACK payload_value_decl (COMMA payload_value_decl)* RBRACK | LBRACK RBRACK; -payload_value_decl: payload_binding | payload_arr_decl | payload_tmpl_decl | payload_value_lit; +payload_value_decl: payload_arr_decl | payload_tmpl_decl | payload_value_lit; payload_value_lit: NUMBER # payload_value_float @@ -151,6 +233,80 @@ payload_value_lit: | keyword_or_string # payload_value_str ; +assign_decl: ASSIGN COLON assign_decl_body; + +assign_decl_body: LBRACE RBRACE | LBRACE assign_decl_binding (COMMA assign_decl_binding)* RBRACE; + +assign_decl_binding: assign_template_binding; + +assign_template_value_object: + LBRACE RBRACE + | LBRACE assign_template_binding (COMMA assign_template_binding)* RBRACE +; + +// TODO: add support for jsonata expression in assign declarations. +assign_template_binding: + STRINGDOLLAR COLON STRINGPATH # assign_template_binding_path + | STRINGDOLLAR COLON STRINGPATHCONTEXTOBJ # assign_template_binding_path_context + | STRINGDOLLAR COLON variable_sample # assign_template_binding_var + | STRINGDOLLAR COLON STRINGINTRINSICFUNC # assign_template_binding_intrinsic_func + | STRING COLON assign_template_value # assign_template_binding_assign_value +; + +assign_template_value: + assign_template_value_object + | assign_template_value_array + | assign_template_value_terminal +; + +assign_template_value_array: + LBRACK RBRACK + | LBRACK assign_template_value (COMMA assign_template_value)* RBRACK +; + +assign_template_value_terminal: + NUMBER # assign_template_value_terminal_float + | INT # assign_template_value_terminal_int + | (TRUE | FALSE) # assign_template_value_terminal_bool + | NULL # assign_template_value_terminal_null + | STRINGJSONATA # assign_template_value_terminal_expression + | keyword_or_string # assign_template_value_terminal_str +; + +arguments_decl: + ARGUMENTS COLON jsonata_template_value_object # arguments_object + | ARGUMENTS COLON STRINGJSONATA # arguments_expr +; + +output_decl: OUTPUT COLON jsonata_template_value; + +jsonata_template_value_object: + LBRACE RBRACE + | LBRACE jsonata_template_binding (COMMA jsonata_template_binding)* RBRACE +; + +jsonata_template_binding: keyword_or_string COLON jsonata_template_value; + +jsonata_template_value: + jsonata_template_value_object + | jsonata_template_value_array + | jsonata_template_value_terminal +; + +jsonata_template_value_array: + LBRACK RBRACK + | LBRACK jsonata_template_value (COMMA jsonata_template_value)* RBRACK +; + +jsonata_template_value_terminal: + NUMBER # jsonata_template_value_terminal_float + | INT # jsonata_template_value_terminal_int + | (TRUE | FALSE) # jsonata_template_value_terminal_bool + | NULL # jsonata_template_value_terminal_null + | STRINGJSONATA # jsonata_template_value_terminal_expression + | keyword_or_string # jsonata_template_value_terminal_str +; + result_selector_decl: RESULTSELECTOR COLON payload_tmpl_decl; state_type: TASK | PASS | CHOICE | FAIL | SUCCEED | WAIT | MAP | PARALLEL; @@ -162,17 +318,32 @@ choice_rule: | LBRACE comparison_composite_stmt (COMMA comparison_composite_stmt)* RBRACE # choice_rule_comparison_composite ; -comparison_variable_stmt: variable_decl | comparison_func | next_decl | comment_decl; +comparison_variable_stmt: + variable_decl + | comparison_func + | next_decl + | assign_decl + | comment_decl +; -comparison_composite_stmt: comparison_composite | next_decl; +comparison_composite_stmt: comparison_composite | next_decl | assign_decl | comment_decl; comparison_composite // TODO: this allows for Next definitions in nested choice_rules, is this supported at parse time? - : choice_operator COLON ( choice_rule | LBRACK choice_rule (COMMA choice_rule)* RBRACK); + : choice_operator COLON (choice_rule | LBRACK choice_rule (COMMA choice_rule)* RBRACK); -variable_decl: VARIABLE COLON keyword_or_string; +variable_decl: + VARIABLE COLON STRINGPATH # variable_decl_path + | VARIABLE COLON variable_sample # variable_decl_var + | VARIABLE COLON STRINGPATHCONTEXTOBJ # variable_decl_path_context_object +; -comparison_func: comparison_op COLON json_value_decl; +comparison_func: + CONDITION COLON (TRUE | FALSE) # condition_lit + | CONDITION COLON STRINGJSONATA # condition_expr + | comparison_op COLON variable_sample # comparison_func_var + | comparison_op COLON json_value_decl # comparison_func_value +; branches_decl: BRANCHES COLON LBRACK program_decl (COMMA program_decl)* RBRACK; @@ -204,7 +375,7 @@ item_selector_decl: ITEMSELECTOR COLON payload_tmpl_decl; item_reader_decl: ITEMREADER COLON LBRACE items_reader_field (COMMA items_reader_field)* RBRACE; -items_reader_field: resource_decl | parameters_decl | reader_config_decl; +items_reader_field: resource_decl | reader_config_decl | parameters_decl | arguments_decl; reader_config_decl: READERCONFIG COLON LBRACE reader_config_field (COMMA reader_config_field)* RBRACE @@ -225,20 +396,44 @@ csv_header_location_decl: CSVHEADERLOCATION COLON keyword_or_string; csv_headers_decl // TODO: are empty "CSVHeaders" list values supported? : CSVHEADERS COLON LBRACK keyword_or_string (COMMA keyword_or_string)* RBRACK; -max_items_decl: MAXITEMS COLON INT; +max_items_decl: + MAXITEMS COLON STRINGJSONATA # max_items_jsonata + | MAXITEMS COLON INT # max_items_int +; -max_items_path_decl: MAXITEMSPATH COLON STRINGPATH; +max_items_path_decl: + MAXITEMSPATH COLON variable_sample # max_items_path_var + | MAXITEMSPATH COLON STRINGPATH # max_items_path +; -tolerated_failure_count_decl: TOLERATEDFAILURECOUNT COLON INT; +tolerated_failure_count_decl: + TOLERATEDFAILURECOUNT COLON STRINGJSONATA # tolerated_failure_count_jsonata + | TOLERATEDFAILURECOUNT COLON INT # tolerated_failure_count_int +; -tolerated_failure_count_path_decl: TOLERATEDFAILURECOUNTPATH COLON STRINGPATH; +tolerated_failure_count_path_decl: + TOLERATEDFAILURECOUNTPATH COLON variable_sample # tolerated_failure_count_path_var + | TOLERATEDFAILURECOUNTPATH COLON STRINGPATH # tolerated_failure_count_path +; -tolerated_failure_percentage_decl: TOLERATEDFAILUREPERCENTAGE COLON NUMBER; +tolerated_failure_percentage_decl: + TOLERATEDFAILUREPERCENTAGE COLON STRINGJSONATA # tolerated_failure_percentage_jsonata + | TOLERATEDFAILUREPERCENTAGE COLON NUMBER # tolerated_failure_percentage_number +; -tolerated_failure_percentage_path_decl: TOLERATEDFAILUREPERCENTAGEPATH COLON STRINGPATH; +tolerated_failure_percentage_path_decl: + TOLERATEDFAILUREPERCENTAGEPATH COLON variable_sample # tolerated_failure_percentage_path_var + | TOLERATEDFAILUREPERCENTAGEPATH COLON STRINGPATH # tolerated_failure_percentage_path +; label_decl: LABEL COLON keyword_or_string; +result_writer_decl: + RESULTWRITER COLON LBRACE result_writer_field (COMMA result_writer_field)* RBRACE +; + +result_writer_field: resource_decl | parameters_decl; + retry_decl: RETRY COLON LBRACK (retrier_decl (COMMA retrier_decl)*)? RBRACK; retrier_decl: LBRACE retrier_stmt (COMMA retrier_stmt)* RBRACE; @@ -269,7 +464,14 @@ catch_decl: CATCH COLON LBRACK (catcher_decl (COMMA catcher_decl)*)? RBRACK; catcher_decl: LBRACE catcher_stmt (COMMA catcher_stmt)* RBRACE; -catcher_stmt: error_equals_decl | result_path_decl | next_decl | comment_decl; +catcher_stmt: + error_equals_decl + | result_path_decl + | next_decl + | assign_decl + | output_decl + | comment_decl +; comparison_op: BOOLEANEQUALS @@ -331,6 +533,7 @@ states_error_name: | ERRORNAMEStatesItemReaderFailed | ERRORNAMEStatesResultWriterFailed | ERRORNAMEStatesRuntime + | ERRORNAMEStatesQueryEvaluationError ; error_name: states_error_name | keyword_or_string; @@ -355,10 +558,17 @@ json_value_decl: keyword_or_string: STRINGDOLLAR + | STRINGINTRINSICFUNC + | STRINGVAR | STRINGPATHCONTEXTOBJ | STRINGPATH + | STRINGJSONATA | STRING // + | QUERYLANGUAGE + | ASSIGN + | ARGUMENTS + | OUTPUT | COMMENT | STATES | STARTAT @@ -373,6 +583,7 @@ keyword_or_string: | PARALLEL | MAP | CHOICES + | CONDITION | VARIABLE | DEFAULT | BRANCHES @@ -432,6 +643,7 @@ keyword_or_string: | DISTRIBUTED | EXECUTIONTYPE | STANDARD + | ITEMS | ITEMPROCESSOR | ITERATOR | ITEMSELECTOR @@ -444,6 +656,9 @@ keyword_or_string: | RESULTPATH | RESULT | PARAMETERS + | CREDENTIALS + | ROLEARN + | ROLEARNPATH | RESULTSELECTOR | ITEMREADER | READERCONFIG @@ -457,6 +672,7 @@ keyword_or_string: | TOLERATEDFAILUREPERCENTAGE | TOLERATEDFAILUREPERCENTAGEPATH | LABEL + | RESULTWRITER | NEXT | END | CAUSE @@ -485,4 +701,5 @@ keyword_or_string: | ERRORNAMEStatesItemReaderFailed | ERRORNAMEStatesResultWriterFailed | ERRORNAMEStatesRuntime + | ERRORNAMEStatesQueryEvaluationError ; \ No newline at end of file diff --git a/moto/stepfunctions/parser/asl/antlr/runtime/ASLIntrinsicLexer.interp b/moto/stepfunctions/parser/asl/antlr/runtime/ASLIntrinsicLexer.interp deleted file mode 100644 index a433e3d53ed5..000000000000 --- a/moto/stepfunctions/parser/asl/antlr/runtime/ASLIntrinsicLexer.interp +++ /dev/null @@ -1,148 +0,0 @@ -token literal names: -null -'$' -'.' -'*' -',' -'(' -')' -'[' -']' -'<' -'>' -'@.' -'@.length-' -'&&' -'||' -'==' -'=' -'true' -'false' -'States' -'Format' -'StringToJson' -'JsonToString' -'Array' -'ArrayPartition' -'ArrayContains' -'ArrayRange' -'ArrayGetItem' -'ArrayLength' -'ArrayUnique' -'Base64Encode' -'Base64Decode' -'Hash' -'JsonMerge' -'MathRandom' -'MathAdd' -'StringSplit' -'UUID' -null -null -null -null -null - -token symbolic names: -null -DOLLAR -DOT -STAR -COMMA -LPAREN -RPAREN -LBRACK -RBRACK -LDIAM -RDIAM -ATDOT -ATDOTLENGTHDASH -ANDAND -OROR -EQEQ -EQ -TRUE -FALSE -States -Format -StringToJson -JsonToString -Array -ArrayPartition -ArrayContains -ArrayRange -ArrayGetItem -ArrayLength -ArrayUnique -Base64Encode -Base64Decode -Hash -JsonMerge -MathRandom -MathAdd -StringSplit -UUID -STRING -INT -NUMBER -IDENTIFIER -WS - -rule names: -DOLLAR -DOT -STAR -COMMA -LPAREN -RPAREN -LBRACK -RBRACK -LDIAM -RDIAM -ATDOT -ATDOTLENGTHDASH -ANDAND -OROR -EQEQ -EQ -TRUE -FALSE -States -Format -StringToJson -JsonToString -Array -ArrayPartition -ArrayContains -ArrayRange -ArrayGetItem -ArrayLength -ArrayUnique -Base64Encode -Base64Decode -Hash -JsonMerge -MathRandom -MathAdd -StringSplit -UUID -STRING -ESC -UNICODE -HEX -SAFECODEPOINT -INT -NUMBER -EXP -IDENTIFIER -WS - -channel names: -DEFAULT_TOKEN_CHANNEL -HIDDEN - -mode names: -DEFAULT_MODE - -atn: -[4, 0, 42, 423, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, 41, 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, 46, 7, 46, 1, 0, 1, 0, 1, 1, 1, 1, 1, 2, 1, 2, 1, 3, 1, 3, 1, 4, 1, 4, 1, 5, 1, 5, 1, 6, 1, 6, 1, 7, 1, 7, 1, 8, 1, 8, 1, 9, 1, 9, 1, 10, 1, 10, 1, 10, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 12, 1, 12, 1, 12, 1, 13, 1, 13, 1, 13, 1, 14, 1, 14, 1, 14, 1, 15, 1, 15, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 37, 1, 37, 1, 37, 1, 37, 5, 37, 355, 8, 37, 10, 37, 12, 37, 358, 9, 37, 1, 37, 1, 37, 1, 38, 1, 38, 1, 38, 3, 38, 365, 8, 38, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 40, 1, 40, 1, 41, 1, 41, 1, 42, 3, 42, 378, 8, 42, 1, 42, 1, 42, 1, 42, 5, 42, 383, 8, 42, 10, 42, 12, 42, 386, 9, 42, 3, 42, 388, 8, 42, 1, 43, 3, 43, 391, 8, 43, 1, 43, 1, 43, 1, 43, 4, 43, 396, 8, 43, 11, 43, 12, 43, 397, 3, 43, 400, 8, 43, 1, 43, 3, 43, 403, 8, 43, 1, 44, 1, 44, 3, 44, 407, 8, 44, 1, 44, 1, 44, 1, 45, 1, 45, 4, 45, 413, 8, 45, 11, 45, 12, 45, 414, 1, 46, 4, 46, 418, 8, 46, 11, 46, 12, 46, 419, 1, 46, 1, 46, 1, 356, 0, 47, 1, 1, 3, 2, 5, 3, 7, 4, 9, 5, 11, 6, 13, 7, 15, 8, 17, 9, 19, 10, 21, 11, 23, 12, 25, 13, 27, 14, 29, 15, 31, 16, 33, 17, 35, 18, 37, 19, 39, 20, 41, 21, 43, 22, 45, 23, 47, 24, 49, 25, 51, 26, 53, 27, 55, 28, 57, 29, 59, 30, 61, 31, 63, 32, 65, 33, 67, 34, 69, 35, 71, 36, 73, 37, 75, 38, 77, 0, 79, 0, 81, 0, 83, 0, 85, 39, 87, 40, 89, 0, 91, 41, 93, 42, 1, 0, 8, 3, 0, 48, 57, 65, 70, 97, 102, 3, 0, 0, 31, 39, 39, 92, 92, 1, 0, 49, 57, 1, 0, 48, 57, 2, 0, 69, 69, 101, 101, 2, 0, 43, 43, 45, 45, 4, 0, 48, 57, 65, 90, 95, 95, 97, 122, 2, 0, 9, 10, 32, 32, 432, 0, 1, 1, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 5, 1, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, 9, 1, 0, 0, 0, 0, 11, 1, 0, 0, 0, 0, 13, 1, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 17, 1, 0, 0, 0, 0, 19, 1, 0, 0, 0, 0, 21, 1, 0, 0, 0, 0, 23, 1, 0, 0, 0, 0, 25, 1, 0, 0, 0, 0, 27, 1, 0, 0, 0, 0, 29, 1, 0, 0, 0, 0, 31, 1, 0, 0, 0, 0, 33, 1, 0, 0, 0, 0, 35, 1, 0, 0, 0, 0, 37, 1, 0, 0, 0, 0, 39, 1, 0, 0, 0, 0, 41, 1, 0, 0, 0, 0, 43, 1, 0, 0, 0, 0, 45, 1, 0, 0, 0, 0, 47, 1, 0, 0, 0, 0, 49, 1, 0, 0, 0, 0, 51, 1, 0, 0, 0, 0, 53, 1, 0, 0, 0, 0, 55, 1, 0, 0, 0, 0, 57, 1, 0, 0, 0, 0, 59, 1, 0, 0, 0, 0, 61, 1, 0, 0, 0, 0, 63, 1, 0, 0, 0, 0, 65, 1, 0, 0, 0, 0, 67, 1, 0, 0, 0, 0, 69, 1, 0, 0, 0, 0, 71, 1, 0, 0, 0, 0, 73, 1, 0, 0, 0, 0, 75, 1, 0, 0, 0, 0, 85, 1, 0, 0, 0, 0, 87, 1, 0, 0, 0, 0, 91, 1, 0, 0, 0, 0, 93, 1, 0, 0, 0, 1, 95, 1, 0, 0, 0, 3, 97, 1, 0, 0, 0, 5, 99, 1, 0, 0, 0, 7, 101, 1, 0, 0, 0, 9, 103, 1, 0, 0, 0, 11, 105, 1, 0, 0, 0, 13, 107, 1, 0, 0, 0, 15, 109, 1, 0, 0, 0, 17, 111, 1, 0, 0, 0, 19, 113, 1, 0, 0, 0, 21, 115, 1, 0, 0, 0, 23, 118, 1, 0, 0, 0, 25, 128, 1, 0, 0, 0, 27, 131, 1, 0, 0, 0, 29, 134, 1, 0, 0, 0, 31, 137, 1, 0, 0, 0, 33, 139, 1, 0, 0, 0, 35, 144, 1, 0, 0, 0, 37, 150, 1, 0, 0, 0, 39, 157, 1, 0, 0, 0, 41, 164, 1, 0, 0, 0, 43, 177, 1, 0, 0, 0, 45, 190, 1, 0, 0, 0, 47, 196, 1, 0, 0, 0, 49, 211, 1, 0, 0, 0, 51, 225, 1, 0, 0, 0, 53, 236, 1, 0, 0, 0, 55, 249, 1, 0, 0, 0, 57, 261, 1, 0, 0, 0, 59, 273, 1, 0, 0, 0, 61, 286, 1, 0, 0, 0, 63, 299, 1, 0, 0, 0, 65, 304, 1, 0, 0, 0, 67, 314, 1, 0, 0, 0, 69, 325, 1, 0, 0, 0, 71, 333, 1, 0, 0, 0, 73, 345, 1, 0, 0, 0, 75, 350, 1, 0, 0, 0, 77, 361, 1, 0, 0, 0, 79, 366, 1, 0, 0, 0, 81, 372, 1, 0, 0, 0, 83, 374, 1, 0, 0, 0, 85, 377, 1, 0, 0, 0, 87, 390, 1, 0, 0, 0, 89, 404, 1, 0, 0, 0, 91, 412, 1, 0, 0, 0, 93, 417, 1, 0, 0, 0, 95, 96, 5, 36, 0, 0, 96, 2, 1, 0, 0, 0, 97, 98, 5, 46, 0, 0, 98, 4, 1, 0, 0, 0, 99, 100, 5, 42, 0, 0, 100, 6, 1, 0, 0, 0, 101, 102, 5, 44, 0, 0, 102, 8, 1, 0, 0, 0, 103, 104, 5, 40, 0, 0, 104, 10, 1, 0, 0, 0, 105, 106, 5, 41, 0, 0, 106, 12, 1, 0, 0, 0, 107, 108, 5, 91, 0, 0, 108, 14, 1, 0, 0, 0, 109, 110, 5, 93, 0, 0, 110, 16, 1, 0, 0, 0, 111, 112, 5, 60, 0, 0, 112, 18, 1, 0, 0, 0, 113, 114, 5, 62, 0, 0, 114, 20, 1, 0, 0, 0, 115, 116, 5, 64, 0, 0, 116, 117, 5, 46, 0, 0, 117, 22, 1, 0, 0, 0, 118, 119, 5, 64, 0, 0, 119, 120, 5, 46, 0, 0, 120, 121, 5, 108, 0, 0, 121, 122, 5, 101, 0, 0, 122, 123, 5, 110, 0, 0, 123, 124, 5, 103, 0, 0, 124, 125, 5, 116, 0, 0, 125, 126, 5, 104, 0, 0, 126, 127, 5, 45, 0, 0, 127, 24, 1, 0, 0, 0, 128, 129, 5, 38, 0, 0, 129, 130, 5, 38, 0, 0, 130, 26, 1, 0, 0, 0, 131, 132, 5, 124, 0, 0, 132, 133, 5, 124, 0, 0, 133, 28, 1, 0, 0, 0, 134, 135, 5, 61, 0, 0, 135, 136, 5, 61, 0, 0, 136, 30, 1, 0, 0, 0, 137, 138, 5, 61, 0, 0, 138, 32, 1, 0, 0, 0, 139, 140, 5, 116, 0, 0, 140, 141, 5, 114, 0, 0, 141, 142, 5, 117, 0, 0, 142, 143, 5, 101, 0, 0, 143, 34, 1, 0, 0, 0, 144, 145, 5, 102, 0, 0, 145, 146, 5, 97, 0, 0, 146, 147, 5, 108, 0, 0, 147, 148, 5, 115, 0, 0, 148, 149, 5, 101, 0, 0, 149, 36, 1, 0, 0, 0, 150, 151, 5, 83, 0, 0, 151, 152, 5, 116, 0, 0, 152, 153, 5, 97, 0, 0, 153, 154, 5, 116, 0, 0, 154, 155, 5, 101, 0, 0, 155, 156, 5, 115, 0, 0, 156, 38, 1, 0, 0, 0, 157, 158, 5, 70, 0, 0, 158, 159, 5, 111, 0, 0, 159, 160, 5, 114, 0, 0, 160, 161, 5, 109, 0, 0, 161, 162, 5, 97, 0, 0, 162, 163, 5, 116, 0, 0, 163, 40, 1, 0, 0, 0, 164, 165, 5, 83, 0, 0, 165, 166, 5, 116, 0, 0, 166, 167, 5, 114, 0, 0, 167, 168, 5, 105, 0, 0, 168, 169, 5, 110, 0, 0, 169, 170, 5, 103, 0, 0, 170, 171, 5, 84, 0, 0, 171, 172, 5, 111, 0, 0, 172, 173, 5, 74, 0, 0, 173, 174, 5, 115, 0, 0, 174, 175, 5, 111, 0, 0, 175, 176, 5, 110, 0, 0, 176, 42, 1, 0, 0, 0, 177, 178, 5, 74, 0, 0, 178, 179, 5, 115, 0, 0, 179, 180, 5, 111, 0, 0, 180, 181, 5, 110, 0, 0, 181, 182, 5, 84, 0, 0, 182, 183, 5, 111, 0, 0, 183, 184, 5, 83, 0, 0, 184, 185, 5, 116, 0, 0, 185, 186, 5, 114, 0, 0, 186, 187, 5, 105, 0, 0, 187, 188, 5, 110, 0, 0, 188, 189, 5, 103, 0, 0, 189, 44, 1, 0, 0, 0, 190, 191, 5, 65, 0, 0, 191, 192, 5, 114, 0, 0, 192, 193, 5, 114, 0, 0, 193, 194, 5, 97, 0, 0, 194, 195, 5, 121, 0, 0, 195, 46, 1, 0, 0, 0, 196, 197, 5, 65, 0, 0, 197, 198, 5, 114, 0, 0, 198, 199, 5, 114, 0, 0, 199, 200, 5, 97, 0, 0, 200, 201, 5, 121, 0, 0, 201, 202, 5, 80, 0, 0, 202, 203, 5, 97, 0, 0, 203, 204, 5, 114, 0, 0, 204, 205, 5, 116, 0, 0, 205, 206, 5, 105, 0, 0, 206, 207, 5, 116, 0, 0, 207, 208, 5, 105, 0, 0, 208, 209, 5, 111, 0, 0, 209, 210, 5, 110, 0, 0, 210, 48, 1, 0, 0, 0, 211, 212, 5, 65, 0, 0, 212, 213, 5, 114, 0, 0, 213, 214, 5, 114, 0, 0, 214, 215, 5, 97, 0, 0, 215, 216, 5, 121, 0, 0, 216, 217, 5, 67, 0, 0, 217, 218, 5, 111, 0, 0, 218, 219, 5, 110, 0, 0, 219, 220, 5, 116, 0, 0, 220, 221, 5, 97, 0, 0, 221, 222, 5, 105, 0, 0, 222, 223, 5, 110, 0, 0, 223, 224, 5, 115, 0, 0, 224, 50, 1, 0, 0, 0, 225, 226, 5, 65, 0, 0, 226, 227, 5, 114, 0, 0, 227, 228, 5, 114, 0, 0, 228, 229, 5, 97, 0, 0, 229, 230, 5, 121, 0, 0, 230, 231, 5, 82, 0, 0, 231, 232, 5, 97, 0, 0, 232, 233, 5, 110, 0, 0, 233, 234, 5, 103, 0, 0, 234, 235, 5, 101, 0, 0, 235, 52, 1, 0, 0, 0, 236, 237, 5, 65, 0, 0, 237, 238, 5, 114, 0, 0, 238, 239, 5, 114, 0, 0, 239, 240, 5, 97, 0, 0, 240, 241, 5, 121, 0, 0, 241, 242, 5, 71, 0, 0, 242, 243, 5, 101, 0, 0, 243, 244, 5, 116, 0, 0, 244, 245, 5, 73, 0, 0, 245, 246, 5, 116, 0, 0, 246, 247, 5, 101, 0, 0, 247, 248, 5, 109, 0, 0, 248, 54, 1, 0, 0, 0, 249, 250, 5, 65, 0, 0, 250, 251, 5, 114, 0, 0, 251, 252, 5, 114, 0, 0, 252, 253, 5, 97, 0, 0, 253, 254, 5, 121, 0, 0, 254, 255, 5, 76, 0, 0, 255, 256, 5, 101, 0, 0, 256, 257, 5, 110, 0, 0, 257, 258, 5, 103, 0, 0, 258, 259, 5, 116, 0, 0, 259, 260, 5, 104, 0, 0, 260, 56, 1, 0, 0, 0, 261, 262, 5, 65, 0, 0, 262, 263, 5, 114, 0, 0, 263, 264, 5, 114, 0, 0, 264, 265, 5, 97, 0, 0, 265, 266, 5, 121, 0, 0, 266, 267, 5, 85, 0, 0, 267, 268, 5, 110, 0, 0, 268, 269, 5, 105, 0, 0, 269, 270, 5, 113, 0, 0, 270, 271, 5, 117, 0, 0, 271, 272, 5, 101, 0, 0, 272, 58, 1, 0, 0, 0, 273, 274, 5, 66, 0, 0, 274, 275, 5, 97, 0, 0, 275, 276, 5, 115, 0, 0, 276, 277, 5, 101, 0, 0, 277, 278, 5, 54, 0, 0, 278, 279, 5, 52, 0, 0, 279, 280, 5, 69, 0, 0, 280, 281, 5, 110, 0, 0, 281, 282, 5, 99, 0, 0, 282, 283, 5, 111, 0, 0, 283, 284, 5, 100, 0, 0, 284, 285, 5, 101, 0, 0, 285, 60, 1, 0, 0, 0, 286, 287, 5, 66, 0, 0, 287, 288, 5, 97, 0, 0, 288, 289, 5, 115, 0, 0, 289, 290, 5, 101, 0, 0, 290, 291, 5, 54, 0, 0, 291, 292, 5, 52, 0, 0, 292, 293, 5, 68, 0, 0, 293, 294, 5, 101, 0, 0, 294, 295, 5, 99, 0, 0, 295, 296, 5, 111, 0, 0, 296, 297, 5, 100, 0, 0, 297, 298, 5, 101, 0, 0, 298, 62, 1, 0, 0, 0, 299, 300, 5, 72, 0, 0, 300, 301, 5, 97, 0, 0, 301, 302, 5, 115, 0, 0, 302, 303, 5, 104, 0, 0, 303, 64, 1, 0, 0, 0, 304, 305, 5, 74, 0, 0, 305, 306, 5, 115, 0, 0, 306, 307, 5, 111, 0, 0, 307, 308, 5, 110, 0, 0, 308, 309, 5, 77, 0, 0, 309, 310, 5, 101, 0, 0, 310, 311, 5, 114, 0, 0, 311, 312, 5, 103, 0, 0, 312, 313, 5, 101, 0, 0, 313, 66, 1, 0, 0, 0, 314, 315, 5, 77, 0, 0, 315, 316, 5, 97, 0, 0, 316, 317, 5, 116, 0, 0, 317, 318, 5, 104, 0, 0, 318, 319, 5, 82, 0, 0, 319, 320, 5, 97, 0, 0, 320, 321, 5, 110, 0, 0, 321, 322, 5, 100, 0, 0, 322, 323, 5, 111, 0, 0, 323, 324, 5, 109, 0, 0, 324, 68, 1, 0, 0, 0, 325, 326, 5, 77, 0, 0, 326, 327, 5, 97, 0, 0, 327, 328, 5, 116, 0, 0, 328, 329, 5, 104, 0, 0, 329, 330, 5, 65, 0, 0, 330, 331, 5, 100, 0, 0, 331, 332, 5, 100, 0, 0, 332, 70, 1, 0, 0, 0, 333, 334, 5, 83, 0, 0, 334, 335, 5, 116, 0, 0, 335, 336, 5, 114, 0, 0, 336, 337, 5, 105, 0, 0, 337, 338, 5, 110, 0, 0, 338, 339, 5, 103, 0, 0, 339, 340, 5, 83, 0, 0, 340, 341, 5, 112, 0, 0, 341, 342, 5, 108, 0, 0, 342, 343, 5, 105, 0, 0, 343, 344, 5, 116, 0, 0, 344, 72, 1, 0, 0, 0, 345, 346, 5, 85, 0, 0, 346, 347, 5, 85, 0, 0, 347, 348, 5, 73, 0, 0, 348, 349, 5, 68, 0, 0, 349, 74, 1, 0, 0, 0, 350, 356, 5, 39, 0, 0, 351, 355, 5, 10, 0, 0, 352, 355, 3, 77, 38, 0, 353, 355, 3, 83, 41, 0, 354, 351, 1, 0, 0, 0, 354, 352, 1, 0, 0, 0, 354, 353, 1, 0, 0, 0, 355, 358, 1, 0, 0, 0, 356, 357, 1, 0, 0, 0, 356, 354, 1, 0, 0, 0, 357, 359, 1, 0, 0, 0, 358, 356, 1, 0, 0, 0, 359, 360, 5, 39, 0, 0, 360, 76, 1, 0, 0, 0, 361, 364, 5, 92, 0, 0, 362, 365, 3, 79, 39, 0, 363, 365, 9, 0, 0, 0, 364, 362, 1, 0, 0, 0, 364, 363, 1, 0, 0, 0, 365, 78, 1, 0, 0, 0, 366, 367, 5, 117, 0, 0, 367, 368, 3, 81, 40, 0, 368, 369, 3, 81, 40, 0, 369, 370, 3, 81, 40, 0, 370, 371, 3, 81, 40, 0, 371, 80, 1, 0, 0, 0, 372, 373, 7, 0, 0, 0, 373, 82, 1, 0, 0, 0, 374, 375, 8, 1, 0, 0, 375, 84, 1, 0, 0, 0, 376, 378, 5, 45, 0, 0, 377, 376, 1, 0, 0, 0, 377, 378, 1, 0, 0, 0, 378, 387, 1, 0, 0, 0, 379, 388, 5, 48, 0, 0, 380, 384, 7, 2, 0, 0, 381, 383, 7, 3, 0, 0, 382, 381, 1, 0, 0, 0, 383, 386, 1, 0, 0, 0, 384, 382, 1, 0, 0, 0, 384, 385, 1, 0, 0, 0, 385, 388, 1, 0, 0, 0, 386, 384, 1, 0, 0, 0, 387, 379, 1, 0, 0, 0, 387, 380, 1, 0, 0, 0, 388, 86, 1, 0, 0, 0, 389, 391, 5, 45, 0, 0, 390, 389, 1, 0, 0, 0, 390, 391, 1, 0, 0, 0, 391, 392, 1, 0, 0, 0, 392, 399, 3, 85, 42, 0, 393, 395, 5, 46, 0, 0, 394, 396, 7, 3, 0, 0, 395, 394, 1, 0, 0, 0, 396, 397, 1, 0, 0, 0, 397, 395, 1, 0, 0, 0, 397, 398, 1, 0, 0, 0, 398, 400, 1, 0, 0, 0, 399, 393, 1, 0, 0, 0, 399, 400, 1, 0, 0, 0, 400, 402, 1, 0, 0, 0, 401, 403, 3, 89, 44, 0, 402, 401, 1, 0, 0, 0, 402, 403, 1, 0, 0, 0, 403, 88, 1, 0, 0, 0, 404, 406, 7, 4, 0, 0, 405, 407, 7, 5, 0, 0, 406, 405, 1, 0, 0, 0, 406, 407, 1, 0, 0, 0, 407, 408, 1, 0, 0, 0, 408, 409, 3, 85, 42, 0, 409, 90, 1, 0, 0, 0, 410, 413, 7, 6, 0, 0, 411, 413, 3, 79, 39, 0, 412, 410, 1, 0, 0, 0, 412, 411, 1, 0, 0, 0, 413, 414, 1, 0, 0, 0, 414, 412, 1, 0, 0, 0, 414, 415, 1, 0, 0, 0, 415, 92, 1, 0, 0, 0, 416, 418, 7, 7, 0, 0, 417, 416, 1, 0, 0, 0, 418, 419, 1, 0, 0, 0, 419, 417, 1, 0, 0, 0, 419, 420, 1, 0, 0, 0, 420, 421, 1, 0, 0, 0, 421, 422, 6, 46, 0, 0, 422, 94, 1, 0, 0, 0, 15, 0, 354, 356, 364, 377, 384, 387, 390, 397, 399, 402, 406, 412, 414, 419, 1, 6, 0, 0] \ No newline at end of file diff --git a/moto/stepfunctions/parser/asl/antlr/runtime/ASLIntrinsicLexer.py b/moto/stepfunctions/parser/asl/antlr/runtime/ASLIntrinsicLexer.py index 20a11ceb7097..9eee12a2adb3 100644 --- a/moto/stepfunctions/parser/asl/antlr/runtime/ASLIntrinsicLexer.py +++ b/moto/stepfunctions/parser/asl/antlr/runtime/ASLIntrinsicLexer.py @@ -1,4 +1,4 @@ -# Generated from ASLIntrinsicLexer.g4 by ANTLR 4.13.1 +# Generated from ASLIntrinsicLexer.g4 by ANTLR 4.13.2 import sys from typing import TextIO @@ -15,8 +15,8 @@ def serializedATN(): return [ 4, 0, - 33, - 406, + 34, + 412, 6, -1, 2, @@ -179,6 +179,10 @@ def serializedATN(): 39, 7, 39, + 2, + 40, + 7, + 40, 1, 0, 1, @@ -195,61 +199,65 @@ def serializedATN(): 1, 1, 2, - 3, - 2, - 90, - 8, - 2, 1, 2, 1, 2, - 3, - 2, - 94, - 8, - 2, 1, 2, + 1, 3, - 2, - 97, - 8, - 2, - 5, - 2, - 99, + 3, + 3, + 96, 8, - 2, - 10, - 2, - 12, - 2, - 102, - 9, - 2, + 3, 1, 3, 1, 3, + 3, + 3, + 100, + 8, + 3, 1, 3, + 3, + 3, + 103, + 8, + 3, 5, 3, - 107, + 105, 8, 3, 10, 3, 12, 3, - 110, + 108, 9, 3, 1, - 3, + 4, 1, - 3, + 4, + 1, + 4, + 5, + 4, + 113, + 8, + 4, + 10, + 4, + 12, + 4, + 116, + 9, + 4, 1, 4, 1, @@ -275,14 +283,6 @@ def serializedATN(): 1, 9, 1, - 9, - 1, - 9, - 1, - 9, - 1, - 10, - 1, 10, 1, 10, @@ -305,8 +305,6 @@ def serializedATN(): 1, 11, 1, - 11, - 1, 12, 1, 12, @@ -335,18 +333,6 @@ def serializedATN(): 1, 13, 1, - 13, - 1, - 13, - 1, - 13, - 1, - 13, - 1, - 13, - 1, - 13, - 1, 14, 1, 14, @@ -385,21 +371,19 @@ def serializedATN(): 1, 15, 1, - 16, - 1, - 16, + 15, 1, - 16, + 15, 1, - 16, + 15, 1, - 16, + 15, 1, - 16, + 15, 1, - 16, + 15, 1, - 16, + 15, 1, 16, 1, @@ -413,7 +397,7 @@ def serializedATN(): 1, 16, 1, - 16, + 17, 1, 17, 1, @@ -465,9 +449,11 @@ def serializedATN(): 1, 18, 1, - 19, + 18, 1, - 19, + 18, + 1, + 18, 1, 19, 1, @@ -515,7 +501,7 @@ def serializedATN(): 1, 20, 1, - 21, + 20, 1, 21, 1, @@ -539,7 +525,7 @@ def serializedATN(): 1, 21, 1, - 22, + 21, 1, 22, 1, @@ -601,15 +587,21 @@ def serializedATN(): 1, 24, 1, - 25, + 24, 1, - 25, + 24, 1, - 25, + 24, 1, - 25, + 24, 1, - 25, + 24, + 1, + 24, + 1, + 24, + 1, + 24, 1, 25, 1, @@ -641,7 +633,7 @@ def serializedATN(): 1, 26, 1, - 26, + 27, 1, 27, 1, @@ -659,9 +651,9 @@ def serializedATN(): 1, 27, 1, - 28, + 27, 1, - 28, + 27, 1, 28, 1, @@ -679,9 +671,9 @@ def serializedATN(): 1, 28, 1, - 28, + 29, 1, - 28, + 29, 1, 29, 1, @@ -693,22 +685,20 @@ def serializedATN(): 1, 29, 1, - 30, + 29, 1, - 30, + 29, + 1, + 29, + 1, + 29, + 1, + 29, 1, 30, - 5, - 30, - 338, - 8, - 30, - 10, - 30, - 12, + 1, 30, - 341, - 9, + 1, 30, 1, 30, @@ -720,66 +710,58 @@ def serializedATN(): 31, 1, 31, - 3, + 5, 31, - 348, + 344, 8, 31, + 10, + 31, + 12, + 31, + 347, + 9, + 31, 1, - 32, + 31, 1, - 32, + 31, 1, 32, 1, 32, 1, 32, - 1, + 3, + 32, + 354, + 8, 32, 1, 33, 1, 33, 1, - 34, + 33, 1, - 34, + 33, 1, - 35, - 3, - 35, - 361, - 8, - 35, + 33, 1, - 35, + 33, 1, - 35, + 34, + 1, + 34, 1, 35, - 5, - 35, - 366, - 8, - 35, - 10, - 35, - 12, - 35, - 369, - 9, - 35, - 3, - 35, - 371, - 8, + 1, 35, 1, 36, 3, 36, - 374, + 367, 8, 36, 1, @@ -788,35 +770,28 @@ def serializedATN(): 36, 1, 36, - 4, + 5, 36, - 379, + 372, 8, 36, - 11, + 10, 36, 12, 36, - 380, - 3, - 36, - 383, - 8, - 36, - 1, + 375, + 9, 36, 3, 36, - 386, + 377, 8, 36, 1, 37, - 1, - 37, 3, 37, - 390, + 380, 8, 37, 1, @@ -824,49 +799,86 @@ def serializedATN(): 1, 37, 1, - 38, - 1, - 38, + 37, 4, - 38, - 396, + 37, + 385, 8, - 38, + 37, 11, - 38, + 37, 12, + 37, + 386, + 3, + 37, + 389, + 8, + 37, + 1, + 37, + 3, + 37, + 392, + 8, + 37, + 1, 38, - 397, + 1, + 38, + 3, + 38, + 396, + 8, + 38, + 1, + 38, + 1, + 38, + 1, + 39, 1, 39, 4, 39, - 401, + 402, 8, 39, 11, 39, 12, 39, - 402, + 403, 1, - 39, + 40, + 4, + 40, + 407, + 8, + 40, + 11, + 40, + 12, + 40, + 408, 1, - 39, + 40, 1, - 339, - 0, 40, 1, + 345, + 0, + 41, + 1, 1, 3, 2, 5, - 0, + 3, 7, 0, 9, - 3, + 0, 11, 4, 13, @@ -920,7 +932,7 @@ def serializedATN(): 61, 29, 63, - 0, + 30, 65, 0, 67, @@ -928,15 +940,17 @@ def serializedATN(): 69, 0, 71, - 30, + 0, 73, 31, 75, - 0, - 77, 32, + 77, + 0, 79, 33, + 81, + 34, 1, 0, 9, @@ -996,7 +1010,7 @@ def serializedATN(): 10, 32, 32, - 418, + 424, 0, 1, 1, @@ -1010,7 +1024,7 @@ def serializedATN(): 0, 0, 0, - 9, + 5, 1, 0, 0, @@ -1172,7 +1186,7 @@ def serializedATN(): 0, 0, 0, - 71, + 63, 1, 0, 0, @@ -1184,7 +1198,7 @@ def serializedATN(): 0, 0, 0, - 77, + 75, 1, 0, 0, @@ -1195,68 +1209,74 @@ def serializedATN(): 0, 0, 0, - 1, + 0, 81, 1, 0, 0, 0, + 1, + 83, + 1, + 0, + 0, + 0, 3, - 85, + 87, 1, 0, 0, 0, 5, - 89, + 90, 1, 0, 0, 0, 7, - 103, + 95, 1, 0, 0, 0, 9, - 113, + 109, 1, 0, 0, 0, 11, - 115, + 119, 1, 0, 0, 0, 13, - 117, + 121, 1, 0, 0, 0, 15, - 119, + 123, 1, 0, 0, 0, 17, - 121, + 125, 1, 0, 0, 0, 19, - 123, + 127, 1, 0, 0, 0, 21, - 128, + 129, 1, 0, 0, @@ -1268,25 +1288,25 @@ def serializedATN(): 0, 0, 25, - 141, + 140, 1, 0, 0, 0, 27, - 148, + 147, 1, 0, 0, 0, 29, - 161, + 154, 1, 0, 0, 0, 31, - 174, + 167, 1, 0, 0, @@ -1298,97 +1318,97 @@ def serializedATN(): 0, 0, 35, - 195, + 186, 1, 0, 0, 0, 37, - 209, + 201, 1, 0, 0, 0, 39, - 220, + 215, 1, 0, 0, 0, 41, - 233, + 226, 1, 0, 0, 0, 43, - 245, + 239, 1, 0, 0, 0, 45, - 257, + 251, 1, 0, 0, 0, 47, - 270, + 263, 1, 0, 0, 0, 49, - 283, + 276, 1, 0, 0, 0, 51, - 288, + 289, 1, 0, 0, 0, 53, - 298, + 294, 1, 0, 0, 0, 55, - 309, + 304, 1, 0, 0, 0, 57, - 317, + 315, 1, 0, 0, 0, 59, - 329, + 323, 1, 0, 0, 0, 61, - 334, + 335, 1, 0, 0, 0, 63, - 344, + 340, 1, 0, 0, 0, 65, - 349, + 350, 1, 0, 0, @@ -1400,212 +1420,200 @@ def serializedATN(): 0, 0, 69, - 357, + 361, 1, 0, 0, 0, 71, - 360, + 363, 1, 0, 0, 0, 73, - 373, + 366, 1, 0, 0, 0, 75, - 387, + 379, 1, 0, 0, 0, 77, - 395, + 393, 1, 0, 0, 0, 79, - 400, + 401, 1, 0, 0, 0, 81, - 82, - 3, - 9, - 4, + 406, + 1, + 0, 0, - 82, - 83, - 3, - 9, - 4, 0, 83, 84, 3, + 11, 5, - 2, 0, 84, - 2, - 1, - 0, - 0, + 85, + 3, + 11, + 5, 0, 85, 86, 3, - 9, - 4, + 7, + 3, 0, 86, - 87, - 3, - 5, 2, - 0, - 87, - 4, 1, 0, 0, 0, + 87, 88, - 90, - 3, - 7, 3, + 11, + 5, 0, - 89, 88, - 1, - 0, - 0, + 89, + 3, + 7, + 3, 0, 89, - 90, + 4, 1, 0, 0, 0, 90, - 100, - 1, - 0, - 0, - 0, 91, - 93, 3, - 17, - 8, + 11, + 5, 0, + 91, 92, - 94, 3, - 77, - 38, + 79, + 39, 0, - 93, 92, - 1, - 0, - 0, + 93, + 3, + 7, + 3, 0, 93, - 94, + 6, 1, 0, 0, 0, 94, 96, + 3, + 9, + 4, + 0, + 95, + 94, 1, 0, 0, 0, 95, - 97, - 3, - 7, - 3, - 0, 96, - 95, 1, 0, 0, 0, 96, - 97, + 106, 1, 0, 0, 0, 97, 99, - 1, - 0, + 3, + 19, + 9, 0, + 98, + 100, + 3, + 79, + 39, 0, + 99, 98, - 91, 1, 0, 0, 0, 99, - 102, + 100, 1, 0, 0, 0, 100, - 98, + 102, 1, 0, 0, 0, - 100, 101, - 1, - 0, - 0, + 103, + 3, + 9, + 4, 0, + 102, 101, - 6, 1, 0, 0, 0, 102, - 100, + 103, 1, 0, 0, 0, 103, - 108, - 5, - 91, + 105, + 1, + 0, 0, 0, 104, - 107, - 3, - 7, - 3, + 97, + 1, + 0, + 0, 0, 105, - 107, - 8, + 108, + 1, 0, 0, 0, @@ -1616,13 +1624,13 @@ def serializedATN(): 0, 0, 106, - 105, + 107, 1, 0, 0, 0, 107, - 110, + 8, 1, 0, 0, @@ -1633,56 +1641,62 @@ def serializedATN(): 0, 0, 0, - 108, 109, - 1, + 114, + 5, + 91, 0, 0, + 110, + 113, + 3, + 9, + 4, 0, - 109, 111, - 1, + 113, + 8, 0, 0, 0, + 112, 110, - 108, 1, 0, 0, 0, - 111, 112, - 5, - 93, + 111, + 1, 0, 0, - 112, - 8, + 0, + 113, + 116, 1, 0, 0, 0, - 113, 114, - 5, - 36, + 112, + 1, + 0, 0, 0, 114, - 10, + 115, 1, 0, 0, 0, 115, - 116, - 5, - 40, + 117, + 1, + 0, 0, 0, 116, - 12, + 114, 1, 0, 0, @@ -1690,11 +1704,11 @@ def serializedATN(): 117, 118, 5, - 41, + 93, 0, 0, 118, - 14, + 10, 1, 0, 0, @@ -1702,11 +1716,11 @@ def serializedATN(): 119, 120, 5, - 44, + 36, 0, 0, 120, - 16, + 12, 1, 0, 0, @@ -1714,11 +1728,11 @@ def serializedATN(): 121, 122, 5, - 46, + 40, 0, 0, 122, - 18, + 14, 1, 0, 0, @@ -1726,55 +1740,55 @@ def serializedATN(): 123, 124, 5, - 116, + 41, 0, 0, 124, - 125, - 5, - 114, + 16, + 1, + 0, 0, 0, 125, 126, 5, - 117, + 44, 0, 0, 126, + 18, + 1, + 0, + 0, + 0, 127, + 128, 5, - 101, + 46, 0, 0, - 127, + 128, 20, 1, 0, 0, 0, - 128, - 129, - 5, - 102, - 0, - 0, 129, 130, 5, - 97, + 116, 0, 0, 130, 131, 5, - 108, + 114, 0, 0, 131, 132, 5, - 115, + 117, 0, 0, 132, @@ -1792,25 +1806,25 @@ def serializedATN(): 134, 135, 5, - 83, + 102, 0, 0, 135, 136, 5, - 116, + 97, 0, 0, 136, 137, 5, - 97, + 108, 0, 0, 137, 138, 5, - 116, + 115, 0, 0, 138, @@ -1820,219 +1834,219 @@ def serializedATN(): 0, 0, 139, - 140, - 5, - 115, - 0, - 0, - 140, 24, 1, 0, 0, 0, + 140, + 141, + 5, + 83, + 0, + 0, 141, 142, 5, - 70, + 116, 0, 0, 142, 143, 5, - 111, + 97, 0, 0, 143, 144, 5, - 114, + 116, 0, 0, 144, 145, 5, - 109, + 101, 0, 0, 145, 146, 5, - 97, + 115, 0, 0, 146, - 147, - 5, - 116, - 0, - 0, - 147, 26, 1, 0, 0, 0, + 147, + 148, + 5, + 70, + 0, + 0, 148, 149, 5, - 83, + 111, 0, 0, 149, 150, 5, - 116, + 114, 0, 0, 150, 151, 5, - 114, + 109, 0, 0, 151, 152, 5, - 105, + 97, 0, 0, 152, 153, 5, - 110, + 116, 0, 0, 153, - 154, - 5, - 103, + 28, + 1, + 0, 0, 0, 154, 155, 5, - 84, + 83, 0, 0, 155, 156, 5, - 111, + 116, 0, 0, 156, 157, 5, - 74, + 114, 0, 0, 157, 158, 5, - 115, + 105, 0, 0, 158, 159, 5, - 111, + 110, 0, 0, 159, 160, 5, - 110, + 103, 0, 0, 160, - 28, - 1, - 0, + 161, + 5, + 84, 0, 0, 161, 162, 5, - 74, + 111, 0, 0, 162, 163, 5, - 115, + 74, 0, 0, 163, 164, 5, - 111, + 115, 0, 0, 164, 165, 5, - 110, + 111, 0, 0, 165, 166, 5, - 84, + 110, 0, 0, 166, - 167, - 5, - 111, + 30, + 1, + 0, 0, 0, 167, 168, 5, - 83, + 74, 0, 0, 168, 169, 5, - 116, + 115, 0, 0, 169, 170, 5, - 114, + 111, 0, 0, 170, 171, 5, - 105, + 110, 0, 0, 171, 172, 5, - 110, + 84, 0, 0, 172, 173, 5, - 103, + 111, 0, 0, 173, - 30, - 1, - 0, + 174, + 5, + 83, 0, 0, 174, 175, 5, - 65, + 116, 0, 0, 175, @@ -2044,19 +2058,19 @@ def serializedATN(): 176, 177, 5, - 114, + 105, 0, 0, 177, 178, 5, - 97, + 110, 0, 0, 178, 179, 5, - 121, + 103, 0, 0, 179, @@ -2096,15 +2110,15 @@ def serializedATN(): 0, 0, 185, - 186, - 5, - 80, + 34, + 1, + 0, 0, 0, 186, 187, 5, - 97, + 65, 0, 0, 187, @@ -2116,97 +2130,97 @@ def serializedATN(): 188, 189, 5, - 116, + 114, 0, 0, 189, 190, 5, - 105, + 97, 0, 0, 190, 191, 5, - 116, + 121, 0, 0, 191, 192, 5, - 105, + 80, 0, 0, 192, 193, 5, - 111, + 97, 0, 0, 193, 194, 5, - 110, + 114, 0, 0, 194, - 34, - 1, - 0, + 195, + 5, + 116, 0, 0, 195, 196, 5, - 65, + 105, 0, 0, 196, 197, 5, - 114, + 116, 0, 0, 197, 198, 5, - 114, + 105, 0, 0, 198, 199, 5, - 97, + 111, 0, 0, 199, 200, 5, - 121, + 110, 0, 0, 200, - 201, - 5, - 67, + 36, + 1, + 0, 0, 0, 201, 202, 5, - 111, + 65, 0, 0, 202, 203, 5, - 110, + 114, 0, 0, 203, 204, 5, - 116, + 114, 0, 0, 204, @@ -2218,559 +2232,559 @@ def serializedATN(): 205, 206, 5, - 105, + 121, 0, 0, 206, 207, 5, - 110, + 67, 0, 0, 207, 208, 5, - 115, + 111, 0, 0, 208, - 36, - 1, - 0, + 209, + 5, + 110, 0, 0, 209, 210, 5, - 65, + 116, 0, 0, 210, 211, 5, - 114, + 97, 0, 0, 211, 212, 5, - 114, + 105, 0, 0, 212, 213, 5, - 97, + 110, 0, 0, 213, 214, 5, - 121, + 115, 0, 0, 214, - 215, - 5, - 82, + 38, + 1, + 0, 0, 0, 215, 216, 5, - 97, + 65, 0, 0, 216, 217, 5, - 110, + 114, 0, 0, 217, 218, 5, - 103, + 114, 0, 0, 218, 219, 5, - 101, + 97, 0, 0, 219, - 38, - 1, - 0, + 220, + 5, + 121, 0, 0, 220, 221, 5, - 65, + 82, 0, 0, 221, 222, 5, - 114, + 97, 0, 0, 222, 223, 5, - 114, + 110, 0, 0, 223, 224, 5, - 97, + 103, 0, 0, 224, 225, 5, - 121, + 101, 0, 0, 225, - 226, - 5, - 71, + 40, + 1, + 0, 0, 0, 226, 227, 5, - 101, + 65, 0, 0, 227, 228, 5, - 116, + 114, 0, 0, 228, 229, 5, - 73, + 114, 0, 0, 229, 230, 5, - 116, + 97, 0, 0, 230, 231, 5, - 101, + 121, 0, 0, 231, 232, 5, - 109, + 71, 0, 0, 232, - 40, - 1, - 0, + 233, + 5, + 101, 0, 0, 233, 234, 5, - 65, + 116, 0, 0, 234, 235, 5, - 114, + 73, 0, 0, 235, 236, 5, - 114, + 116, 0, 0, 236, 237, 5, - 97, + 101, 0, 0, 237, 238, 5, - 121, + 109, 0, 0, 238, - 239, - 5, - 76, + 42, + 1, + 0, 0, 0, 239, 240, 5, - 101, + 65, 0, 0, 240, 241, 5, - 110, + 114, 0, 0, 241, 242, 5, - 103, + 114, 0, 0, 242, 243, 5, - 116, + 97, 0, 0, 243, 244, 5, - 104, + 121, 0, 0, 244, - 42, - 1, - 0, + 245, + 5, + 76, 0, 0, 245, 246, 5, - 65, + 101, 0, 0, 246, 247, 5, - 114, + 110, 0, 0, 247, 248, 5, - 114, + 103, 0, 0, 248, 249, 5, - 97, + 116, 0, 0, 249, 250, 5, - 121, + 104, 0, 0, 250, - 251, - 5, - 85, + 44, + 1, + 0, 0, 0, 251, 252, 5, - 110, + 65, 0, 0, 252, 253, 5, - 105, + 114, 0, 0, 253, 254, 5, - 113, + 114, 0, 0, 254, 255, 5, - 117, + 97, 0, 0, 255, 256, 5, - 101, + 121, 0, 0, 256, - 44, - 1, - 0, + 257, + 5, + 85, 0, 0, 257, 258, 5, - 66, + 110, 0, 0, 258, 259, 5, - 97, + 105, 0, 0, 259, 260, 5, - 115, + 113, 0, 0, 260, 261, 5, - 101, + 117, 0, 0, 261, 262, 5, - 54, + 101, 0, 0, 262, - 263, - 5, - 52, + 46, + 1, + 0, 0, 0, 263, 264, 5, - 69, + 66, 0, 0, 264, 265, 5, - 110, + 97, 0, 0, 265, 266, 5, - 99, + 115, 0, 0, 266, 267, 5, - 111, + 101, 0, 0, 267, 268, 5, - 100, + 54, 0, 0, 268, 269, 5, - 101, + 52, 0, 0, 269, - 46, - 1, - 0, + 270, + 5, + 69, 0, 0, 270, 271, 5, - 66, + 110, 0, 0, 271, 272, 5, - 97, + 99, 0, 0, 272, 273, 5, - 115, + 111, 0, 0, 273, 274, 5, - 101, + 100, 0, 0, 274, 275, 5, - 54, + 101, 0, 0, 275, - 276, - 5, - 52, + 48, + 1, + 0, 0, 0, 276, 277, 5, - 68, + 66, 0, 0, 277, 278, 5, - 101, + 97, 0, 0, 278, 279, 5, - 99, + 115, 0, 0, 279, 280, 5, - 111, + 101, 0, 0, 280, 281, 5, - 100, + 54, 0, 0, 281, 282, 5, - 101, + 52, 0, 0, 282, - 48, - 1, - 0, + 283, + 5, + 68, 0, 0, 283, 284, 5, - 72, + 101, 0, 0, 284, 285, 5, - 97, + 99, 0, 0, 285, 286, 5, - 115, + 111, 0, 0, 286, 287, 5, - 104, + 100, 0, 0, 287, + 288, + 5, + 101, + 0, + 0, + 288, 50, 1, 0, 0, 0, - 288, 289, + 290, 5, - 74, - 0, - 0, - 289, - 290, - 5, - 115, + 72, 0, 0, 290, 291, 5, - 111, + 97, 0, 0, 291, 292, 5, - 110, + 115, 0, 0, 292, 293, 5, - 77, + 104, 0, 0, 293, - 294, - 5, - 101, + 52, + 1, + 0, 0, 0, 294, 295, 5, - 114, + 74, 0, 0, 295, 296, 5, - 103, + 115, 0, 0, 296, 297, 5, - 101, + 111, 0, 0, 297, - 52, - 1, - 0, + 298, + 5, + 110, 0, 0, 298, @@ -2782,145 +2796,145 @@ def serializedATN(): 299, 300, 5, - 97, + 101, 0, 0, 300, 301, 5, - 116, + 114, 0, 0, 301, 302, 5, - 104, + 103, 0, 0, 302, 303, 5, - 82, + 101, 0, 0, 303, - 304, - 5, - 97, + 54, + 1, + 0, 0, 0, 304, 305, 5, - 110, + 77, 0, 0, 305, 306, 5, - 100, + 97, 0, 0, 306, 307, 5, - 111, + 116, 0, 0, 307, 308, 5, - 109, + 104, 0, 0, 308, - 54, - 1, - 0, + 309, + 5, + 82, 0, 0, 309, 310, 5, - 77, + 97, 0, 0, 310, 311, 5, - 97, + 110, 0, 0, 311, 312, 5, - 116, + 100, 0, 0, 312, 313, 5, - 104, + 111, 0, 0, 313, 314, 5, - 65, + 109, 0, 0, 314, - 315, - 5, - 100, + 56, + 1, + 0, 0, 0, 315, 316, 5, - 100, + 77, 0, 0, 316, - 56, - 1, - 0, + 317, + 5, + 97, 0, 0, 317, 318, 5, - 83, + 116, 0, 0, 318, 319, 5, - 116, + 104, 0, 0, 319, 320, 5, - 114, + 65, 0, 0, 320, 321, 5, - 105, + 100, 0, 0, 321, 322, 5, - 110, + 100, 0, 0, 322, - 323, - 5, - 103, + 58, + 1, + 0, 0, 0, 323, @@ -2932,13 +2946,13 @@ def serializedATN(): 324, 325, 5, - 112, + 116, 0, 0, 325, 326, 5, - 108, + 114, 0, 0, 326, @@ -2950,182 +2964,182 @@ def serializedATN(): 327, 328, 5, - 116, + 110, 0, 0, 328, - 58, - 1, - 0, + 329, + 5, + 103, 0, 0, 329, 330, 5, - 85, + 83, 0, 0, 330, 331, 5, - 85, + 112, 0, 0, 331, 332, 5, - 73, + 108, 0, 0, 332, 333, 5, - 68, + 105, 0, 0, 333, + 334, + 5, + 116, + 0, + 0, + 334, 60, 1, 0, 0, 0, - 334, - 339, + 335, + 336, 5, - 39, - 0, + 85, 0, - 335, - 338, - 3, - 63, - 31, 0, 336, - 338, - 3, - 69, - 34, - 0, 337, - 335, - 1, - 0, + 5, + 85, 0, 0, 337, - 336, - 1, - 0, - 0, - 0, 338, - 341, - 1, - 0, + 5, + 73, 0, 0, + 338, 339, - 340, - 1, - 0, + 5, + 68, 0, 0, 339, - 337, + 62, 1, 0, 0, 0, 340, - 342, - 1, - 0, + 345, + 5, + 39, 0, 0, 341, - 339, - 1, - 0, - 0, + 344, + 3, + 65, + 32, 0, 342, + 344, + 3, + 71, + 35, + 0, 343, - 5, - 39, + 341, + 1, + 0, 0, 0, 343, - 62, + 342, 1, 0, 0, 0, 344, 347, - 5, - 92, + 1, 0, 0, - 345, - 348, - 3, - 65, - 32, 0, + 345, 346, - 348, - 9, + 1, 0, 0, 0, - 347, 345, + 343, 1, 0, 0, 0, - 347, 346, + 348, + 1, + 0, + 0, + 0, + 347, + 345, 1, 0, 0, 0, 348, + 349, + 5, + 39, + 0, + 0, + 349, 64, 1, 0, 0, 0, - 349, 350, + 353, 5, - 117, + 92, 0, 0, - 350, 351, + 354, 3, 67, 33, 0, - 351, 352, - 3, - 67, - 33, + 354, + 9, + 0, + 0, 0, - 352, 353, - 3, - 67, - 33, + 351, + 1, + 0, + 0, 0, 353, - 354, - 3, - 67, - 33, + 352, + 1, + 0, + 0, 0, 354, 66, @@ -3135,132 +3149,120 @@ def serializedATN(): 0, 355, 356, - 7, - 1, + 5, + 117, 0, 0, 356, - 68, - 1, - 0, - 0, - 0, 357, - 358, - 8, - 2, - 0, + 3, + 69, + 34, 0, + 357, 358, - 70, - 1, - 0, - 0, + 3, + 69, + 34, 0, + 358, 359, - 361, - 5, - 45, - 0, + 3, + 69, + 34, 0, - 360, 359, - 1, - 0, - 0, + 360, + 3, + 69, + 34, 0, 360, - 361, + 68, 1, 0, 0, 0, 361, - 370, + 362, + 7, 1, 0, 0, - 0, 362, - 371, - 5, - 48, - 0, + 70, + 1, 0, - 363, - 367, - 7, - 3, 0, 0, + 363, 364, - 366, - 7, - 4, + 8, + 2, 0, 0, - 365, 364, + 72, 1, 0, 0, 0, + 365, + 367, + 5, + 45, + 0, + 0, 366, - 369, + 365, 1, 0, 0, 0, + 366, 367, - 365, 1, 0, 0, 0, 367, - 368, + 376, 1, 0, 0, 0, 368, - 371, - 1, - 0, + 377, + 5, + 48, 0, 0, 369, - 367, - 1, - 0, + 373, + 7, + 3, 0, 0, 370, - 362, - 1, - 0, + 372, + 7, + 4, 0, 0, + 371, 370, - 363, 1, 0, 0, 0, - 371, - 72, + 372, + 375, 1, 0, 0, 0, - 372, - 374, - 5, - 45, - 0, - 0, 373, - 372, + 371, 1, 0, 0, @@ -3272,136 +3274,142 @@ def serializedATN(): 0, 0, 374, - 375, + 377, 1, 0, 0, 0, 375, - 382, - 3, - 71, - 35, + 373, + 1, 0, - 376, - 378, - 5, - 46, 0, 0, - 377, - 379, - 7, - 4, + 376, + 368, + 1, 0, 0, - 378, - 377, + 0, + 376, + 369, 1, 0, 0, 0, - 379, - 380, + 377, + 74, 1, 0, 0, 0, + 378, 380, + 5, + 45, + 0, + 0, + 379, 378, 1, 0, 0, 0, + 379, 380, - 381, 1, 0, 0, 0, + 380, 381, - 383, 1, 0, 0, 0, - 382, - 376, - 1, + 381, + 388, + 3, + 73, + 36, 0, + 382, + 384, + 5, + 46, 0, 0, - 382, 383, - 1, - 0, + 385, + 7, + 4, 0, 0, + 384, 383, - 385, 1, 0, 0, 0, - 384, - 386, - 3, - 75, - 37, - 0, 385, - 384, + 386, 1, 0, 0, 0, - 385, 386, + 384, 1, 0, 0, 0, 386, - 74, + 387, 1, 0, 0, 0, 387, 389, - 7, - 5, + 1, + 0, 0, 0, 388, - 390, - 7, - 6, + 382, + 1, + 0, 0, 0, - 389, 388, + 389, 1, 0, 0, 0, 389, - 390, + 391, 1, 0, 0, 0, 390, + 392, + 3, + 77, + 38, + 0, 391, + 390, 1, 0, 0, 0, 391, 392, - 3, - 71, - 35, + 1, + 0, + 0, 0, 392, 76, @@ -3410,21 +3418,15 @@ def serializedATN(): 0, 0, 393, - 396, - 7, + 395, 7, + 5, 0, 0, 394, 396, - 3, - 65, - 32, - 0, - 395, - 393, - 1, - 0, + 7, + 6, 0, 0, 395, @@ -3433,23 +3435,23 @@ def serializedATN(): 0, 0, 0, + 395, 396, - 397, 1, 0, 0, 0, + 396, 397, - 395, 1, 0, 0, 0, 397, 398, - 1, - 0, - 0, + 3, + 73, + 36, 0, 398, 78, @@ -3458,31 +3460,37 @@ def serializedATN(): 0, 0, 399, - 401, + 402, + 7, 7, - 8, 0, 0, 400, + 402, + 3, + 67, + 33, + 0, + 401, 399, 1, 0, 0, 0, 401, - 402, + 400, 1, 0, 0, 0, 402, - 400, + 403, 1, 0, 0, 0, - 402, 403, + 401, 1, 0, 0, @@ -3494,39 +3502,81 @@ def serializedATN(): 0, 0, 404, + 80, + 1, + 0, + 0, + 0, 405, - 6, - 39, + 407, + 7, + 8, 0, 0, + 406, 405, - 80, + 1, + 0, + 0, + 0, + 407, + 408, + 1, + 0, + 0, + 0, + 408, + 406, + 1, + 0, + 0, + 0, + 408, + 409, + 1, + 0, + 0, + 0, + 409, + 410, + 1, + 0, + 0, + 0, + 410, + 411, + 6, + 40, + 0, + 0, + 411, + 82, 1, 0, 0, 0, 21, 0, - 89, - 93, - 96, - 100, + 95, + 99, + 102, 106, - 108, - 337, - 339, - 347, - 360, - 367, - 370, + 112, + 114, + 343, + 345, + 353, + 366, 373, - 380, - 382, - 385, - 389, + 376, + 379, + 386, + 388, + 391, 395, - 397, - 402, + 401, + 403, + 408, 1, 6, 0, @@ -3541,37 +3591,38 @@ class ASLIntrinsicLexer(Lexer): CONTEXT_PATH_STRING = 1 JSON_PATH_STRING = 2 - DOLLAR = 3 - LPAREN = 4 - RPAREN = 5 - COMMA = 6 - DOT = 7 - TRUE = 8 - FALSE = 9 - States = 10 - Format = 11 - StringToJson = 12 - JsonToString = 13 - Array = 14 - ArrayPartition = 15 - ArrayContains = 16 - ArrayRange = 17 - ArrayGetItem = 18 - ArrayLength = 19 - ArrayUnique = 20 - Base64Encode = 21 - Base64Decode = 22 - Hash = 23 - JsonMerge = 24 - MathRandom = 25 - MathAdd = 26 - StringSplit = 27 - UUID = 28 - STRING = 29 - INT = 30 - NUMBER = 31 - IDENTIFIER = 32 - WS = 33 + STRING_VARIABLE = 3 + DOLLAR = 4 + LPAREN = 5 + RPAREN = 6 + COMMA = 7 + DOT = 8 + TRUE = 9 + FALSE = 10 + States = 11 + Format = 12 + StringToJson = 13 + JsonToString = 14 + Array = 15 + ArrayPartition = 16 + ArrayContains = 17 + ArrayRange = 18 + ArrayGetItem = 19 + ArrayLength = 20 + ArrayUnique = 21 + Base64Encode = 22 + Base64Decode = 23 + Hash = 24 + JsonMerge = 25 + MathRandom = 26 + MathAdd = 27 + StringSplit = 28 + UUID = 29 + STRING = 30 + INT = 31 + NUMBER = 32 + IDENTIFIER = 33 + WS = 34 channelNames = ["DEFAULT_TOKEN_CHANNEL", "HIDDEN"] @@ -3611,6 +3662,7 @@ class ASLIntrinsicLexer(Lexer): "", "CONTEXT_PATH_STRING", "JSON_PATH_STRING", + "STRING_VARIABLE", "DOLLAR", "LPAREN", "RPAREN", @@ -3647,6 +3699,7 @@ class ASLIntrinsicLexer(Lexer): ruleNames = [ "CONTEXT_PATH_STRING", "JSON_PATH_STRING", + "STRING_VARIABLE", "JSON_PATH_BODY", "JSON_PATH_BRACK", "DOLLAR", @@ -3691,7 +3744,7 @@ class ASLIntrinsicLexer(Lexer): def __init__(self, input=None, output: TextIO = sys.stdout): super().__init__(input, output) - self.checkVersion("4.13.1") + self.checkVersion("4.13.2") self._interp = LexerATNSimulator( self, self.atn, self.decisionsToDFA, PredictionContextCache() ) diff --git a/moto/stepfunctions/parser/asl/antlr/runtime/ASLIntrinsicLexer.tokens b/moto/stepfunctions/parser/asl/antlr/runtime/ASLIntrinsicLexer.tokens deleted file mode 100644 index 1759d141157c..000000000000 --- a/moto/stepfunctions/parser/asl/antlr/runtime/ASLIntrinsicLexer.tokens +++ /dev/null @@ -1,79 +0,0 @@ -DOLLAR=1 -DOT=2 -STAR=3 -COMMA=4 -LPAREN=5 -RPAREN=6 -LBRACK=7 -RBRACK=8 -LDIAM=9 -RDIAM=10 -ATDOT=11 -ATDOTLENGTHDASH=12 -ANDAND=13 -OROR=14 -EQEQ=15 -EQ=16 -TRUE=17 -FALSE=18 -States=19 -Format=20 -StringToJson=21 -JsonToString=22 -Array=23 -ArrayPartition=24 -ArrayContains=25 -ArrayRange=26 -ArrayGetItem=27 -ArrayLength=28 -ArrayUnique=29 -Base64Encode=30 -Base64Decode=31 -Hash=32 -JsonMerge=33 -MathRandom=34 -MathAdd=35 -StringSplit=36 -UUID=37 -STRING=38 -INT=39 -NUMBER=40 -IDENTIFIER=41 -WS=42 -'$'=1 -'.'=2 -'*'=3 -','=4 -'('=5 -')'=6 -'['=7 -']'=8 -'<'=9 -'>'=10 -'@.'=11 -'@.length-'=12 -'&&'=13 -'||'=14 -'=='=15 -'='=16 -'true'=17 -'false'=18 -'States'=19 -'Format'=20 -'StringToJson'=21 -'JsonToString'=22 -'Array'=23 -'ArrayPartition'=24 -'ArrayContains'=25 -'ArrayRange'=26 -'ArrayGetItem'=27 -'ArrayLength'=28 -'ArrayUnique'=29 -'Base64Encode'=30 -'Base64Decode'=31 -'Hash'=32 -'JsonMerge'=33 -'MathRandom'=34 -'MathAdd'=35 -'StringSplit'=36 -'UUID'=37 diff --git a/moto/stepfunctions/parser/asl/antlr/runtime/ASLIntrinsicParser.interp b/moto/stepfunctions/parser/asl/antlr/runtime/ASLIntrinsicParser.interp deleted file mode 100644 index 58cfb0be6a6b..000000000000 --- a/moto/stepfunctions/parser/asl/antlr/runtime/ASLIntrinsicParser.interp +++ /dev/null @@ -1,108 +0,0 @@ -token literal names: -null -'$' -'.' -'*' -',' -'(' -')' -'[' -']' -'<' -'>' -'@.' -'@.length-' -'&&' -'||' -'==' -'=' -'true' -'false' -'States' -'Format' -'StringToJson' -'JsonToString' -'Array' -'ArrayPartition' -'ArrayContains' -'ArrayRange' -'ArrayGetItem' -'ArrayLength' -'ArrayUnique' -'Base64Encode' -'Base64Decode' -'Hash' -'JsonMerge' -'MathRandom' -'MathAdd' -'StringSplit' -'UUID' -null -null -null -null -null - -token symbolic names: -null -DOLLAR -DOT -STAR -COMMA -LPAREN -RPAREN -LBRACK -RBRACK -LDIAM -RDIAM -ATDOT -ATDOTLENGTHDASH -ANDAND -OROR -EQEQ -EQ -TRUE -FALSE -States -Format -StringToJson -JsonToString -Array -ArrayPartition -ArrayContains -ArrayRange -ArrayGetItem -ArrayLength -ArrayUnique -Base64Encode -Base64Decode -Hash -JsonMerge -MathRandom -MathAdd -StringSplit -UUID -STRING -INT -NUMBER -IDENTIFIER -WS - -rule names: -func_decl -states_func_decl -state_fun_name -func_arg_list -func_arg -context_path -json_path -json_path_part -json_path_iden -json_path_iden_qual -json_path_qual -json_path_query -identifier - - -atn: -[4, 1, 42, 123, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 3, 1, 3, 1, 3, 1, 3, 5, 3, 40, 8, 3, 10, 3, 12, 3, 43, 9, 3, 1, 3, 1, 3, 1, 3, 1, 3, 3, 3, 49, 8, 3, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 1, 4, 3, 4, 58, 8, 4, 1, 5, 1, 5, 1, 5, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 5, 6, 68, 8, 6, 10, 6, 12, 6, 71, 9, 6, 1, 7, 1, 7, 3, 7, 75, 8, 7, 1, 8, 1, 8, 1, 9, 1, 9, 1, 9, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 3, 10, 91, 8, 10, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 3, 11, 101, 8, 11, 1, 11, 1, 11, 3, 11, 105, 8, 11, 1, 11, 1, 11, 1, 11, 4, 11, 110, 8, 11, 11, 11, 12, 11, 111, 5, 11, 114, 8, 11, 10, 11, 12, 11, 117, 9, 11, 1, 12, 1, 12, 3, 12, 121, 8, 12, 1, 12, 0, 1, 22, 13, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 0, 4, 1, 0, 20, 37, 1, 0, 17, 18, 2, 0, 9, 10, 15, 15, 1, 0, 13, 14, 127, 0, 26, 1, 0, 0, 0, 2, 28, 1, 0, 0, 0, 4, 33, 1, 0, 0, 0, 6, 48, 1, 0, 0, 0, 8, 57, 1, 0, 0, 0, 10, 59, 1, 0, 0, 0, 12, 62, 1, 0, 0, 0, 14, 74, 1, 0, 0, 0, 16, 76, 1, 0, 0, 0, 18, 78, 1, 0, 0, 0, 20, 90, 1, 0, 0, 0, 22, 104, 1, 0, 0, 0, 24, 120, 1, 0, 0, 0, 26, 27, 3, 2, 1, 0, 27, 1, 1, 0, 0, 0, 28, 29, 5, 19, 0, 0, 29, 30, 5, 2, 0, 0, 30, 31, 3, 4, 2, 0, 31, 32, 3, 6, 3, 0, 32, 3, 1, 0, 0, 0, 33, 34, 7, 0, 0, 0, 34, 5, 1, 0, 0, 0, 35, 36, 5, 5, 0, 0, 36, 41, 3, 8, 4, 0, 37, 38, 5, 4, 0, 0, 38, 40, 3, 8, 4, 0, 39, 37, 1, 0, 0, 0, 40, 43, 1, 0, 0, 0, 41, 39, 1, 0, 0, 0, 41, 42, 1, 0, 0, 0, 42, 44, 1, 0, 0, 0, 43, 41, 1, 0, 0, 0, 44, 45, 5, 6, 0, 0, 45, 49, 1, 0, 0, 0, 46, 47, 5, 5, 0, 0, 47, 49, 5, 6, 0, 0, 48, 35, 1, 0, 0, 0, 48, 46, 1, 0, 0, 0, 49, 7, 1, 0, 0, 0, 50, 58, 5, 38, 0, 0, 51, 58, 5, 39, 0, 0, 52, 58, 5, 40, 0, 0, 53, 58, 7, 1, 0, 0, 54, 58, 3, 10, 5, 0, 55, 58, 3, 12, 6, 0, 56, 58, 3, 0, 0, 0, 57, 50, 1, 0, 0, 0, 57, 51, 1, 0, 0, 0, 57, 52, 1, 0, 0, 0, 57, 53, 1, 0, 0, 0, 57, 54, 1, 0, 0, 0, 57, 55, 1, 0, 0, 0, 57, 56, 1, 0, 0, 0, 58, 9, 1, 0, 0, 0, 59, 60, 5, 1, 0, 0, 60, 61, 3, 12, 6, 0, 61, 11, 1, 0, 0, 0, 62, 63, 5, 1, 0, 0, 63, 64, 5, 2, 0, 0, 64, 69, 3, 14, 7, 0, 65, 66, 5, 2, 0, 0, 66, 68, 3, 14, 7, 0, 67, 65, 1, 0, 0, 0, 68, 71, 1, 0, 0, 0, 69, 67, 1, 0, 0, 0, 69, 70, 1, 0, 0, 0, 70, 13, 1, 0, 0, 0, 71, 69, 1, 0, 0, 0, 72, 75, 3, 16, 8, 0, 73, 75, 3, 18, 9, 0, 74, 72, 1, 0, 0, 0, 74, 73, 1, 0, 0, 0, 75, 15, 1, 0, 0, 0, 76, 77, 3, 24, 12, 0, 77, 17, 1, 0, 0, 0, 78, 79, 3, 16, 8, 0, 79, 80, 3, 20, 10, 0, 80, 19, 1, 0, 0, 0, 81, 82, 5, 7, 0, 0, 82, 91, 5, 8, 0, 0, 83, 84, 5, 7, 0, 0, 84, 85, 5, 39, 0, 0, 85, 91, 5, 8, 0, 0, 86, 87, 5, 7, 0, 0, 87, 88, 3, 22, 11, 0, 88, 89, 5, 8, 0, 0, 89, 91, 1, 0, 0, 0, 90, 81, 1, 0, 0, 0, 90, 83, 1, 0, 0, 0, 90, 86, 1, 0, 0, 0, 91, 21, 1, 0, 0, 0, 92, 93, 6, 11, -1, 0, 93, 105, 5, 3, 0, 0, 94, 95, 5, 11, 0, 0, 95, 100, 3, 16, 8, 0, 96, 97, 7, 2, 0, 0, 97, 101, 5, 39, 0, 0, 98, 99, 5, 16, 0, 0, 99, 101, 5, 38, 0, 0, 100, 96, 1, 0, 0, 0, 100, 98, 1, 0, 0, 0, 101, 105, 1, 0, 0, 0, 102, 103, 5, 12, 0, 0, 103, 105, 5, 39, 0, 0, 104, 92, 1, 0, 0, 0, 104, 94, 1, 0, 0, 0, 104, 102, 1, 0, 0, 0, 105, 115, 1, 0, 0, 0, 106, 109, 10, 1, 0, 0, 107, 108, 7, 3, 0, 0, 108, 110, 3, 22, 11, 0, 109, 107, 1, 0, 0, 0, 110, 111, 1, 0, 0, 0, 111, 109, 1, 0, 0, 0, 111, 112, 1, 0, 0, 0, 112, 114, 1, 0, 0, 0, 113, 106, 1, 0, 0, 0, 114, 117, 1, 0, 0, 0, 115, 113, 1, 0, 0, 0, 115, 116, 1, 0, 0, 0, 116, 23, 1, 0, 0, 0, 117, 115, 1, 0, 0, 0, 118, 121, 5, 41, 0, 0, 119, 121, 3, 4, 2, 0, 120, 118, 1, 0, 0, 0, 120, 119, 1, 0, 0, 0, 121, 25, 1, 0, 0, 0, 11, 41, 48, 57, 69, 74, 90, 100, 104, 111, 115, 120] \ No newline at end of file diff --git a/moto/stepfunctions/parser/asl/antlr/runtime/ASLIntrinsicParser.py b/moto/stepfunctions/parser/asl/antlr/runtime/ASLIntrinsicParser.py index d54b6c350a5a..4c66358e670d 100644 --- a/moto/stepfunctions/parser/asl/antlr/runtime/ASLIntrinsicParser.py +++ b/moto/stepfunctions/parser/asl/antlr/runtime/ASLIntrinsicParser.py @@ -1,4 +1,4 @@ -# Generated from ASLIntrinsicParser.g4 by ANTLR 4.13.1 +# Generated from ASLIntrinsicParser.g4 by ANTLR 4.13.2 # encoding: utf-8 import sys from typing import TextIO @@ -23,8 +23,8 @@ def serializedATN(): return [ 4, 1, - 33, - 45, + 34, + 46, 2, 0, 7, @@ -112,9 +112,11 @@ def serializedATN(): 4, 1, 4, + 1, + 4, 3, 4, - 43, + 44, 8, 4, 1, @@ -131,13 +133,13 @@ def serializedATN(): 2, 1, 0, - 11, - 28, + 12, + 29, 1, 0, - 8, 9, - 47, + 10, + 49, 0, 10, 1, @@ -163,7 +165,7 @@ def serializedATN(): 0, 0, 8, - 42, + 43, 1, 0, 0, @@ -189,13 +191,13 @@ def serializedATN(): 13, 14, 5, - 10, + 11, 0, 0, 14, 15, 5, - 7, + 8, 0, 0, 15, @@ -231,7 +233,7 @@ def serializedATN(): 20, 21, 5, - 4, + 5, 0, 0, 21, @@ -243,7 +245,7 @@ def serializedATN(): 22, 23, 5, - 6, + 7, 0, 0, 23, @@ -291,7 +293,7 @@ def serializedATN(): 29, 30, 5, - 5, + 6, 0, 0, 30, @@ -303,13 +305,13 @@ def serializedATN(): 31, 32, 5, - 4, + 5, 0, 0, 32, 34, 5, - 5, + 6, 0, 0, 33, @@ -331,90 +333,102 @@ def serializedATN(): 0, 0, 35, - 43, + 44, 5, - 29, + 30, 0, 0, 36, - 43, + 44, 5, - 30, + 31, 0, 0, 37, - 43, + 44, 5, - 31, + 32, 0, 0, 38, - 43, + 44, 7, 1, 0, 0, 39, - 43, + 44, 5, 1, 0, 0, 40, - 43, + 44, 5, 2, 0, 0, 41, - 43, + 44, + 5, + 3, + 0, + 0, + 42, + 44, 3, 2, 1, 0, - 42, + 43, 35, 1, 0, 0, 0, - 42, + 43, 36, 1, 0, 0, 0, - 42, + 43, 37, 1, 0, 0, 0, - 42, + 43, 38, 1, 0, 0, 0, - 42, + 43, 39, 1, 0, 0, 0, - 42, + 43, 40, 1, 0, 0, 0, - 42, + 43, 41, 1, 0, 0, 0, 43, + 42, + 1, + 0, + 0, + 0, + 44, 9, 1, 0, @@ -423,7 +437,7 @@ def serializedATN(): 3, 26, 33, - 42, + 43, ] @@ -440,6 +454,7 @@ class ASLIntrinsicParser(Parser): "", "", "", + "", "'$'", "'('", "')'", @@ -472,6 +487,7 @@ class ASLIntrinsicParser(Parser): "", "CONTEXT_PATH_STRING", "JSON_PATH_STRING", + "STRING_VARIABLE", "DOLLAR", "LPAREN", "RPAREN", @@ -522,41 +538,42 @@ class ASLIntrinsicParser(Parser): EOF = Token.EOF CONTEXT_PATH_STRING = 1 JSON_PATH_STRING = 2 - DOLLAR = 3 - LPAREN = 4 - RPAREN = 5 - COMMA = 6 - DOT = 7 - TRUE = 8 - FALSE = 9 - States = 10 - Format = 11 - StringToJson = 12 - JsonToString = 13 - Array = 14 - ArrayPartition = 15 - ArrayContains = 16 - ArrayRange = 17 - ArrayGetItem = 18 - ArrayLength = 19 - ArrayUnique = 20 - Base64Encode = 21 - Base64Decode = 22 - Hash = 23 - JsonMerge = 24 - MathRandom = 25 - MathAdd = 26 - StringSplit = 27 - UUID = 28 - STRING = 29 - INT = 30 - NUMBER = 31 - IDENTIFIER = 32 - WS = 33 + STRING_VARIABLE = 3 + DOLLAR = 4 + LPAREN = 5 + RPAREN = 6 + COMMA = 7 + DOT = 8 + TRUE = 9 + FALSE = 10 + States = 11 + Format = 12 + StringToJson = 13 + JsonToString = 14 + Array = 15 + ArrayPartition = 16 + ArrayContains = 17 + ArrayRange = 18 + ArrayGetItem = 19 + ArrayLength = 20 + ArrayUnique = 21 + Base64Encode = 22 + Base64Decode = 23 + Hash = 24 + JsonMerge = 25 + MathRandom = 26 + MathAdd = 27 + StringSplit = 28 + UUID = 29 + STRING = 30 + INT = 31 + NUMBER = 32 + IDENTIFIER = 33 + WS = 34 def __init__(self, input: TokenStream, output: TextIO = sys.stdout): super().__init__(input, output) - self.checkVersion("4.13.1") + self.checkVersion("4.13.2") self._interp = ParserATNSimulator( self, self.atn, self.decisionsToDFA, self.sharedContextCache ) @@ -762,7 +779,7 @@ def state_fun_name(self): self.enterOuterAlt(localctx, 1) self.state = 18 _la = self._input.LA(1) - if not (((_la) & ~0x3F) == 0 and ((1 << _la) & 536868864) != 0): + if not (((_la) & ~0x3F) == 0 and ((1 << _la) & 1073737728) != 0): self._errHandler.recoverInline(self) else: self._errHandler.reportMatch(self) @@ -836,7 +853,7 @@ def func_arg_list(self): self.state = 26 self._errHandler.sync(self) _la = self._input.LA(1) - while _la == 6: + while _la == 7: self.state = 22 self.match(ASLIntrinsicParser.COMMA) self.state = 23 @@ -928,6 +945,30 @@ def accept(self, visitor: ParseTreeVisitor): else: return visitor.visitChildren(self) + class Func_arg_varContext(Func_argContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLIntrinsicParser.Func_argContext + super().__init__(parser) + self.copyFrom(ctx) + + def STRING_VARIABLE(self): + return self.getToken(ASLIntrinsicParser.STRING_VARIABLE, 0) + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterFunc_arg_var"): + listener.enterFunc_arg_var(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitFunc_arg_var"): + listener.exitFunc_arg_var(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitFunc_arg_var"): + return visitor.visitFunc_arg_var(self) + else: + return visitor.visitChildren(self) + class Func_arg_func_declContext(Func_argContext): def __init__( self, parser, ctx: ParserRuleContext @@ -1058,33 +1099,33 @@ def func_arg(self): self.enterRule(localctx, 8, self.RULE_func_arg) self._la = 0 # Token type try: - self.state = 42 + self.state = 43 self._errHandler.sync(self) token = self._input.LA(1) - if token in [29]: + if token in [30]: localctx = ASLIntrinsicParser.Func_arg_stringContext(self, localctx) self.enterOuterAlt(localctx, 1) self.state = 35 self.match(ASLIntrinsicParser.STRING) pass - elif token in [30]: + elif token in [31]: localctx = ASLIntrinsicParser.Func_arg_intContext(self, localctx) self.enterOuterAlt(localctx, 2) self.state = 36 self.match(ASLIntrinsicParser.INT) pass - elif token in [31]: + elif token in [32]: localctx = ASLIntrinsicParser.Func_arg_floatContext(self, localctx) self.enterOuterAlt(localctx, 3) self.state = 37 self.match(ASLIntrinsicParser.NUMBER) pass - elif token in [8, 9]: + elif token in [9, 10]: localctx = ASLIntrinsicParser.Func_arg_boolContext(self, localctx) self.enterOuterAlt(localctx, 4) self.state = 38 _la = self._input.LA(1) - if not (_la == 8 or _la == 9): + if not (_la == 9 or _la == 10): self._errHandler.recoverInline(self) else: self._errHandler.reportMatch(self) @@ -1104,10 +1145,16 @@ def func_arg(self): self.state = 40 self.match(ASLIntrinsicParser.JSON_PATH_STRING) pass - elif token in [10]: - localctx = ASLIntrinsicParser.Func_arg_func_declContext(self, localctx) + elif token in [3]: + localctx = ASLIntrinsicParser.Func_arg_varContext(self, localctx) self.enterOuterAlt(localctx, 7) self.state = 41 + self.match(ASLIntrinsicParser.STRING_VARIABLE) + pass + elif token in [11]: + localctx = ASLIntrinsicParser.Func_arg_func_declContext(self, localctx) + self.enterOuterAlt(localctx, 8) + self.state = 42 self.states_func_decl() pass else: diff --git a/moto/stepfunctions/parser/asl/antlr/runtime/ASLIntrinsicParser.tokens b/moto/stepfunctions/parser/asl/antlr/runtime/ASLIntrinsicParser.tokens deleted file mode 100644 index 1759d141157c..000000000000 --- a/moto/stepfunctions/parser/asl/antlr/runtime/ASLIntrinsicParser.tokens +++ /dev/null @@ -1,79 +0,0 @@ -DOLLAR=1 -DOT=2 -STAR=3 -COMMA=4 -LPAREN=5 -RPAREN=6 -LBRACK=7 -RBRACK=8 -LDIAM=9 -RDIAM=10 -ATDOT=11 -ATDOTLENGTHDASH=12 -ANDAND=13 -OROR=14 -EQEQ=15 -EQ=16 -TRUE=17 -FALSE=18 -States=19 -Format=20 -StringToJson=21 -JsonToString=22 -Array=23 -ArrayPartition=24 -ArrayContains=25 -ArrayRange=26 -ArrayGetItem=27 -ArrayLength=28 -ArrayUnique=29 -Base64Encode=30 -Base64Decode=31 -Hash=32 -JsonMerge=33 -MathRandom=34 -MathAdd=35 -StringSplit=36 -UUID=37 -STRING=38 -INT=39 -NUMBER=40 -IDENTIFIER=41 -WS=42 -'$'=1 -'.'=2 -'*'=3 -','=4 -'('=5 -')'=6 -'['=7 -']'=8 -'<'=9 -'>'=10 -'@.'=11 -'@.length-'=12 -'&&'=13 -'||'=14 -'=='=15 -'='=16 -'true'=17 -'false'=18 -'States'=19 -'Format'=20 -'StringToJson'=21 -'JsonToString'=22 -'Array'=23 -'ArrayPartition'=24 -'ArrayContains'=25 -'ArrayRange'=26 -'ArrayGetItem'=27 -'ArrayLength'=28 -'ArrayUnique'=29 -'Base64Encode'=30 -'Base64Decode'=31 -'Hash'=32 -'JsonMerge'=33 -'MathRandom'=34 -'MathAdd'=35 -'StringSplit'=36 -'UUID'=37 diff --git a/moto/stepfunctions/parser/asl/antlr/runtime/ASLIntrinsicParserListener.py b/moto/stepfunctions/parser/asl/antlr/runtime/ASLIntrinsicParserListener.py index d2a62583419e..216214df09ae 100644 --- a/moto/stepfunctions/parser/asl/antlr/runtime/ASLIntrinsicParserListener.py +++ b/moto/stepfunctions/parser/asl/antlr/runtime/ASLIntrinsicParserListener.py @@ -1,4 +1,4 @@ -# Generated from ASLIntrinsicParser.g4 by ANTLR 4.13.1 +# Generated from ASLIntrinsicParser.g4 by ANTLR 4.13.2 from antlr4 import ParseTreeListener if "." in __name__: @@ -95,6 +95,14 @@ def enterFunc_arg_json_path( def exitFunc_arg_json_path(self, ctx: ASLIntrinsicParser.Func_arg_json_pathContext): pass + # Enter a parse tree produced by ASLIntrinsicParser#func_arg_var. + def enterFunc_arg_var(self, ctx: ASLIntrinsicParser.Func_arg_varContext): + pass + + # Exit a parse tree produced by ASLIntrinsicParser#func_arg_var. + def exitFunc_arg_var(self, ctx: ASLIntrinsicParser.Func_arg_varContext): + pass + # Enter a parse tree produced by ASLIntrinsicParser#func_arg_func_decl. def enterFunc_arg_func_decl( self, ctx: ASLIntrinsicParser.Func_arg_func_declContext diff --git a/moto/stepfunctions/parser/asl/antlr/runtime/ASLIntrinsicParserVisitor.py b/moto/stepfunctions/parser/asl/antlr/runtime/ASLIntrinsicParserVisitor.py index 8099d84739ea..c31e716924ff 100644 --- a/moto/stepfunctions/parser/asl/antlr/runtime/ASLIntrinsicParserVisitor.py +++ b/moto/stepfunctions/parser/asl/antlr/runtime/ASLIntrinsicParserVisitor.py @@ -1,4 +1,4 @@ -# Generated from ASLIntrinsicParser.g4 by ANTLR 4.13.1 +# Generated from ASLIntrinsicParser.g4 by ANTLR 4.13.2 from antlr4 import ParseTreeVisitor if "." in __name__: @@ -54,6 +54,10 @@ def visitFunc_arg_json_path( ): return self.visitChildren(ctx) + # Visit a parse tree produced by ASLIntrinsicParser#func_arg_var. + def visitFunc_arg_var(self, ctx: ASLIntrinsicParser.Func_arg_varContext): + return self.visitChildren(ctx) + # Visit a parse tree produced by ASLIntrinsicParser#func_arg_func_decl. def visitFunc_arg_func_decl( self, ctx: ASLIntrinsicParser.Func_arg_func_declContext diff --git a/moto/stepfunctions/parser/asl/antlr/runtime/ASLLexer.interp b/moto/stepfunctions/parser/asl/antlr/runtime/ASLLexer.interp deleted file mode 100644 index 8bf4c1c2af21..000000000000 --- a/moto/stepfunctions/parser/asl/antlr/runtime/ASLLexer.interp +++ /dev/null @@ -1,421 +0,0 @@ -token literal names: -null -',' -':' -'[' -']' -'{' -'}' -'true' -'false' -'null' -'"Comment"' -'"States"' -'"StartAt"' -'"NextState"' -'"Version"' -'"Type"' -'"Task"' -'"Choice"' -'"Fail"' -'"Succeed"' -'"Pass"' -'"Wait"' -'"Parallel"' -'"Map"' -'"Choices"' -'"Variable"' -'"Default"' -'"Branches"' -'"And"' -'"BooleanEquals"' -'"BooleanEqualsPath"' -'"IsBoolean"' -'"IsNull"' -'"IsNumeric"' -'"IsPresent"' -'"IsString"' -'"IsTimestamp"' -'"Not"' -'"NumericEquals"' -'"NumericEqualsPath"' -'"NumericGreaterThan"' -'"NumericGreaterThanPath"' -'"NumericGreaterThanEquals"' -'"NumericGreaterThanEqualsPath"' -'"NumericLessThan"' -'"NumericLessThanPath"' -'"NumericLessThanEquals"' -'"NumericLessThanEqualsPath"' -'"Or"' -'"StringEquals"' -'"StringEqualsPath"' -'"StringGreaterThan"' -'"StringGreaterThanPath"' -'"StringGreaterThanEquals"' -'"StringGreaterThanEqualsPath"' -'"StringLessThan"' -'"StringLessThanPath"' -'"StringLessThanEquals"' -'"StringLessThanEqualsPath"' -'"StringMatches"' -'"TimestampEquals"' -'"TimestampEqualsPath"' -'"TimestampGreaterThan"' -'"TimestampGreaterThanPath"' -'"TimestampGreaterThanEquals"' -'"TimestampGreaterThanEqualsPath"' -'"TimestampLessThan"' -'"TimestampLessThanPath"' -'"TimestampLessThanEquals"' -'"TimestampLessThanEqualsPath"' -'"SecondsPath"' -'"Seconds"' -'"TimestampPath"' -'"Timestamp"' -'"TimeoutSeconds"' -'"TimeoutSecondsPath"' -'"HeartbeatSeconds"' -'"HeartbeatSecondsPath"' -'"ProcessorConfig"' -'"Mode"' -'"INLINE"' -'"DISTRIBUTED"' -'"ExecutionType"' -'"STANDARD"' -'"ItemProcessor"' -'"Iterator"' -'"ItemSelector"' -'"MaxConcurrency"' -'"Resource"' -'"InputPath"' -'"OutputPath"' -'"ItemsPath"' -'"ResultPath"' -'"Result"' -'"Parameters"' -'"ResultSelector"' -'"ItemReader"' -'"ReaderConfig"' -'"InputType"' -'"CSVHeaderLocation"' -'"CSVHeaders"' -'"MaxItems"' -'"MaxItemsPath"' -'"Next"' -'"End"' -'"Cause"' -'"Error"' -'"Retry"' -'"ErrorEquals"' -'"IntervalSeconds"' -'"MaxAttempts"' -'"BackoffRate"' -'"Catch"' -'"States.ALL"' -'"States.HeartbeatTimeout"' -'"States.Timeout"' -'"States.TaskFailed"' -'"States.Permissions"' -'"States.ResultPathMatchFailure"' -'"States.ParameterPathFailure"' -'"States.BranchFailed"' -'"States.NoChoiceMatched"' -'"States.IntrinsicFailure"' -'"States.ExceedToleratedFailureThreshold"' -'"States.ItemReaderFailed"' -'"States.ResultWriterFailed"' -'"States.Runtime"' -null -null -null -null -null -null -null - -token symbolic names: -null -COMMA -COLON -LBRACK -RBRACK -LBRACE -RBRACE -TRUE -FALSE -NULL -COMMENT -STATES -STARTAT -NEXTSTATE -VERSION -TYPE -TASK -CHOICE -FAIL -SUCCEED -PASS -WAIT -PARALLEL -MAP -CHOICES -VARIABLE -DEFAULT -BRANCHES -AND -BOOLEANEQUALS -BOOLEANQUALSPATH -ISBOOLEAN -ISNULL -ISNUMERIC -ISPRESENT -ISSTRING -ISTIMESTAMP -NOT -NUMERICEQUALS -NUMERICEQUALSPATH -NUMERICGREATERTHAN -NUMERICGREATERTHANPATH -NUMERICGREATERTHANEQUALS -NUMERICGREATERTHANEQUALSPATH -NUMERICLESSTHAN -NUMERICLESSTHANPATH -NUMERICLESSTHANEQUALS -NUMERICLESSTHANEQUALSPATH -OR -STRINGEQUALS -STRINGEQUALSPATH -STRINGGREATERTHAN -STRINGGREATERTHANPATH -STRINGGREATERTHANEQUALS -STRINGGREATERTHANEQUALSPATH -STRINGLESSTHAN -STRINGLESSTHANPATH -STRINGLESSTHANEQUALS -STRINGLESSTHANEQUALSPATH -STRINGMATCHES -TIMESTAMPEQUALS -TIMESTAMPEQUALSPATH -TIMESTAMPGREATERTHAN -TIMESTAMPGREATERTHANPATH -TIMESTAMPGREATERTHANEQUALS -TIMESTAMPGREATERTHANEQUALSPATH -TIMESTAMPLESSTHAN -TIMESTAMPLESSTHANPATH -TIMESTAMPLESSTHANEQUALS -TIMESTAMPLESSTHANEQUALSPATH -SECONDSPATH -SECONDS -TIMESTAMPPATH -TIMESTAMP -TIMEOUTSECONDS -TIMEOUTSECONDSPATH -HEARTBEATSECONDS -HEARTBEATSECONDSPATH -PROCESSORCONFIG -MODE -INLINE -DISTRIBUTED -EXECUTIONTYPE -STANDARD -ITEMPROCESSOR -ITERATOR -ITEMSELECTOR -MAXCONCURRENCY -RESOURCE -INPUTPATH -OUTPUTPATH -ITEMSPATH -RESULTPATH -RESULT -PARAMETERS -RESULTSELECTOR -ITEMREADER -READERCONFIG -INPUTTYPE -CSVHEADERLOCATION -CSVHEADERS -MAXITEMS -MAXITEMSPATH -NEXT -END -CAUSE -ERROR -RETRY -ERROREQUALS -INTERVALSECONDS -MAXATTEMPTS -BACKOFFRATE -CATCH -ERRORNAMEStatesALL -ERRORNAMEStatesHeartbeatTimeout -ERRORNAMEStatesTimeout -ERRORNAMEStatesTaskFailed -ERRORNAMEStatesPermissions -ERRORNAMEStatesResultPathMatchFailure -ERRORNAMEStatesParameterPathFailure -ERRORNAMEStatesBranchFailed -ERRORNAMEStatesNoChoiceMatched -ERRORNAMEStatesIntrinsicFailure -ERRORNAMEStatesExceedToleratedFailureThreshold -ERRORNAMEStatesItemReaderFailed -ERRORNAMEStatesResultWriterFailed -ERRORNAMEStatesRuntime -STRINGDOLLAR -STRINGPATHCONTEXTOBJ -STRINGPATH -STRING -INT -NUMBER -WS - -rule names: -COMMA -COLON -LBRACK -RBRACK -LBRACE -RBRACE -TRUE -FALSE -NULL -COMMENT -STATES -STARTAT -NEXTSTATE -VERSION -TYPE -TASK -CHOICE -FAIL -SUCCEED -PASS -WAIT -PARALLEL -MAP -CHOICES -VARIABLE -DEFAULT -BRANCHES -AND -BOOLEANEQUALS -BOOLEANQUALSPATH -ISBOOLEAN -ISNULL -ISNUMERIC -ISPRESENT -ISSTRING -ISTIMESTAMP -NOT -NUMERICEQUALS -NUMERICEQUALSPATH -NUMERICGREATERTHAN -NUMERICGREATERTHANPATH -NUMERICGREATERTHANEQUALS -NUMERICGREATERTHANEQUALSPATH -NUMERICLESSTHAN -NUMERICLESSTHANPATH -NUMERICLESSTHANEQUALS -NUMERICLESSTHANEQUALSPATH -OR -STRINGEQUALS -STRINGEQUALSPATH -STRINGGREATERTHAN -STRINGGREATERTHANPATH -STRINGGREATERTHANEQUALS -STRINGGREATERTHANEQUALSPATH -STRINGLESSTHAN -STRINGLESSTHANPATH -STRINGLESSTHANEQUALS -STRINGLESSTHANEQUALSPATH -STRINGMATCHES -TIMESTAMPEQUALS -TIMESTAMPEQUALSPATH -TIMESTAMPGREATERTHAN -TIMESTAMPGREATERTHANPATH -TIMESTAMPGREATERTHANEQUALS -TIMESTAMPGREATERTHANEQUALSPATH -TIMESTAMPLESSTHAN -TIMESTAMPLESSTHANPATH -TIMESTAMPLESSTHANEQUALS -TIMESTAMPLESSTHANEQUALSPATH -SECONDSPATH -SECONDS -TIMESTAMPPATH -TIMESTAMP -TIMEOUTSECONDS -TIMEOUTSECONDSPATH -HEARTBEATSECONDS -HEARTBEATSECONDSPATH -PROCESSORCONFIG -MODE -INLINE -DISTRIBUTED -EXECUTIONTYPE -STANDARD -ITEMPROCESSOR -ITERATOR -ITEMSELECTOR -MAXCONCURRENCY -RESOURCE -INPUTPATH -OUTPUTPATH -ITEMSPATH -RESULTPATH -RESULT -PARAMETERS -RESULTSELECTOR -ITEMREADER -READERCONFIG -INPUTTYPE -CSVHEADERLOCATION -CSVHEADERS -MAXITEMS -MAXITEMSPATH -NEXT -END -CAUSE -ERROR -RETRY -ERROREQUALS -INTERVALSECONDS -MAXATTEMPTS -BACKOFFRATE -CATCH -ERRORNAMEStatesALL -ERRORNAMEStatesHeartbeatTimeout -ERRORNAMEStatesTimeout -ERRORNAMEStatesTaskFailed -ERRORNAMEStatesPermissions -ERRORNAMEStatesResultPathMatchFailure -ERRORNAMEStatesParameterPathFailure -ERRORNAMEStatesBranchFailed -ERRORNAMEStatesNoChoiceMatched -ERRORNAMEStatesIntrinsicFailure -ERRORNAMEStatesExceedToleratedFailureThreshold -ERRORNAMEStatesItemReaderFailed -ERRORNAMEStatesResultWriterFailed -ERRORNAMEStatesRuntime -STRINGDOLLAR -STRINGPATHCONTEXTOBJ -STRINGPATH -STRING -ESC -UNICODE -HEX -SAFECODEPOINT -INT -NUMBER -EXP -WS - -channel names: -DEFAULT_TOKEN_CHANNEL -HIDDEN - -mode names: -DEFAULT_MODE - -atn: -[4, 0, 133, 2328, 6, -1, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, 41, 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, 46, 7, 46, 2, 47, 7, 47, 2, 48, 7, 48, 2, 49, 7, 49, 2, 50, 7, 50, 2, 51, 7, 51, 2, 52, 7, 52, 2, 53, 7, 53, 2, 54, 7, 54, 2, 55, 7, 55, 2, 56, 7, 56, 2, 57, 7, 57, 2, 58, 7, 58, 2, 59, 7, 59, 2, 60, 7, 60, 2, 61, 7, 61, 2, 62, 7, 62, 2, 63, 7, 63, 2, 64, 7, 64, 2, 65, 7, 65, 2, 66, 7, 66, 2, 67, 7, 67, 2, 68, 7, 68, 2, 69, 7, 69, 2, 70, 7, 70, 2, 71, 7, 71, 2, 72, 7, 72, 2, 73, 7, 73, 2, 74, 7, 74, 2, 75, 7, 75, 2, 76, 7, 76, 2, 77, 7, 77, 2, 78, 7, 78, 2, 79, 7, 79, 2, 80, 7, 80, 2, 81, 7, 81, 2, 82, 7, 82, 2, 83, 7, 83, 2, 84, 7, 84, 2, 85, 7, 85, 2, 86, 7, 86, 2, 87, 7, 87, 2, 88, 7, 88, 2, 89, 7, 89, 2, 90, 7, 90, 2, 91, 7, 91, 2, 92, 7, 92, 2, 93, 7, 93, 2, 94, 7, 94, 2, 95, 7, 95, 2, 96, 7, 96, 2, 97, 7, 97, 2, 98, 7, 98, 2, 99, 7, 99, 2, 100, 7, 100, 2, 101, 7, 101, 2, 102, 7, 102, 2, 103, 7, 103, 2, 104, 7, 104, 2, 105, 7, 105, 2, 106, 7, 106, 2, 107, 7, 107, 2, 108, 7, 108, 2, 109, 7, 109, 2, 110, 7, 110, 2, 111, 7, 111, 2, 112, 7, 112, 2, 113, 7, 113, 2, 114, 7, 114, 2, 115, 7, 115, 2, 116, 7, 116, 2, 117, 7, 117, 2, 118, 7, 118, 2, 119, 7, 119, 2, 120, 7, 120, 2, 121, 7, 121, 2, 122, 7, 122, 2, 123, 7, 123, 2, 124, 7, 124, 2, 125, 7, 125, 2, 126, 7, 126, 2, 127, 7, 127, 2, 128, 7, 128, 2, 129, 7, 129, 2, 130, 7, 130, 2, 131, 7, 131, 2, 132, 7, 132, 2, 133, 7, 133, 2, 134, 7, 134, 2, 135, 7, 135, 2, 136, 7, 136, 2, 137, 7, 137, 1, 0, 1, 0, 1, 1, 1, 1, 1, 2, 1, 2, 1, 3, 1, 3, 1, 4, 1, 4, 1, 5, 1, 5, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 7, 1, 8, 1, 8, 1, 8, 1, 8, 1, 8, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 9, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 10, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 11, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 12, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 13, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 14, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 15, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 16, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 17, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 18, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 19, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 20, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 21, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 22, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 23, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 24, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 25, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 26, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 27, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 28, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 29, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 30, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 31, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 32, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 34, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 35, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 36, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 38, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 39, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 42, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 43, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 45, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 46, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 49, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 51, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 52, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 53, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 54, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 55, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 57, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 58, 1, 59, 1, 59, 1, 59, 1, 59, 1, 59, 1, 59, 1, 59, 1, 59, 1, 59, 1, 59, 1, 59, 1, 59, 1, 59, 1, 59, 1, 59, 1, 59, 1, 59, 1, 59, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 60, 1, 61, 1, 61, 1, 61, 1, 61, 1, 61, 1, 61, 1, 61, 1, 61, 1, 61, 1, 61, 1, 61, 1, 61, 1, 61, 1, 61, 1, 61, 1, 61, 1, 61, 1, 61, 1, 61, 1, 61, 1, 61, 1, 61, 1, 61, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 63, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 64, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 66, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 67, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 69, 1, 69, 1, 69, 1, 69, 1, 69, 1, 69, 1, 69, 1, 69, 1, 69, 1, 69, 1, 69, 1, 69, 1, 69, 1, 69, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 70, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 72, 1, 73, 1, 73, 1, 73, 1, 73, 1, 73, 1, 73, 1, 73, 1, 73, 1, 73, 1, 73, 1, 73, 1, 73, 1, 73, 1, 73, 1, 73, 1, 73, 1, 73, 1, 74, 1, 74, 1, 74, 1, 74, 1, 74, 1, 74, 1, 74, 1, 74, 1, 74, 1, 74, 1, 74, 1, 74, 1, 74, 1, 74, 1, 74, 1, 74, 1, 74, 1, 74, 1, 74, 1, 74, 1, 74, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 76, 1, 77, 1, 77, 1, 77, 1, 77, 1, 77, 1, 77, 1, 77, 1, 77, 1, 77, 1, 77, 1, 77, 1, 77, 1, 77, 1, 77, 1, 77, 1, 77, 1, 77, 1, 77, 1, 78, 1, 78, 1, 78, 1, 78, 1, 78, 1, 78, 1, 78, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 79, 1, 80, 1, 80, 1, 80, 1, 80, 1, 80, 1, 80, 1, 80, 1, 80, 1, 80, 1, 80, 1, 80, 1, 80, 1, 80, 1, 80, 1, 81, 1, 81, 1, 81, 1, 81, 1, 81, 1, 81, 1, 81, 1, 81, 1, 81, 1, 81, 1, 81, 1, 81, 1, 81, 1, 81, 1, 81, 1, 81, 1, 82, 1, 82, 1, 82, 1, 82, 1, 82, 1, 82, 1, 82, 1, 82, 1, 82, 1, 82, 1, 82, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 83, 1, 84, 1, 84, 1, 84, 1, 84, 1, 84, 1, 84, 1, 84, 1, 84, 1, 84, 1, 84, 1, 84, 1, 85, 1, 85, 1, 85, 1, 85, 1, 85, 1, 85, 1, 85, 1, 85, 1, 85, 1, 85, 1, 85, 1, 85, 1, 85, 1, 85, 1, 85, 1, 86, 1, 86, 1, 86, 1, 86, 1, 86, 1, 86, 1, 86, 1, 86, 1, 86, 1, 86, 1, 86, 1, 86, 1, 86, 1, 86, 1, 86, 1, 86, 1, 86, 1, 87, 1, 87, 1, 87, 1, 87, 1, 87, 1, 87, 1, 87, 1, 87, 1, 87, 1, 87, 1, 87, 1, 88, 1, 88, 1, 88, 1, 88, 1, 88, 1, 88, 1, 88, 1, 88, 1, 88, 1, 88, 1, 88, 1, 88, 1, 89, 1, 89, 1, 89, 1, 89, 1, 89, 1, 89, 1, 89, 1, 89, 1, 89, 1, 89, 1, 89, 1, 89, 1, 89, 1, 90, 1, 90, 1, 90, 1, 90, 1, 90, 1, 90, 1, 90, 1, 90, 1, 90, 1, 90, 1, 90, 1, 90, 1, 91, 1, 91, 1, 91, 1, 91, 1, 91, 1, 91, 1, 91, 1, 91, 1, 91, 1, 91, 1, 91, 1, 91, 1, 91, 1, 92, 1, 92, 1, 92, 1, 92, 1, 92, 1, 92, 1, 92, 1, 92, 1, 92, 1, 93, 1, 93, 1, 93, 1, 93, 1, 93, 1, 93, 1, 93, 1, 93, 1, 93, 1, 93, 1, 93, 1, 93, 1, 93, 1, 94, 1, 94, 1, 94, 1, 94, 1, 94, 1, 94, 1, 94, 1, 94, 1, 94, 1, 94, 1, 94, 1, 94, 1, 94, 1, 94, 1, 94, 1, 94, 1, 94, 1, 95, 1, 95, 1, 95, 1, 95, 1, 95, 1, 95, 1, 95, 1, 95, 1, 95, 1, 95, 1, 95, 1, 95, 1, 95, 1, 96, 1, 96, 1, 96, 1, 96, 1, 96, 1, 96, 1, 96, 1, 96, 1, 96, 1, 96, 1, 96, 1, 96, 1, 96, 1, 96, 1, 96, 1, 97, 1, 97, 1, 97, 1, 97, 1, 97, 1, 97, 1, 97, 1, 97, 1, 97, 1, 97, 1, 97, 1, 97, 1, 98, 1, 98, 1, 98, 1, 98, 1, 98, 1, 98, 1, 98, 1, 98, 1, 98, 1, 98, 1, 98, 1, 98, 1, 98, 1, 98, 1, 98, 1, 98, 1, 98, 1, 98, 1, 98, 1, 98, 1, 99, 1, 99, 1, 99, 1, 99, 1, 99, 1, 99, 1, 99, 1, 99, 1, 99, 1, 99, 1, 99, 1, 99, 1, 99, 1, 100, 1, 100, 1, 100, 1, 100, 1, 100, 1, 100, 1, 100, 1, 100, 1, 100, 1, 100, 1, 100, 1, 101, 1, 101, 1, 101, 1, 101, 1, 101, 1, 101, 1, 101, 1, 101, 1, 101, 1, 101, 1, 101, 1, 101, 1, 101, 1, 101, 1, 101, 1, 102, 1, 102, 1, 102, 1, 102, 1, 102, 1, 102, 1, 102, 1, 103, 1, 103, 1, 103, 1, 103, 1, 103, 1, 103, 1, 104, 1, 104, 1, 104, 1, 104, 1, 104, 1, 104, 1, 104, 1, 104, 1, 105, 1, 105, 1, 105, 1, 105, 1, 105, 1, 105, 1, 105, 1, 105, 1, 106, 1, 106, 1, 106, 1, 106, 1, 106, 1, 106, 1, 106, 1, 106, 1, 107, 1, 107, 1, 107, 1, 107, 1, 107, 1, 107, 1, 107, 1, 107, 1, 107, 1, 107, 1, 107, 1, 107, 1, 107, 1, 107, 1, 108, 1, 108, 1, 108, 1, 108, 1, 108, 1, 108, 1, 108, 1, 108, 1, 108, 1, 108, 1, 108, 1, 108, 1, 108, 1, 108, 1, 108, 1, 108, 1, 108, 1, 108, 1, 109, 1, 109, 1, 109, 1, 109, 1, 109, 1, 109, 1, 109, 1, 109, 1, 109, 1, 109, 1, 109, 1, 109, 1, 109, 1, 109, 1, 110, 1, 110, 1, 110, 1, 110, 1, 110, 1, 110, 1, 110, 1, 110, 1, 110, 1, 110, 1, 110, 1, 110, 1, 110, 1, 110, 1, 111, 1, 111, 1, 111, 1, 111, 1, 111, 1, 111, 1, 111, 1, 111, 1, 112, 1, 112, 1, 112, 1, 112, 1, 112, 1, 112, 1, 112, 1, 112, 1, 112, 1, 112, 1, 112, 1, 112, 1, 112, 1, 113, 1, 113, 1, 113, 1, 113, 1, 113, 1, 113, 1, 113, 1, 113, 1, 113, 1, 113, 1, 113, 1, 113, 1, 113, 1, 113, 1, 113, 1, 113, 1, 113, 1, 113, 1, 113, 1, 113, 1, 113, 1, 113, 1, 113, 1, 113, 1, 113, 1, 113, 1, 114, 1, 114, 1, 114, 1, 114, 1, 114, 1, 114, 1, 114, 1, 114, 1, 114, 1, 114, 1, 114, 1, 114, 1, 114, 1, 114, 1, 114, 1, 114, 1, 114, 1, 115, 1, 115, 1, 115, 1, 115, 1, 115, 1, 115, 1, 115, 1, 115, 1, 115, 1, 115, 1, 115, 1, 115, 1, 115, 1, 115, 1, 115, 1, 115, 1, 115, 1, 115, 1, 115, 1, 115, 1, 116, 1, 116, 1, 116, 1, 116, 1, 116, 1, 116, 1, 116, 1, 116, 1, 116, 1, 116, 1, 116, 1, 116, 1, 116, 1, 116, 1, 116, 1, 116, 1, 116, 1, 116, 1, 116, 1, 116, 1, 116, 1, 117, 1, 117, 1, 117, 1, 117, 1, 117, 1, 117, 1, 117, 1, 117, 1, 117, 1, 117, 1, 117, 1, 117, 1, 117, 1, 117, 1, 117, 1, 117, 1, 117, 1, 117, 1, 117, 1, 117, 1, 117, 1, 117, 1, 117, 1, 117, 1, 117, 1, 117, 1, 117, 1, 117, 1, 117, 1, 117, 1, 117, 1, 117, 1, 118, 1, 118, 1, 118, 1, 118, 1, 118, 1, 118, 1, 118, 1, 118, 1, 118, 1, 118, 1, 118, 1, 118, 1, 118, 1, 118, 1, 118, 1, 118, 1, 118, 1, 118, 1, 118, 1, 118, 1, 118, 1, 118, 1, 118, 1, 118, 1, 118, 1, 118, 1, 118, 1, 118, 1, 118, 1, 118, 1, 119, 1, 119, 1, 119, 1, 119, 1, 119, 1, 119, 1, 119, 1, 119, 1, 119, 1, 119, 1, 119, 1, 119, 1, 119, 1, 119, 1, 119, 1, 119, 1, 119, 1, 119, 1, 119, 1, 119, 1, 119, 1, 119, 1, 120, 1, 120, 1, 120, 1, 120, 1, 120, 1, 120, 1, 120, 1, 120, 1, 120, 1, 120, 1, 120, 1, 120, 1, 120, 1, 120, 1, 120, 1, 120, 1, 120, 1, 120, 1, 120, 1, 120, 1, 120, 1, 120, 1, 120, 1, 120, 1, 120, 1, 121, 1, 121, 1, 121, 1, 121, 1, 121, 1, 121, 1, 121, 1, 121, 1, 121, 1, 121, 1, 121, 1, 121, 1, 121, 1, 121, 1, 121, 1, 121, 1, 121, 1, 121, 1, 121, 1, 121, 1, 121, 1, 121, 1, 121, 1, 121, 1, 121, 1, 121, 1, 122, 1, 122, 1, 122, 1, 122, 1, 122, 1, 122, 1, 122, 1, 122, 1, 122, 1, 122, 1, 122, 1, 122, 1, 122, 1, 122, 1, 122, 1, 122, 1, 122, 1, 122, 1, 122, 1, 122, 1, 122, 1, 122, 1, 122, 1, 122, 1, 122, 1, 122, 1, 122, 1, 122, 1, 122, 1, 122, 1, 122, 1, 122, 1, 122, 1, 122, 1, 122, 1, 122, 1, 122, 1, 122, 1, 122, 1, 122, 1, 122, 1, 123, 1, 123, 1, 123, 1, 123, 1, 123, 1, 123, 1, 123, 1, 123, 1, 123, 1, 123, 1, 123, 1, 123, 1, 123, 1, 123, 1, 123, 1, 123, 1, 123, 1, 123, 1, 123, 1, 123, 1, 123, 1, 123, 1, 123, 1, 123, 1, 123, 1, 123, 1, 124, 1, 124, 1, 124, 1, 124, 1, 124, 1, 124, 1, 124, 1, 124, 1, 124, 1, 124, 1, 124, 1, 124, 1, 124, 1, 124, 1, 124, 1, 124, 1, 124, 1, 124, 1, 124, 1, 124, 1, 124, 1, 124, 1, 124, 1, 124, 1, 124, 1, 124, 1, 124, 1, 124, 1, 125, 1, 125, 1, 125, 1, 125, 1, 125, 1, 125, 1, 125, 1, 125, 1, 125, 1, 125, 1, 125, 1, 125, 1, 125, 1, 125, 1, 125, 1, 125, 1, 125, 1, 126, 1, 126, 1, 126, 5, 126, 2232, 8, 126, 10, 126, 12, 126, 2235, 9, 126, 1, 126, 1, 126, 1, 126, 1, 126, 1, 127, 1, 127, 1, 127, 1, 127, 1, 127, 1, 127, 5, 127, 2247, 8, 127, 10, 127, 12, 127, 2250, 9, 127, 1, 127, 1, 127, 1, 128, 1, 128, 1, 128, 1, 128, 1, 128, 5, 128, 2259, 8, 128, 10, 128, 12, 128, 2262, 9, 128, 1, 128, 1, 128, 1, 129, 1, 129, 1, 129, 5, 129, 2269, 8, 129, 10, 129, 12, 129, 2272, 9, 129, 1, 129, 1, 129, 1, 130, 1, 130, 1, 130, 3, 130, 2279, 8, 130, 1, 131, 1, 131, 1, 131, 1, 131, 1, 131, 1, 131, 1, 132, 1, 132, 1, 133, 1, 133, 1, 134, 1, 134, 1, 134, 5, 134, 2294, 8, 134, 10, 134, 12, 134, 2297, 9, 134, 3, 134, 2299, 8, 134, 1, 135, 3, 135, 2302, 8, 135, 1, 135, 1, 135, 1, 135, 4, 135, 2307, 8, 135, 11, 135, 12, 135, 2308, 3, 135, 2311, 8, 135, 1, 135, 3, 135, 2314, 8, 135, 1, 136, 1, 136, 3, 136, 2318, 8, 136, 1, 136, 1, 136, 1, 137, 4, 137, 2323, 8, 137, 11, 137, 12, 137, 2324, 1, 137, 1, 137, 0, 0, 138, 1, 1, 3, 2, 5, 3, 7, 4, 9, 5, 11, 6, 13, 7, 15, 8, 17, 9, 19, 10, 21, 11, 23, 12, 25, 13, 27, 14, 29, 15, 31, 16, 33, 17, 35, 18, 37, 19, 39, 20, 41, 21, 43, 22, 45, 23, 47, 24, 49, 25, 51, 26, 53, 27, 55, 28, 57, 29, 59, 30, 61, 31, 63, 32, 65, 33, 67, 34, 69, 35, 71, 36, 73, 37, 75, 38, 77, 39, 79, 40, 81, 41, 83, 42, 85, 43, 87, 44, 89, 45, 91, 46, 93, 47, 95, 48, 97, 49, 99, 50, 101, 51, 103, 52, 105, 53, 107, 54, 109, 55, 111, 56, 113, 57, 115, 58, 117, 59, 119, 60, 121, 61, 123, 62, 125, 63, 127, 64, 129, 65, 131, 66, 133, 67, 135, 68, 137, 69, 139, 70, 141, 71, 143, 72, 145, 73, 147, 74, 149, 75, 151, 76, 153, 77, 155, 78, 157, 79, 159, 80, 161, 81, 163, 82, 165, 83, 167, 84, 169, 85, 171, 86, 173, 87, 175, 88, 177, 89, 179, 90, 181, 91, 183, 92, 185, 93, 187, 94, 189, 95, 191, 96, 193, 97, 195, 98, 197, 99, 199, 100, 201, 101, 203, 102, 205, 103, 207, 104, 209, 105, 211, 106, 213, 107, 215, 108, 217, 109, 219, 110, 221, 111, 223, 112, 225, 113, 227, 114, 229, 115, 231, 116, 233, 117, 235, 118, 237, 119, 239, 120, 241, 121, 243, 122, 245, 123, 247, 124, 249, 125, 251, 126, 253, 127, 255, 128, 257, 129, 259, 130, 261, 0, 263, 0, 265, 0, 267, 0, 269, 131, 271, 132, 273, 0, 275, 133, 1, 0, 8, 8, 0, 34, 34, 47, 47, 92, 92, 98, 98, 102, 102, 110, 110, 114, 114, 116, 116, 3, 0, 48, 57, 65, 70, 97, 102, 3, 0, 0, 31, 34, 34, 92, 92, 1, 0, 49, 57, 1, 0, 48, 57, 2, 0, 69, 69, 101, 101, 2, 0, 43, 43, 45, 45, 3, 0, 9, 10, 13, 13, 32, 32, 2339, 0, 1, 1, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 5, 1, 0, 0, 0, 0, 7, 1, 0, 0, 0, 0, 9, 1, 0, 0, 0, 0, 11, 1, 0, 0, 0, 0, 13, 1, 0, 0, 0, 0, 15, 1, 0, 0, 0, 0, 17, 1, 0, 0, 0, 0, 19, 1, 0, 0, 0, 0, 21, 1, 0, 0, 0, 0, 23, 1, 0, 0, 0, 0, 25, 1, 0, 0, 0, 0, 27, 1, 0, 0, 0, 0, 29, 1, 0, 0, 0, 0, 31, 1, 0, 0, 0, 0, 33, 1, 0, 0, 0, 0, 35, 1, 0, 0, 0, 0, 37, 1, 0, 0, 0, 0, 39, 1, 0, 0, 0, 0, 41, 1, 0, 0, 0, 0, 43, 1, 0, 0, 0, 0, 45, 1, 0, 0, 0, 0, 47, 1, 0, 0, 0, 0, 49, 1, 0, 0, 0, 0, 51, 1, 0, 0, 0, 0, 53, 1, 0, 0, 0, 0, 55, 1, 0, 0, 0, 0, 57, 1, 0, 0, 0, 0, 59, 1, 0, 0, 0, 0, 61, 1, 0, 0, 0, 0, 63, 1, 0, 0, 0, 0, 65, 1, 0, 0, 0, 0, 67, 1, 0, 0, 0, 0, 69, 1, 0, 0, 0, 0, 71, 1, 0, 0, 0, 0, 73, 1, 0, 0, 0, 0, 75, 1, 0, 0, 0, 0, 77, 1, 0, 0, 0, 0, 79, 1, 0, 0, 0, 0, 81, 1, 0, 0, 0, 0, 83, 1, 0, 0, 0, 0, 85, 1, 0, 0, 0, 0, 87, 1, 0, 0, 0, 0, 89, 1, 0, 0, 0, 0, 91, 1, 0, 0, 0, 0, 93, 1, 0, 0, 0, 0, 95, 1, 0, 0, 0, 0, 97, 1, 0, 0, 0, 0, 99, 1, 0, 0, 0, 0, 101, 1, 0, 0, 0, 0, 103, 1, 0, 0, 0, 0, 105, 1, 0, 0, 0, 0, 107, 1, 0, 0, 0, 0, 109, 1, 0, 0, 0, 0, 111, 1, 0, 0, 0, 0, 113, 1, 0, 0, 0, 0, 115, 1, 0, 0, 0, 0, 117, 1, 0, 0, 0, 0, 119, 1, 0, 0, 0, 0, 121, 1, 0, 0, 0, 0, 123, 1, 0, 0, 0, 0, 125, 1, 0, 0, 0, 0, 127, 1, 0, 0, 0, 0, 129, 1, 0, 0, 0, 0, 131, 1, 0, 0, 0, 0, 133, 1, 0, 0, 0, 0, 135, 1, 0, 0, 0, 0, 137, 1, 0, 0, 0, 0, 139, 1, 0, 0, 0, 0, 141, 1, 0, 0, 0, 0, 143, 1, 0, 0, 0, 0, 145, 1, 0, 0, 0, 0, 147, 1, 0, 0, 0, 0, 149, 1, 0, 0, 0, 0, 151, 1, 0, 0, 0, 0, 153, 1, 0, 0, 0, 0, 155, 1, 0, 0, 0, 0, 157, 1, 0, 0, 0, 0, 159, 1, 0, 0, 0, 0, 161, 1, 0, 0, 0, 0, 163, 1, 0, 0, 0, 0, 165, 1, 0, 0, 0, 0, 167, 1, 0, 0, 0, 0, 169, 1, 0, 0, 0, 0, 171, 1, 0, 0, 0, 0, 173, 1, 0, 0, 0, 0, 175, 1, 0, 0, 0, 0, 177, 1, 0, 0, 0, 0, 179, 1, 0, 0, 0, 0, 181, 1, 0, 0, 0, 0, 183, 1, 0, 0, 0, 0, 185, 1, 0, 0, 0, 0, 187, 1, 0, 0, 0, 0, 189, 1, 0, 0, 0, 0, 191, 1, 0, 0, 0, 0, 193, 1, 0, 0, 0, 0, 195, 1, 0, 0, 0, 0, 197, 1, 0, 0, 0, 0, 199, 1, 0, 0, 0, 0, 201, 1, 0, 0, 0, 0, 203, 1, 0, 0, 0, 0, 205, 1, 0, 0, 0, 0, 207, 1, 0, 0, 0, 0, 209, 1, 0, 0, 0, 0, 211, 1, 0, 0, 0, 0, 213, 1, 0, 0, 0, 0, 215, 1, 0, 0, 0, 0, 217, 1, 0, 0, 0, 0, 219, 1, 0, 0, 0, 0, 221, 1, 0, 0, 0, 0, 223, 1, 0, 0, 0, 0, 225, 1, 0, 0, 0, 0, 227, 1, 0, 0, 0, 0, 229, 1, 0, 0, 0, 0, 231, 1, 0, 0, 0, 0, 233, 1, 0, 0, 0, 0, 235, 1, 0, 0, 0, 0, 237, 1, 0, 0, 0, 0, 239, 1, 0, 0, 0, 0, 241, 1, 0, 0, 0, 0, 243, 1, 0, 0, 0, 0, 245, 1, 0, 0, 0, 0, 247, 1, 0, 0, 0, 0, 249, 1, 0, 0, 0, 0, 251, 1, 0, 0, 0, 0, 253, 1, 0, 0, 0, 0, 255, 1, 0, 0, 0, 0, 257, 1, 0, 0, 0, 0, 259, 1, 0, 0, 0, 0, 269, 1, 0, 0, 0, 0, 271, 1, 0, 0, 0, 0, 275, 1, 0, 0, 0, 1, 277, 1, 0, 0, 0, 3, 279, 1, 0, 0, 0, 5, 281, 1, 0, 0, 0, 7, 283, 1, 0, 0, 0, 9, 285, 1, 0, 0, 0, 11, 287, 1, 0, 0, 0, 13, 289, 1, 0, 0, 0, 15, 294, 1, 0, 0, 0, 17, 300, 1, 0, 0, 0, 19, 305, 1, 0, 0, 0, 21, 315, 1, 0, 0, 0, 23, 324, 1, 0, 0, 0, 25, 334, 1, 0, 0, 0, 27, 346, 1, 0, 0, 0, 29, 356, 1, 0, 0, 0, 31, 363, 1, 0, 0, 0, 33, 370, 1, 0, 0, 0, 35, 379, 1, 0, 0, 0, 37, 386, 1, 0, 0, 0, 39, 396, 1, 0, 0, 0, 41, 403, 1, 0, 0, 0, 43, 410, 1, 0, 0, 0, 45, 421, 1, 0, 0, 0, 47, 427, 1, 0, 0, 0, 49, 437, 1, 0, 0, 0, 51, 448, 1, 0, 0, 0, 53, 458, 1, 0, 0, 0, 55, 469, 1, 0, 0, 0, 57, 475, 1, 0, 0, 0, 59, 491, 1, 0, 0, 0, 61, 511, 1, 0, 0, 0, 63, 523, 1, 0, 0, 0, 65, 532, 1, 0, 0, 0, 67, 544, 1, 0, 0, 0, 69, 556, 1, 0, 0, 0, 71, 567, 1, 0, 0, 0, 73, 581, 1, 0, 0, 0, 75, 587, 1, 0, 0, 0, 77, 603, 1, 0, 0, 0, 79, 623, 1, 0, 0, 0, 81, 644, 1, 0, 0, 0, 83, 669, 1, 0, 0, 0, 85, 696, 1, 0, 0, 0, 87, 727, 1, 0, 0, 0, 89, 745, 1, 0, 0, 0, 91, 767, 1, 0, 0, 0, 93, 791, 1, 0, 0, 0, 95, 819, 1, 0, 0, 0, 97, 824, 1, 0, 0, 0, 99, 839, 1, 0, 0, 0, 101, 858, 1, 0, 0, 0, 103, 878, 1, 0, 0, 0, 105, 902, 1, 0, 0, 0, 107, 928, 1, 0, 0, 0, 109, 958, 1, 0, 0, 0, 111, 975, 1, 0, 0, 0, 113, 996, 1, 0, 0, 0, 115, 1019, 1, 0, 0, 0, 117, 1046, 1, 0, 0, 0, 119, 1062, 1, 0, 0, 0, 121, 1080, 1, 0, 0, 0, 123, 1102, 1, 0, 0, 0, 125, 1125, 1, 0, 0, 0, 127, 1152, 1, 0, 0, 0, 129, 1181, 1, 0, 0, 0, 131, 1214, 1, 0, 0, 0, 133, 1234, 1, 0, 0, 0, 135, 1258, 1, 0, 0, 0, 137, 1284, 1, 0, 0, 0, 139, 1314, 1, 0, 0, 0, 141, 1328, 1, 0, 0, 0, 143, 1338, 1, 0, 0, 0, 145, 1354, 1, 0, 0, 0, 147, 1366, 1, 0, 0, 0, 149, 1383, 1, 0, 0, 0, 151, 1404, 1, 0, 0, 0, 153, 1423, 1, 0, 0, 0, 155, 1446, 1, 0, 0, 0, 157, 1464, 1, 0, 0, 0, 159, 1471, 1, 0, 0, 0, 161, 1480, 1, 0, 0, 0, 163, 1494, 1, 0, 0, 0, 165, 1510, 1, 0, 0, 0, 167, 1521, 1, 0, 0, 0, 169, 1537, 1, 0, 0, 0, 171, 1548, 1, 0, 0, 0, 173, 1563, 1, 0, 0, 0, 175, 1580, 1, 0, 0, 0, 177, 1591, 1, 0, 0, 0, 179, 1603, 1, 0, 0, 0, 181, 1616, 1, 0, 0, 0, 183, 1628, 1, 0, 0, 0, 185, 1641, 1, 0, 0, 0, 187, 1650, 1, 0, 0, 0, 189, 1663, 1, 0, 0, 0, 191, 1680, 1, 0, 0, 0, 193, 1693, 1, 0, 0, 0, 195, 1708, 1, 0, 0, 0, 197, 1720, 1, 0, 0, 0, 199, 1740, 1, 0, 0, 0, 201, 1753, 1, 0, 0, 0, 203, 1764, 1, 0, 0, 0, 205, 1779, 1, 0, 0, 0, 207, 1786, 1, 0, 0, 0, 209, 1792, 1, 0, 0, 0, 211, 1800, 1, 0, 0, 0, 213, 1808, 1, 0, 0, 0, 215, 1816, 1, 0, 0, 0, 217, 1830, 1, 0, 0, 0, 219, 1848, 1, 0, 0, 0, 221, 1862, 1, 0, 0, 0, 223, 1876, 1, 0, 0, 0, 225, 1884, 1, 0, 0, 0, 227, 1897, 1, 0, 0, 0, 229, 1923, 1, 0, 0, 0, 231, 1940, 1, 0, 0, 0, 233, 1960, 1, 0, 0, 0, 235, 1981, 1, 0, 0, 0, 237, 2013, 1, 0, 0, 0, 239, 2043, 1, 0, 0, 0, 241, 2065, 1, 0, 0, 0, 243, 2090, 1, 0, 0, 0, 245, 2116, 1, 0, 0, 0, 247, 2157, 1, 0, 0, 0, 249, 2183, 1, 0, 0, 0, 251, 2211, 1, 0, 0, 0, 253, 2228, 1, 0, 0, 0, 255, 2240, 1, 0, 0, 0, 257, 2253, 1, 0, 0, 0, 259, 2265, 1, 0, 0, 0, 261, 2275, 1, 0, 0, 0, 263, 2280, 1, 0, 0, 0, 265, 2286, 1, 0, 0, 0, 267, 2288, 1, 0, 0, 0, 269, 2298, 1, 0, 0, 0, 271, 2301, 1, 0, 0, 0, 273, 2315, 1, 0, 0, 0, 275, 2322, 1, 0, 0, 0, 277, 278, 5, 44, 0, 0, 278, 2, 1, 0, 0, 0, 279, 280, 5, 58, 0, 0, 280, 4, 1, 0, 0, 0, 281, 282, 5, 91, 0, 0, 282, 6, 1, 0, 0, 0, 283, 284, 5, 93, 0, 0, 284, 8, 1, 0, 0, 0, 285, 286, 5, 123, 0, 0, 286, 10, 1, 0, 0, 0, 287, 288, 5, 125, 0, 0, 288, 12, 1, 0, 0, 0, 289, 290, 5, 116, 0, 0, 290, 291, 5, 114, 0, 0, 291, 292, 5, 117, 0, 0, 292, 293, 5, 101, 0, 0, 293, 14, 1, 0, 0, 0, 294, 295, 5, 102, 0, 0, 295, 296, 5, 97, 0, 0, 296, 297, 5, 108, 0, 0, 297, 298, 5, 115, 0, 0, 298, 299, 5, 101, 0, 0, 299, 16, 1, 0, 0, 0, 300, 301, 5, 110, 0, 0, 301, 302, 5, 117, 0, 0, 302, 303, 5, 108, 0, 0, 303, 304, 5, 108, 0, 0, 304, 18, 1, 0, 0, 0, 305, 306, 5, 34, 0, 0, 306, 307, 5, 67, 0, 0, 307, 308, 5, 111, 0, 0, 308, 309, 5, 109, 0, 0, 309, 310, 5, 109, 0, 0, 310, 311, 5, 101, 0, 0, 311, 312, 5, 110, 0, 0, 312, 313, 5, 116, 0, 0, 313, 314, 5, 34, 0, 0, 314, 20, 1, 0, 0, 0, 315, 316, 5, 34, 0, 0, 316, 317, 5, 83, 0, 0, 317, 318, 5, 116, 0, 0, 318, 319, 5, 97, 0, 0, 319, 320, 5, 116, 0, 0, 320, 321, 5, 101, 0, 0, 321, 322, 5, 115, 0, 0, 322, 323, 5, 34, 0, 0, 323, 22, 1, 0, 0, 0, 324, 325, 5, 34, 0, 0, 325, 326, 5, 83, 0, 0, 326, 327, 5, 116, 0, 0, 327, 328, 5, 97, 0, 0, 328, 329, 5, 114, 0, 0, 329, 330, 5, 116, 0, 0, 330, 331, 5, 65, 0, 0, 331, 332, 5, 116, 0, 0, 332, 333, 5, 34, 0, 0, 333, 24, 1, 0, 0, 0, 334, 335, 5, 34, 0, 0, 335, 336, 5, 78, 0, 0, 336, 337, 5, 101, 0, 0, 337, 338, 5, 120, 0, 0, 338, 339, 5, 116, 0, 0, 339, 340, 5, 83, 0, 0, 340, 341, 5, 116, 0, 0, 341, 342, 5, 97, 0, 0, 342, 343, 5, 116, 0, 0, 343, 344, 5, 101, 0, 0, 344, 345, 5, 34, 0, 0, 345, 26, 1, 0, 0, 0, 346, 347, 5, 34, 0, 0, 347, 348, 5, 86, 0, 0, 348, 349, 5, 101, 0, 0, 349, 350, 5, 114, 0, 0, 350, 351, 5, 115, 0, 0, 351, 352, 5, 105, 0, 0, 352, 353, 5, 111, 0, 0, 353, 354, 5, 110, 0, 0, 354, 355, 5, 34, 0, 0, 355, 28, 1, 0, 0, 0, 356, 357, 5, 34, 0, 0, 357, 358, 5, 84, 0, 0, 358, 359, 5, 121, 0, 0, 359, 360, 5, 112, 0, 0, 360, 361, 5, 101, 0, 0, 361, 362, 5, 34, 0, 0, 362, 30, 1, 0, 0, 0, 363, 364, 5, 34, 0, 0, 364, 365, 5, 84, 0, 0, 365, 366, 5, 97, 0, 0, 366, 367, 5, 115, 0, 0, 367, 368, 5, 107, 0, 0, 368, 369, 5, 34, 0, 0, 369, 32, 1, 0, 0, 0, 370, 371, 5, 34, 0, 0, 371, 372, 5, 67, 0, 0, 372, 373, 5, 104, 0, 0, 373, 374, 5, 111, 0, 0, 374, 375, 5, 105, 0, 0, 375, 376, 5, 99, 0, 0, 376, 377, 5, 101, 0, 0, 377, 378, 5, 34, 0, 0, 378, 34, 1, 0, 0, 0, 379, 380, 5, 34, 0, 0, 380, 381, 5, 70, 0, 0, 381, 382, 5, 97, 0, 0, 382, 383, 5, 105, 0, 0, 383, 384, 5, 108, 0, 0, 384, 385, 5, 34, 0, 0, 385, 36, 1, 0, 0, 0, 386, 387, 5, 34, 0, 0, 387, 388, 5, 83, 0, 0, 388, 389, 5, 117, 0, 0, 389, 390, 5, 99, 0, 0, 390, 391, 5, 99, 0, 0, 391, 392, 5, 101, 0, 0, 392, 393, 5, 101, 0, 0, 393, 394, 5, 100, 0, 0, 394, 395, 5, 34, 0, 0, 395, 38, 1, 0, 0, 0, 396, 397, 5, 34, 0, 0, 397, 398, 5, 80, 0, 0, 398, 399, 5, 97, 0, 0, 399, 400, 5, 115, 0, 0, 400, 401, 5, 115, 0, 0, 401, 402, 5, 34, 0, 0, 402, 40, 1, 0, 0, 0, 403, 404, 5, 34, 0, 0, 404, 405, 5, 87, 0, 0, 405, 406, 5, 97, 0, 0, 406, 407, 5, 105, 0, 0, 407, 408, 5, 116, 0, 0, 408, 409, 5, 34, 0, 0, 409, 42, 1, 0, 0, 0, 410, 411, 5, 34, 0, 0, 411, 412, 5, 80, 0, 0, 412, 413, 5, 97, 0, 0, 413, 414, 5, 114, 0, 0, 414, 415, 5, 97, 0, 0, 415, 416, 5, 108, 0, 0, 416, 417, 5, 108, 0, 0, 417, 418, 5, 101, 0, 0, 418, 419, 5, 108, 0, 0, 419, 420, 5, 34, 0, 0, 420, 44, 1, 0, 0, 0, 421, 422, 5, 34, 0, 0, 422, 423, 5, 77, 0, 0, 423, 424, 5, 97, 0, 0, 424, 425, 5, 112, 0, 0, 425, 426, 5, 34, 0, 0, 426, 46, 1, 0, 0, 0, 427, 428, 5, 34, 0, 0, 428, 429, 5, 67, 0, 0, 429, 430, 5, 104, 0, 0, 430, 431, 5, 111, 0, 0, 431, 432, 5, 105, 0, 0, 432, 433, 5, 99, 0, 0, 433, 434, 5, 101, 0, 0, 434, 435, 5, 115, 0, 0, 435, 436, 5, 34, 0, 0, 436, 48, 1, 0, 0, 0, 437, 438, 5, 34, 0, 0, 438, 439, 5, 86, 0, 0, 439, 440, 5, 97, 0, 0, 440, 441, 5, 114, 0, 0, 441, 442, 5, 105, 0, 0, 442, 443, 5, 97, 0, 0, 443, 444, 5, 98, 0, 0, 444, 445, 5, 108, 0, 0, 445, 446, 5, 101, 0, 0, 446, 447, 5, 34, 0, 0, 447, 50, 1, 0, 0, 0, 448, 449, 5, 34, 0, 0, 449, 450, 5, 68, 0, 0, 450, 451, 5, 101, 0, 0, 451, 452, 5, 102, 0, 0, 452, 453, 5, 97, 0, 0, 453, 454, 5, 117, 0, 0, 454, 455, 5, 108, 0, 0, 455, 456, 5, 116, 0, 0, 456, 457, 5, 34, 0, 0, 457, 52, 1, 0, 0, 0, 458, 459, 5, 34, 0, 0, 459, 460, 5, 66, 0, 0, 460, 461, 5, 114, 0, 0, 461, 462, 5, 97, 0, 0, 462, 463, 5, 110, 0, 0, 463, 464, 5, 99, 0, 0, 464, 465, 5, 104, 0, 0, 465, 466, 5, 101, 0, 0, 466, 467, 5, 115, 0, 0, 467, 468, 5, 34, 0, 0, 468, 54, 1, 0, 0, 0, 469, 470, 5, 34, 0, 0, 470, 471, 5, 65, 0, 0, 471, 472, 5, 110, 0, 0, 472, 473, 5, 100, 0, 0, 473, 474, 5, 34, 0, 0, 474, 56, 1, 0, 0, 0, 475, 476, 5, 34, 0, 0, 476, 477, 5, 66, 0, 0, 477, 478, 5, 111, 0, 0, 478, 479, 5, 111, 0, 0, 479, 480, 5, 108, 0, 0, 480, 481, 5, 101, 0, 0, 481, 482, 5, 97, 0, 0, 482, 483, 5, 110, 0, 0, 483, 484, 5, 69, 0, 0, 484, 485, 5, 113, 0, 0, 485, 486, 5, 117, 0, 0, 486, 487, 5, 97, 0, 0, 487, 488, 5, 108, 0, 0, 488, 489, 5, 115, 0, 0, 489, 490, 5, 34, 0, 0, 490, 58, 1, 0, 0, 0, 491, 492, 5, 34, 0, 0, 492, 493, 5, 66, 0, 0, 493, 494, 5, 111, 0, 0, 494, 495, 5, 111, 0, 0, 495, 496, 5, 108, 0, 0, 496, 497, 5, 101, 0, 0, 497, 498, 5, 97, 0, 0, 498, 499, 5, 110, 0, 0, 499, 500, 5, 69, 0, 0, 500, 501, 5, 113, 0, 0, 501, 502, 5, 117, 0, 0, 502, 503, 5, 97, 0, 0, 503, 504, 5, 108, 0, 0, 504, 505, 5, 115, 0, 0, 505, 506, 5, 80, 0, 0, 506, 507, 5, 97, 0, 0, 507, 508, 5, 116, 0, 0, 508, 509, 5, 104, 0, 0, 509, 510, 5, 34, 0, 0, 510, 60, 1, 0, 0, 0, 511, 512, 5, 34, 0, 0, 512, 513, 5, 73, 0, 0, 513, 514, 5, 115, 0, 0, 514, 515, 5, 66, 0, 0, 515, 516, 5, 111, 0, 0, 516, 517, 5, 111, 0, 0, 517, 518, 5, 108, 0, 0, 518, 519, 5, 101, 0, 0, 519, 520, 5, 97, 0, 0, 520, 521, 5, 110, 0, 0, 521, 522, 5, 34, 0, 0, 522, 62, 1, 0, 0, 0, 523, 524, 5, 34, 0, 0, 524, 525, 5, 73, 0, 0, 525, 526, 5, 115, 0, 0, 526, 527, 5, 78, 0, 0, 527, 528, 5, 117, 0, 0, 528, 529, 5, 108, 0, 0, 529, 530, 5, 108, 0, 0, 530, 531, 5, 34, 0, 0, 531, 64, 1, 0, 0, 0, 532, 533, 5, 34, 0, 0, 533, 534, 5, 73, 0, 0, 534, 535, 5, 115, 0, 0, 535, 536, 5, 78, 0, 0, 536, 537, 5, 117, 0, 0, 537, 538, 5, 109, 0, 0, 538, 539, 5, 101, 0, 0, 539, 540, 5, 114, 0, 0, 540, 541, 5, 105, 0, 0, 541, 542, 5, 99, 0, 0, 542, 543, 5, 34, 0, 0, 543, 66, 1, 0, 0, 0, 544, 545, 5, 34, 0, 0, 545, 546, 5, 73, 0, 0, 546, 547, 5, 115, 0, 0, 547, 548, 5, 80, 0, 0, 548, 549, 5, 114, 0, 0, 549, 550, 5, 101, 0, 0, 550, 551, 5, 115, 0, 0, 551, 552, 5, 101, 0, 0, 552, 553, 5, 110, 0, 0, 553, 554, 5, 116, 0, 0, 554, 555, 5, 34, 0, 0, 555, 68, 1, 0, 0, 0, 556, 557, 5, 34, 0, 0, 557, 558, 5, 73, 0, 0, 558, 559, 5, 115, 0, 0, 559, 560, 5, 83, 0, 0, 560, 561, 5, 116, 0, 0, 561, 562, 5, 114, 0, 0, 562, 563, 5, 105, 0, 0, 563, 564, 5, 110, 0, 0, 564, 565, 5, 103, 0, 0, 565, 566, 5, 34, 0, 0, 566, 70, 1, 0, 0, 0, 567, 568, 5, 34, 0, 0, 568, 569, 5, 73, 0, 0, 569, 570, 5, 115, 0, 0, 570, 571, 5, 84, 0, 0, 571, 572, 5, 105, 0, 0, 572, 573, 5, 109, 0, 0, 573, 574, 5, 101, 0, 0, 574, 575, 5, 115, 0, 0, 575, 576, 5, 116, 0, 0, 576, 577, 5, 97, 0, 0, 577, 578, 5, 109, 0, 0, 578, 579, 5, 112, 0, 0, 579, 580, 5, 34, 0, 0, 580, 72, 1, 0, 0, 0, 581, 582, 5, 34, 0, 0, 582, 583, 5, 78, 0, 0, 583, 584, 5, 111, 0, 0, 584, 585, 5, 116, 0, 0, 585, 586, 5, 34, 0, 0, 586, 74, 1, 0, 0, 0, 587, 588, 5, 34, 0, 0, 588, 589, 5, 78, 0, 0, 589, 590, 5, 117, 0, 0, 590, 591, 5, 109, 0, 0, 591, 592, 5, 101, 0, 0, 592, 593, 5, 114, 0, 0, 593, 594, 5, 105, 0, 0, 594, 595, 5, 99, 0, 0, 595, 596, 5, 69, 0, 0, 596, 597, 5, 113, 0, 0, 597, 598, 5, 117, 0, 0, 598, 599, 5, 97, 0, 0, 599, 600, 5, 108, 0, 0, 600, 601, 5, 115, 0, 0, 601, 602, 5, 34, 0, 0, 602, 76, 1, 0, 0, 0, 603, 604, 5, 34, 0, 0, 604, 605, 5, 78, 0, 0, 605, 606, 5, 117, 0, 0, 606, 607, 5, 109, 0, 0, 607, 608, 5, 101, 0, 0, 608, 609, 5, 114, 0, 0, 609, 610, 5, 105, 0, 0, 610, 611, 5, 99, 0, 0, 611, 612, 5, 69, 0, 0, 612, 613, 5, 113, 0, 0, 613, 614, 5, 117, 0, 0, 614, 615, 5, 97, 0, 0, 615, 616, 5, 108, 0, 0, 616, 617, 5, 115, 0, 0, 617, 618, 5, 80, 0, 0, 618, 619, 5, 97, 0, 0, 619, 620, 5, 116, 0, 0, 620, 621, 5, 104, 0, 0, 621, 622, 5, 34, 0, 0, 622, 78, 1, 0, 0, 0, 623, 624, 5, 34, 0, 0, 624, 625, 5, 78, 0, 0, 625, 626, 5, 117, 0, 0, 626, 627, 5, 109, 0, 0, 627, 628, 5, 101, 0, 0, 628, 629, 5, 114, 0, 0, 629, 630, 5, 105, 0, 0, 630, 631, 5, 99, 0, 0, 631, 632, 5, 71, 0, 0, 632, 633, 5, 114, 0, 0, 633, 634, 5, 101, 0, 0, 634, 635, 5, 97, 0, 0, 635, 636, 5, 116, 0, 0, 636, 637, 5, 101, 0, 0, 637, 638, 5, 114, 0, 0, 638, 639, 5, 84, 0, 0, 639, 640, 5, 104, 0, 0, 640, 641, 5, 97, 0, 0, 641, 642, 5, 110, 0, 0, 642, 643, 5, 34, 0, 0, 643, 80, 1, 0, 0, 0, 644, 645, 5, 34, 0, 0, 645, 646, 5, 78, 0, 0, 646, 647, 5, 117, 0, 0, 647, 648, 5, 109, 0, 0, 648, 649, 5, 101, 0, 0, 649, 650, 5, 114, 0, 0, 650, 651, 5, 105, 0, 0, 651, 652, 5, 99, 0, 0, 652, 653, 5, 71, 0, 0, 653, 654, 5, 114, 0, 0, 654, 655, 5, 101, 0, 0, 655, 656, 5, 97, 0, 0, 656, 657, 5, 116, 0, 0, 657, 658, 5, 101, 0, 0, 658, 659, 5, 114, 0, 0, 659, 660, 5, 84, 0, 0, 660, 661, 5, 104, 0, 0, 661, 662, 5, 97, 0, 0, 662, 663, 5, 110, 0, 0, 663, 664, 5, 80, 0, 0, 664, 665, 5, 97, 0, 0, 665, 666, 5, 116, 0, 0, 666, 667, 5, 104, 0, 0, 667, 668, 5, 34, 0, 0, 668, 82, 1, 0, 0, 0, 669, 670, 5, 34, 0, 0, 670, 671, 5, 78, 0, 0, 671, 672, 5, 117, 0, 0, 672, 673, 5, 109, 0, 0, 673, 674, 5, 101, 0, 0, 674, 675, 5, 114, 0, 0, 675, 676, 5, 105, 0, 0, 676, 677, 5, 99, 0, 0, 677, 678, 5, 71, 0, 0, 678, 679, 5, 114, 0, 0, 679, 680, 5, 101, 0, 0, 680, 681, 5, 97, 0, 0, 681, 682, 5, 116, 0, 0, 682, 683, 5, 101, 0, 0, 683, 684, 5, 114, 0, 0, 684, 685, 5, 84, 0, 0, 685, 686, 5, 104, 0, 0, 686, 687, 5, 97, 0, 0, 687, 688, 5, 110, 0, 0, 688, 689, 5, 69, 0, 0, 689, 690, 5, 113, 0, 0, 690, 691, 5, 117, 0, 0, 691, 692, 5, 97, 0, 0, 692, 693, 5, 108, 0, 0, 693, 694, 5, 115, 0, 0, 694, 695, 5, 34, 0, 0, 695, 84, 1, 0, 0, 0, 696, 697, 5, 34, 0, 0, 697, 698, 5, 78, 0, 0, 698, 699, 5, 117, 0, 0, 699, 700, 5, 109, 0, 0, 700, 701, 5, 101, 0, 0, 701, 702, 5, 114, 0, 0, 702, 703, 5, 105, 0, 0, 703, 704, 5, 99, 0, 0, 704, 705, 5, 71, 0, 0, 705, 706, 5, 114, 0, 0, 706, 707, 5, 101, 0, 0, 707, 708, 5, 97, 0, 0, 708, 709, 5, 116, 0, 0, 709, 710, 5, 101, 0, 0, 710, 711, 5, 114, 0, 0, 711, 712, 5, 84, 0, 0, 712, 713, 5, 104, 0, 0, 713, 714, 5, 97, 0, 0, 714, 715, 5, 110, 0, 0, 715, 716, 5, 69, 0, 0, 716, 717, 5, 113, 0, 0, 717, 718, 5, 117, 0, 0, 718, 719, 5, 97, 0, 0, 719, 720, 5, 108, 0, 0, 720, 721, 5, 115, 0, 0, 721, 722, 5, 80, 0, 0, 722, 723, 5, 97, 0, 0, 723, 724, 5, 116, 0, 0, 724, 725, 5, 104, 0, 0, 725, 726, 5, 34, 0, 0, 726, 86, 1, 0, 0, 0, 727, 728, 5, 34, 0, 0, 728, 729, 5, 78, 0, 0, 729, 730, 5, 117, 0, 0, 730, 731, 5, 109, 0, 0, 731, 732, 5, 101, 0, 0, 732, 733, 5, 114, 0, 0, 733, 734, 5, 105, 0, 0, 734, 735, 5, 99, 0, 0, 735, 736, 5, 76, 0, 0, 736, 737, 5, 101, 0, 0, 737, 738, 5, 115, 0, 0, 738, 739, 5, 115, 0, 0, 739, 740, 5, 84, 0, 0, 740, 741, 5, 104, 0, 0, 741, 742, 5, 97, 0, 0, 742, 743, 5, 110, 0, 0, 743, 744, 5, 34, 0, 0, 744, 88, 1, 0, 0, 0, 745, 746, 5, 34, 0, 0, 746, 747, 5, 78, 0, 0, 747, 748, 5, 117, 0, 0, 748, 749, 5, 109, 0, 0, 749, 750, 5, 101, 0, 0, 750, 751, 5, 114, 0, 0, 751, 752, 5, 105, 0, 0, 752, 753, 5, 99, 0, 0, 753, 754, 5, 76, 0, 0, 754, 755, 5, 101, 0, 0, 755, 756, 5, 115, 0, 0, 756, 757, 5, 115, 0, 0, 757, 758, 5, 84, 0, 0, 758, 759, 5, 104, 0, 0, 759, 760, 5, 97, 0, 0, 760, 761, 5, 110, 0, 0, 761, 762, 5, 80, 0, 0, 762, 763, 5, 97, 0, 0, 763, 764, 5, 116, 0, 0, 764, 765, 5, 104, 0, 0, 765, 766, 5, 34, 0, 0, 766, 90, 1, 0, 0, 0, 767, 768, 5, 34, 0, 0, 768, 769, 5, 78, 0, 0, 769, 770, 5, 117, 0, 0, 770, 771, 5, 109, 0, 0, 771, 772, 5, 101, 0, 0, 772, 773, 5, 114, 0, 0, 773, 774, 5, 105, 0, 0, 774, 775, 5, 99, 0, 0, 775, 776, 5, 76, 0, 0, 776, 777, 5, 101, 0, 0, 777, 778, 5, 115, 0, 0, 778, 779, 5, 115, 0, 0, 779, 780, 5, 84, 0, 0, 780, 781, 5, 104, 0, 0, 781, 782, 5, 97, 0, 0, 782, 783, 5, 110, 0, 0, 783, 784, 5, 69, 0, 0, 784, 785, 5, 113, 0, 0, 785, 786, 5, 117, 0, 0, 786, 787, 5, 97, 0, 0, 787, 788, 5, 108, 0, 0, 788, 789, 5, 115, 0, 0, 789, 790, 5, 34, 0, 0, 790, 92, 1, 0, 0, 0, 791, 792, 5, 34, 0, 0, 792, 793, 5, 78, 0, 0, 793, 794, 5, 117, 0, 0, 794, 795, 5, 109, 0, 0, 795, 796, 5, 101, 0, 0, 796, 797, 5, 114, 0, 0, 797, 798, 5, 105, 0, 0, 798, 799, 5, 99, 0, 0, 799, 800, 5, 76, 0, 0, 800, 801, 5, 101, 0, 0, 801, 802, 5, 115, 0, 0, 802, 803, 5, 115, 0, 0, 803, 804, 5, 84, 0, 0, 804, 805, 5, 104, 0, 0, 805, 806, 5, 97, 0, 0, 806, 807, 5, 110, 0, 0, 807, 808, 5, 69, 0, 0, 808, 809, 5, 113, 0, 0, 809, 810, 5, 117, 0, 0, 810, 811, 5, 97, 0, 0, 811, 812, 5, 108, 0, 0, 812, 813, 5, 115, 0, 0, 813, 814, 5, 80, 0, 0, 814, 815, 5, 97, 0, 0, 815, 816, 5, 116, 0, 0, 816, 817, 5, 104, 0, 0, 817, 818, 5, 34, 0, 0, 818, 94, 1, 0, 0, 0, 819, 820, 5, 34, 0, 0, 820, 821, 5, 79, 0, 0, 821, 822, 5, 114, 0, 0, 822, 823, 5, 34, 0, 0, 823, 96, 1, 0, 0, 0, 824, 825, 5, 34, 0, 0, 825, 826, 5, 83, 0, 0, 826, 827, 5, 116, 0, 0, 827, 828, 5, 114, 0, 0, 828, 829, 5, 105, 0, 0, 829, 830, 5, 110, 0, 0, 830, 831, 5, 103, 0, 0, 831, 832, 5, 69, 0, 0, 832, 833, 5, 113, 0, 0, 833, 834, 5, 117, 0, 0, 834, 835, 5, 97, 0, 0, 835, 836, 5, 108, 0, 0, 836, 837, 5, 115, 0, 0, 837, 838, 5, 34, 0, 0, 838, 98, 1, 0, 0, 0, 839, 840, 5, 34, 0, 0, 840, 841, 5, 83, 0, 0, 841, 842, 5, 116, 0, 0, 842, 843, 5, 114, 0, 0, 843, 844, 5, 105, 0, 0, 844, 845, 5, 110, 0, 0, 845, 846, 5, 103, 0, 0, 846, 847, 5, 69, 0, 0, 847, 848, 5, 113, 0, 0, 848, 849, 5, 117, 0, 0, 849, 850, 5, 97, 0, 0, 850, 851, 5, 108, 0, 0, 851, 852, 5, 115, 0, 0, 852, 853, 5, 80, 0, 0, 853, 854, 5, 97, 0, 0, 854, 855, 5, 116, 0, 0, 855, 856, 5, 104, 0, 0, 856, 857, 5, 34, 0, 0, 857, 100, 1, 0, 0, 0, 858, 859, 5, 34, 0, 0, 859, 860, 5, 83, 0, 0, 860, 861, 5, 116, 0, 0, 861, 862, 5, 114, 0, 0, 862, 863, 5, 105, 0, 0, 863, 864, 5, 110, 0, 0, 864, 865, 5, 103, 0, 0, 865, 866, 5, 71, 0, 0, 866, 867, 5, 114, 0, 0, 867, 868, 5, 101, 0, 0, 868, 869, 5, 97, 0, 0, 869, 870, 5, 116, 0, 0, 870, 871, 5, 101, 0, 0, 871, 872, 5, 114, 0, 0, 872, 873, 5, 84, 0, 0, 873, 874, 5, 104, 0, 0, 874, 875, 5, 97, 0, 0, 875, 876, 5, 110, 0, 0, 876, 877, 5, 34, 0, 0, 877, 102, 1, 0, 0, 0, 878, 879, 5, 34, 0, 0, 879, 880, 5, 83, 0, 0, 880, 881, 5, 116, 0, 0, 881, 882, 5, 114, 0, 0, 882, 883, 5, 105, 0, 0, 883, 884, 5, 110, 0, 0, 884, 885, 5, 103, 0, 0, 885, 886, 5, 71, 0, 0, 886, 887, 5, 114, 0, 0, 887, 888, 5, 101, 0, 0, 888, 889, 5, 97, 0, 0, 889, 890, 5, 116, 0, 0, 890, 891, 5, 101, 0, 0, 891, 892, 5, 114, 0, 0, 892, 893, 5, 84, 0, 0, 893, 894, 5, 104, 0, 0, 894, 895, 5, 97, 0, 0, 895, 896, 5, 110, 0, 0, 896, 897, 5, 80, 0, 0, 897, 898, 5, 97, 0, 0, 898, 899, 5, 116, 0, 0, 899, 900, 5, 104, 0, 0, 900, 901, 5, 34, 0, 0, 901, 104, 1, 0, 0, 0, 902, 903, 5, 34, 0, 0, 903, 904, 5, 83, 0, 0, 904, 905, 5, 116, 0, 0, 905, 906, 5, 114, 0, 0, 906, 907, 5, 105, 0, 0, 907, 908, 5, 110, 0, 0, 908, 909, 5, 103, 0, 0, 909, 910, 5, 71, 0, 0, 910, 911, 5, 114, 0, 0, 911, 912, 5, 101, 0, 0, 912, 913, 5, 97, 0, 0, 913, 914, 5, 116, 0, 0, 914, 915, 5, 101, 0, 0, 915, 916, 5, 114, 0, 0, 916, 917, 5, 84, 0, 0, 917, 918, 5, 104, 0, 0, 918, 919, 5, 97, 0, 0, 919, 920, 5, 110, 0, 0, 920, 921, 5, 69, 0, 0, 921, 922, 5, 113, 0, 0, 922, 923, 5, 117, 0, 0, 923, 924, 5, 97, 0, 0, 924, 925, 5, 108, 0, 0, 925, 926, 5, 115, 0, 0, 926, 927, 5, 34, 0, 0, 927, 106, 1, 0, 0, 0, 928, 929, 5, 34, 0, 0, 929, 930, 5, 83, 0, 0, 930, 931, 5, 116, 0, 0, 931, 932, 5, 114, 0, 0, 932, 933, 5, 105, 0, 0, 933, 934, 5, 110, 0, 0, 934, 935, 5, 103, 0, 0, 935, 936, 5, 71, 0, 0, 936, 937, 5, 114, 0, 0, 937, 938, 5, 101, 0, 0, 938, 939, 5, 97, 0, 0, 939, 940, 5, 116, 0, 0, 940, 941, 5, 101, 0, 0, 941, 942, 5, 114, 0, 0, 942, 943, 5, 84, 0, 0, 943, 944, 5, 104, 0, 0, 944, 945, 5, 97, 0, 0, 945, 946, 5, 110, 0, 0, 946, 947, 5, 69, 0, 0, 947, 948, 5, 113, 0, 0, 948, 949, 5, 117, 0, 0, 949, 950, 5, 97, 0, 0, 950, 951, 5, 108, 0, 0, 951, 952, 5, 115, 0, 0, 952, 953, 5, 80, 0, 0, 953, 954, 5, 97, 0, 0, 954, 955, 5, 116, 0, 0, 955, 956, 5, 104, 0, 0, 956, 957, 5, 34, 0, 0, 957, 108, 1, 0, 0, 0, 958, 959, 5, 34, 0, 0, 959, 960, 5, 83, 0, 0, 960, 961, 5, 116, 0, 0, 961, 962, 5, 114, 0, 0, 962, 963, 5, 105, 0, 0, 963, 964, 5, 110, 0, 0, 964, 965, 5, 103, 0, 0, 965, 966, 5, 76, 0, 0, 966, 967, 5, 101, 0, 0, 967, 968, 5, 115, 0, 0, 968, 969, 5, 115, 0, 0, 969, 970, 5, 84, 0, 0, 970, 971, 5, 104, 0, 0, 971, 972, 5, 97, 0, 0, 972, 973, 5, 110, 0, 0, 973, 974, 5, 34, 0, 0, 974, 110, 1, 0, 0, 0, 975, 976, 5, 34, 0, 0, 976, 977, 5, 83, 0, 0, 977, 978, 5, 116, 0, 0, 978, 979, 5, 114, 0, 0, 979, 980, 5, 105, 0, 0, 980, 981, 5, 110, 0, 0, 981, 982, 5, 103, 0, 0, 982, 983, 5, 76, 0, 0, 983, 984, 5, 101, 0, 0, 984, 985, 5, 115, 0, 0, 985, 986, 5, 115, 0, 0, 986, 987, 5, 84, 0, 0, 987, 988, 5, 104, 0, 0, 988, 989, 5, 97, 0, 0, 989, 990, 5, 110, 0, 0, 990, 991, 5, 80, 0, 0, 991, 992, 5, 97, 0, 0, 992, 993, 5, 116, 0, 0, 993, 994, 5, 104, 0, 0, 994, 995, 5, 34, 0, 0, 995, 112, 1, 0, 0, 0, 996, 997, 5, 34, 0, 0, 997, 998, 5, 83, 0, 0, 998, 999, 5, 116, 0, 0, 999, 1000, 5, 114, 0, 0, 1000, 1001, 5, 105, 0, 0, 1001, 1002, 5, 110, 0, 0, 1002, 1003, 5, 103, 0, 0, 1003, 1004, 5, 76, 0, 0, 1004, 1005, 5, 101, 0, 0, 1005, 1006, 5, 115, 0, 0, 1006, 1007, 5, 115, 0, 0, 1007, 1008, 5, 84, 0, 0, 1008, 1009, 5, 104, 0, 0, 1009, 1010, 5, 97, 0, 0, 1010, 1011, 5, 110, 0, 0, 1011, 1012, 5, 69, 0, 0, 1012, 1013, 5, 113, 0, 0, 1013, 1014, 5, 117, 0, 0, 1014, 1015, 5, 97, 0, 0, 1015, 1016, 5, 108, 0, 0, 1016, 1017, 5, 115, 0, 0, 1017, 1018, 5, 34, 0, 0, 1018, 114, 1, 0, 0, 0, 1019, 1020, 5, 34, 0, 0, 1020, 1021, 5, 83, 0, 0, 1021, 1022, 5, 116, 0, 0, 1022, 1023, 5, 114, 0, 0, 1023, 1024, 5, 105, 0, 0, 1024, 1025, 5, 110, 0, 0, 1025, 1026, 5, 103, 0, 0, 1026, 1027, 5, 76, 0, 0, 1027, 1028, 5, 101, 0, 0, 1028, 1029, 5, 115, 0, 0, 1029, 1030, 5, 115, 0, 0, 1030, 1031, 5, 84, 0, 0, 1031, 1032, 5, 104, 0, 0, 1032, 1033, 5, 97, 0, 0, 1033, 1034, 5, 110, 0, 0, 1034, 1035, 5, 69, 0, 0, 1035, 1036, 5, 113, 0, 0, 1036, 1037, 5, 117, 0, 0, 1037, 1038, 5, 97, 0, 0, 1038, 1039, 5, 108, 0, 0, 1039, 1040, 5, 115, 0, 0, 1040, 1041, 5, 80, 0, 0, 1041, 1042, 5, 97, 0, 0, 1042, 1043, 5, 116, 0, 0, 1043, 1044, 5, 104, 0, 0, 1044, 1045, 5, 34, 0, 0, 1045, 116, 1, 0, 0, 0, 1046, 1047, 5, 34, 0, 0, 1047, 1048, 5, 83, 0, 0, 1048, 1049, 5, 116, 0, 0, 1049, 1050, 5, 114, 0, 0, 1050, 1051, 5, 105, 0, 0, 1051, 1052, 5, 110, 0, 0, 1052, 1053, 5, 103, 0, 0, 1053, 1054, 5, 77, 0, 0, 1054, 1055, 5, 97, 0, 0, 1055, 1056, 5, 116, 0, 0, 1056, 1057, 5, 99, 0, 0, 1057, 1058, 5, 104, 0, 0, 1058, 1059, 5, 101, 0, 0, 1059, 1060, 5, 115, 0, 0, 1060, 1061, 5, 34, 0, 0, 1061, 118, 1, 0, 0, 0, 1062, 1063, 5, 34, 0, 0, 1063, 1064, 5, 84, 0, 0, 1064, 1065, 5, 105, 0, 0, 1065, 1066, 5, 109, 0, 0, 1066, 1067, 5, 101, 0, 0, 1067, 1068, 5, 115, 0, 0, 1068, 1069, 5, 116, 0, 0, 1069, 1070, 5, 97, 0, 0, 1070, 1071, 5, 109, 0, 0, 1071, 1072, 5, 112, 0, 0, 1072, 1073, 5, 69, 0, 0, 1073, 1074, 5, 113, 0, 0, 1074, 1075, 5, 117, 0, 0, 1075, 1076, 5, 97, 0, 0, 1076, 1077, 5, 108, 0, 0, 1077, 1078, 5, 115, 0, 0, 1078, 1079, 5, 34, 0, 0, 1079, 120, 1, 0, 0, 0, 1080, 1081, 5, 34, 0, 0, 1081, 1082, 5, 84, 0, 0, 1082, 1083, 5, 105, 0, 0, 1083, 1084, 5, 109, 0, 0, 1084, 1085, 5, 101, 0, 0, 1085, 1086, 5, 115, 0, 0, 1086, 1087, 5, 116, 0, 0, 1087, 1088, 5, 97, 0, 0, 1088, 1089, 5, 109, 0, 0, 1089, 1090, 5, 112, 0, 0, 1090, 1091, 5, 69, 0, 0, 1091, 1092, 5, 113, 0, 0, 1092, 1093, 5, 117, 0, 0, 1093, 1094, 5, 97, 0, 0, 1094, 1095, 5, 108, 0, 0, 1095, 1096, 5, 115, 0, 0, 1096, 1097, 5, 80, 0, 0, 1097, 1098, 5, 97, 0, 0, 1098, 1099, 5, 116, 0, 0, 1099, 1100, 5, 104, 0, 0, 1100, 1101, 5, 34, 0, 0, 1101, 122, 1, 0, 0, 0, 1102, 1103, 5, 34, 0, 0, 1103, 1104, 5, 84, 0, 0, 1104, 1105, 5, 105, 0, 0, 1105, 1106, 5, 109, 0, 0, 1106, 1107, 5, 101, 0, 0, 1107, 1108, 5, 115, 0, 0, 1108, 1109, 5, 116, 0, 0, 1109, 1110, 5, 97, 0, 0, 1110, 1111, 5, 109, 0, 0, 1111, 1112, 5, 112, 0, 0, 1112, 1113, 5, 71, 0, 0, 1113, 1114, 5, 114, 0, 0, 1114, 1115, 5, 101, 0, 0, 1115, 1116, 5, 97, 0, 0, 1116, 1117, 5, 116, 0, 0, 1117, 1118, 5, 101, 0, 0, 1118, 1119, 5, 114, 0, 0, 1119, 1120, 5, 84, 0, 0, 1120, 1121, 5, 104, 0, 0, 1121, 1122, 5, 97, 0, 0, 1122, 1123, 5, 110, 0, 0, 1123, 1124, 5, 34, 0, 0, 1124, 124, 1, 0, 0, 0, 1125, 1126, 5, 34, 0, 0, 1126, 1127, 5, 84, 0, 0, 1127, 1128, 5, 105, 0, 0, 1128, 1129, 5, 109, 0, 0, 1129, 1130, 5, 101, 0, 0, 1130, 1131, 5, 115, 0, 0, 1131, 1132, 5, 116, 0, 0, 1132, 1133, 5, 97, 0, 0, 1133, 1134, 5, 109, 0, 0, 1134, 1135, 5, 112, 0, 0, 1135, 1136, 5, 71, 0, 0, 1136, 1137, 5, 114, 0, 0, 1137, 1138, 5, 101, 0, 0, 1138, 1139, 5, 97, 0, 0, 1139, 1140, 5, 116, 0, 0, 1140, 1141, 5, 101, 0, 0, 1141, 1142, 5, 114, 0, 0, 1142, 1143, 5, 84, 0, 0, 1143, 1144, 5, 104, 0, 0, 1144, 1145, 5, 97, 0, 0, 1145, 1146, 5, 110, 0, 0, 1146, 1147, 5, 80, 0, 0, 1147, 1148, 5, 97, 0, 0, 1148, 1149, 5, 116, 0, 0, 1149, 1150, 5, 104, 0, 0, 1150, 1151, 5, 34, 0, 0, 1151, 126, 1, 0, 0, 0, 1152, 1153, 5, 34, 0, 0, 1153, 1154, 5, 84, 0, 0, 1154, 1155, 5, 105, 0, 0, 1155, 1156, 5, 109, 0, 0, 1156, 1157, 5, 101, 0, 0, 1157, 1158, 5, 115, 0, 0, 1158, 1159, 5, 116, 0, 0, 1159, 1160, 5, 97, 0, 0, 1160, 1161, 5, 109, 0, 0, 1161, 1162, 5, 112, 0, 0, 1162, 1163, 5, 71, 0, 0, 1163, 1164, 5, 114, 0, 0, 1164, 1165, 5, 101, 0, 0, 1165, 1166, 5, 97, 0, 0, 1166, 1167, 5, 116, 0, 0, 1167, 1168, 5, 101, 0, 0, 1168, 1169, 5, 114, 0, 0, 1169, 1170, 5, 84, 0, 0, 1170, 1171, 5, 104, 0, 0, 1171, 1172, 5, 97, 0, 0, 1172, 1173, 5, 110, 0, 0, 1173, 1174, 5, 69, 0, 0, 1174, 1175, 5, 113, 0, 0, 1175, 1176, 5, 117, 0, 0, 1176, 1177, 5, 97, 0, 0, 1177, 1178, 5, 108, 0, 0, 1178, 1179, 5, 115, 0, 0, 1179, 1180, 5, 34, 0, 0, 1180, 128, 1, 0, 0, 0, 1181, 1182, 5, 34, 0, 0, 1182, 1183, 5, 84, 0, 0, 1183, 1184, 5, 105, 0, 0, 1184, 1185, 5, 109, 0, 0, 1185, 1186, 5, 101, 0, 0, 1186, 1187, 5, 115, 0, 0, 1187, 1188, 5, 116, 0, 0, 1188, 1189, 5, 97, 0, 0, 1189, 1190, 5, 109, 0, 0, 1190, 1191, 5, 112, 0, 0, 1191, 1192, 5, 71, 0, 0, 1192, 1193, 5, 114, 0, 0, 1193, 1194, 5, 101, 0, 0, 1194, 1195, 5, 97, 0, 0, 1195, 1196, 5, 116, 0, 0, 1196, 1197, 5, 101, 0, 0, 1197, 1198, 5, 114, 0, 0, 1198, 1199, 5, 84, 0, 0, 1199, 1200, 5, 104, 0, 0, 1200, 1201, 5, 97, 0, 0, 1201, 1202, 5, 110, 0, 0, 1202, 1203, 5, 69, 0, 0, 1203, 1204, 5, 113, 0, 0, 1204, 1205, 5, 117, 0, 0, 1205, 1206, 5, 97, 0, 0, 1206, 1207, 5, 108, 0, 0, 1207, 1208, 5, 115, 0, 0, 1208, 1209, 5, 80, 0, 0, 1209, 1210, 5, 97, 0, 0, 1210, 1211, 5, 116, 0, 0, 1211, 1212, 5, 104, 0, 0, 1212, 1213, 5, 34, 0, 0, 1213, 130, 1, 0, 0, 0, 1214, 1215, 5, 34, 0, 0, 1215, 1216, 5, 84, 0, 0, 1216, 1217, 5, 105, 0, 0, 1217, 1218, 5, 109, 0, 0, 1218, 1219, 5, 101, 0, 0, 1219, 1220, 5, 115, 0, 0, 1220, 1221, 5, 116, 0, 0, 1221, 1222, 5, 97, 0, 0, 1222, 1223, 5, 109, 0, 0, 1223, 1224, 5, 112, 0, 0, 1224, 1225, 5, 76, 0, 0, 1225, 1226, 5, 101, 0, 0, 1226, 1227, 5, 115, 0, 0, 1227, 1228, 5, 115, 0, 0, 1228, 1229, 5, 84, 0, 0, 1229, 1230, 5, 104, 0, 0, 1230, 1231, 5, 97, 0, 0, 1231, 1232, 5, 110, 0, 0, 1232, 1233, 5, 34, 0, 0, 1233, 132, 1, 0, 0, 0, 1234, 1235, 5, 34, 0, 0, 1235, 1236, 5, 84, 0, 0, 1236, 1237, 5, 105, 0, 0, 1237, 1238, 5, 109, 0, 0, 1238, 1239, 5, 101, 0, 0, 1239, 1240, 5, 115, 0, 0, 1240, 1241, 5, 116, 0, 0, 1241, 1242, 5, 97, 0, 0, 1242, 1243, 5, 109, 0, 0, 1243, 1244, 5, 112, 0, 0, 1244, 1245, 5, 76, 0, 0, 1245, 1246, 5, 101, 0, 0, 1246, 1247, 5, 115, 0, 0, 1247, 1248, 5, 115, 0, 0, 1248, 1249, 5, 84, 0, 0, 1249, 1250, 5, 104, 0, 0, 1250, 1251, 5, 97, 0, 0, 1251, 1252, 5, 110, 0, 0, 1252, 1253, 5, 80, 0, 0, 1253, 1254, 5, 97, 0, 0, 1254, 1255, 5, 116, 0, 0, 1255, 1256, 5, 104, 0, 0, 1256, 1257, 5, 34, 0, 0, 1257, 134, 1, 0, 0, 0, 1258, 1259, 5, 34, 0, 0, 1259, 1260, 5, 84, 0, 0, 1260, 1261, 5, 105, 0, 0, 1261, 1262, 5, 109, 0, 0, 1262, 1263, 5, 101, 0, 0, 1263, 1264, 5, 115, 0, 0, 1264, 1265, 5, 116, 0, 0, 1265, 1266, 5, 97, 0, 0, 1266, 1267, 5, 109, 0, 0, 1267, 1268, 5, 112, 0, 0, 1268, 1269, 5, 76, 0, 0, 1269, 1270, 5, 101, 0, 0, 1270, 1271, 5, 115, 0, 0, 1271, 1272, 5, 115, 0, 0, 1272, 1273, 5, 84, 0, 0, 1273, 1274, 5, 104, 0, 0, 1274, 1275, 5, 97, 0, 0, 1275, 1276, 5, 110, 0, 0, 1276, 1277, 5, 69, 0, 0, 1277, 1278, 5, 113, 0, 0, 1278, 1279, 5, 117, 0, 0, 1279, 1280, 5, 97, 0, 0, 1280, 1281, 5, 108, 0, 0, 1281, 1282, 5, 115, 0, 0, 1282, 1283, 5, 34, 0, 0, 1283, 136, 1, 0, 0, 0, 1284, 1285, 5, 34, 0, 0, 1285, 1286, 5, 84, 0, 0, 1286, 1287, 5, 105, 0, 0, 1287, 1288, 5, 109, 0, 0, 1288, 1289, 5, 101, 0, 0, 1289, 1290, 5, 115, 0, 0, 1290, 1291, 5, 116, 0, 0, 1291, 1292, 5, 97, 0, 0, 1292, 1293, 5, 109, 0, 0, 1293, 1294, 5, 112, 0, 0, 1294, 1295, 5, 76, 0, 0, 1295, 1296, 5, 101, 0, 0, 1296, 1297, 5, 115, 0, 0, 1297, 1298, 5, 115, 0, 0, 1298, 1299, 5, 84, 0, 0, 1299, 1300, 5, 104, 0, 0, 1300, 1301, 5, 97, 0, 0, 1301, 1302, 5, 110, 0, 0, 1302, 1303, 5, 69, 0, 0, 1303, 1304, 5, 113, 0, 0, 1304, 1305, 5, 117, 0, 0, 1305, 1306, 5, 97, 0, 0, 1306, 1307, 5, 108, 0, 0, 1307, 1308, 5, 115, 0, 0, 1308, 1309, 5, 80, 0, 0, 1309, 1310, 5, 97, 0, 0, 1310, 1311, 5, 116, 0, 0, 1311, 1312, 5, 104, 0, 0, 1312, 1313, 5, 34, 0, 0, 1313, 138, 1, 0, 0, 0, 1314, 1315, 5, 34, 0, 0, 1315, 1316, 5, 83, 0, 0, 1316, 1317, 5, 101, 0, 0, 1317, 1318, 5, 99, 0, 0, 1318, 1319, 5, 111, 0, 0, 1319, 1320, 5, 110, 0, 0, 1320, 1321, 5, 100, 0, 0, 1321, 1322, 5, 115, 0, 0, 1322, 1323, 5, 80, 0, 0, 1323, 1324, 5, 97, 0, 0, 1324, 1325, 5, 116, 0, 0, 1325, 1326, 5, 104, 0, 0, 1326, 1327, 5, 34, 0, 0, 1327, 140, 1, 0, 0, 0, 1328, 1329, 5, 34, 0, 0, 1329, 1330, 5, 83, 0, 0, 1330, 1331, 5, 101, 0, 0, 1331, 1332, 5, 99, 0, 0, 1332, 1333, 5, 111, 0, 0, 1333, 1334, 5, 110, 0, 0, 1334, 1335, 5, 100, 0, 0, 1335, 1336, 5, 115, 0, 0, 1336, 1337, 5, 34, 0, 0, 1337, 142, 1, 0, 0, 0, 1338, 1339, 5, 34, 0, 0, 1339, 1340, 5, 84, 0, 0, 1340, 1341, 5, 105, 0, 0, 1341, 1342, 5, 109, 0, 0, 1342, 1343, 5, 101, 0, 0, 1343, 1344, 5, 115, 0, 0, 1344, 1345, 5, 116, 0, 0, 1345, 1346, 5, 97, 0, 0, 1346, 1347, 5, 109, 0, 0, 1347, 1348, 5, 112, 0, 0, 1348, 1349, 5, 80, 0, 0, 1349, 1350, 5, 97, 0, 0, 1350, 1351, 5, 116, 0, 0, 1351, 1352, 5, 104, 0, 0, 1352, 1353, 5, 34, 0, 0, 1353, 144, 1, 0, 0, 0, 1354, 1355, 5, 34, 0, 0, 1355, 1356, 5, 84, 0, 0, 1356, 1357, 5, 105, 0, 0, 1357, 1358, 5, 109, 0, 0, 1358, 1359, 5, 101, 0, 0, 1359, 1360, 5, 115, 0, 0, 1360, 1361, 5, 116, 0, 0, 1361, 1362, 5, 97, 0, 0, 1362, 1363, 5, 109, 0, 0, 1363, 1364, 5, 112, 0, 0, 1364, 1365, 5, 34, 0, 0, 1365, 146, 1, 0, 0, 0, 1366, 1367, 5, 34, 0, 0, 1367, 1368, 5, 84, 0, 0, 1368, 1369, 5, 105, 0, 0, 1369, 1370, 5, 109, 0, 0, 1370, 1371, 5, 101, 0, 0, 1371, 1372, 5, 111, 0, 0, 1372, 1373, 5, 117, 0, 0, 1373, 1374, 5, 116, 0, 0, 1374, 1375, 5, 83, 0, 0, 1375, 1376, 5, 101, 0, 0, 1376, 1377, 5, 99, 0, 0, 1377, 1378, 5, 111, 0, 0, 1378, 1379, 5, 110, 0, 0, 1379, 1380, 5, 100, 0, 0, 1380, 1381, 5, 115, 0, 0, 1381, 1382, 5, 34, 0, 0, 1382, 148, 1, 0, 0, 0, 1383, 1384, 5, 34, 0, 0, 1384, 1385, 5, 84, 0, 0, 1385, 1386, 5, 105, 0, 0, 1386, 1387, 5, 109, 0, 0, 1387, 1388, 5, 101, 0, 0, 1388, 1389, 5, 111, 0, 0, 1389, 1390, 5, 117, 0, 0, 1390, 1391, 5, 116, 0, 0, 1391, 1392, 5, 83, 0, 0, 1392, 1393, 5, 101, 0, 0, 1393, 1394, 5, 99, 0, 0, 1394, 1395, 5, 111, 0, 0, 1395, 1396, 5, 110, 0, 0, 1396, 1397, 5, 100, 0, 0, 1397, 1398, 5, 115, 0, 0, 1398, 1399, 5, 80, 0, 0, 1399, 1400, 5, 97, 0, 0, 1400, 1401, 5, 116, 0, 0, 1401, 1402, 5, 104, 0, 0, 1402, 1403, 5, 34, 0, 0, 1403, 150, 1, 0, 0, 0, 1404, 1405, 5, 34, 0, 0, 1405, 1406, 5, 72, 0, 0, 1406, 1407, 5, 101, 0, 0, 1407, 1408, 5, 97, 0, 0, 1408, 1409, 5, 114, 0, 0, 1409, 1410, 5, 116, 0, 0, 1410, 1411, 5, 98, 0, 0, 1411, 1412, 5, 101, 0, 0, 1412, 1413, 5, 97, 0, 0, 1413, 1414, 5, 116, 0, 0, 1414, 1415, 5, 83, 0, 0, 1415, 1416, 5, 101, 0, 0, 1416, 1417, 5, 99, 0, 0, 1417, 1418, 5, 111, 0, 0, 1418, 1419, 5, 110, 0, 0, 1419, 1420, 5, 100, 0, 0, 1420, 1421, 5, 115, 0, 0, 1421, 1422, 5, 34, 0, 0, 1422, 152, 1, 0, 0, 0, 1423, 1424, 5, 34, 0, 0, 1424, 1425, 5, 72, 0, 0, 1425, 1426, 5, 101, 0, 0, 1426, 1427, 5, 97, 0, 0, 1427, 1428, 5, 114, 0, 0, 1428, 1429, 5, 116, 0, 0, 1429, 1430, 5, 98, 0, 0, 1430, 1431, 5, 101, 0, 0, 1431, 1432, 5, 97, 0, 0, 1432, 1433, 5, 116, 0, 0, 1433, 1434, 5, 83, 0, 0, 1434, 1435, 5, 101, 0, 0, 1435, 1436, 5, 99, 0, 0, 1436, 1437, 5, 111, 0, 0, 1437, 1438, 5, 110, 0, 0, 1438, 1439, 5, 100, 0, 0, 1439, 1440, 5, 115, 0, 0, 1440, 1441, 5, 80, 0, 0, 1441, 1442, 5, 97, 0, 0, 1442, 1443, 5, 116, 0, 0, 1443, 1444, 5, 104, 0, 0, 1444, 1445, 5, 34, 0, 0, 1445, 154, 1, 0, 0, 0, 1446, 1447, 5, 34, 0, 0, 1447, 1448, 5, 80, 0, 0, 1448, 1449, 5, 114, 0, 0, 1449, 1450, 5, 111, 0, 0, 1450, 1451, 5, 99, 0, 0, 1451, 1452, 5, 101, 0, 0, 1452, 1453, 5, 115, 0, 0, 1453, 1454, 5, 115, 0, 0, 1454, 1455, 5, 111, 0, 0, 1455, 1456, 5, 114, 0, 0, 1456, 1457, 5, 67, 0, 0, 1457, 1458, 5, 111, 0, 0, 1458, 1459, 5, 110, 0, 0, 1459, 1460, 5, 102, 0, 0, 1460, 1461, 5, 105, 0, 0, 1461, 1462, 5, 103, 0, 0, 1462, 1463, 5, 34, 0, 0, 1463, 156, 1, 0, 0, 0, 1464, 1465, 5, 34, 0, 0, 1465, 1466, 5, 77, 0, 0, 1466, 1467, 5, 111, 0, 0, 1467, 1468, 5, 100, 0, 0, 1468, 1469, 5, 101, 0, 0, 1469, 1470, 5, 34, 0, 0, 1470, 158, 1, 0, 0, 0, 1471, 1472, 5, 34, 0, 0, 1472, 1473, 5, 73, 0, 0, 1473, 1474, 5, 78, 0, 0, 1474, 1475, 5, 76, 0, 0, 1475, 1476, 5, 73, 0, 0, 1476, 1477, 5, 78, 0, 0, 1477, 1478, 5, 69, 0, 0, 1478, 1479, 5, 34, 0, 0, 1479, 160, 1, 0, 0, 0, 1480, 1481, 5, 34, 0, 0, 1481, 1482, 5, 68, 0, 0, 1482, 1483, 5, 73, 0, 0, 1483, 1484, 5, 83, 0, 0, 1484, 1485, 5, 84, 0, 0, 1485, 1486, 5, 82, 0, 0, 1486, 1487, 5, 73, 0, 0, 1487, 1488, 5, 66, 0, 0, 1488, 1489, 5, 85, 0, 0, 1489, 1490, 5, 84, 0, 0, 1490, 1491, 5, 69, 0, 0, 1491, 1492, 5, 68, 0, 0, 1492, 1493, 5, 34, 0, 0, 1493, 162, 1, 0, 0, 0, 1494, 1495, 5, 34, 0, 0, 1495, 1496, 5, 69, 0, 0, 1496, 1497, 5, 120, 0, 0, 1497, 1498, 5, 101, 0, 0, 1498, 1499, 5, 99, 0, 0, 1499, 1500, 5, 117, 0, 0, 1500, 1501, 5, 116, 0, 0, 1501, 1502, 5, 105, 0, 0, 1502, 1503, 5, 111, 0, 0, 1503, 1504, 5, 110, 0, 0, 1504, 1505, 5, 84, 0, 0, 1505, 1506, 5, 121, 0, 0, 1506, 1507, 5, 112, 0, 0, 1507, 1508, 5, 101, 0, 0, 1508, 1509, 5, 34, 0, 0, 1509, 164, 1, 0, 0, 0, 1510, 1511, 5, 34, 0, 0, 1511, 1512, 5, 83, 0, 0, 1512, 1513, 5, 84, 0, 0, 1513, 1514, 5, 65, 0, 0, 1514, 1515, 5, 78, 0, 0, 1515, 1516, 5, 68, 0, 0, 1516, 1517, 5, 65, 0, 0, 1517, 1518, 5, 82, 0, 0, 1518, 1519, 5, 68, 0, 0, 1519, 1520, 5, 34, 0, 0, 1520, 166, 1, 0, 0, 0, 1521, 1522, 5, 34, 0, 0, 1522, 1523, 5, 73, 0, 0, 1523, 1524, 5, 116, 0, 0, 1524, 1525, 5, 101, 0, 0, 1525, 1526, 5, 109, 0, 0, 1526, 1527, 5, 80, 0, 0, 1527, 1528, 5, 114, 0, 0, 1528, 1529, 5, 111, 0, 0, 1529, 1530, 5, 99, 0, 0, 1530, 1531, 5, 101, 0, 0, 1531, 1532, 5, 115, 0, 0, 1532, 1533, 5, 115, 0, 0, 1533, 1534, 5, 111, 0, 0, 1534, 1535, 5, 114, 0, 0, 1535, 1536, 5, 34, 0, 0, 1536, 168, 1, 0, 0, 0, 1537, 1538, 5, 34, 0, 0, 1538, 1539, 5, 73, 0, 0, 1539, 1540, 5, 116, 0, 0, 1540, 1541, 5, 101, 0, 0, 1541, 1542, 5, 114, 0, 0, 1542, 1543, 5, 97, 0, 0, 1543, 1544, 5, 116, 0, 0, 1544, 1545, 5, 111, 0, 0, 1545, 1546, 5, 114, 0, 0, 1546, 1547, 5, 34, 0, 0, 1547, 170, 1, 0, 0, 0, 1548, 1549, 5, 34, 0, 0, 1549, 1550, 5, 73, 0, 0, 1550, 1551, 5, 116, 0, 0, 1551, 1552, 5, 101, 0, 0, 1552, 1553, 5, 109, 0, 0, 1553, 1554, 5, 83, 0, 0, 1554, 1555, 5, 101, 0, 0, 1555, 1556, 5, 108, 0, 0, 1556, 1557, 5, 101, 0, 0, 1557, 1558, 5, 99, 0, 0, 1558, 1559, 5, 116, 0, 0, 1559, 1560, 5, 111, 0, 0, 1560, 1561, 5, 114, 0, 0, 1561, 1562, 5, 34, 0, 0, 1562, 172, 1, 0, 0, 0, 1563, 1564, 5, 34, 0, 0, 1564, 1565, 5, 77, 0, 0, 1565, 1566, 5, 97, 0, 0, 1566, 1567, 5, 120, 0, 0, 1567, 1568, 5, 67, 0, 0, 1568, 1569, 5, 111, 0, 0, 1569, 1570, 5, 110, 0, 0, 1570, 1571, 5, 99, 0, 0, 1571, 1572, 5, 117, 0, 0, 1572, 1573, 5, 114, 0, 0, 1573, 1574, 5, 114, 0, 0, 1574, 1575, 5, 101, 0, 0, 1575, 1576, 5, 110, 0, 0, 1576, 1577, 5, 99, 0, 0, 1577, 1578, 5, 121, 0, 0, 1578, 1579, 5, 34, 0, 0, 1579, 174, 1, 0, 0, 0, 1580, 1581, 5, 34, 0, 0, 1581, 1582, 5, 82, 0, 0, 1582, 1583, 5, 101, 0, 0, 1583, 1584, 5, 115, 0, 0, 1584, 1585, 5, 111, 0, 0, 1585, 1586, 5, 117, 0, 0, 1586, 1587, 5, 114, 0, 0, 1587, 1588, 5, 99, 0, 0, 1588, 1589, 5, 101, 0, 0, 1589, 1590, 5, 34, 0, 0, 1590, 176, 1, 0, 0, 0, 1591, 1592, 5, 34, 0, 0, 1592, 1593, 5, 73, 0, 0, 1593, 1594, 5, 110, 0, 0, 1594, 1595, 5, 112, 0, 0, 1595, 1596, 5, 117, 0, 0, 1596, 1597, 5, 116, 0, 0, 1597, 1598, 5, 80, 0, 0, 1598, 1599, 5, 97, 0, 0, 1599, 1600, 5, 116, 0, 0, 1600, 1601, 5, 104, 0, 0, 1601, 1602, 5, 34, 0, 0, 1602, 178, 1, 0, 0, 0, 1603, 1604, 5, 34, 0, 0, 1604, 1605, 5, 79, 0, 0, 1605, 1606, 5, 117, 0, 0, 1606, 1607, 5, 116, 0, 0, 1607, 1608, 5, 112, 0, 0, 1608, 1609, 5, 117, 0, 0, 1609, 1610, 5, 116, 0, 0, 1610, 1611, 5, 80, 0, 0, 1611, 1612, 5, 97, 0, 0, 1612, 1613, 5, 116, 0, 0, 1613, 1614, 5, 104, 0, 0, 1614, 1615, 5, 34, 0, 0, 1615, 180, 1, 0, 0, 0, 1616, 1617, 5, 34, 0, 0, 1617, 1618, 5, 73, 0, 0, 1618, 1619, 5, 116, 0, 0, 1619, 1620, 5, 101, 0, 0, 1620, 1621, 5, 109, 0, 0, 1621, 1622, 5, 115, 0, 0, 1622, 1623, 5, 80, 0, 0, 1623, 1624, 5, 97, 0, 0, 1624, 1625, 5, 116, 0, 0, 1625, 1626, 5, 104, 0, 0, 1626, 1627, 5, 34, 0, 0, 1627, 182, 1, 0, 0, 0, 1628, 1629, 5, 34, 0, 0, 1629, 1630, 5, 82, 0, 0, 1630, 1631, 5, 101, 0, 0, 1631, 1632, 5, 115, 0, 0, 1632, 1633, 5, 117, 0, 0, 1633, 1634, 5, 108, 0, 0, 1634, 1635, 5, 116, 0, 0, 1635, 1636, 5, 80, 0, 0, 1636, 1637, 5, 97, 0, 0, 1637, 1638, 5, 116, 0, 0, 1638, 1639, 5, 104, 0, 0, 1639, 1640, 5, 34, 0, 0, 1640, 184, 1, 0, 0, 0, 1641, 1642, 5, 34, 0, 0, 1642, 1643, 5, 82, 0, 0, 1643, 1644, 5, 101, 0, 0, 1644, 1645, 5, 115, 0, 0, 1645, 1646, 5, 117, 0, 0, 1646, 1647, 5, 108, 0, 0, 1647, 1648, 5, 116, 0, 0, 1648, 1649, 5, 34, 0, 0, 1649, 186, 1, 0, 0, 0, 1650, 1651, 5, 34, 0, 0, 1651, 1652, 5, 80, 0, 0, 1652, 1653, 5, 97, 0, 0, 1653, 1654, 5, 114, 0, 0, 1654, 1655, 5, 97, 0, 0, 1655, 1656, 5, 109, 0, 0, 1656, 1657, 5, 101, 0, 0, 1657, 1658, 5, 116, 0, 0, 1658, 1659, 5, 101, 0, 0, 1659, 1660, 5, 114, 0, 0, 1660, 1661, 5, 115, 0, 0, 1661, 1662, 5, 34, 0, 0, 1662, 188, 1, 0, 0, 0, 1663, 1664, 5, 34, 0, 0, 1664, 1665, 5, 82, 0, 0, 1665, 1666, 5, 101, 0, 0, 1666, 1667, 5, 115, 0, 0, 1667, 1668, 5, 117, 0, 0, 1668, 1669, 5, 108, 0, 0, 1669, 1670, 5, 116, 0, 0, 1670, 1671, 5, 83, 0, 0, 1671, 1672, 5, 101, 0, 0, 1672, 1673, 5, 108, 0, 0, 1673, 1674, 5, 101, 0, 0, 1674, 1675, 5, 99, 0, 0, 1675, 1676, 5, 116, 0, 0, 1676, 1677, 5, 111, 0, 0, 1677, 1678, 5, 114, 0, 0, 1678, 1679, 5, 34, 0, 0, 1679, 190, 1, 0, 0, 0, 1680, 1681, 5, 34, 0, 0, 1681, 1682, 5, 73, 0, 0, 1682, 1683, 5, 116, 0, 0, 1683, 1684, 5, 101, 0, 0, 1684, 1685, 5, 109, 0, 0, 1685, 1686, 5, 82, 0, 0, 1686, 1687, 5, 101, 0, 0, 1687, 1688, 5, 97, 0, 0, 1688, 1689, 5, 100, 0, 0, 1689, 1690, 5, 101, 0, 0, 1690, 1691, 5, 114, 0, 0, 1691, 1692, 5, 34, 0, 0, 1692, 192, 1, 0, 0, 0, 1693, 1694, 5, 34, 0, 0, 1694, 1695, 5, 82, 0, 0, 1695, 1696, 5, 101, 0, 0, 1696, 1697, 5, 97, 0, 0, 1697, 1698, 5, 100, 0, 0, 1698, 1699, 5, 101, 0, 0, 1699, 1700, 5, 114, 0, 0, 1700, 1701, 5, 67, 0, 0, 1701, 1702, 5, 111, 0, 0, 1702, 1703, 5, 110, 0, 0, 1703, 1704, 5, 102, 0, 0, 1704, 1705, 5, 105, 0, 0, 1705, 1706, 5, 103, 0, 0, 1706, 1707, 5, 34, 0, 0, 1707, 194, 1, 0, 0, 0, 1708, 1709, 5, 34, 0, 0, 1709, 1710, 5, 73, 0, 0, 1710, 1711, 5, 110, 0, 0, 1711, 1712, 5, 112, 0, 0, 1712, 1713, 5, 117, 0, 0, 1713, 1714, 5, 116, 0, 0, 1714, 1715, 5, 84, 0, 0, 1715, 1716, 5, 121, 0, 0, 1716, 1717, 5, 112, 0, 0, 1717, 1718, 5, 101, 0, 0, 1718, 1719, 5, 34, 0, 0, 1719, 196, 1, 0, 0, 0, 1720, 1721, 5, 34, 0, 0, 1721, 1722, 5, 67, 0, 0, 1722, 1723, 5, 83, 0, 0, 1723, 1724, 5, 86, 0, 0, 1724, 1725, 5, 72, 0, 0, 1725, 1726, 5, 101, 0, 0, 1726, 1727, 5, 97, 0, 0, 1727, 1728, 5, 100, 0, 0, 1728, 1729, 5, 101, 0, 0, 1729, 1730, 5, 114, 0, 0, 1730, 1731, 5, 76, 0, 0, 1731, 1732, 5, 111, 0, 0, 1732, 1733, 5, 99, 0, 0, 1733, 1734, 5, 97, 0, 0, 1734, 1735, 5, 116, 0, 0, 1735, 1736, 5, 105, 0, 0, 1736, 1737, 5, 111, 0, 0, 1737, 1738, 5, 110, 0, 0, 1738, 1739, 5, 34, 0, 0, 1739, 198, 1, 0, 0, 0, 1740, 1741, 5, 34, 0, 0, 1741, 1742, 5, 67, 0, 0, 1742, 1743, 5, 83, 0, 0, 1743, 1744, 5, 86, 0, 0, 1744, 1745, 5, 72, 0, 0, 1745, 1746, 5, 101, 0, 0, 1746, 1747, 5, 97, 0, 0, 1747, 1748, 5, 100, 0, 0, 1748, 1749, 5, 101, 0, 0, 1749, 1750, 5, 114, 0, 0, 1750, 1751, 5, 115, 0, 0, 1751, 1752, 5, 34, 0, 0, 1752, 200, 1, 0, 0, 0, 1753, 1754, 5, 34, 0, 0, 1754, 1755, 5, 77, 0, 0, 1755, 1756, 5, 97, 0, 0, 1756, 1757, 5, 120, 0, 0, 1757, 1758, 5, 73, 0, 0, 1758, 1759, 5, 116, 0, 0, 1759, 1760, 5, 101, 0, 0, 1760, 1761, 5, 109, 0, 0, 1761, 1762, 5, 115, 0, 0, 1762, 1763, 5, 34, 0, 0, 1763, 202, 1, 0, 0, 0, 1764, 1765, 5, 34, 0, 0, 1765, 1766, 5, 77, 0, 0, 1766, 1767, 5, 97, 0, 0, 1767, 1768, 5, 120, 0, 0, 1768, 1769, 5, 73, 0, 0, 1769, 1770, 5, 116, 0, 0, 1770, 1771, 5, 101, 0, 0, 1771, 1772, 5, 109, 0, 0, 1772, 1773, 5, 115, 0, 0, 1773, 1774, 5, 80, 0, 0, 1774, 1775, 5, 97, 0, 0, 1775, 1776, 5, 116, 0, 0, 1776, 1777, 5, 104, 0, 0, 1777, 1778, 5, 34, 0, 0, 1778, 204, 1, 0, 0, 0, 1779, 1780, 5, 34, 0, 0, 1780, 1781, 5, 78, 0, 0, 1781, 1782, 5, 101, 0, 0, 1782, 1783, 5, 120, 0, 0, 1783, 1784, 5, 116, 0, 0, 1784, 1785, 5, 34, 0, 0, 1785, 206, 1, 0, 0, 0, 1786, 1787, 5, 34, 0, 0, 1787, 1788, 5, 69, 0, 0, 1788, 1789, 5, 110, 0, 0, 1789, 1790, 5, 100, 0, 0, 1790, 1791, 5, 34, 0, 0, 1791, 208, 1, 0, 0, 0, 1792, 1793, 5, 34, 0, 0, 1793, 1794, 5, 67, 0, 0, 1794, 1795, 5, 97, 0, 0, 1795, 1796, 5, 117, 0, 0, 1796, 1797, 5, 115, 0, 0, 1797, 1798, 5, 101, 0, 0, 1798, 1799, 5, 34, 0, 0, 1799, 210, 1, 0, 0, 0, 1800, 1801, 5, 34, 0, 0, 1801, 1802, 5, 69, 0, 0, 1802, 1803, 5, 114, 0, 0, 1803, 1804, 5, 114, 0, 0, 1804, 1805, 5, 111, 0, 0, 1805, 1806, 5, 114, 0, 0, 1806, 1807, 5, 34, 0, 0, 1807, 212, 1, 0, 0, 0, 1808, 1809, 5, 34, 0, 0, 1809, 1810, 5, 82, 0, 0, 1810, 1811, 5, 101, 0, 0, 1811, 1812, 5, 116, 0, 0, 1812, 1813, 5, 114, 0, 0, 1813, 1814, 5, 121, 0, 0, 1814, 1815, 5, 34, 0, 0, 1815, 214, 1, 0, 0, 0, 1816, 1817, 5, 34, 0, 0, 1817, 1818, 5, 69, 0, 0, 1818, 1819, 5, 114, 0, 0, 1819, 1820, 5, 114, 0, 0, 1820, 1821, 5, 111, 0, 0, 1821, 1822, 5, 114, 0, 0, 1822, 1823, 5, 69, 0, 0, 1823, 1824, 5, 113, 0, 0, 1824, 1825, 5, 117, 0, 0, 1825, 1826, 5, 97, 0, 0, 1826, 1827, 5, 108, 0, 0, 1827, 1828, 5, 115, 0, 0, 1828, 1829, 5, 34, 0, 0, 1829, 216, 1, 0, 0, 0, 1830, 1831, 5, 34, 0, 0, 1831, 1832, 5, 73, 0, 0, 1832, 1833, 5, 110, 0, 0, 1833, 1834, 5, 116, 0, 0, 1834, 1835, 5, 101, 0, 0, 1835, 1836, 5, 114, 0, 0, 1836, 1837, 5, 118, 0, 0, 1837, 1838, 5, 97, 0, 0, 1838, 1839, 5, 108, 0, 0, 1839, 1840, 5, 83, 0, 0, 1840, 1841, 5, 101, 0, 0, 1841, 1842, 5, 99, 0, 0, 1842, 1843, 5, 111, 0, 0, 1843, 1844, 5, 110, 0, 0, 1844, 1845, 5, 100, 0, 0, 1845, 1846, 5, 115, 0, 0, 1846, 1847, 5, 34, 0, 0, 1847, 218, 1, 0, 0, 0, 1848, 1849, 5, 34, 0, 0, 1849, 1850, 5, 77, 0, 0, 1850, 1851, 5, 97, 0, 0, 1851, 1852, 5, 120, 0, 0, 1852, 1853, 5, 65, 0, 0, 1853, 1854, 5, 116, 0, 0, 1854, 1855, 5, 116, 0, 0, 1855, 1856, 5, 101, 0, 0, 1856, 1857, 5, 109, 0, 0, 1857, 1858, 5, 112, 0, 0, 1858, 1859, 5, 116, 0, 0, 1859, 1860, 5, 115, 0, 0, 1860, 1861, 5, 34, 0, 0, 1861, 220, 1, 0, 0, 0, 1862, 1863, 5, 34, 0, 0, 1863, 1864, 5, 66, 0, 0, 1864, 1865, 5, 97, 0, 0, 1865, 1866, 5, 99, 0, 0, 1866, 1867, 5, 107, 0, 0, 1867, 1868, 5, 111, 0, 0, 1868, 1869, 5, 102, 0, 0, 1869, 1870, 5, 102, 0, 0, 1870, 1871, 5, 82, 0, 0, 1871, 1872, 5, 97, 0, 0, 1872, 1873, 5, 116, 0, 0, 1873, 1874, 5, 101, 0, 0, 1874, 1875, 5, 34, 0, 0, 1875, 222, 1, 0, 0, 0, 1876, 1877, 5, 34, 0, 0, 1877, 1878, 5, 67, 0, 0, 1878, 1879, 5, 97, 0, 0, 1879, 1880, 5, 116, 0, 0, 1880, 1881, 5, 99, 0, 0, 1881, 1882, 5, 104, 0, 0, 1882, 1883, 5, 34, 0, 0, 1883, 224, 1, 0, 0, 0, 1884, 1885, 5, 34, 0, 0, 1885, 1886, 5, 83, 0, 0, 1886, 1887, 5, 116, 0, 0, 1887, 1888, 5, 97, 0, 0, 1888, 1889, 5, 116, 0, 0, 1889, 1890, 5, 101, 0, 0, 1890, 1891, 5, 115, 0, 0, 1891, 1892, 5, 46, 0, 0, 1892, 1893, 5, 65, 0, 0, 1893, 1894, 5, 76, 0, 0, 1894, 1895, 5, 76, 0, 0, 1895, 1896, 5, 34, 0, 0, 1896, 226, 1, 0, 0, 0, 1897, 1898, 5, 34, 0, 0, 1898, 1899, 5, 83, 0, 0, 1899, 1900, 5, 116, 0, 0, 1900, 1901, 5, 97, 0, 0, 1901, 1902, 5, 116, 0, 0, 1902, 1903, 5, 101, 0, 0, 1903, 1904, 5, 115, 0, 0, 1904, 1905, 5, 46, 0, 0, 1905, 1906, 5, 72, 0, 0, 1906, 1907, 5, 101, 0, 0, 1907, 1908, 5, 97, 0, 0, 1908, 1909, 5, 114, 0, 0, 1909, 1910, 5, 116, 0, 0, 1910, 1911, 5, 98, 0, 0, 1911, 1912, 5, 101, 0, 0, 1912, 1913, 5, 97, 0, 0, 1913, 1914, 5, 116, 0, 0, 1914, 1915, 5, 84, 0, 0, 1915, 1916, 5, 105, 0, 0, 1916, 1917, 5, 109, 0, 0, 1917, 1918, 5, 101, 0, 0, 1918, 1919, 5, 111, 0, 0, 1919, 1920, 5, 117, 0, 0, 1920, 1921, 5, 116, 0, 0, 1921, 1922, 5, 34, 0, 0, 1922, 228, 1, 0, 0, 0, 1923, 1924, 5, 34, 0, 0, 1924, 1925, 5, 83, 0, 0, 1925, 1926, 5, 116, 0, 0, 1926, 1927, 5, 97, 0, 0, 1927, 1928, 5, 116, 0, 0, 1928, 1929, 5, 101, 0, 0, 1929, 1930, 5, 115, 0, 0, 1930, 1931, 5, 46, 0, 0, 1931, 1932, 5, 84, 0, 0, 1932, 1933, 5, 105, 0, 0, 1933, 1934, 5, 109, 0, 0, 1934, 1935, 5, 101, 0, 0, 1935, 1936, 5, 111, 0, 0, 1936, 1937, 5, 117, 0, 0, 1937, 1938, 5, 116, 0, 0, 1938, 1939, 5, 34, 0, 0, 1939, 230, 1, 0, 0, 0, 1940, 1941, 5, 34, 0, 0, 1941, 1942, 5, 83, 0, 0, 1942, 1943, 5, 116, 0, 0, 1943, 1944, 5, 97, 0, 0, 1944, 1945, 5, 116, 0, 0, 1945, 1946, 5, 101, 0, 0, 1946, 1947, 5, 115, 0, 0, 1947, 1948, 5, 46, 0, 0, 1948, 1949, 5, 84, 0, 0, 1949, 1950, 5, 97, 0, 0, 1950, 1951, 5, 115, 0, 0, 1951, 1952, 5, 107, 0, 0, 1952, 1953, 5, 70, 0, 0, 1953, 1954, 5, 97, 0, 0, 1954, 1955, 5, 105, 0, 0, 1955, 1956, 5, 108, 0, 0, 1956, 1957, 5, 101, 0, 0, 1957, 1958, 5, 100, 0, 0, 1958, 1959, 5, 34, 0, 0, 1959, 232, 1, 0, 0, 0, 1960, 1961, 5, 34, 0, 0, 1961, 1962, 5, 83, 0, 0, 1962, 1963, 5, 116, 0, 0, 1963, 1964, 5, 97, 0, 0, 1964, 1965, 5, 116, 0, 0, 1965, 1966, 5, 101, 0, 0, 1966, 1967, 5, 115, 0, 0, 1967, 1968, 5, 46, 0, 0, 1968, 1969, 5, 80, 0, 0, 1969, 1970, 5, 101, 0, 0, 1970, 1971, 5, 114, 0, 0, 1971, 1972, 5, 109, 0, 0, 1972, 1973, 5, 105, 0, 0, 1973, 1974, 5, 115, 0, 0, 1974, 1975, 5, 115, 0, 0, 1975, 1976, 5, 105, 0, 0, 1976, 1977, 5, 111, 0, 0, 1977, 1978, 5, 110, 0, 0, 1978, 1979, 5, 115, 0, 0, 1979, 1980, 5, 34, 0, 0, 1980, 234, 1, 0, 0, 0, 1981, 1982, 5, 34, 0, 0, 1982, 1983, 5, 83, 0, 0, 1983, 1984, 5, 116, 0, 0, 1984, 1985, 5, 97, 0, 0, 1985, 1986, 5, 116, 0, 0, 1986, 1987, 5, 101, 0, 0, 1987, 1988, 5, 115, 0, 0, 1988, 1989, 5, 46, 0, 0, 1989, 1990, 5, 82, 0, 0, 1990, 1991, 5, 101, 0, 0, 1991, 1992, 5, 115, 0, 0, 1992, 1993, 5, 117, 0, 0, 1993, 1994, 5, 108, 0, 0, 1994, 1995, 5, 116, 0, 0, 1995, 1996, 5, 80, 0, 0, 1996, 1997, 5, 97, 0, 0, 1997, 1998, 5, 116, 0, 0, 1998, 1999, 5, 104, 0, 0, 1999, 2000, 5, 77, 0, 0, 2000, 2001, 5, 97, 0, 0, 2001, 2002, 5, 116, 0, 0, 2002, 2003, 5, 99, 0, 0, 2003, 2004, 5, 104, 0, 0, 2004, 2005, 5, 70, 0, 0, 2005, 2006, 5, 97, 0, 0, 2006, 2007, 5, 105, 0, 0, 2007, 2008, 5, 108, 0, 0, 2008, 2009, 5, 117, 0, 0, 2009, 2010, 5, 114, 0, 0, 2010, 2011, 5, 101, 0, 0, 2011, 2012, 5, 34, 0, 0, 2012, 236, 1, 0, 0, 0, 2013, 2014, 5, 34, 0, 0, 2014, 2015, 5, 83, 0, 0, 2015, 2016, 5, 116, 0, 0, 2016, 2017, 5, 97, 0, 0, 2017, 2018, 5, 116, 0, 0, 2018, 2019, 5, 101, 0, 0, 2019, 2020, 5, 115, 0, 0, 2020, 2021, 5, 46, 0, 0, 2021, 2022, 5, 80, 0, 0, 2022, 2023, 5, 97, 0, 0, 2023, 2024, 5, 114, 0, 0, 2024, 2025, 5, 97, 0, 0, 2025, 2026, 5, 109, 0, 0, 2026, 2027, 5, 101, 0, 0, 2027, 2028, 5, 116, 0, 0, 2028, 2029, 5, 101, 0, 0, 2029, 2030, 5, 114, 0, 0, 2030, 2031, 5, 80, 0, 0, 2031, 2032, 5, 97, 0, 0, 2032, 2033, 5, 116, 0, 0, 2033, 2034, 5, 104, 0, 0, 2034, 2035, 5, 70, 0, 0, 2035, 2036, 5, 97, 0, 0, 2036, 2037, 5, 105, 0, 0, 2037, 2038, 5, 108, 0, 0, 2038, 2039, 5, 117, 0, 0, 2039, 2040, 5, 114, 0, 0, 2040, 2041, 5, 101, 0, 0, 2041, 2042, 5, 34, 0, 0, 2042, 238, 1, 0, 0, 0, 2043, 2044, 5, 34, 0, 0, 2044, 2045, 5, 83, 0, 0, 2045, 2046, 5, 116, 0, 0, 2046, 2047, 5, 97, 0, 0, 2047, 2048, 5, 116, 0, 0, 2048, 2049, 5, 101, 0, 0, 2049, 2050, 5, 115, 0, 0, 2050, 2051, 5, 46, 0, 0, 2051, 2052, 5, 66, 0, 0, 2052, 2053, 5, 114, 0, 0, 2053, 2054, 5, 97, 0, 0, 2054, 2055, 5, 110, 0, 0, 2055, 2056, 5, 99, 0, 0, 2056, 2057, 5, 104, 0, 0, 2057, 2058, 5, 70, 0, 0, 2058, 2059, 5, 97, 0, 0, 2059, 2060, 5, 105, 0, 0, 2060, 2061, 5, 108, 0, 0, 2061, 2062, 5, 101, 0, 0, 2062, 2063, 5, 100, 0, 0, 2063, 2064, 5, 34, 0, 0, 2064, 240, 1, 0, 0, 0, 2065, 2066, 5, 34, 0, 0, 2066, 2067, 5, 83, 0, 0, 2067, 2068, 5, 116, 0, 0, 2068, 2069, 5, 97, 0, 0, 2069, 2070, 5, 116, 0, 0, 2070, 2071, 5, 101, 0, 0, 2071, 2072, 5, 115, 0, 0, 2072, 2073, 5, 46, 0, 0, 2073, 2074, 5, 78, 0, 0, 2074, 2075, 5, 111, 0, 0, 2075, 2076, 5, 67, 0, 0, 2076, 2077, 5, 104, 0, 0, 2077, 2078, 5, 111, 0, 0, 2078, 2079, 5, 105, 0, 0, 2079, 2080, 5, 99, 0, 0, 2080, 2081, 5, 101, 0, 0, 2081, 2082, 5, 77, 0, 0, 2082, 2083, 5, 97, 0, 0, 2083, 2084, 5, 116, 0, 0, 2084, 2085, 5, 99, 0, 0, 2085, 2086, 5, 104, 0, 0, 2086, 2087, 5, 101, 0, 0, 2087, 2088, 5, 100, 0, 0, 2088, 2089, 5, 34, 0, 0, 2089, 242, 1, 0, 0, 0, 2090, 2091, 5, 34, 0, 0, 2091, 2092, 5, 83, 0, 0, 2092, 2093, 5, 116, 0, 0, 2093, 2094, 5, 97, 0, 0, 2094, 2095, 5, 116, 0, 0, 2095, 2096, 5, 101, 0, 0, 2096, 2097, 5, 115, 0, 0, 2097, 2098, 5, 46, 0, 0, 2098, 2099, 5, 73, 0, 0, 2099, 2100, 5, 110, 0, 0, 2100, 2101, 5, 116, 0, 0, 2101, 2102, 5, 114, 0, 0, 2102, 2103, 5, 105, 0, 0, 2103, 2104, 5, 110, 0, 0, 2104, 2105, 5, 115, 0, 0, 2105, 2106, 5, 105, 0, 0, 2106, 2107, 5, 99, 0, 0, 2107, 2108, 5, 70, 0, 0, 2108, 2109, 5, 97, 0, 0, 2109, 2110, 5, 105, 0, 0, 2110, 2111, 5, 108, 0, 0, 2111, 2112, 5, 117, 0, 0, 2112, 2113, 5, 114, 0, 0, 2113, 2114, 5, 101, 0, 0, 2114, 2115, 5, 34, 0, 0, 2115, 244, 1, 0, 0, 0, 2116, 2117, 5, 34, 0, 0, 2117, 2118, 5, 83, 0, 0, 2118, 2119, 5, 116, 0, 0, 2119, 2120, 5, 97, 0, 0, 2120, 2121, 5, 116, 0, 0, 2121, 2122, 5, 101, 0, 0, 2122, 2123, 5, 115, 0, 0, 2123, 2124, 5, 46, 0, 0, 2124, 2125, 5, 69, 0, 0, 2125, 2126, 5, 120, 0, 0, 2126, 2127, 5, 99, 0, 0, 2127, 2128, 5, 101, 0, 0, 2128, 2129, 5, 101, 0, 0, 2129, 2130, 5, 100, 0, 0, 2130, 2131, 5, 84, 0, 0, 2131, 2132, 5, 111, 0, 0, 2132, 2133, 5, 108, 0, 0, 2133, 2134, 5, 101, 0, 0, 2134, 2135, 5, 114, 0, 0, 2135, 2136, 5, 97, 0, 0, 2136, 2137, 5, 116, 0, 0, 2137, 2138, 5, 101, 0, 0, 2138, 2139, 5, 100, 0, 0, 2139, 2140, 5, 70, 0, 0, 2140, 2141, 5, 97, 0, 0, 2141, 2142, 5, 105, 0, 0, 2142, 2143, 5, 108, 0, 0, 2143, 2144, 5, 117, 0, 0, 2144, 2145, 5, 114, 0, 0, 2145, 2146, 5, 101, 0, 0, 2146, 2147, 5, 84, 0, 0, 2147, 2148, 5, 104, 0, 0, 2148, 2149, 5, 114, 0, 0, 2149, 2150, 5, 101, 0, 0, 2150, 2151, 5, 115, 0, 0, 2151, 2152, 5, 104, 0, 0, 2152, 2153, 5, 111, 0, 0, 2153, 2154, 5, 108, 0, 0, 2154, 2155, 5, 100, 0, 0, 2155, 2156, 5, 34, 0, 0, 2156, 246, 1, 0, 0, 0, 2157, 2158, 5, 34, 0, 0, 2158, 2159, 5, 83, 0, 0, 2159, 2160, 5, 116, 0, 0, 2160, 2161, 5, 97, 0, 0, 2161, 2162, 5, 116, 0, 0, 2162, 2163, 5, 101, 0, 0, 2163, 2164, 5, 115, 0, 0, 2164, 2165, 5, 46, 0, 0, 2165, 2166, 5, 73, 0, 0, 2166, 2167, 5, 116, 0, 0, 2167, 2168, 5, 101, 0, 0, 2168, 2169, 5, 109, 0, 0, 2169, 2170, 5, 82, 0, 0, 2170, 2171, 5, 101, 0, 0, 2171, 2172, 5, 97, 0, 0, 2172, 2173, 5, 100, 0, 0, 2173, 2174, 5, 101, 0, 0, 2174, 2175, 5, 114, 0, 0, 2175, 2176, 5, 70, 0, 0, 2176, 2177, 5, 97, 0, 0, 2177, 2178, 5, 105, 0, 0, 2178, 2179, 5, 108, 0, 0, 2179, 2180, 5, 101, 0, 0, 2180, 2181, 5, 100, 0, 0, 2181, 2182, 5, 34, 0, 0, 2182, 248, 1, 0, 0, 0, 2183, 2184, 5, 34, 0, 0, 2184, 2185, 5, 83, 0, 0, 2185, 2186, 5, 116, 0, 0, 2186, 2187, 5, 97, 0, 0, 2187, 2188, 5, 116, 0, 0, 2188, 2189, 5, 101, 0, 0, 2189, 2190, 5, 115, 0, 0, 2190, 2191, 5, 46, 0, 0, 2191, 2192, 5, 82, 0, 0, 2192, 2193, 5, 101, 0, 0, 2193, 2194, 5, 115, 0, 0, 2194, 2195, 5, 117, 0, 0, 2195, 2196, 5, 108, 0, 0, 2196, 2197, 5, 116, 0, 0, 2197, 2198, 5, 87, 0, 0, 2198, 2199, 5, 114, 0, 0, 2199, 2200, 5, 105, 0, 0, 2200, 2201, 5, 116, 0, 0, 2201, 2202, 5, 101, 0, 0, 2202, 2203, 5, 114, 0, 0, 2203, 2204, 5, 70, 0, 0, 2204, 2205, 5, 97, 0, 0, 2205, 2206, 5, 105, 0, 0, 2206, 2207, 5, 108, 0, 0, 2207, 2208, 5, 101, 0, 0, 2208, 2209, 5, 100, 0, 0, 2209, 2210, 5, 34, 0, 0, 2210, 250, 1, 0, 0, 0, 2211, 2212, 5, 34, 0, 0, 2212, 2213, 5, 83, 0, 0, 2213, 2214, 5, 116, 0, 0, 2214, 2215, 5, 97, 0, 0, 2215, 2216, 5, 116, 0, 0, 2216, 2217, 5, 101, 0, 0, 2217, 2218, 5, 115, 0, 0, 2218, 2219, 5, 46, 0, 0, 2219, 2220, 5, 82, 0, 0, 2220, 2221, 5, 117, 0, 0, 2221, 2222, 5, 110, 0, 0, 2222, 2223, 5, 116, 0, 0, 2223, 2224, 5, 105, 0, 0, 2224, 2225, 5, 109, 0, 0, 2225, 2226, 5, 101, 0, 0, 2226, 2227, 5, 34, 0, 0, 2227, 252, 1, 0, 0, 0, 2228, 2233, 5, 34, 0, 0, 2229, 2232, 3, 261, 130, 0, 2230, 2232, 3, 267, 133, 0, 2231, 2229, 1, 0, 0, 0, 2231, 2230, 1, 0, 0, 0, 2232, 2235, 1, 0, 0, 0, 2233, 2231, 1, 0, 0, 0, 2233, 2234, 1, 0, 0, 0, 2234, 2236, 1, 0, 0, 0, 2235, 2233, 1, 0, 0, 0, 2236, 2237, 5, 46, 0, 0, 2237, 2238, 5, 36, 0, 0, 2238, 2239, 5, 34, 0, 0, 2239, 254, 1, 0, 0, 0, 2240, 2241, 5, 34, 0, 0, 2241, 2242, 5, 36, 0, 0, 2242, 2243, 5, 36, 0, 0, 2243, 2248, 1, 0, 0, 0, 2244, 2247, 3, 261, 130, 0, 2245, 2247, 3, 267, 133, 0, 2246, 2244, 1, 0, 0, 0, 2246, 2245, 1, 0, 0, 0, 2247, 2250, 1, 0, 0, 0, 2248, 2246, 1, 0, 0, 0, 2248, 2249, 1, 0, 0, 0, 2249, 2251, 1, 0, 0, 0, 2250, 2248, 1, 0, 0, 0, 2251, 2252, 5, 34, 0, 0, 2252, 256, 1, 0, 0, 0, 2253, 2254, 5, 34, 0, 0, 2254, 2255, 5, 36, 0, 0, 2255, 2260, 1, 0, 0, 0, 2256, 2259, 3, 261, 130, 0, 2257, 2259, 3, 267, 133, 0, 2258, 2256, 1, 0, 0, 0, 2258, 2257, 1, 0, 0, 0, 2259, 2262, 1, 0, 0, 0, 2260, 2258, 1, 0, 0, 0, 2260, 2261, 1, 0, 0, 0, 2261, 2263, 1, 0, 0, 0, 2262, 2260, 1, 0, 0, 0, 2263, 2264, 5, 34, 0, 0, 2264, 258, 1, 0, 0, 0, 2265, 2270, 5, 34, 0, 0, 2266, 2269, 3, 261, 130, 0, 2267, 2269, 3, 267, 133, 0, 2268, 2266, 1, 0, 0, 0, 2268, 2267, 1, 0, 0, 0, 2269, 2272, 1, 0, 0, 0, 2270, 2268, 1, 0, 0, 0, 2270, 2271, 1, 0, 0, 0, 2271, 2273, 1, 0, 0, 0, 2272, 2270, 1, 0, 0, 0, 2273, 2274, 5, 34, 0, 0, 2274, 260, 1, 0, 0, 0, 2275, 2278, 5, 92, 0, 0, 2276, 2279, 7, 0, 0, 0, 2277, 2279, 3, 263, 131, 0, 2278, 2276, 1, 0, 0, 0, 2278, 2277, 1, 0, 0, 0, 2279, 262, 1, 0, 0, 0, 2280, 2281, 5, 117, 0, 0, 2281, 2282, 3, 265, 132, 0, 2282, 2283, 3, 265, 132, 0, 2283, 2284, 3, 265, 132, 0, 2284, 2285, 3, 265, 132, 0, 2285, 264, 1, 0, 0, 0, 2286, 2287, 7, 1, 0, 0, 2287, 266, 1, 0, 0, 0, 2288, 2289, 8, 2, 0, 0, 2289, 268, 1, 0, 0, 0, 2290, 2299, 5, 48, 0, 0, 2291, 2295, 7, 3, 0, 0, 2292, 2294, 7, 4, 0, 0, 2293, 2292, 1, 0, 0, 0, 2294, 2297, 1, 0, 0, 0, 2295, 2293, 1, 0, 0, 0, 2295, 2296, 1, 0, 0, 0, 2296, 2299, 1, 0, 0, 0, 2297, 2295, 1, 0, 0, 0, 2298, 2290, 1, 0, 0, 0, 2298, 2291, 1, 0, 0, 0, 2299, 270, 1, 0, 0, 0, 2300, 2302, 5, 45, 0, 0, 2301, 2300, 1, 0, 0, 0, 2301, 2302, 1, 0, 0, 0, 2302, 2303, 1, 0, 0, 0, 2303, 2310, 3, 269, 134, 0, 2304, 2306, 5, 46, 0, 0, 2305, 2307, 7, 4, 0, 0, 2306, 2305, 1, 0, 0, 0, 2307, 2308, 1, 0, 0, 0, 2308, 2306, 1, 0, 0, 0, 2308, 2309, 1, 0, 0, 0, 2309, 2311, 1, 0, 0, 0, 2310, 2304, 1, 0, 0, 0, 2310, 2311, 1, 0, 0, 0, 2311, 2313, 1, 0, 0, 0, 2312, 2314, 3, 273, 136, 0, 2313, 2312, 1, 0, 0, 0, 2313, 2314, 1, 0, 0, 0, 2314, 272, 1, 0, 0, 0, 2315, 2317, 7, 5, 0, 0, 2316, 2318, 7, 6, 0, 0, 2317, 2316, 1, 0, 0, 0, 2317, 2318, 1, 0, 0, 0, 2318, 2319, 1, 0, 0, 0, 2319, 2320, 3, 269, 134, 0, 2320, 274, 1, 0, 0, 0, 2321, 2323, 7, 7, 0, 0, 2322, 2321, 1, 0, 0, 0, 2323, 2324, 1, 0, 0, 0, 2324, 2322, 1, 0, 0, 0, 2324, 2325, 1, 0, 0, 0, 2325, 2326, 1, 0, 0, 0, 2326, 2327, 6, 137, 0, 0, 2327, 276, 1, 0, 0, 0, 18, 0, 2231, 2233, 2246, 2248, 2258, 2260, 2268, 2270, 2278, 2295, 2298, 2301, 2308, 2310, 2313, 2317, 2324, 1, 6, 0, 0] \ No newline at end of file diff --git a/moto/stepfunctions/parser/asl/antlr/runtime/ASLLexer.py b/moto/stepfunctions/parser/asl/antlr/runtime/ASLLexer.py index 677d16cd5d20..abb4a1267030 100644 --- a/moto/stepfunctions/parser/asl/antlr/runtime/ASLLexer.py +++ b/moto/stepfunctions/parser/asl/antlr/runtime/ASLLexer.py @@ -1,4 +1,4 @@ -# Generated from ASLLexer.g4 by ANTLR 4.13.1 +# Generated from ASLLexer.g4 by ANTLR 4.13.2 import sys from typing import TextIO @@ -15,8 +15,8 @@ def serializedATN(): return [ 4, 0, - 146, - 2597, + 162, + 2863, 6, -1, 2, @@ -623,6 +623,78 @@ def serializedATN(): 150, 7, 150, + 2, + 151, + 7, + 151, + 2, + 152, + 7, + 152, + 2, + 153, + 7, + 153, + 2, + 154, + 7, + 154, + 2, + 155, + 7, + 155, + 2, + 156, + 7, + 156, + 2, + 157, + 7, + 157, + 2, + 158, + 7, + 158, + 2, + 159, + 7, + 159, + 2, + 160, + 7, + 160, + 2, + 161, + 7, + 161, + 2, + 162, + 7, + 162, + 2, + 163, + 7, + 163, + 2, + 164, + 7, + 164, + 2, + 165, + 7, + 165, + 2, + 166, + 7, + 166, + 2, + 167, + 7, + 167, + 2, + 168, + 7, + 168, 1, 0, 1, @@ -966,6 +1038,8 @@ def serializedATN(): 1, 24, 1, + 24, + 1, 25, 1, 25, @@ -986,7 +1060,7 @@ def serializedATN(): 1, 25, 1, - 26, + 25, 1, 26, 1, @@ -1020,25 +1094,15 @@ def serializedATN(): 1, 27, 1, - 28, - 1, - 28, - 1, - 28, - 1, - 28, - 1, - 28, - 1, - 28, + 27, 1, - 28, + 27, 1, - 28, + 27, 1, - 28, + 27, 1, - 28, + 27, 1, 28, 1, @@ -1084,13 +1148,21 @@ def serializedATN(): 1, 29, 1, - 29, + 30, 1, - 29, + 30, 1, - 29, + 30, 1, - 29, + 30, + 1, + 30, + 1, + 30, + 1, + 30, + 1, + 30, 1, 30, 1, @@ -1134,11 +1206,11 @@ def serializedATN(): 1, 31, 1, - 32, + 31, 1, - 32, + 31, 1, - 32, + 31, 1, 32, 1, @@ -1204,11 +1276,7 @@ def serializedATN(): 1, 34, 1, - 35, - 1, - 35, - 1, - 35, + 34, 1, 35, 1, @@ -1244,25 +1312,21 @@ def serializedATN(): 1, 36, 1, - 37, - 1, - 37, - 1, - 37, + 36, 1, - 37, + 36, 1, - 37, + 36, 1, - 37, + 36, 1, - 37, + 36, 1, - 37, + 36, 1, - 37, + 36, 1, - 37, + 36, 1, 37, 1, @@ -1308,16 +1372,6 @@ def serializedATN(): 1, 38, 1, - 38, - 1, - 38, - 1, - 38, - 1, - 38, - 1, - 39, - 1, 39, 1, 39, @@ -1400,18 +1454,6 @@ def serializedATN(): 1, 40, 1, - 40, - 1, - 40, - 1, - 40, - 1, - 40, - 1, - 41, - 1, - 41, - 1, 41, 1, 41, @@ -1516,13 +1558,13 @@ def serializedATN(): 1, 42, 1, - 42, + 43, 1, - 42, + 43, 1, - 42, + 43, 1, - 42, + 43, 1, 43, 1, @@ -1560,17 +1602,23 @@ def serializedATN(): 1, 43, 1, - 44, + 43, 1, - 44, + 43, 1, - 44, + 43, 1, - 44, + 43, 1, - 44, + 43, 1, - 44, + 43, + 1, + 43, + 1, + 43, + 1, + 43, 1, 44, 1, @@ -1604,9 +1652,9 @@ def serializedATN(): 1, 44, 1, - 45, + 44, 1, - 45, + 44, 1, 45, 1, @@ -1700,13 +1748,13 @@ def serializedATN(): 1, 46, 1, - 46, + 47, 1, - 46, + 47, 1, - 46, + 47, 1, - 46, + 47, 1, 47, 1, @@ -1718,43 +1766,53 @@ def serializedATN(): 1, 47, 1, - 48, + 47, 1, - 48, + 47, 1, - 48, + 47, 1, - 48, + 47, 1, - 48, + 47, 1, - 48, + 47, 1, - 48, + 47, 1, - 48, + 47, 1, - 48, + 47, 1, - 48, + 47, 1, - 48, + 47, 1, - 48, + 47, 1, - 48, + 47, 1, - 48, + 47, + 1, + 47, + 1, + 47, + 1, + 47, + 1, + 47, + 1, + 47, 1, 48, 1, - 49, + 48, 1, - 49, + 48, 1, - 49, + 48, 1, - 49, + 48, 1, 49, 1, @@ -1824,8 +1882,6 @@ def serializedATN(): 1, 50, 1, - 50, - 1, 51, 1, 51, @@ -1866,18 +1922,6 @@ def serializedATN(): 1, 51, 1, - 51, - 1, - 51, - 1, - 51, - 1, - 51, - 1, - 52, - 1, - 52, - 1, 52, 1, 52, @@ -1978,13 +2022,13 @@ def serializedATN(): 1, 53, 1, - 53, + 54, 1, - 53, + 54, 1, - 53, + 54, 1, - 53, + 54, 1, 54, 1, @@ -2020,17 +2064,23 @@ def serializedATN(): 1, 54, 1, - 55, + 54, 1, - 55, + 54, 1, - 55, + 54, 1, - 55, + 54, 1, - 55, + 54, 1, - 55, + 54, + 1, + 54, + 1, + 54, + 1, + 54, 1, 55, 1, @@ -2062,9 +2112,9 @@ def serializedATN(): 1, 55, 1, - 56, + 55, 1, - 56, + 55, 1, 56, 1, @@ -2154,13 +2204,13 @@ def serializedATN(): 1, 57, 1, - 57, + 58, 1, - 57, + 58, 1, - 57, + 58, 1, - 57, + 58, 1, 58, 1, @@ -2194,17 +2244,19 @@ def serializedATN(): 1, 58, 1, - 59, + 58, 1, - 59, + 58, 1, - 59, + 58, 1, - 59, + 58, 1, - 59, + 58, 1, - 59, + 58, + 1, + 58, 1, 59, 1, @@ -2230,13 +2282,13 @@ def serializedATN(): 1, 59, 1, - 60, + 59, 1, - 60, + 59, 1, - 60, + 59, 1, - 60, + 59, 1, 60, 1, @@ -2318,16 +2370,6 @@ def serializedATN(): 1, 61, 1, - 61, - 1, - 62, - 1, - 62, - 1, - 62, - 1, - 62, - 1, 62, 1, 62, @@ -2428,10 +2470,6 @@ def serializedATN(): 1, 63, 1, - 63, - 1, - 63, - 1, 64, 1, 64, @@ -2490,13 +2528,13 @@ def serializedATN(): 1, 64, 1, - 64, + 65, 1, - 64, + 65, 1, - 64, + 65, 1, - 64, + 65, 1, 65, 1, @@ -2538,17 +2576,23 @@ def serializedATN(): 1, 65, 1, - 66, + 65, 1, - 66, + 65, 1, - 66, + 65, 1, - 66, + 65, 1, - 66, + 65, 1, - 66, + 65, + 1, + 65, + 1, + 65, + 1, + 65, 1, 66, 1, @@ -2586,9 +2630,9 @@ def serializedATN(): 1, 66, 1, - 67, + 66, 1, - 67, + 66, 1, 67, 1, @@ -2690,13 +2734,13 @@ def serializedATN(): 1, 68, 1, - 68, + 69, 1, - 68, + 69, 1, - 68, + 69, 1, - 68, + 69, 1, 69, 1, @@ -2726,9 +2770,29 @@ def serializedATN(): 1, 69, 1, - 70, + 69, 1, - 70, + 69, + 1, + 69, + 1, + 69, + 1, + 69, + 1, + 69, + 1, + 69, + 1, + 69, + 1, + 69, + 1, + 69, + 1, + 69, + 1, + 69, 1, 70, 1, @@ -2746,17 +2810,17 @@ def serializedATN(): 1, 70, 1, - 71, + 70, 1, - 71, + 70, 1, - 71, + 70, 1, - 71, + 70, 1, - 71, + 70, 1, - 71, + 70, 1, 71, 1, @@ -2802,15 +2866,13 @@ def serializedATN(): 1, 72, 1, - 73, - 1, - 73, + 72, 1, - 73, + 72, 1, - 73, + 72, 1, - 73, + 72, 1, 73, 1, @@ -2870,13 +2932,9 @@ def serializedATN(): 1, 74, 1, - 74, - 1, - 74, - 1, - 74, + 75, 1, - 74, + 75, 1, 75, 1, @@ -2954,13 +3012,15 @@ def serializedATN(): 1, 76, 1, - 76, + 77, 1, - 76, + 77, 1, - 76, + 77, 1, - 76, + 77, + 1, + 77, 1, 77, 1, @@ -3012,33 +3072,41 @@ def serializedATN(): 1, 78, 1, - 79, + 78, 1, - 79, + 78, 1, - 79, + 78, 1, - 79, + 78, 1, - 79, + 78, 1, - 79, + 78, 1, - 79, + 78, + 1, + 78, + 1, + 78, + 1, + 78, + 1, + 78, 1, 79, 1, 79, 1, - 80, + 79, 1, - 80, + 79, 1, - 80, + 79, 1, - 80, + 79, 1, - 80, + 79, 1, 80, 1, @@ -3086,9 +3154,7 @@ def serializedATN(): 1, 81, 1, - 81, - 1, - 81, + 82, 1, 82, 1, @@ -3112,13 +3178,13 @@ def serializedATN(): 1, 82, 1, - 83, + 82, 1, - 83, + 82, 1, - 83, + 82, 1, - 83, + 82, 1, 83, 1, @@ -3142,7 +3208,7 @@ def serializedATN(): 1, 83, 1, - 83, + 84, 1, 84, 1, @@ -3166,13 +3232,13 @@ def serializedATN(): 1, 84, 1, - 85, + 84, 1, - 85, + 84, 1, - 85, + 84, 1, - 85, + 84, 1, 85, 1, @@ -3226,17 +3292,13 @@ def serializedATN(): 1, 86, 1, - 86, - 1, - 86, - 1, - 86, + 87, 1, - 86, + 87, 1, - 86, + 87, 1, - 86, + 87, 1, 87, 1, @@ -3294,9 +3356,17 @@ def serializedATN(): 1, 88, 1, - 89, + 88, 1, - 89, + 88, + 1, + 88, + 1, + 88, + 1, + 88, + 1, + 88, 1, 89, 1, @@ -3318,7 +3388,7 @@ def serializedATN(): 1, 89, 1, - 90, + 89, 1, 90, 1, @@ -3368,9 +3438,7 @@ def serializedATN(): 1, 91, 1, - 92, - 1, - 92, + 91, 1, 92, 1, @@ -3388,11 +3456,11 @@ def serializedATN(): 1, 92, 1, - 92, + 93, 1, - 92, + 93, 1, - 92, + 93, 1, 93, 1, @@ -3456,22 +3524,6 @@ def serializedATN(): 1, 95, 1, - 95, - 1, - 95, - 1, - 95, - 1, - 95, - 1, - 95, - 1, - 95, - 1, - 95, - 1, - 95, - 1, 96, 1, 96, @@ -3526,12 +3578,6 @@ def serializedATN(): 1, 97, 1, - 97, - 1, - 98, - 1, - 98, - 1, 98, 1, 98, @@ -3576,21 +3622,13 @@ def serializedATN(): 1, 99, 1, - 99, - 1, - 99, - 1, - 99, - 1, - 99, - 1, - 99, + 100, 1, - 99, + 100, 1, - 99, + 100, 1, - 99, + 100, 1, 100, 1, @@ -3640,9 +3678,9 @@ def serializedATN(): 1, 101, 1, - 102, + 101, 1, - 102, + 101, 1, 102, 1, @@ -3670,29 +3708,9 @@ def serializedATN(): 1, 102, 1, - 103, - 1, - 103, - 1, - 103, - 1, - 103, - 1, - 103, - 1, - 103, - 1, - 103, - 1, - 103, - 1, - 103, - 1, - 103, - 1, - 103, + 102, 1, - 103, + 102, 1, 103, 1, @@ -3758,54 +3776,6 @@ def serializedATN(): 1, 104, 1, - 104, - 1, - 104, - 1, - 104, - 1, - 104, - 1, - 104, - 1, - 104, - 1, - 104, - 1, - 104, - 1, - 105, - 1, - 105, - 1, - 105, - 1, - 105, - 1, - 105, - 1, - 105, - 1, - 105, - 1, - 105, - 1, - 105, - 1, - 105, - 1, - 105, - 1, - 105, - 1, - 105, - 1, - 105, - 1, - 105, - 1, - 105, - 1, 105, 1, 105, @@ -3854,65 +3824,69 @@ def serializedATN(): 1, 106, 1, - 106, + 107, 1, - 106, + 107, 1, - 106, + 107, 1, - 106, + 107, 1, - 106, + 107, 1, - 106, + 107, 1, - 106, + 107, 1, - 106, + 107, 1, - 106, + 107, 1, - 106, + 107, 1, - 106, + 107, 1, - 106, + 107, 1, - 106, + 107, 1, - 106, + 107, 1, - 106, + 107, 1, - 106, + 108, 1, - 106, + 108, 1, - 106, + 108, 1, - 106, + 108, 1, - 106, + 108, 1, - 106, + 108, 1, - 106, + 108, 1, - 107, + 108, 1, - 107, + 108, 1, - 107, + 108, 1, - 107, + 108, 1, - 107, + 108, 1, - 107, + 108, 1, - 107, + 108, 1, - 107, + 108, + 1, + 108, + 1, + 108, 1, 108, 1, @@ -3940,63 +3914,189 @@ def serializedATN(): 1, 109, 1, - 110, + 109, 1, - 110, + 109, 1, - 110, + 109, 1, - 110, + 109, 1, - 110, + 109, 1, - 110, + 109, 1, - 110, + 109, 1, - 110, + 109, 1, - 111, + 109, 1, - 111, + 109, 1, - 111, + 109, 1, - 111, + 109, 1, - 111, + 109, 1, - 111, + 109, 1, - 111, + 109, 1, - 111, + 109, 1, - 111, + 109, 1, - 111, + 109, 1, - 111, + 109, 1, - 111, + 109, 1, - 112, + 109, 1, - 112, + 109, 1, - 112, + 110, 1, - 112, + 110, 1, - 112, + 110, 1, - 112, + 110, 1, - 112, + 110, 1, - 112, + 110, 1, - 113, + 110, + 1, + 110, + 1, + 110, + 1, + 110, + 1, + 110, + 1, + 110, + 1, + 110, + 1, + 110, + 1, + 110, + 1, + 110, + 1, + 110, + 1, + 110, + 1, + 110, + 1, + 110, + 1, + 110, + 1, + 110, + 1, + 110, + 1, + 110, + 1, + 110, + 1, + 110, + 1, + 110, + 1, + 110, + 1, + 110, + 1, + 111, + 1, + 111, + 1, + 111, + 1, + 111, + 1, + 111, + 1, + 111, + 1, + 111, + 1, + 111, + 1, + 111, + 1, + 111, + 1, + 111, + 1, + 111, + 1, + 111, + 1, + 111, + 1, + 111, + 1, + 111, + 1, + 111, + 1, + 111, + 1, + 111, + 1, + 111, + 1, + 111, + 1, + 111, + 1, + 111, + 1, + 111, + 1, + 111, + 1, + 111, + 1, + 111, + 1, + 111, + 1, + 111, + 1, + 111, + 1, + 111, + 1, + 111, + 1, + 111, + 1, + 112, + 1, + 112, + 1, + 112, + 1, + 112, + 1, + 112, + 1, + 112, + 1, + 112, + 1, + 112, 1, 113, 1, @@ -4020,13 +4120,13 @@ def serializedATN(): 1, 113, 1, - 114, + 113, 1, - 114, + 113, 1, - 114, + 113, 1, - 114, + 113, 1, 114, 1, @@ -4036,21 +4136,11 @@ def serializedATN(): 1, 114, 1, - 115, - 1, - 115, - 1, - 115, - 1, - 115, - 1, - 115, - 1, - 115, + 114, 1, - 115, + 114, 1, - 115, + 114, 1, 115, 1, @@ -4080,30 +4170,6 @@ def serializedATN(): 1, 116, 1, - 116, - 1, - 116, - 1, - 116, - 1, - 116, - 1, - 116, - 1, - 116, - 1, - 116, - 1, - 116, - 1, - 116, - 1, - 116, - 1, - 117, - 1, - 117, - 1, 117, 1, 117, @@ -4144,30 +4210,6 @@ def serializedATN(): 1, 118, 1, - 118, - 1, - 118, - 1, - 118, - 1, - 118, - 1, - 118, - 1, - 118, - 1, - 119, - 1, - 119, - 1, - 119, - 1, - 119, - 1, - 119, - 1, - 119, - 1, 119, 1, 119, @@ -4208,23 +4250,19 @@ def serializedATN(): 1, 120, 1, - 120, - 1, - 120, - 1, - 120, + 121, 1, - 120, + 121, 1, - 120, + 121, 1, - 120, + 121, 1, - 120, + 121, 1, - 120, + 121, 1, - 120, + 121, 1, 121, 1, @@ -4254,6 +4292,40 @@ def serializedATN(): 1, 122, 1, + 122, + 1, + 122, + 1, + 122, + 1, + 122, + 1, + 122, + 1, + 122, + 1, + 122, + 1, + 122, + 1, + 122, + 1, + 122, + 1, + 122, + 1, + 123, + 1, + 123, + 1, + 123, + 1, + 123, + 1, + 123, + 1, + 123, + 1, 123, 1, 123, @@ -4296,7 +4368,7 @@ def serializedATN(): 1, 124, 1, - 125, + 124, 1, 125, 1, @@ -4334,41 +4406,7 @@ def serializedATN(): 1, 125, 1, - 125, - 1, - 125, - 1, - 125, - 1, - 125, - 1, - 125, - 1, - 125, - 1, - 125, - 1, - 125, - 1, - 126, - 1, - 126, - 1, - 126, - 1, - 126, - 1, - 126, - 1, - 126, - 1, - 126, - 1, - 126, - 1, - 126, - 1, - 126, + 126, 1, 126, 1, @@ -4416,52 +4454,6 @@ def serializedATN(): 1, 127, 1, - 127, - 1, - 127, - 1, - 127, - 1, - 127, - 1, - 127, - 1, - 127, - 1, - 127, - 1, - 127, - 1, - 127, - 1, - 127, - 1, - 128, - 1, - 128, - 1, - 128, - 1, - 128, - 1, - 128, - 1, - 128, - 1, - 128, - 1, - 128, - 1, - 128, - 1, - 128, - 1, - 128, - 1, - 128, - 1, - 128, - 1, 128, 1, 128, @@ -4492,64 +4484,6 @@ def serializedATN(): 1, 129, 1, - 129, - 1, - 129, - 1, - 129, - 1, - 129, - 1, - 129, - 1, - 129, - 1, - 129, - 1, - 129, - 1, - 129, - 1, - 129, - 1, - 129, - 1, - 129, - 1, - 129, - 1, - 130, - 1, - 130, - 1, - 130, - 1, - 130, - 1, - 130, - 1, - 130, - 1, - 130, - 1, - 130, - 1, - 130, - 1, - 130, - 1, - 130, - 1, - 130, - 1, - 130, - 1, - 130, - 1, - 130, - 1, - 130, - 1, 130, 1, 130, @@ -4604,68 +4538,6 @@ def serializedATN(): 1, 131, 1, - 131, - 1, - 131, - 1, - 131, - 1, - 131, - 1, - 131, - 1, - 131, - 1, - 131, - 1, - 131, - 1, - 131, - 1, - 131, - 1, - 131, - 1, - 131, - 1, - 131, - 1, - 131, - 1, - 131, - 1, - 131, - 1, - 131, - 1, - 131, - 1, - 131, - 1, - 132, - 1, - 132, - 1, - 132, - 1, - 132, - 1, - 132, - 1, - 132, - 1, - 132, - 1, - 132, - 1, - 132, - 1, - 132, - 1, - 132, - 1, - 132, - 1, 132, 1, 132, @@ -4704,38 +4576,6 @@ def serializedATN(): 1, 133, 1, - 133, - 1, - 133, - 1, - 133, - 1, - 133, - 1, - 133, - 1, - 133, - 1, - 133, - 1, - 133, - 1, - 133, - 1, - 133, - 1, - 133, - 1, - 133, - 1, - 133, - 1, - 133, - 1, - 133, - 1, - 133, - 1, 134, 1, 134, @@ -4754,147 +4594,29 @@ def serializedATN(): 1, 134, 1, - 134, + 135, 1, - 134, + 135, 1, - 134, + 135, 1, - 134, + 135, 1, - 134, + 135, 1, - 134, + 135, 1, - 134, + 135, 1, - 134, + 135, 1, - 134, + 135, 1, - 134, + 135, 1, - 134, + 135, 1, - 134, - 1, - 134, - 1, - 134, - 1, - 134, - 1, - 134, - 1, - 134, - 1, - 135, - 1, - 135, - 1, - 135, - 1, - 135, - 1, - 135, - 1, - 135, - 1, - 135, - 1, - 135, - 1, - 135, - 1, - 135, - 1, - 135, - 1, - 135, - 1, - 135, - 1, - 135, - 1, - 135, - 1, - 135, - 1, - 135, - 1, - 135, - 1, - 135, - 1, - 135, - 1, - 135, - 1, - 135, - 1, - 135, - 1, - 135, - 1, - 135, - 1, - 135, - 1, - 135, - 1, - 135, - 1, - 135, - 1, - 135, - 1, - 135, - 1, - 135, - 1, - 135, - 1, - 135, - 1, - 135, - 1, - 135, - 1, - 135, - 1, - 135, - 1, - 135, - 1, - 135, - 1, - 135, - 1, - 136, - 1, - 136, - 1, - 136, - 1, - 136, - 1, - 136, - 1, - 136, - 1, - 136, - 1, - 136, - 1, - 136, - 1, - 136, - 1, - 136, - 1, - 136, - 1, - 136, + 135, 1, 136, 1, @@ -4976,7 +4698,23 @@ def serializedATN(): 1, 137, 1, - 137, + 138, + 1, + 138, + 1, + 138, + 1, + 138, + 1, + 138, + 1, + 138, + 1, + 138, + 1, + 138, + 1, + 138, 1, 138, 1, @@ -5017,17 +4755,25 @@ def serializedATN(): 139, 1, 139, - 5, + 1, 139, - 2501, - 8, + 1, 139, - 10, + 1, 139, - 12, + 1, 139, - 2504, - 9, + 1, + 139, + 1, + 139, + 1, + 139, + 1, + 139, + 1, + 139, + 1, 139, 1, 139, @@ -5049,17 +4795,29 @@ def serializedATN(): 140, 1, 140, - 5, + 1, 140, - 2516, - 8, + 1, 140, - 10, + 1, 140, - 12, + 1, 140, - 2519, - 9, + 1, + 140, + 1, + 140, + 1, + 140, + 1, + 140, + 1, + 140, + 1, + 140, + 1, + 140, + 1, 140, 1, 140, @@ -5075,17 +4833,33 @@ def serializedATN(): 141, 1, 141, - 5, + 1, 141, - 2528, - 8, + 1, 141, - 10, + 1, 141, - 12, + 1, 141, - 2531, - 9, + 1, + 141, + 1, + 141, + 1, + 141, + 1, + 141, + 1, + 141, + 1, + 141, + 1, + 141, + 1, + 141, + 1, + 141, + 1, 141, 1, 141, @@ -5097,16178 +4871,18642 @@ def serializedATN(): 142, 1, 142, - 5, + 1, 142, - 2538, - 8, + 1, 142, - 10, + 1, 142, - 12, + 1, 142, - 2541, - 9, + 1, 142, 1, 142, 1, 142, 1, - 143, + 142, 1, - 143, + 142, 1, - 143, - 3, - 143, - 2548, - 8, - 143, + 142, 1, - 144, + 142, 1, - 144, + 142, 1, - 144, + 142, 1, - 144, + 142, 1, - 144, + 142, 1, - 144, + 142, 1, - 145, + 142, 1, - 145, + 142, 1, - 146, + 142, 1, - 146, + 142, + 1, + 142, + 1, + 142, + 1, + 142, + 1, + 142, + 1, + 142, + 1, + 142, + 1, + 142, + 1, + 142, + 1, + 142, + 1, + 143, + 1, + 143, + 1, + 143, + 1, + 143, + 1, + 143, + 1, + 143, + 1, + 143, + 1, + 143, + 1, + 143, + 1, + 143, + 1, + 143, + 1, + 143, + 1, + 143, + 1, + 143, + 1, + 143, + 1, + 143, + 1, + 143, + 1, + 143, + 1, + 143, + 1, + 143, + 1, + 143, + 1, + 143, + 1, + 143, + 1, + 143, + 1, + 143, + 1, + 143, + 1, + 143, + 1, + 143, + 1, + 143, + 1, + 143, + 1, + 144, + 1, + 144, + 1, + 144, + 1, + 144, + 1, + 144, + 1, + 144, + 1, + 144, + 1, + 144, + 1, + 144, + 1, + 144, + 1, + 144, + 1, + 144, + 1, + 144, + 1, + 144, + 1, + 144, + 1, + 144, + 1, + 144, + 1, + 144, + 1, + 144, + 1, + 144, + 1, + 144, + 1, + 144, + 1, + 145, + 1, + 145, + 1, + 145, + 1, + 145, + 1, + 145, + 1, + 145, + 1, + 145, + 1, + 145, + 1, + 145, + 1, + 145, + 1, + 145, + 1, + 145, + 1, + 145, + 1, + 145, + 1, + 145, + 1, + 145, + 1, + 145, + 1, + 145, + 1, + 145, + 1, + 145, + 1, + 145, + 1, + 145, + 1, + 145, + 1, + 145, + 1, + 145, + 1, + 146, + 1, + 146, + 1, + 146, + 1, + 146, + 1, + 146, + 1, + 146, + 1, + 146, + 1, + 146, + 1, + 146, + 1, + 146, + 1, + 146, + 1, + 146, + 1, + 146, + 1, + 146, + 1, + 146, + 1, + 146, + 1, + 146, + 1, + 146, + 1, + 146, + 1, + 146, + 1, + 146, + 1, + 146, + 1, + 146, + 1, + 146, + 1, + 146, + 1, + 146, 1, 147, 1, 147, 1, 147, - 5, + 1, 147, - 2563, - 8, + 1, 147, - 10, + 1, 147, - 12, + 1, 147, - 2566, - 9, + 1, 147, - 3, + 1, 147, - 2568, - 8, + 1, 147, 1, - 148, - 3, - 148, - 2571, - 8, - 148, + 147, 1, - 148, + 147, 1, - 148, + 147, + 1, + 147, + 1, + 147, + 1, + 147, + 1, + 147, + 1, + 147, + 1, + 147, + 1, + 147, + 1, + 147, + 1, + 147, + 1, + 147, + 1, + 147, + 1, + 147, + 1, + 147, + 1, + 147, + 1, + 147, + 1, + 147, + 1, + 147, + 1, + 147, + 1, + 147, + 1, + 147, + 1, + 147, + 1, + 147, + 1, + 147, + 1, + 147, + 1, + 147, + 1, + 147, + 1, + 147, + 1, + 147, + 1, + 148, + 1, + 148, + 1, + 148, + 1, + 148, + 1, + 148, + 1, + 148, + 1, + 148, + 1, + 148, + 1, + 148, + 1, + 148, + 1, + 148, + 1, + 148, + 1, + 148, + 1, + 148, + 1, + 148, + 1, + 148, + 1, + 148, + 1, + 148, + 1, + 148, + 1, + 148, + 1, + 148, + 1, + 148, + 1, + 148, + 1, + 148, + 1, + 148, + 1, + 148, + 1, + 149, + 1, + 149, + 1, + 149, + 1, + 149, + 1, + 149, + 1, + 149, + 1, + 149, + 1, + 149, + 1, + 149, + 1, + 149, + 1, + 149, + 1, + 149, + 1, + 149, + 1, + 149, + 1, + 149, + 1, + 149, + 1, + 149, + 1, + 149, + 1, + 149, + 1, + 149, + 1, + 149, + 1, + 149, + 1, + 149, + 1, + 149, + 1, + 149, + 1, + 149, + 1, + 149, + 1, + 149, + 1, + 150, + 1, + 150, + 1, + 150, + 1, + 150, + 1, + 150, + 1, + 150, + 1, + 150, + 1, + 150, + 1, + 150, + 1, + 150, + 1, + 150, + 1, + 150, + 1, + 150, + 1, + 150, + 1, + 150, + 1, + 150, + 1, + 150, + 1, + 150, + 1, + 150, + 1, + 150, + 1, + 150, + 1, + 150, + 1, + 150, + 1, + 150, + 1, + 150, + 1, + 150, + 1, + 150, + 1, + 150, + 1, + 150, + 1, + 150, + 1, + 151, + 1, + 151, + 1, + 151, + 1, + 151, + 1, + 151, + 1, + 151, + 1, + 151, + 1, + 151, + 1, + 151, + 1, + 151, + 1, + 151, + 1, + 151, + 1, + 151, + 1, + 151, + 1, + 151, + 1, + 151, + 1, + 151, + 1, + 152, + 1, + 152, + 1, + 152, + 5, + 152, + 2705, + 8, + 152, + 10, + 152, + 12, + 152, + 2708, + 9, + 152, + 1, + 152, + 1, + 152, + 1, + 152, + 1, + 152, + 1, + 153, + 1, + 153, + 1, + 153, + 1, + 153, + 1, + 153, + 1, + 153, + 5, + 153, + 2720, + 8, + 153, + 10, + 153, + 12, + 153, + 2723, + 9, + 153, + 1, + 153, + 1, + 153, + 1, + 154, + 1, + 154, + 1, + 154, + 1, + 154, + 1, + 154, + 1, + 154, + 1, + 154, + 1, + 154, + 1, + 154, + 5, + 154, + 2736, + 8, + 154, + 10, + 154, + 12, + 154, + 2739, + 9, + 154, + 1, + 154, + 3, + 154, + 2742, + 8, + 154, + 1, + 155, + 1, + 155, + 1, + 155, + 1, + 155, + 1, + 155, + 1, + 155, + 5, + 155, + 2750, + 8, + 155, + 10, + 155, + 12, + 155, + 2753, + 9, + 155, + 1, + 155, + 1, + 155, + 1, + 156, + 1, + 156, + 1, + 156, + 1, + 156, + 1, + 156, + 1, + 156, + 1, + 156, + 1, + 156, + 1, + 156, + 1, + 156, + 1, + 156, + 4, + 156, + 2768, + 8, + 156, + 11, + 156, + 12, + 156, + 2769, + 1, + 156, + 1, + 156, + 1, + 156, + 5, + 156, + 2775, + 8, + 156, + 10, + 156, + 12, + 156, + 2778, + 9, + 156, + 1, + 156, + 1, + 156, + 1, + 156, + 1, + 157, + 1, + 157, + 1, + 157, + 5, + 157, + 2786, + 8, + 157, + 10, + 157, + 12, + 157, + 2789, + 9, + 157, + 1, + 157, + 1, + 157, + 1, + 158, + 1, + 158, + 1, + 158, + 5, + 158, + 2796, + 8, + 158, + 10, + 158, + 12, + 158, + 2799, + 9, + 158, + 1, + 158, + 1, + 158, + 1, + 159, + 1, + 159, + 1, + 159, + 3, + 159, + 2806, + 8, + 159, + 1, + 160, + 1, + 160, + 1, + 160, + 1, + 160, + 1, + 160, + 1, + 160, + 1, + 161, + 1, + 161, + 1, + 162, + 1, + 162, + 1, + 163, + 1, + 163, + 1, + 163, + 1, + 163, + 1, + 164, + 1, + 164, + 1, + 164, + 1, + 164, + 1, + 165, + 1, + 165, + 1, + 165, + 5, + 165, + 2829, + 8, + 165, + 10, + 165, + 12, + 165, + 2832, + 9, + 165, + 3, + 165, + 2834, + 8, + 165, + 1, + 166, + 3, + 166, + 2837, + 8, + 166, + 1, + 166, + 1, + 166, + 1, + 166, + 4, + 166, + 2842, + 8, + 166, + 11, + 166, + 12, + 166, + 2843, + 3, + 166, + 2846, + 8, + 166, + 1, + 166, + 3, + 166, + 2849, + 8, + 166, + 1, + 167, + 1, + 167, + 3, + 167, + 2853, + 8, + 167, + 1, + 167, + 1, + 167, + 1, + 168, + 4, + 168, + 2858, + 8, + 168, + 11, + 168, + 12, + 168, + 2859, + 1, + 168, + 1, + 168, + 0, + 0, + 169, + 1, + 1, + 3, + 2, + 5, + 3, + 7, + 4, + 9, + 5, + 11, + 6, + 13, + 7, + 15, + 8, + 17, + 9, + 19, + 10, + 21, + 11, + 23, + 12, + 25, + 13, + 27, + 14, + 29, + 15, + 31, + 16, + 33, + 17, + 35, + 18, + 37, + 19, + 39, + 20, + 41, + 21, + 43, + 22, + 45, + 23, + 47, + 24, + 49, + 25, + 51, + 26, + 53, + 27, + 55, + 28, + 57, + 29, + 59, + 30, + 61, + 31, + 63, + 32, + 65, + 33, + 67, + 34, + 69, + 35, + 71, + 36, + 73, + 37, + 75, + 38, + 77, + 39, + 79, + 40, + 81, + 41, + 83, + 42, + 85, + 43, + 87, + 44, + 89, + 45, + 91, + 46, + 93, + 47, + 95, + 48, + 97, + 49, + 99, + 50, + 101, + 51, + 103, + 52, + 105, + 53, + 107, + 54, + 109, + 55, + 111, + 56, + 113, + 57, + 115, + 58, + 117, + 59, + 119, + 60, + 121, + 61, + 123, + 62, + 125, + 63, + 127, + 64, + 129, + 65, + 131, + 66, + 133, + 67, + 135, + 68, + 137, + 69, + 139, + 70, + 141, + 71, + 143, + 72, + 145, + 73, + 147, + 74, + 149, + 75, + 151, + 76, + 153, + 77, + 155, + 78, + 157, + 79, + 159, + 80, + 161, + 81, + 163, + 82, + 165, + 83, + 167, + 84, + 169, + 85, + 171, + 86, + 173, + 87, + 175, + 88, + 177, + 89, + 179, + 90, + 181, + 91, + 183, + 92, + 185, + 93, + 187, + 94, + 189, + 95, + 191, + 96, + 193, + 97, + 195, + 98, + 197, + 99, + 199, + 100, + 201, + 101, + 203, + 102, + 205, + 103, + 207, + 104, + 209, + 105, + 211, + 106, + 213, + 107, + 215, + 108, + 217, + 109, + 219, + 110, + 221, + 111, + 223, + 112, + 225, + 113, + 227, + 114, + 229, + 115, + 231, + 116, + 233, + 117, + 235, + 118, + 237, + 119, + 239, + 120, + 241, + 121, + 243, + 122, + 245, + 123, + 247, + 124, + 249, + 125, + 251, + 126, + 253, + 127, + 255, + 128, + 257, + 129, + 259, + 130, + 261, + 131, + 263, + 132, + 265, + 133, + 267, + 134, + 269, + 135, + 271, + 136, + 273, + 137, + 275, + 138, + 277, + 139, + 279, + 140, + 281, + 141, + 283, + 142, + 285, + 143, + 287, + 144, + 289, + 145, + 291, + 146, + 293, + 147, + 295, + 148, + 297, + 149, + 299, + 150, + 301, + 151, + 303, + 152, + 305, + 153, + 307, + 154, + 309, + 155, + 311, + 156, + 313, + 157, + 315, + 158, + 317, + 159, + 319, + 0, + 321, + 0, + 323, + 0, + 325, + 0, + 327, + 0, + 329, + 0, + 331, + 160, + 333, + 161, + 335, + 0, + 337, + 162, 1, - 148, - 4, - 148, - 2576, - 8, - 148, - 11, - 148, - 12, - 148, - 2577, + 0, + 10, + 2, + 0, + 46, + 46, + 91, + 91, 3, - 148, - 2580, + 0, + 65, + 90, + 95, + 95, + 97, + 122, 8, - 148, - 1, - 148, + 0, + 34, + 34, + 47, + 47, + 92, + 92, + 98, + 98, + 102, + 102, + 110, + 110, + 114, + 114, + 116, + 116, 3, - 148, - 2583, - 8, - 148, - 1, - 149, - 1, - 149, + 0, + 48, + 57, + 65, + 70, + 97, + 102, 3, - 149, - 2587, - 8, - 149, - 1, - 149, - 1, - 149, - 1, - 150, - 4, - 150, - 2592, - 8, - 150, - 11, - 150, - 12, - 150, - 2593, + 0, + 0, + 31, + 34, + 34, + 92, + 92, 1, - 150, + 0, + 49, + 57, 1, - 150, 0, + 48, + 57, + 2, + 0, + 69, + 69, + 101, + 101, + 2, + 0, + 43, + 43, + 45, + 45, + 3, + 0, + 9, + 10, + 13, + 13, + 32, + 32, + 2881, 0, - 151, 1, 1, + 0, + 0, + 0, + 0, 3, - 2, + 1, + 0, + 0, + 0, + 0, 5, - 3, + 1, + 0, + 0, + 0, + 0, 7, - 4, + 1, + 0, + 0, + 0, + 0, 9, - 5, + 1, + 0, + 0, + 0, + 0, 11, - 6, + 1, + 0, + 0, + 0, + 0, 13, - 7, + 1, + 0, + 0, + 0, + 0, 15, - 8, + 1, + 0, + 0, + 0, + 0, 17, - 9, + 1, + 0, + 0, + 0, + 0, 19, - 10, + 1, + 0, + 0, + 0, + 0, 21, - 11, + 1, + 0, + 0, + 0, + 0, 23, - 12, + 1, + 0, + 0, + 0, + 0, 25, - 13, + 1, + 0, + 0, + 0, + 0, 27, - 14, + 1, + 0, + 0, + 0, + 0, 29, - 15, + 1, + 0, + 0, + 0, + 0, 31, - 16, + 1, + 0, + 0, + 0, + 0, 33, - 17, + 1, + 0, + 0, + 0, + 0, 35, - 18, + 1, + 0, + 0, + 0, + 0, 37, - 19, + 1, + 0, + 0, + 0, + 0, 39, - 20, + 1, + 0, + 0, + 0, + 0, 41, - 21, + 1, + 0, + 0, + 0, + 0, 43, - 22, + 1, + 0, + 0, + 0, + 0, 45, - 23, + 1, + 0, + 0, + 0, + 0, 47, - 24, + 1, + 0, + 0, + 0, + 0, 49, - 25, + 1, + 0, + 0, + 0, + 0, 51, - 26, + 1, + 0, + 0, + 0, + 0, 53, - 27, + 1, + 0, + 0, + 0, + 0, 55, - 28, + 1, + 0, + 0, + 0, + 0, 57, - 29, + 1, + 0, + 0, + 0, + 0, 59, - 30, + 1, + 0, + 0, + 0, + 0, 61, - 31, + 1, + 0, + 0, + 0, + 0, 63, - 32, + 1, + 0, + 0, + 0, + 0, 65, - 33, + 1, + 0, + 0, + 0, + 0, 67, - 34, + 1, + 0, + 0, + 0, + 0, 69, - 35, + 1, + 0, + 0, + 0, + 0, 71, - 36, + 1, + 0, + 0, + 0, + 0, 73, - 37, + 1, + 0, + 0, + 0, + 0, 75, - 38, + 1, + 0, + 0, + 0, + 0, 77, - 39, + 1, + 0, + 0, + 0, + 0, 79, - 40, + 1, + 0, + 0, + 0, + 0, 81, - 41, + 1, + 0, + 0, + 0, + 0, 83, - 42, + 1, + 0, + 0, + 0, + 0, 85, - 43, + 1, + 0, + 0, + 0, + 0, 87, - 44, + 1, + 0, + 0, + 0, + 0, 89, - 45, + 1, + 0, + 0, + 0, + 0, 91, - 46, + 1, + 0, + 0, + 0, + 0, 93, - 47, + 1, + 0, + 0, + 0, + 0, 95, - 48, + 1, + 0, + 0, + 0, + 0, 97, - 49, + 1, + 0, + 0, + 0, + 0, 99, - 50, + 1, + 0, + 0, + 0, + 0, 101, - 51, + 1, + 0, + 0, + 0, + 0, 103, - 52, + 1, + 0, + 0, + 0, + 0, 105, - 53, + 1, + 0, + 0, + 0, + 0, 107, - 54, + 1, + 0, + 0, + 0, + 0, 109, - 55, + 1, + 0, + 0, + 0, + 0, 111, - 56, + 1, + 0, + 0, + 0, + 0, 113, - 57, + 1, + 0, + 0, + 0, + 0, 115, - 58, + 1, + 0, + 0, + 0, + 0, 117, - 59, + 1, + 0, + 0, + 0, + 0, 119, - 60, + 1, + 0, + 0, + 0, + 0, 121, - 61, + 1, + 0, + 0, + 0, + 0, 123, - 62, + 1, + 0, + 0, + 0, + 0, 125, - 63, + 1, + 0, + 0, + 0, + 0, 127, - 64, + 1, + 0, + 0, + 0, + 0, 129, - 65, + 1, + 0, + 0, + 0, + 0, 131, - 66, + 1, + 0, + 0, + 0, + 0, 133, - 67, + 1, + 0, + 0, + 0, + 0, 135, - 68, + 1, + 0, + 0, + 0, + 0, 137, - 69, + 1, + 0, + 0, + 0, + 0, 139, - 70, + 1, + 0, + 0, + 0, + 0, 141, - 71, + 1, + 0, + 0, + 0, + 0, 143, - 72, + 1, + 0, + 0, + 0, + 0, 145, - 73, + 1, + 0, + 0, + 0, + 0, 147, - 74, + 1, + 0, + 0, + 0, + 0, 149, - 75, + 1, + 0, + 0, + 0, + 0, 151, - 76, + 1, + 0, + 0, + 0, + 0, 153, - 77, + 1, + 0, + 0, + 0, + 0, 155, - 78, + 1, + 0, + 0, + 0, + 0, 157, - 79, + 1, + 0, + 0, + 0, + 0, 159, - 80, + 1, + 0, + 0, + 0, + 0, 161, - 81, + 1, + 0, + 0, + 0, + 0, 163, - 82, + 1, + 0, + 0, + 0, + 0, 165, - 83, + 1, + 0, + 0, + 0, + 0, 167, - 84, + 1, + 0, + 0, + 0, + 0, 169, - 85, + 1, + 0, + 0, + 0, + 0, 171, - 86, + 1, + 0, + 0, + 0, + 0, 173, - 87, + 1, + 0, + 0, + 0, + 0, 175, - 88, + 1, + 0, + 0, + 0, + 0, 177, - 89, + 1, + 0, + 0, + 0, + 0, 179, - 90, + 1, + 0, + 0, + 0, + 0, 181, - 91, + 1, + 0, + 0, + 0, + 0, 183, - 92, - 185, - 93, - 187, - 94, - 189, - 95, - 191, - 96, - 193, - 97, - 195, - 98, - 197, - 99, - 199, - 100, - 201, - 101, - 203, - 102, - 205, - 103, - 207, - 104, - 209, - 105, - 211, - 106, - 213, - 107, - 215, - 108, - 217, - 109, - 219, - 110, - 221, - 111, - 223, - 112, - 225, - 113, - 227, - 114, - 229, - 115, - 231, - 116, - 233, - 117, - 235, - 118, - 237, - 119, - 239, - 120, - 241, - 121, - 243, - 122, - 245, - 123, - 247, - 124, - 249, - 125, - 251, - 126, - 253, - 127, - 255, - 128, - 257, - 129, - 259, - 130, - 261, - 131, - 263, - 132, - 265, - 133, - 267, - 134, - 269, - 135, - 271, - 136, - 273, - 137, - 275, - 138, - 277, - 139, - 279, - 140, - 281, - 141, - 283, - 142, - 285, - 143, - 287, + 1, + 0, 0, - 289, 0, - 291, 0, - 293, + 185, + 1, 0, - 295, - 144, - 297, - 145, - 299, 0, - 301, - 146, + 0, + 0, + 187, 1, 0, - 8, - 8, 0, - 34, - 34, - 47, - 47, - 92, - 92, - 98, - 98, - 102, - 102, - 110, - 110, - 114, - 114, - 116, - 116, - 3, 0, - 48, - 57, - 65, - 70, - 97, - 102, - 3, 0, + 189, + 1, 0, - 31, - 34, - 34, - 92, - 92, + 0, + 0, + 0, + 191, 1, 0, - 49, - 57, + 0, + 0, + 0, + 193, 1, 0, - 48, - 57, - 2, 0, - 69, - 69, - 101, - 101, - 2, 0, - 43, - 43, - 45, - 45, - 3, 0, - 9, - 10, - 13, - 13, - 32, - 32, - 2608, + 195, + 1, 0, + 0, + 0, + 0, + 197, 1, + 0, + 0, + 0, + 0, + 199, 1, 0, 0, 0, 0, - 3, + 201, 1, 0, 0, 0, 0, - 5, + 203, 1, 0, 0, 0, 0, - 7, + 205, 1, 0, 0, 0, 0, - 9, + 207, 1, 0, 0, 0, 0, - 11, + 209, 1, 0, 0, 0, 0, - 13, + 211, 1, 0, 0, 0, 0, - 15, + 213, 1, 0, 0, 0, 0, - 17, + 215, 1, 0, 0, 0, 0, - 19, + 217, 1, 0, 0, 0, 0, - 21, + 219, 1, 0, 0, 0, 0, - 23, + 221, 1, 0, 0, 0, 0, - 25, + 223, 1, 0, 0, 0, 0, - 27, + 225, 1, 0, 0, 0, 0, - 29, + 227, 1, 0, 0, 0, 0, - 31, + 229, 1, 0, 0, 0, 0, - 33, + 231, 1, 0, 0, 0, 0, - 35, + 233, 1, 0, 0, 0, 0, - 37, + 235, 1, 0, 0, 0, 0, - 39, + 237, 1, 0, 0, 0, 0, - 41, + 239, 1, 0, 0, 0, 0, - 43, + 241, 1, 0, 0, 0, 0, - 45, + 243, 1, 0, 0, 0, 0, - 47, + 245, 1, 0, 0, 0, 0, - 49, + 247, 1, 0, 0, 0, 0, - 51, + 249, 1, 0, 0, 0, 0, - 53, + 251, 1, 0, 0, 0, 0, - 55, + 253, 1, 0, 0, 0, 0, - 57, + 255, 1, 0, 0, 0, 0, - 59, + 257, 1, 0, 0, 0, 0, - 61, + 259, 1, 0, 0, 0, 0, - 63, + 261, 1, 0, 0, 0, 0, - 65, + 263, 1, 0, 0, 0, 0, - 67, + 265, 1, 0, 0, 0, 0, - 69, + 267, 1, 0, 0, 0, 0, - 71, + 269, 1, 0, 0, 0, 0, - 73, + 271, 1, 0, 0, 0, 0, - 75, + 273, 1, 0, 0, 0, 0, - 77, + 275, 1, 0, 0, 0, 0, - 79, + 277, 1, 0, 0, 0, 0, - 81, + 279, 1, 0, 0, 0, 0, - 83, + 281, 1, 0, 0, 0, 0, - 85, + 283, 1, 0, 0, 0, 0, - 87, + 285, 1, 0, 0, 0, 0, - 89, + 287, 1, 0, 0, 0, 0, - 91, + 289, 1, 0, 0, 0, 0, - 93, + 291, 1, 0, 0, 0, 0, - 95, + 293, 1, 0, 0, 0, 0, - 97, + 295, 1, 0, 0, 0, 0, - 99, + 297, 1, 0, 0, 0, 0, - 101, + 299, 1, 0, 0, 0, 0, - 103, + 301, 1, 0, 0, 0, 0, - 105, + 303, 1, 0, 0, 0, 0, - 107, + 305, 1, 0, 0, 0, 0, - 109, + 307, 1, 0, 0, 0, 0, - 111, + 309, 1, 0, 0, 0, 0, - 113, + 311, 1, 0, 0, 0, 0, - 115, + 313, 1, 0, 0, 0, 0, - 117, + 315, 1, 0, 0, 0, 0, - 119, + 317, 1, 0, 0, 0, 0, - 121, + 331, 1, 0, 0, 0, 0, - 123, + 333, 1, 0, 0, 0, 0, - 125, + 337, + 1, + 0, + 0, + 0, + 1, + 339, 1, 0, 0, 0, + 3, + 341, + 1, + 0, 0, - 127, + 0, + 5, + 343, 1, 0, 0, 0, + 7, + 345, + 1, + 0, 0, - 129, + 0, + 9, + 347, 1, 0, 0, 0, + 11, + 349, + 1, + 0, 0, - 131, + 0, + 13, + 351, 1, 0, 0, 0, + 15, + 356, + 1, + 0, 0, - 133, + 0, + 17, + 362, + 1, + 0, + 0, + 0, + 19, + 367, 1, 0, 0, 0, - 0, - 135, + 21, + 377, 1, 0, 0, 0, - 0, - 137, + 23, + 386, 1, 0, 0, 0, - 0, - 139, + 25, + 396, 1, 0, 0, 0, - 0, - 141, + 27, + 408, 1, 0, 0, 0, - 0, - 143, + 29, + 418, 1, 0, 0, 0, - 0, - 145, + 31, + 425, 1, 0, 0, 0, - 0, - 147, + 33, + 432, 1, 0, 0, 0, - 0, - 149, + 35, + 441, 1, 0, 0, 0, - 0, - 151, + 37, + 448, 1, 0, 0, 0, - 0, - 153, + 39, + 458, 1, 0, 0, 0, - 0, - 155, + 41, + 465, 1, 0, 0, 0, - 0, - 157, + 43, + 472, 1, 0, 0, 0, - 0, - 159, + 45, + 483, 1, 0, 0, 0, - 0, - 161, + 47, + 489, 1, 0, 0, 0, - 0, - 163, + 49, + 499, 1, 0, 0, 0, - 0, - 165, + 51, + 511, 1, 0, 0, 0, - 0, - 167, + 53, + 522, 1, 0, 0, 0, - 0, - 169, + 55, + 532, 1, 0, 0, 0, - 0, - 171, + 57, + 543, 1, 0, 0, 0, - 0, - 173, + 59, + 549, 1, 0, 0, 0, - 0, - 175, + 61, + 565, 1, 0, 0, 0, - 0, - 177, + 63, + 585, 1, 0, 0, 0, - 0, - 179, + 65, + 597, 1, 0, 0, 0, - 0, - 181, + 67, + 606, 1, 0, 0, 0, - 0, - 183, + 69, + 618, 1, 0, 0, 0, - 0, - 185, + 71, + 630, 1, 0, 0, 0, - 0, - 187, + 73, + 641, 1, 0, 0, 0, - 0, - 189, + 75, + 655, 1, 0, 0, 0, - 0, - 191, + 77, + 661, 1, 0, 0, 0, - 0, - 193, + 79, + 677, 1, 0, 0, 0, - 0, - 195, + 81, + 697, 1, 0, 0, 0, - 0, - 197, + 83, + 718, 1, 0, 0, 0, - 0, - 199, + 85, + 743, 1, 0, 0, 0, - 0, - 201, + 87, + 770, 1, 0, 0, 0, - 0, - 203, + 89, + 801, 1, 0, 0, 0, - 0, - 205, + 91, + 819, 1, 0, 0, 0, - 0, - 207, + 93, + 841, 1, 0, 0, 0, - 0, - 209, + 95, + 865, 1, 0, 0, 0, - 0, - 211, + 97, + 893, 1, 0, 0, 0, - 0, - 213, + 99, + 898, 1, 0, 0, 0, - 0, - 215, + 101, + 913, 1, 0, 0, 0, - 0, - 217, + 103, + 932, 1, 0, 0, 0, - 0, - 219, + 105, + 952, 1, 0, 0, 0, - 0, - 221, + 107, + 976, 1, 0, 0, 0, - 0, - 223, + 109, + 1002, 1, 0, 0, 0, - 0, - 225, + 111, + 1032, 1, 0, 0, 0, - 0, - 227, + 113, + 1049, 1, 0, 0, 0, - 0, - 229, + 115, + 1070, 1, 0, 0, 0, - 0, - 231, + 117, + 1093, 1, 0, 0, 0, - 0, - 233, + 119, + 1120, 1, 0, 0, 0, - 0, - 235, + 121, + 1136, 1, 0, 0, 0, - 0, - 237, + 123, + 1154, 1, 0, 0, 0, - 0, - 239, + 125, + 1176, 1, 0, 0, 0, - 0, - 241, + 127, + 1199, 1, 0, 0, 0, - 0, - 243, + 129, + 1226, 1, 0, 0, 0, - 0, - 245, + 131, + 1255, 1, 0, 0, 0, - 0, - 247, + 133, + 1288, 1, 0, 0, 0, - 0, - 249, + 135, + 1308, 1, 0, 0, 0, - 0, - 251, + 137, + 1332, 1, 0, 0, 0, - 0, - 253, + 139, + 1358, 1, 0, 0, 0, - 0, - 255, + 141, + 1388, 1, 0, 0, 0, - 0, - 257, + 143, + 1402, 1, 0, 0, 0, - 0, - 259, + 145, + 1412, 1, 0, 0, 0, - 0, - 261, + 147, + 1428, 1, 0, 0, 0, - 0, - 263, + 149, + 1440, 1, 0, 0, 0, - 0, - 265, + 151, + 1457, 1, 0, 0, 0, - 0, - 267, + 153, + 1478, 1, 0, 0, 0, - 0, - 269, + 155, + 1497, 1, 0, 0, 0, - 0, - 271, + 157, + 1520, 1, 0, 0, 0, - 0, - 273, + 159, + 1538, 1, 0, 0, 0, - 0, - 275, + 161, + 1545, 1, 0, 0, 0, - 0, - 277, + 163, + 1554, 1, 0, 0, 0, - 0, - 279, + 165, + 1568, 1, 0, 0, 0, - 0, - 281, + 167, + 1584, 1, 0, 0, 0, - 0, - 283, + 169, + 1595, 1, 0, 0, 0, - 0, - 285, + 171, + 1611, 1, 0, 0, 0, - 0, - 295, + 173, + 1622, 1, 0, 0, 0, - 0, - 297, + 175, + 1637, 1, 0, 0, 0, - 0, - 301, + 177, + 1658, 1, 0, 0, 0, - 1, - 303, + 179, + 1675, 1, 0, 0, 0, - 3, - 305, + 181, + 1686, 1, 0, 0, 0, - 5, - 307, + 183, + 1698, 1, 0, 0, 0, - 7, - 309, + 185, + 1711, 1, 0, 0, 0, - 9, - 311, + 187, + 1719, 1, 0, 0, 0, - 11, - 313, + 189, + 1731, 1, 0, 0, 0, - 13, - 315, + 191, + 1744, 1, 0, 0, 0, - 15, - 320, + 193, + 1753, 1, 0, 0, 0, - 17, - 326, + 195, + 1766, 1, 0, 0, 0, - 19, - 331, + 197, + 1780, 1, 0, 0, 0, - 21, - 341, + 199, + 1790, 1, 0, 0, 0, - 23, - 350, + 201, + 1802, 1, 0, 0, 0, - 25, - 360, + 203, + 1819, 1, 0, 0, 0, - 27, - 372, + 205, + 1832, 1, 0, 0, 0, - 29, - 382, + 207, + 1847, 1, 0, 0, 0, - 31, - 389, + 209, + 1859, 1, 0, 0, 0, - 33, - 396, + 211, + 1879, 1, 0, 0, 0, - 35, - 405, + 213, + 1892, 1, 0, 0, 0, - 37, - 412, + 215, + 1903, 1, 0, 0, 0, - 39, - 422, + 217, + 1918, 1, 0, 0, 0, - 41, - 429, + 219, + 1942, 1, 0, 0, 0, - 43, - 436, + 221, + 1970, 1, 0, 0, 0, - 45, - 447, + 223, + 1999, 1, 0, 0, 0, - 47, - 453, + 225, + 2032, 1, 0, 0, 0, - 49, - 463, + 227, + 2040, 1, 0, 0, 0, - 51, - 474, + 229, + 2055, 1, 0, 0, 0, - 53, - 484, + 231, + 2062, 1, 0, 0, 0, - 55, - 495, + 233, + 2068, 1, 0, 0, 0, - 57, - 501, + 235, + 2076, 1, 0, 0, 0, - 59, - 517, + 237, + 2088, 1, 0, 0, 0, - 61, - 537, + 239, + 2096, 1, 0, 0, 0, - 63, - 549, + 241, + 2108, 1, 0, 0, 0, - 65, - 558, + 243, + 2116, 1, 0, 0, 0, - 67, - 570, + 245, + 2130, 1, 0, 0, 0, - 69, - 582, + 247, + 2148, 1, 0, 0, 0, - 71, - 593, + 249, + 2162, 1, 0, 0, 0, - 73, - 607, + 251, + 2176, 1, 0, 0, 0, - 75, - 613, + 253, + 2194, 1, 0, 0, 0, - 77, - 629, + 255, + 2211, 1, 0, 0, 0, - 79, - 649, + 257, + 2218, 1, 0, 0, 0, - 81, - 670, + 259, + 2225, 1, 0, 0, 0, - 83, - 695, + 261, + 2233, 1, 0, 0, 0, - 85, - 722, + 263, + 2249, 1, 0, 0, 0, - 87, - 753, + 265, + 2260, 1, 0, 0, 0, - 89, - 771, + 267, + 2270, 1, 0, 0, 0, - 91, - 793, + 269, + 2279, 1, 0, 0, 0, - 93, - 817, + 271, + 2288, 1, 0, 0, 0, - 95, - 845, + 273, + 2300, 1, 0, 0, 0, - 97, - 850, + 275, + 2313, 1, 0, 0, 0, - 99, - 865, + 277, + 2340, 1, 0, 0, 0, - 101, - 884, + 279, + 2366, 1, 0, 0, 0, - 103, - 904, + 281, + 2383, 1, 0, 0, 0, - 105, - 928, + 283, + 2403, 1, 0, 0, 0, - 107, - 954, + 285, + 2424, 1, 0, 0, 0, - 109, - 984, + 287, + 2456, 1, 0, 0, 0, - 111, - 1001, + 289, + 2486, 1, 0, 0, 0, - 113, - 1022, + 291, + 2508, 1, 0, 0, 0, - 115, - 1045, + 293, + 2533, 1, 0, 0, 0, - 117, - 1072, + 295, + 2559, 1, 0, 0, 0, - 119, - 1088, + 297, + 2600, 1, 0, 0, 0, - 121, - 1106, + 299, + 2626, 1, 0, 0, 0, - 123, - 1128, + 301, + 2654, 1, 0, 0, 0, - 125, - 1151, + 303, + 2684, 1, 0, 0, 0, - 127, - 1178, + 305, + 2701, 1, 0, 0, 0, - 129, - 1207, + 307, + 2713, 1, 0, 0, 0, - 131, - 1240, + 309, + 2741, 1, 0, 0, 0, - 133, - 1260, + 311, + 2743, 1, 0, 0, 0, - 135, - 1284, + 313, + 2756, 1, 0, 0, 0, - 137, - 1310, + 315, + 2782, 1, 0, 0, 0, - 139, - 1340, + 317, + 2792, 1, 0, 0, 0, - 141, - 1354, + 319, + 2802, 1, 0, 0, 0, - 143, - 1364, + 321, + 2807, 1, 0, 0, 0, - 145, - 1380, + 323, + 2813, 1, 0, 0, 0, - 147, - 1392, + 325, + 2815, 1, 0, 0, 0, - 149, - 1409, + 327, + 2817, 1, 0, 0, 0, - 151, - 1430, + 329, + 2821, 1, 0, 0, 0, - 153, - 1449, + 331, + 2833, 1, 0, 0, 0, - 155, - 1472, + 333, + 2836, 1, 0, 0, 0, - 157, - 1490, + 335, + 2850, 1, 0, 0, 0, - 159, - 1497, + 337, + 2857, 1, 0, 0, 0, - 161, - 1506, - 1, - 0, + 339, + 340, + 5, + 44, 0, 0, - 163, - 1520, + 340, + 2, 1, 0, 0, 0, - 165, - 1536, + 341, + 342, + 5, + 58, + 0, + 0, + 342, + 4, 1, 0, 0, 0, - 167, - 1547, + 343, + 344, + 5, + 91, + 0, + 0, + 344, + 6, 1, 0, 0, 0, - 169, - 1563, + 345, + 346, + 5, + 93, + 0, + 0, + 346, + 8, 1, 0, 0, 0, - 171, - 1574, + 347, + 348, + 5, + 123, + 0, + 0, + 348, + 10, 1, 0, 0, 0, - 173, - 1589, + 349, + 350, + 5, + 125, + 0, + 0, + 350, + 12, 1, 0, 0, 0, - 175, - 1610, - 1, + 351, + 352, + 5, + 116, + 0, + 0, + 352, + 353, + 5, + 114, 0, 0, + 353, + 354, + 5, + 117, 0, - 177, - 1627, - 1, 0, + 354, + 355, + 5, + 101, 0, 0, - 179, - 1638, + 355, + 14, 1, 0, 0, 0, - 181, - 1650, - 1, + 356, + 357, + 5, + 102, 0, 0, + 357, + 358, + 5, + 97, 0, - 183, - 1663, - 1, 0, + 358, + 359, + 5, + 108, 0, 0, - 185, - 1675, - 1, + 359, + 360, + 5, + 115, 0, 0, + 360, + 361, + 5, + 101, 0, - 187, - 1688, + 0, + 361, + 16, 1, 0, 0, 0, - 189, - 1697, - 1, + 362, + 363, + 5, + 110, 0, 0, + 363, + 364, + 5, + 117, 0, - 191, - 1710, - 1, 0, + 364, + 365, + 5, + 108, 0, 0, - 193, - 1727, + 365, + 366, + 5, + 108, + 0, + 0, + 366, + 18, 1, 0, 0, 0, - 195, - 1740, - 1, + 367, + 368, + 5, + 34, 0, 0, + 368, + 369, + 5, + 67, 0, - 197, - 1755, - 1, 0, + 369, + 370, + 5, + 111, 0, 0, - 199, - 1767, - 1, + 370, + 371, + 5, + 109, 0, 0, + 371, + 372, + 5, + 109, 0, - 201, - 1787, - 1, 0, + 372, + 373, + 5, + 101, 0, 0, - 203, - 1800, - 1, + 373, + 374, + 5, + 110, 0, 0, + 374, + 375, + 5, + 116, 0, - 205, - 1811, - 1, 0, + 375, + 376, + 5, + 34, 0, 0, - 207, - 1826, + 376, + 20, 1, 0, 0, 0, - 209, - 1850, - 1, + 377, + 378, + 5, + 34, 0, 0, + 378, + 379, + 5, + 83, 0, - 211, - 1878, - 1, 0, + 379, + 380, + 5, + 116, 0, 0, - 213, - 1907, - 1, + 380, + 381, + 5, + 97, 0, 0, + 381, + 382, + 5, + 116, 0, - 215, - 1940, - 1, 0, + 382, + 383, + 5, + 101, 0, 0, - 217, - 1948, - 1, + 383, + 384, + 5, + 115, + 0, 0, + 384, + 385, + 5, + 34, 0, 0, - 219, - 1955, + 385, + 22, 1, 0, 0, 0, - 221, - 1961, - 1, + 386, + 387, + 5, + 34, 0, 0, + 387, + 388, + 5, + 83, 0, - 223, - 1969, - 1, 0, + 388, + 389, + 5, + 116, 0, 0, - 225, - 1981, - 1, + 389, + 390, + 5, + 97, 0, 0, + 390, + 391, + 5, + 114, 0, - 227, - 1989, - 1, 0, + 391, + 392, + 5, + 116, 0, 0, - 229, - 2001, - 1, + 392, + 393, + 5, + 65, 0, 0, + 393, + 394, + 5, + 116, 0, - 231, - 2009, - 1, 0, + 394, + 395, + 5, + 34, 0, 0, - 233, - 2023, + 395, + 24, 1, 0, 0, 0, - 235, - 2041, - 1, + 396, + 397, + 5, + 34, 0, 0, + 397, + 398, + 5, + 78, 0, - 237, - 2055, - 1, 0, + 398, + 399, + 5, + 101, 0, 0, - 239, - 2069, - 1, + 399, + 400, + 5, + 120, 0, 0, + 400, + 401, + 5, + 116, 0, - 241, - 2087, - 1, 0, + 401, + 402, + 5, + 83, 0, 0, - 243, - 2104, - 1, + 402, + 403, + 5, + 116, 0, 0, + 403, + 404, + 5, + 97, 0, - 245, - 2111, - 1, 0, + 404, + 405, + 5, + 116, 0, 0, - 247, - 2118, - 1, + 405, + 406, + 5, + 101, + 0, 0, + 406, + 407, + 5, + 34, 0, 0, - 249, - 2126, + 407, + 26, 1, 0, 0, 0, - 251, - 2139, - 1, + 408, + 409, + 5, + 34, 0, 0, + 409, + 410, + 5, + 86, 0, - 253, - 2166, - 1, 0, + 410, + 411, + 5, + 101, 0, 0, - 255, - 2192, - 1, + 411, + 412, + 5, + 114, 0, 0, + 412, + 413, + 5, + 115, 0, - 257, - 2209, - 1, 0, + 413, + 414, + 5, + 105, 0, 0, - 259, - 2229, - 1, + 414, + 415, + 5, + 111, 0, 0, + 415, + 416, + 5, + 110, 0, - 261, - 2250, - 1, 0, + 416, + 417, + 5, + 34, 0, 0, - 263, - 2282, + 417, + 28, 1, 0, 0, 0, - 265, - 2312, - 1, + 418, + 419, + 5, + 34, 0, 0, + 419, + 420, + 5, + 84, 0, - 267, - 2334, - 1, 0, + 420, + 421, + 5, + 121, 0, 0, - 269, - 2359, - 1, + 421, + 422, + 5, + 112, 0, 0, + 422, + 423, + 5, + 101, 0, - 271, - 2385, - 1, 0, + 423, + 424, + 5, + 34, 0, 0, - 273, - 2426, + 424, + 30, 1, 0, 0, 0, - 275, - 2452, - 1, + 425, + 426, + 5, + 34, 0, 0, + 426, + 427, + 5, + 84, 0, - 277, - 2480, - 1, 0, + 427, + 428, + 5, + 97, 0, 0, - 279, - 2497, - 1, + 428, + 429, + 5, + 115, 0, 0, + 429, + 430, + 5, + 107, 0, - 281, - 2509, - 1, 0, + 430, + 431, + 5, + 34, 0, 0, - 283, - 2522, + 431, + 32, 1, 0, 0, 0, - 285, - 2534, - 1, + 432, + 433, + 5, + 34, + 0, 0, + 433, + 434, + 5, + 67, 0, 0, - 287, - 2544, - 1, + 434, + 435, + 5, + 104, 0, 0, + 435, + 436, + 5, + 111, 0, - 289, - 2549, - 1, 0, + 436, + 437, + 5, + 105, 0, 0, - 291, - 2555, - 1, + 437, + 438, + 5, + 99, 0, 0, + 438, + 439, + 5, + 101, 0, - 293, - 2557, - 1, 0, + 439, + 440, + 5, + 34, 0, 0, - 295, - 2567, + 440, + 34, 1, 0, 0, 0, - 297, - 2570, - 1, + 441, + 442, + 5, + 34, 0, 0, + 442, + 443, + 5, + 70, 0, - 299, - 2584, - 1, 0, + 443, + 444, + 5, + 97, 0, 0, - 301, - 2591, - 1, + 444, + 445, + 5, + 105, + 0, 0, + 445, + 446, + 5, + 108, 0, 0, - 303, - 304, + 446, + 447, 5, - 44, + 34, 0, 0, - 304, - 2, + 447, + 36, 1, 0, 0, 0, - 305, - 306, + 448, + 449, 5, - 58, - 0, + 34, 0, - 306, - 4, - 1, 0, + 449, + 450, + 5, + 83, 0, 0, - 307, - 308, + 450, + 451, 5, - 91, + 117, 0, 0, - 308, - 6, - 1, + 451, + 452, + 5, + 99, + 0, 0, + 452, + 453, + 5, + 99, 0, 0, - 309, - 310, + 453, + 454, 5, - 93, + 101, 0, 0, - 310, - 8, - 1, + 454, + 455, + 5, + 101, + 0, 0, + 455, + 456, + 5, + 100, 0, 0, - 311, - 312, + 456, + 457, 5, - 123, + 34, 0, 0, - 312, - 10, + 457, + 38, 1, 0, 0, 0, - 313, - 314, + 458, + 459, 5, - 125, - 0, + 34, 0, - 314, - 12, - 1, 0, + 459, + 460, + 5, + 80, 0, 0, - 315, - 316, + 460, + 461, 5, - 116, + 97, 0, 0, - 316, - 317, + 461, + 462, 5, - 114, + 115, 0, 0, - 317, - 318, + 462, + 463, 5, - 117, + 115, 0, 0, - 318, - 319, + 463, + 464, 5, - 101, + 34, 0, 0, - 319, - 14, + 464, + 40, 1, 0, 0, 0, - 320, - 321, + 465, + 466, 5, - 102, + 34, 0, 0, - 321, - 322, + 466, + 467, + 5, + 87, + 0, + 0, + 467, + 468, 5, 97, 0, 0, - 322, - 323, + 468, + 469, 5, - 108, + 105, 0, 0, - 323, - 324, + 469, + 470, 5, - 115, + 116, 0, 0, - 324, - 325, + 470, + 471, 5, - 101, + 34, 0, 0, - 325, - 16, + 471, + 42, 1, 0, 0, 0, - 326, - 327, + 472, + 473, 5, - 110, + 34, 0, 0, - 327, - 328, + 473, + 474, 5, - 117, + 80, 0, 0, - 328, - 329, + 474, + 475, 5, - 108, + 97, 0, 0, - 329, - 330, + 475, + 476, 5, - 108, + 114, 0, 0, - 330, - 18, - 1, + 476, + 477, + 5, + 97, + 0, 0, + 477, + 478, + 5, + 108, 0, 0, - 331, - 332, + 478, + 479, 5, - 34, + 108, 0, 0, - 332, - 333, + 479, + 480, 5, - 67, + 101, 0, 0, - 333, - 334, + 480, + 481, 5, - 111, + 108, 0, 0, - 334, - 335, + 481, + 482, 5, - 109, + 34, 0, 0, - 335, - 336, + 482, + 44, + 1, + 0, + 0, + 0, + 483, + 484, 5, - 109, + 34, 0, 0, - 336, - 337, + 484, + 485, 5, - 101, + 77, 0, 0, - 337, - 338, + 485, + 486, 5, - 110, + 97, 0, 0, - 338, - 339, + 486, + 487, 5, - 116, + 112, 0, 0, - 339, - 340, + 487, + 488, 5, 34, 0, 0, - 340, - 20, + 488, + 46, 1, 0, 0, 0, - 341, - 342, + 489, + 490, 5, 34, 0, 0, - 342, - 343, + 490, + 491, 5, - 83, + 67, 0, 0, - 343, - 344, + 491, + 492, 5, - 116, + 104, 0, 0, - 344, - 345, + 492, + 493, 5, - 97, + 111, 0, 0, - 345, - 346, + 493, + 494, 5, - 116, + 105, 0, 0, - 346, - 347, + 494, + 495, + 5, + 99, + 0, + 0, + 495, + 496, 5, 101, 0, 0, - 347, - 348, + 496, + 497, 5, 115, 0, 0, - 348, - 349, + 497, + 498, 5, 34, 0, 0, - 349, - 22, + 498, + 48, 1, 0, 0, 0, - 350, - 351, + 499, + 500, + 5, + 34, + 0, + 0, + 500, + 501, + 5, + 67, + 0, + 0, + 501, + 502, 5, - 34, + 111, 0, 0, - 351, - 352, + 502, + 503, 5, - 83, + 110, 0, 0, - 352, - 353, + 503, + 504, 5, - 116, + 100, 0, 0, - 353, - 354, + 504, + 505, 5, - 97, + 105, 0, 0, - 354, - 355, + 505, + 506, 5, - 114, + 116, 0, 0, - 355, - 356, + 506, + 507, 5, - 116, + 105, 0, 0, - 356, - 357, + 507, + 508, 5, - 65, + 111, 0, 0, - 357, - 358, + 508, + 509, 5, - 116, + 110, 0, 0, - 358, - 359, + 509, + 510, 5, 34, 0, 0, - 359, - 24, + 510, + 50, 1, 0, 0, 0, - 360, - 361, + 511, + 512, 5, 34, 0, 0, - 361, - 362, - 5, - 78, - 0, - 0, - 362, - 363, + 512, + 513, 5, - 101, + 86, 0, 0, - 363, - 364, + 513, + 514, 5, - 120, + 97, 0, 0, - 364, - 365, + 514, + 515, 5, - 116, + 114, 0, 0, - 365, - 366, + 515, + 516, 5, - 83, + 105, 0, 0, - 366, - 367, + 516, + 517, 5, - 116, + 97, 0, 0, - 367, - 368, + 517, + 518, 5, - 97, + 98, 0, 0, - 368, - 369, + 518, + 519, 5, - 116, + 108, 0, 0, - 369, - 370, + 519, + 520, 5, 101, 0, 0, - 370, - 371, + 520, + 521, 5, 34, 0, 0, - 371, - 26, + 521, + 52, 1, 0, 0, 0, - 372, - 373, + 522, + 523, 5, 34, 0, 0, - 373, - 374, + 523, + 524, 5, - 86, + 68, 0, 0, - 374, - 375, + 524, + 525, 5, 101, 0, 0, - 375, - 376, + 525, + 526, 5, - 114, + 102, 0, 0, - 376, - 377, + 526, + 527, 5, - 115, + 97, 0, 0, - 377, - 378, + 527, + 528, 5, - 105, + 117, 0, 0, - 378, - 379, + 528, + 529, 5, - 111, + 108, 0, 0, - 379, - 380, + 529, + 530, 5, - 110, + 116, 0, 0, - 380, - 381, + 530, + 531, 5, 34, 0, 0, - 381, - 28, + 531, + 54, 1, 0, 0, 0, - 382, - 383, + 532, + 533, 5, 34, 0, 0, - 383, - 384, + 533, + 534, 5, - 84, + 66, 0, 0, - 384, - 385, + 534, + 535, 5, - 121, + 114, 0, 0, - 385, - 386, + 535, + 536, 5, - 112, + 97, 0, 0, - 386, - 387, + 536, + 537, 5, - 101, + 110, 0, 0, - 387, - 388, + 537, + 538, 5, - 34, + 99, 0, 0, - 388, - 30, - 1, + 538, + 539, + 5, + 104, + 0, 0, + 539, + 540, + 5, + 101, 0, 0, - 389, - 390, + 540, + 541, + 5, + 115, + 0, + 0, + 541, + 542, 5, 34, 0, 0, - 390, - 391, + 542, + 56, + 1, + 0, + 0, + 0, + 543, + 544, 5, - 84, + 34, 0, 0, - 391, - 392, + 544, + 545, 5, - 97, + 65, 0, 0, - 392, - 393, + 545, + 546, 5, - 115, + 110, 0, 0, - 393, - 394, + 546, + 547, 5, - 107, + 100, 0, 0, - 394, - 395, + 547, + 548, 5, 34, 0, 0, - 395, - 32, + 548, + 58, 1, 0, 0, 0, - 396, - 397, + 549, + 550, 5, 34, 0, 0, - 397, - 398, + 550, + 551, 5, - 67, + 66, 0, 0, - 398, - 399, + 551, + 552, 5, - 104, + 111, 0, 0, - 399, - 400, + 552, + 553, 5, 111, 0, 0, - 400, - 401, + 553, + 554, 5, - 105, + 108, 0, 0, - 401, - 402, + 554, + 555, 5, - 99, + 101, 0, 0, - 402, - 403, + 555, + 556, 5, - 101, + 97, 0, 0, - 403, - 404, + 556, + 557, 5, - 34, - 0, + 110, 0, - 404, - 34, - 1, 0, + 557, + 558, + 5, + 69, 0, 0, - 405, - 406, + 558, + 559, 5, - 34, + 113, 0, 0, - 406, - 407, + 559, + 560, 5, - 70, + 117, 0, 0, - 407, - 408, + 560, + 561, 5, 97, 0, 0, - 408, - 409, + 561, + 562, 5, - 105, + 108, 0, 0, - 409, - 410, + 562, + 563, 5, - 108, + 115, 0, 0, - 410, - 411, + 563, + 564, 5, 34, 0, 0, - 411, - 36, + 564, + 60, 1, 0, 0, 0, - 412, - 413, + 565, + 566, 5, 34, 0, 0, - 413, - 414, + 566, + 567, 5, - 83, + 66, 0, 0, - 414, - 415, + 567, + 568, 5, - 117, + 111, 0, 0, - 415, - 416, + 568, + 569, 5, - 99, + 111, 0, 0, - 416, - 417, + 569, + 570, 5, - 99, + 108, 0, 0, - 417, - 418, + 570, + 571, 5, 101, 0, 0, - 418, - 419, + 571, + 572, 5, - 101, + 97, 0, 0, - 419, - 420, + 572, + 573, 5, - 100, + 110, 0, 0, - 420, - 421, + 573, + 574, 5, - 34, - 0, - 0, - 421, - 38, - 1, - 0, + 69, 0, 0, - 422, - 423, + 574, + 575, 5, - 34, + 113, 0, 0, - 423, - 424, + 575, + 576, 5, - 80, + 117, 0, 0, - 424, - 425, + 576, + 577, 5, 97, 0, 0, - 425, - 426, + 577, + 578, 5, - 115, + 108, 0, 0, - 426, - 427, + 578, + 579, 5, 115, 0, 0, - 427, - 428, - 5, - 34, - 0, - 0, - 428, - 40, - 1, - 0, - 0, - 0, - 429, - 430, - 5, - 34, - 0, - 0, - 430, - 431, + 579, + 580, 5, - 87, + 80, 0, 0, - 431, - 432, + 580, + 581, 5, 97, 0, 0, - 432, - 433, + 581, + 582, 5, - 105, + 116, 0, 0, - 433, - 434, + 582, + 583, 5, - 116, + 104, 0, 0, - 434, - 435, + 583, + 584, 5, 34, 0, 0, - 435, - 42, + 584, + 62, 1, 0, 0, 0, - 436, - 437, + 585, + 586, 5, 34, 0, 0, - 437, - 438, + 586, + 587, 5, - 80, + 73, 0, 0, - 438, - 439, + 587, + 588, 5, - 97, + 115, 0, 0, - 439, - 440, + 588, + 589, 5, - 114, + 66, + 0, + 0, + 589, + 590, + 5, + 111, 0, 0, - 440, - 441, + 590, + 591, 5, - 97, + 111, 0, 0, - 441, - 442, + 591, + 592, 5, 108, 0, 0, - 442, - 443, + 592, + 593, 5, - 108, + 101, 0, 0, - 443, - 444, + 593, + 594, 5, - 101, + 97, 0, 0, - 444, - 445, + 594, + 595, 5, - 108, + 110, 0, 0, - 445, - 446, + 595, + 596, 5, 34, 0, 0, - 446, - 44, + 596, + 64, 1, 0, 0, 0, - 447, - 448, + 597, + 598, 5, 34, 0, 0, - 448, - 449, + 598, + 599, 5, - 77, + 73, 0, 0, - 449, - 450, + 599, + 600, 5, - 97, + 115, 0, 0, - 450, - 451, + 600, + 601, 5, - 112, + 78, 0, 0, - 451, - 452, + 601, + 602, + 5, + 117, + 0, + 0, + 602, + 603, + 5, + 108, + 0, + 0, + 603, + 604, + 5, + 108, + 0, + 0, + 604, + 605, 5, 34, 0, 0, - 452, - 46, + 605, + 66, 1, 0, 0, 0, - 453, - 454, + 606, + 607, 5, 34, 0, 0, - 454, - 455, + 607, + 608, 5, - 67, + 73, 0, 0, - 455, - 456, + 608, + 609, 5, - 104, + 115, 0, 0, - 456, - 457, + 609, + 610, 5, - 111, + 78, 0, 0, - 457, - 458, + 610, + 611, 5, - 105, + 117, 0, 0, - 458, - 459, + 611, + 612, 5, - 99, + 109, 0, 0, - 459, - 460, + 612, + 613, 5, 101, 0, 0, - 460, - 461, + 613, + 614, 5, - 115, + 114, 0, 0, - 461, - 462, + 614, + 615, + 5, + 105, + 0, + 0, + 615, + 616, + 5, + 99, + 0, + 0, + 616, + 617, 5, 34, 0, 0, - 462, - 48, + 617, + 68, 1, 0, 0, 0, - 463, - 464, + 618, + 619, 5, 34, 0, 0, - 464, - 465, + 619, + 620, 5, - 86, + 73, 0, 0, - 465, - 466, + 620, + 621, 5, - 97, + 115, 0, 0, - 466, - 467, + 621, + 622, + 5, + 80, + 0, + 0, + 622, + 623, 5, 114, 0, 0, - 467, - 468, + 623, + 624, 5, - 105, + 101, 0, 0, - 468, - 469, + 624, + 625, 5, - 97, + 115, 0, 0, - 469, - 470, + 625, + 626, 5, - 98, + 101, 0, 0, - 470, - 471, + 626, + 627, 5, - 108, + 110, 0, 0, - 471, - 472, + 627, + 628, 5, - 101, + 116, 0, 0, - 472, - 473, + 628, + 629, 5, 34, 0, 0, - 473, - 50, + 629, + 70, 1, 0, 0, 0, - 474, - 475, + 630, + 631, 5, 34, 0, 0, - 475, - 476, + 631, + 632, 5, - 68, + 73, 0, 0, - 476, - 477, + 632, + 633, 5, - 101, + 115, 0, 0, - 477, - 478, + 633, + 634, 5, - 102, + 83, 0, 0, - 478, - 479, + 634, + 635, 5, - 97, + 116, 0, 0, - 479, - 480, + 635, + 636, 5, - 117, + 114, 0, 0, - 480, - 481, + 636, + 637, + 5, + 105, + 0, + 0, + 637, + 638, 5, - 108, + 110, 0, 0, - 481, - 482, + 638, + 639, 5, - 116, + 103, 0, 0, - 482, - 483, + 639, + 640, 5, 34, 0, 0, - 483, - 52, + 640, + 72, 1, 0, 0, 0, - 484, - 485, + 641, + 642, 5, 34, 0, 0, - 485, - 486, + 642, + 643, 5, - 66, + 73, 0, 0, - 486, - 487, + 643, + 644, 5, - 114, + 115, 0, 0, - 487, - 488, + 644, + 645, 5, - 97, + 84, 0, 0, - 488, - 489, + 645, + 646, 5, - 110, + 105, 0, 0, - 489, - 490, + 646, + 647, 5, - 99, + 109, 0, 0, - 490, - 491, + 647, + 648, 5, - 104, + 101, 0, 0, - 491, - 492, + 648, + 649, 5, - 101, + 115, 0, 0, - 492, - 493, + 649, + 650, 5, - 115, + 116, 0, 0, - 493, - 494, + 650, + 651, + 5, + 97, + 0, + 0, + 651, + 652, + 5, + 109, + 0, + 0, + 652, + 653, + 5, + 112, + 0, + 0, + 653, + 654, 5, 34, 0, 0, - 494, - 54, + 654, + 74, 1, 0, 0, 0, - 495, - 496, + 655, + 656, 5, 34, 0, 0, - 496, - 497, + 656, + 657, 5, - 65, + 78, 0, 0, - 497, - 498, + 657, + 658, 5, - 110, + 111, 0, 0, - 498, - 499, + 658, + 659, 5, - 100, + 116, 0, 0, - 499, - 500, + 659, + 660, 5, 34, 0, 0, - 500, - 56, + 660, + 76, 1, 0, 0, 0, - 501, - 502, + 661, + 662, 5, 34, 0, 0, - 502, - 503, + 662, + 663, 5, - 66, + 78, 0, 0, - 503, - 504, + 663, + 664, 5, - 111, + 117, 0, 0, - 504, - 505, + 664, + 665, 5, - 111, + 109, 0, 0, - 505, - 506, + 665, + 666, 5, - 108, + 101, 0, 0, - 506, - 507, + 666, + 667, 5, - 101, + 114, 0, 0, - 507, - 508, + 667, + 668, 5, - 97, + 105, 0, 0, - 508, - 509, + 668, + 669, 5, - 110, + 99, 0, 0, - 509, - 510, + 669, + 670, 5, 69, 0, 0, - 510, - 511, + 670, + 671, 5, 113, 0, 0, - 511, - 512, + 671, + 672, 5, 117, 0, 0, - 512, - 513, + 672, + 673, 5, 97, 0, 0, - 513, - 514, + 673, + 674, 5, 108, 0, 0, - 514, - 515, + 674, + 675, 5, 115, 0, 0, - 515, - 516, + 675, + 676, 5, 34, 0, 0, - 516, - 58, + 676, + 78, 1, 0, 0, 0, - 517, - 518, + 677, + 678, 5, 34, 0, 0, - 518, - 519, + 678, + 679, 5, - 66, + 78, 0, 0, - 519, - 520, + 679, + 680, 5, - 111, + 117, 0, 0, - 520, - 521, + 680, + 681, 5, - 111, + 109, 0, 0, - 521, - 522, + 681, + 682, 5, - 108, + 101, 0, 0, - 522, - 523, + 682, + 683, 5, - 101, + 114, 0, 0, - 523, - 524, + 683, + 684, 5, - 97, + 105, 0, 0, - 524, - 525, + 684, + 685, 5, - 110, + 99, 0, 0, - 525, - 526, + 685, + 686, 5, 69, 0, 0, - 526, - 527, + 686, + 687, 5, 113, 0, 0, - 527, - 528, + 687, + 688, 5, 117, 0, 0, - 528, - 529, + 688, + 689, 5, 97, 0, 0, - 529, - 530, + 689, + 690, 5, 108, 0, 0, - 530, - 531, + 690, + 691, 5, 115, 0, 0, - 531, - 532, + 691, + 692, 5, 80, 0, 0, - 532, - 533, + 692, + 693, 5, 97, 0, 0, - 533, - 534, + 693, + 694, 5, 116, 0, 0, - 534, - 535, + 694, + 695, 5, 104, 0, 0, - 535, - 536, + 695, + 696, 5, 34, 0, 0, - 536, - 60, + 696, + 80, 1, 0, 0, 0, - 537, - 538, + 697, + 698, 5, 34, 0, 0, - 538, - 539, + 698, + 699, 5, - 73, + 78, 0, 0, - 539, - 540, + 699, + 700, 5, - 115, + 117, 0, 0, - 540, - 541, + 700, + 701, 5, - 66, + 109, 0, 0, - 541, - 542, + 701, + 702, 5, - 111, + 101, 0, 0, - 542, - 543, + 702, + 703, 5, - 111, + 114, 0, 0, - 543, - 544, + 703, + 704, 5, - 108, + 105, 0, 0, - 544, - 545, + 704, + 705, + 5, + 99, + 0, + 0, + 705, + 706, + 5, + 71, + 0, + 0, + 706, + 707, + 5, + 114, + 0, + 0, + 707, + 708, 5, 101, 0, 0, - 545, - 546, + 708, + 709, 5, 97, 0, 0, - 546, - 547, + 709, + 710, + 5, + 116, + 0, + 0, + 710, + 711, + 5, + 101, + 0, + 0, + 711, + 712, + 5, + 114, + 0, + 0, + 712, + 713, + 5, + 84, + 0, + 0, + 713, + 714, + 5, + 104, + 0, + 0, + 714, + 715, + 5, + 97, + 0, + 0, + 715, + 716, 5, 110, 0, 0, - 547, - 548, + 716, + 717, 5, 34, 0, 0, - 548, - 62, + 717, + 82, 1, 0, 0, 0, - 549, - 550, + 718, + 719, 5, 34, 0, 0, - 550, - 551, + 719, + 720, 5, - 73, + 78, 0, 0, - 551, - 552, + 720, + 721, 5, - 115, + 117, 0, 0, - 552, - 553, + 721, + 722, 5, - 78, + 109, 0, 0, - 553, - 554, + 722, + 723, 5, - 117, + 101, 0, 0, - 554, - 555, + 723, + 724, 5, - 108, + 114, 0, 0, - 555, - 556, + 724, + 725, 5, - 108, + 105, 0, 0, - 556, - 557, + 725, + 726, 5, - 34, + 99, 0, 0, - 557, - 64, - 1, + 726, + 727, + 5, + 71, + 0, 0, + 727, + 728, + 5, + 114, 0, 0, - 558, - 559, + 728, + 729, 5, - 34, + 101, 0, 0, - 559, - 560, + 729, + 730, 5, - 73, + 97, 0, 0, - 560, - 561, + 730, + 731, 5, - 115, + 116, 0, 0, - 561, - 562, + 731, + 732, 5, - 78, + 101, 0, 0, - 562, - 563, + 732, + 733, + 5, + 114, + 0, + 0, + 733, + 734, + 5, + 84, + 0, + 0, + 734, + 735, + 5, + 104, + 0, + 0, + 735, + 736, 5, - 117, + 97, 0, 0, - 563, - 564, + 736, + 737, 5, - 109, + 110, 0, 0, - 564, - 565, + 737, + 738, 5, - 101, + 80, 0, 0, - 565, - 566, + 738, + 739, 5, - 114, + 97, 0, 0, - 566, - 567, + 739, + 740, 5, - 105, + 116, 0, 0, - 567, - 568, + 740, + 741, 5, - 99, + 104, 0, 0, - 568, - 569, + 741, + 742, 5, 34, 0, 0, - 569, - 66, + 742, + 84, 1, 0, 0, 0, - 570, - 571, + 743, + 744, 5, 34, 0, 0, - 571, - 572, - 5, - 73, - 0, - 0, - 572, - 573, + 744, + 745, 5, - 115, + 78, 0, 0, - 573, - 574, + 745, + 746, 5, - 80, + 117, 0, 0, - 574, - 575, + 746, + 747, 5, - 114, + 109, 0, 0, - 575, - 576, + 747, + 748, 5, 101, 0, 0, - 576, - 577, + 748, + 749, 5, - 115, + 114, 0, 0, - 577, - 578, + 749, + 750, 5, - 101, + 105, 0, 0, - 578, - 579, + 750, + 751, 5, - 110, + 99, 0, 0, - 579, - 580, + 751, + 752, 5, - 116, + 71, 0, 0, - 580, - 581, + 752, + 753, 5, - 34, - 0, + 114, 0, - 581, - 68, - 1, 0, + 753, + 754, + 5, + 101, 0, 0, - 582, - 583, + 754, + 755, 5, - 34, + 97, 0, 0, - 583, - 584, + 755, + 756, 5, - 73, + 116, 0, 0, - 584, - 585, + 756, + 757, 5, - 115, + 101, 0, 0, - 585, - 586, + 757, + 758, 5, - 83, + 114, 0, 0, - 586, - 587, + 758, + 759, 5, - 116, + 84, 0, 0, - 587, - 588, + 759, + 760, 5, - 114, + 104, 0, 0, - 588, - 589, + 760, + 761, 5, - 105, + 97, 0, 0, - 589, - 590, + 761, + 762, 5, 110, 0, 0, - 590, - 591, + 762, + 763, 5, - 103, + 69, 0, 0, - 591, - 592, + 763, + 764, 5, - 34, - 0, + 113, 0, - 592, - 70, - 1, 0, + 764, + 765, + 5, + 117, 0, 0, - 593, - 594, + 765, + 766, 5, - 34, + 97, 0, 0, - 594, - 595, + 766, + 767, 5, - 73, + 108, 0, 0, - 595, - 596, + 767, + 768, 5, 115, 0, 0, - 596, - 597, + 768, + 769, 5, - 84, + 34, 0, 0, - 597, - 598, - 5, - 105, + 769, + 86, + 1, 0, 0, - 598, - 599, + 0, + 770, + 771, 5, - 109, + 34, 0, 0, - 599, - 600, + 771, + 772, 5, - 101, + 78, 0, 0, - 600, - 601, + 772, + 773, 5, - 115, + 117, 0, 0, - 601, - 602, + 773, + 774, 5, - 116, + 109, 0, 0, - 602, - 603, + 774, + 775, 5, - 97, + 101, 0, 0, - 603, - 604, + 775, + 776, 5, - 109, + 114, 0, 0, - 604, - 605, + 776, + 777, 5, - 112, + 105, 0, 0, - 605, - 606, + 777, + 778, 5, - 34, - 0, + 99, 0, - 606, - 72, - 1, 0, + 778, + 779, + 5, + 71, 0, 0, - 607, - 608, + 779, + 780, 5, - 34, + 114, 0, 0, - 608, - 609, + 780, + 781, 5, - 78, + 101, 0, 0, - 609, - 610, + 781, + 782, 5, - 111, + 97, 0, 0, - 610, - 611, + 782, + 783, 5, 116, 0, 0, - 611, - 612, + 783, + 784, 5, - 34, - 0, + 101, 0, - 612, - 74, - 1, 0, + 784, + 785, + 5, + 114, 0, 0, - 613, - 614, + 785, + 786, 5, - 34, + 84, 0, 0, - 614, - 615, + 786, + 787, 5, - 78, + 104, 0, 0, - 615, - 616, + 787, + 788, 5, - 117, + 97, 0, 0, - 616, - 617, + 788, + 789, 5, - 109, + 110, 0, 0, - 617, - 618, + 789, + 790, 5, - 101, + 69, 0, 0, - 618, - 619, + 790, + 791, 5, - 114, + 113, 0, 0, - 619, - 620, + 791, + 792, 5, - 105, + 117, 0, 0, - 620, - 621, + 792, + 793, 5, - 99, + 97, 0, 0, - 621, - 622, + 793, + 794, 5, - 69, + 108, 0, 0, - 622, - 623, + 794, + 795, 5, - 113, + 115, 0, 0, - 623, - 624, + 795, + 796, 5, - 117, + 80, 0, 0, - 624, - 625, + 796, + 797, 5, 97, 0, 0, - 625, - 626, + 797, + 798, 5, - 108, + 116, 0, 0, - 626, - 627, + 798, + 799, 5, - 115, + 104, 0, 0, - 627, - 628, + 799, + 800, 5, 34, 0, 0, - 628, - 76, + 800, + 88, 1, 0, 0, 0, - 629, - 630, + 801, + 802, 5, 34, 0, 0, - 630, - 631, + 802, + 803, 5, 78, 0, 0, - 631, - 632, + 803, + 804, 5, 117, 0, 0, - 632, - 633, + 804, + 805, 5, 109, 0, 0, - 633, - 634, + 805, + 806, 5, 101, 0, 0, - 634, - 635, + 806, + 807, 5, 114, 0, 0, - 635, - 636, + 807, + 808, 5, 105, 0, 0, - 636, - 637, + 808, + 809, 5, 99, 0, 0, - 637, - 638, - 5, - 69, - 0, - 0, - 638, - 639, - 5, - 113, - 0, - 0, - 639, - 640, + 809, + 810, 5, - 117, + 76, 0, 0, - 640, - 641, + 810, + 811, 5, - 97, + 101, 0, 0, - 641, - 642, + 811, + 812, 5, - 108, + 115, 0, 0, - 642, - 643, + 812, + 813, 5, 115, 0, 0, - 643, - 644, + 813, + 814, 5, - 80, + 84, 0, 0, - 644, - 645, + 814, + 815, 5, - 97, + 104, 0, 0, - 645, - 646, + 815, + 816, 5, - 116, + 97, 0, 0, - 646, - 647, + 816, + 817, 5, - 104, + 110, 0, 0, - 647, - 648, + 817, + 818, 5, 34, 0, 0, - 648, - 78, + 818, + 90, 1, 0, 0, 0, - 649, - 650, + 819, + 820, 5, 34, 0, 0, - 650, - 651, + 820, + 821, 5, 78, 0, 0, - 651, - 652, + 821, + 822, 5, 117, 0, 0, - 652, - 653, + 822, + 823, 5, 109, 0, 0, - 653, - 654, + 823, + 824, 5, 101, 0, 0, - 654, - 655, + 824, + 825, 5, 114, 0, 0, - 655, - 656, + 825, + 826, 5, 105, 0, 0, - 656, - 657, + 826, + 827, 5, 99, 0, 0, - 657, - 658, + 827, + 828, 5, - 71, + 76, 0, 0, - 658, - 659, + 828, + 829, 5, - 114, + 101, 0, 0, - 659, - 660, + 829, + 830, 5, - 101, + 115, 0, 0, - 660, - 661, + 830, + 831, 5, - 97, + 115, 0, 0, - 661, - 662, + 831, + 832, 5, - 116, + 84, 0, 0, - 662, - 663, + 832, + 833, 5, - 101, + 104, 0, 0, - 663, - 664, + 833, + 834, 5, - 114, + 97, 0, 0, - 664, - 665, + 834, + 835, 5, - 84, + 110, 0, 0, - 665, - 666, + 835, + 836, 5, - 104, + 80, 0, 0, - 666, - 667, + 836, + 837, 5, 97, 0, 0, - 667, - 668, + 837, + 838, 5, - 110, + 116, 0, 0, - 668, - 669, + 838, + 839, + 5, + 104, + 0, + 0, + 839, + 840, 5, 34, 0, 0, - 669, - 80, + 840, + 92, 1, 0, 0, 0, - 670, - 671, + 841, + 842, 5, 34, 0, 0, - 671, - 672, + 842, + 843, 5, 78, 0, 0, - 672, - 673, + 843, + 844, 5, 117, 0, 0, - 673, - 674, + 844, + 845, 5, 109, 0, 0, - 674, - 675, + 845, + 846, 5, 101, 0, 0, - 675, - 676, + 846, + 847, 5, 114, 0, 0, - 676, - 677, + 847, + 848, 5, 105, 0, 0, - 677, - 678, + 848, + 849, 5, 99, 0, 0, - 678, - 679, - 5, - 71, - 0, - 0, - 679, - 680, + 849, + 850, 5, - 114, + 76, 0, 0, - 680, - 681, + 850, + 851, 5, 101, 0, 0, - 681, - 682, + 851, + 852, 5, - 97, + 115, 0, 0, - 682, - 683, + 852, + 853, 5, - 116, + 115, 0, 0, - 683, - 684, + 853, + 854, 5, - 101, + 84, 0, 0, - 684, - 685, + 854, + 855, 5, - 114, + 104, 0, 0, - 685, - 686, + 855, + 856, 5, - 84, + 97, 0, 0, - 686, - 687, + 856, + 857, 5, - 104, + 110, 0, 0, - 687, - 688, + 857, + 858, 5, - 97, + 69, 0, 0, - 688, - 689, + 858, + 859, 5, - 110, + 113, 0, 0, - 689, - 690, + 859, + 860, 5, - 80, + 117, 0, 0, - 690, - 691, + 860, + 861, 5, 97, 0, 0, - 691, - 692, + 861, + 862, 5, - 116, + 108, 0, 0, - 692, - 693, + 862, + 863, 5, - 104, + 115, 0, 0, - 693, - 694, + 863, + 864, 5, 34, 0, 0, - 694, - 82, + 864, + 94, 1, 0, 0, 0, - 695, - 696, + 865, + 866, 5, 34, 0, 0, - 696, - 697, + 866, + 867, 5, 78, 0, 0, - 697, - 698, + 867, + 868, 5, 117, 0, 0, - 698, - 699, + 868, + 869, 5, 109, 0, 0, - 699, - 700, + 869, + 870, 5, 101, 0, 0, - 700, - 701, - 5, - 114, - 0, - 0, - 701, - 702, - 5, - 105, - 0, - 0, - 702, - 703, - 5, - 99, - 0, - 0, - 703, - 704, - 5, - 71, - 0, - 0, - 704, - 705, + 870, + 871, 5, 114, 0, 0, - 705, - 706, + 871, + 872, 5, - 101, + 105, 0, 0, - 706, - 707, + 872, + 873, 5, - 97, + 99, 0, 0, - 707, - 708, + 873, + 874, 5, - 116, + 76, 0, 0, - 708, - 709, + 874, + 875, 5, 101, 0, 0, - 709, - 710, + 875, + 876, 5, - 114, + 115, 0, 0, - 710, - 711, + 876, + 877, + 5, + 115, + 0, + 0, + 877, + 878, 5, 84, 0, 0, - 711, - 712, + 878, + 879, 5, 104, 0, 0, - 712, - 713, + 879, + 880, 5, 97, 0, 0, - 713, - 714, + 880, + 881, 5, 110, 0, 0, - 714, - 715, + 881, + 882, 5, 69, 0, 0, - 715, - 716, + 882, + 883, 5, 113, 0, 0, - 716, - 717, + 883, + 884, 5, 117, 0, 0, - 717, - 718, + 884, + 885, 5, 97, 0, 0, - 718, - 719, + 885, + 886, 5, 108, 0, 0, - 719, - 720, + 886, + 887, 5, 115, 0, 0, - 720, - 721, + 887, + 888, + 5, + 80, + 0, + 0, + 888, + 889, + 5, + 97, + 0, + 0, + 889, + 890, + 5, + 116, + 0, + 0, + 890, + 891, + 5, + 104, + 0, + 0, + 891, + 892, 5, 34, 0, 0, - 721, - 84, + 892, + 96, 1, 0, 0, 0, - 722, - 723, + 893, + 894, 5, 34, 0, 0, - 723, - 724, + 894, + 895, 5, - 78, + 79, 0, 0, - 724, - 725, + 895, + 896, 5, - 117, + 114, 0, 0, - 725, - 726, + 896, + 897, 5, - 109, + 34, 0, 0, - 726, - 727, + 897, + 98, + 1, + 0, + 0, + 0, + 898, + 899, 5, - 101, + 34, 0, 0, - 727, - 728, + 899, + 900, + 5, + 83, + 0, + 0, + 900, + 901, + 5, + 116, + 0, + 0, + 901, + 902, 5, 114, 0, 0, - 728, - 729, + 902, + 903, 5, 105, 0, 0, - 729, - 730, + 903, + 904, 5, - 99, + 110, 0, 0, - 730, - 731, + 904, + 905, 5, - 71, + 103, 0, 0, - 731, - 732, + 905, + 906, 5, - 114, + 69, 0, 0, - 732, - 733, + 906, + 907, 5, - 101, + 113, 0, 0, - 733, - 734, + 907, + 908, + 5, + 117, + 0, + 0, + 908, + 909, 5, 97, 0, 0, - 734, - 735, + 909, + 910, 5, - 116, + 108, 0, 0, - 735, - 736, + 910, + 911, 5, - 101, + 115, 0, 0, - 736, - 737, + 911, + 912, 5, - 114, + 34, 0, 0, - 737, - 738, + 912, + 100, + 1, + 0, + 0, + 0, + 913, + 914, 5, - 84, + 34, 0, 0, - 738, - 739, + 914, + 915, 5, - 104, + 83, 0, 0, - 739, - 740, + 915, + 916, + 5, + 116, + 0, + 0, + 916, + 917, + 5, + 114, + 0, + 0, + 917, + 918, + 5, + 105, + 0, + 0, + 918, + 919, 5, - 97, + 110, 0, 0, - 740, - 741, + 919, + 920, 5, - 110, + 103, 0, 0, - 741, - 742, + 920, + 921, 5, 69, 0, 0, - 742, - 743, + 921, + 922, 5, 113, 0, 0, - 743, - 744, + 922, + 923, 5, 117, 0, 0, - 744, - 745, + 923, + 924, 5, 97, 0, 0, - 745, - 746, + 924, + 925, 5, 108, 0, 0, - 746, - 747, + 925, + 926, 5, 115, 0, 0, - 747, - 748, + 926, + 927, 5, 80, 0, 0, - 748, - 749, + 927, + 928, 5, 97, 0, 0, - 749, - 750, + 928, + 929, 5, 116, 0, 0, - 750, - 751, + 929, + 930, 5, 104, 0, 0, - 751, - 752, + 930, + 931, 5, 34, 0, 0, - 752, - 86, + 931, + 102, 1, 0, 0, 0, - 753, - 754, + 932, + 933, 5, 34, 0, 0, - 754, - 755, + 933, + 934, 5, - 78, + 83, 0, 0, - 755, - 756, + 934, + 935, 5, - 117, + 116, 0, 0, - 756, - 757, + 935, + 936, 5, - 109, + 114, 0, 0, - 757, - 758, + 936, + 937, 5, - 101, + 105, 0, 0, - 758, - 759, + 937, + 938, 5, - 114, + 110, 0, 0, - 759, - 760, + 938, + 939, 5, - 105, + 103, 0, 0, - 760, - 761, + 939, + 940, 5, - 99, + 71, 0, 0, - 761, - 762, + 940, + 941, 5, - 76, + 114, 0, 0, - 762, - 763, + 941, + 942, 5, 101, 0, 0, - 763, - 764, + 942, + 943, 5, - 115, + 97, 0, 0, - 764, - 765, + 943, + 944, 5, - 115, + 116, 0, 0, - 765, - 766, + 944, + 945, + 5, + 101, + 0, + 0, + 945, + 946, + 5, + 114, + 0, + 0, + 946, + 947, 5, 84, 0, 0, - 766, - 767, + 947, + 948, 5, 104, 0, 0, - 767, - 768, + 948, + 949, 5, 97, 0, 0, - 768, - 769, + 949, + 950, 5, 110, 0, 0, - 769, - 770, + 950, + 951, 5, 34, 0, 0, - 770, - 88, + 951, + 104, 1, 0, 0, 0, - 771, - 772, + 952, + 953, 5, 34, 0, 0, - 772, - 773, + 953, + 954, 5, - 78, + 83, 0, 0, - 773, - 774, + 954, + 955, 5, - 117, + 116, 0, 0, - 774, - 775, + 955, + 956, 5, - 109, + 114, 0, 0, - 775, - 776, + 956, + 957, 5, - 101, + 105, 0, 0, - 776, - 777, + 957, + 958, 5, - 114, + 110, 0, 0, - 777, - 778, + 958, + 959, 5, - 105, + 103, 0, 0, - 778, - 779, + 959, + 960, 5, - 99, + 71, 0, 0, - 779, - 780, + 960, + 961, 5, - 76, + 114, 0, 0, - 780, - 781, + 961, + 962, 5, 101, 0, 0, - 781, - 782, + 962, + 963, 5, - 115, + 97, 0, 0, - 782, - 783, + 963, + 964, 5, - 115, + 116, 0, 0, - 783, - 784, + 964, + 965, + 5, + 101, + 0, + 0, + 965, + 966, + 5, + 114, + 0, + 0, + 966, + 967, 5, 84, 0, 0, - 784, - 785, + 967, + 968, 5, 104, 0, 0, - 785, - 786, + 968, + 969, 5, 97, 0, 0, - 786, - 787, + 969, + 970, 5, 110, 0, 0, - 787, - 788, + 970, + 971, 5, 80, 0, 0, - 788, - 789, + 971, + 972, 5, 97, 0, 0, - 789, - 790, + 972, + 973, 5, 116, 0, 0, - 790, - 791, + 973, + 974, 5, 104, 0, 0, - 791, - 792, + 974, + 975, 5, 34, 0, 0, - 792, - 90, + 975, + 106, 1, 0, 0, 0, - 793, - 794, + 976, + 977, 5, 34, 0, 0, - 794, - 795, + 977, + 978, 5, - 78, + 83, 0, 0, - 795, - 796, + 978, + 979, 5, - 117, + 116, 0, 0, - 796, - 797, + 979, + 980, 5, - 109, + 114, 0, 0, - 797, - 798, + 980, + 981, 5, - 101, + 105, 0, 0, - 798, - 799, + 981, + 982, 5, - 114, + 110, 0, 0, - 799, - 800, + 982, + 983, 5, - 105, + 103, 0, 0, - 800, - 801, + 983, + 984, 5, - 99, + 71, 0, 0, - 801, - 802, + 984, + 985, 5, - 76, + 114, 0, 0, - 802, - 803, + 985, + 986, 5, 101, 0, 0, - 803, - 804, + 986, + 987, 5, - 115, + 97, 0, 0, - 804, - 805, + 987, + 988, 5, - 115, + 116, 0, 0, - 805, - 806, + 988, + 989, + 5, + 101, + 0, + 0, + 989, + 990, + 5, + 114, + 0, + 0, + 990, + 991, 5, 84, 0, 0, - 806, - 807, + 991, + 992, 5, 104, 0, 0, - 807, - 808, + 992, + 993, 5, 97, 0, 0, - 808, - 809, + 993, + 994, 5, 110, 0, 0, - 809, - 810, + 994, + 995, 5, 69, 0, 0, - 810, - 811, + 995, + 996, 5, 113, 0, 0, - 811, - 812, + 996, + 997, 5, 117, 0, 0, - 812, - 813, + 997, + 998, 5, 97, 0, 0, - 813, - 814, + 998, + 999, 5, 108, 0, 0, - 814, - 815, + 999, + 1000, 5, 115, 0, 0, - 815, - 816, + 1000, + 1001, 5, 34, 0, 0, - 816, - 92, + 1001, + 108, 1, 0, 0, 0, - 817, - 818, + 1002, + 1003, 5, 34, 0, 0, - 818, - 819, + 1003, + 1004, 5, - 78, + 83, 0, 0, - 819, - 820, + 1004, + 1005, 5, - 117, + 116, 0, 0, - 820, - 821, + 1005, + 1006, 5, - 109, + 114, 0, 0, - 821, - 822, + 1006, + 1007, 5, - 101, + 105, 0, 0, - 822, - 823, + 1007, + 1008, 5, - 114, + 110, 0, 0, - 823, - 824, + 1008, + 1009, 5, - 105, + 103, 0, 0, - 824, - 825, + 1009, + 1010, 5, - 99, + 71, 0, 0, - 825, - 826, + 1010, + 1011, 5, - 76, + 114, 0, 0, - 826, - 827, + 1011, + 1012, 5, 101, 0, 0, - 827, - 828, + 1012, + 1013, 5, - 115, + 97, 0, 0, - 828, - 829, + 1013, + 1014, 5, - 115, + 116, 0, 0, - 829, - 830, + 1014, + 1015, + 5, + 101, + 0, + 0, + 1015, + 1016, + 5, + 114, + 0, + 0, + 1016, + 1017, 5, 84, 0, 0, - 830, - 831, + 1017, + 1018, 5, 104, 0, 0, - 831, - 832, + 1018, + 1019, 5, 97, 0, 0, - 832, - 833, + 1019, + 1020, 5, 110, 0, 0, - 833, - 834, + 1020, + 1021, 5, 69, 0, 0, - 834, - 835, + 1021, + 1022, 5, 113, 0, 0, - 835, - 836, + 1022, + 1023, 5, 117, 0, 0, - 836, - 837, + 1023, + 1024, 5, 97, 0, 0, - 837, - 838, + 1024, + 1025, 5, 108, 0, 0, - 838, - 839, + 1025, + 1026, 5, 115, 0, 0, - 839, - 840, + 1026, + 1027, 5, 80, 0, 0, - 840, - 841, + 1027, + 1028, 5, 97, 0, 0, - 841, - 842, + 1028, + 1029, 5, 116, 0, 0, - 842, - 843, + 1029, + 1030, 5, 104, 0, 0, - 843, - 844, + 1030, + 1031, 5, 34, 0, 0, - 844, - 94, + 1031, + 110, 1, 0, 0, 0, - 845, - 846, + 1032, + 1033, 5, 34, 0, 0, - 846, - 847, - 5, - 79, - 0, - 0, - 847, - 848, + 1033, + 1034, 5, - 114, + 83, 0, 0, - 848, - 849, + 1034, + 1035, 5, - 34, - 0, - 0, - 849, - 96, - 1, - 0, + 116, 0, 0, - 850, - 851, + 1035, + 1036, 5, - 34, + 114, 0, 0, - 851, - 852, + 1036, + 1037, 5, - 83, + 105, 0, 0, - 852, - 853, + 1037, + 1038, 5, - 116, + 110, 0, 0, - 853, - 854, + 1038, + 1039, 5, - 114, + 103, 0, 0, - 854, - 855, + 1039, + 1040, 5, - 105, + 76, 0, 0, - 855, - 856, + 1040, + 1041, 5, - 110, + 101, 0, 0, - 856, - 857, + 1041, + 1042, 5, - 103, + 115, 0, 0, - 857, - 858, + 1042, + 1043, 5, - 69, + 115, 0, 0, - 858, - 859, + 1043, + 1044, 5, - 113, + 84, 0, 0, - 859, - 860, + 1044, + 1045, 5, - 117, + 104, 0, 0, - 860, - 861, + 1045, + 1046, 5, 97, 0, 0, - 861, - 862, - 5, - 108, - 0, - 0, - 862, - 863, + 1046, + 1047, 5, - 115, + 110, 0, 0, - 863, - 864, + 1047, + 1048, 5, 34, 0, 0, - 864, - 98, + 1048, + 112, 1, 0, 0, 0, - 865, - 866, + 1049, + 1050, 5, 34, 0, 0, - 866, - 867, + 1050, + 1051, 5, 83, 0, 0, - 867, - 868, + 1051, + 1052, 5, 116, 0, 0, - 868, - 869, + 1052, + 1053, 5, 114, 0, 0, - 869, - 870, + 1053, + 1054, 5, 105, 0, 0, - 870, - 871, + 1054, + 1055, 5, 110, 0, 0, - 871, - 872, + 1055, + 1056, 5, 103, 0, 0, - 872, - 873, + 1056, + 1057, 5, - 69, + 76, 0, 0, - 873, - 874, + 1057, + 1058, 5, - 113, + 101, 0, 0, - 874, - 875, + 1058, + 1059, 5, - 117, + 115, 0, 0, - 875, - 876, + 1059, + 1060, 5, - 97, + 115, 0, 0, - 876, - 877, + 1060, + 1061, 5, - 108, + 84, 0, 0, - 877, - 878, + 1061, + 1062, 5, - 115, + 104, 0, 0, - 878, - 879, + 1062, + 1063, + 5, + 97, + 0, + 0, + 1063, + 1064, + 5, + 110, + 0, + 0, + 1064, + 1065, 5, 80, 0, 0, - 879, - 880, + 1065, + 1066, 5, 97, 0, 0, - 880, - 881, + 1066, + 1067, 5, 116, 0, 0, - 881, - 882, + 1067, + 1068, 5, 104, 0, 0, - 882, - 883, + 1068, + 1069, 5, 34, 0, 0, - 883, - 100, + 1069, + 114, 1, 0, 0, 0, - 884, - 885, + 1070, + 1071, 5, 34, 0, 0, - 885, - 886, + 1071, + 1072, 5, 83, 0, 0, - 886, - 887, + 1072, + 1073, 5, 116, 0, 0, - 887, - 888, + 1073, + 1074, 5, 114, 0, 0, - 888, - 889, + 1074, + 1075, 5, 105, 0, 0, - 889, - 890, + 1075, + 1076, 5, 110, 0, 0, - 890, - 891, + 1076, + 1077, 5, 103, 0, 0, - 891, - 892, + 1077, + 1078, 5, - 71, + 76, 0, 0, - 892, - 893, + 1078, + 1079, 5, - 114, + 101, 0, 0, - 893, - 894, + 1079, + 1080, 5, - 101, + 115, 0, 0, - 894, - 895, + 1080, + 1081, 5, - 97, + 115, 0, 0, - 895, - 896, + 1081, + 1082, 5, - 116, + 84, 0, 0, - 896, - 897, + 1082, + 1083, 5, - 101, + 104, 0, 0, - 897, - 898, + 1083, + 1084, 5, - 114, + 97, 0, 0, - 898, - 899, + 1084, + 1085, 5, - 84, + 110, 0, 0, - 899, - 900, + 1085, + 1086, 5, - 104, + 69, 0, 0, - 900, - 901, + 1086, + 1087, + 5, + 113, + 0, + 0, + 1087, + 1088, + 5, + 117, + 0, + 0, + 1088, + 1089, 5, 97, 0, 0, - 901, - 902, + 1089, + 1090, 5, - 110, + 108, 0, 0, - 902, - 903, + 1090, + 1091, + 5, + 115, + 0, + 0, + 1091, + 1092, 5, 34, 0, 0, - 903, - 102, + 1092, + 116, 1, 0, 0, 0, - 904, - 905, + 1093, + 1094, 5, 34, 0, 0, - 905, - 906, + 1094, + 1095, 5, 83, 0, 0, - 906, - 907, + 1095, + 1096, 5, 116, 0, 0, - 907, - 908, + 1096, + 1097, 5, 114, 0, 0, - 908, - 909, + 1097, + 1098, 5, 105, 0, 0, - 909, - 910, + 1098, + 1099, 5, 110, 0, 0, - 910, - 911, + 1099, + 1100, 5, 103, 0, 0, - 911, - 912, + 1100, + 1101, 5, - 71, + 76, 0, 0, - 912, - 913, + 1101, + 1102, 5, - 114, + 101, 0, 0, - 913, - 914, + 1102, + 1103, 5, - 101, + 115, 0, 0, - 914, - 915, + 1103, + 1104, 5, - 97, + 115, 0, 0, - 915, - 916, + 1104, + 1105, 5, - 116, + 84, 0, 0, - 916, - 917, + 1105, + 1106, 5, - 101, + 104, 0, 0, - 917, - 918, + 1106, + 1107, 5, - 114, + 97, 0, 0, - 918, - 919, + 1107, + 1108, 5, - 84, + 110, 0, 0, - 919, - 920, + 1108, + 1109, 5, - 104, + 69, 0, 0, - 920, - 921, + 1109, + 1110, + 5, + 113, + 0, + 0, + 1110, + 1111, + 5, + 117, + 0, + 0, + 1111, + 1112, 5, 97, 0, 0, - 921, - 922, + 1112, + 1113, 5, - 110, + 108, 0, 0, - 922, - 923, + 1113, + 1114, + 5, + 115, + 0, + 0, + 1114, + 1115, 5, 80, 0, 0, - 923, - 924, + 1115, + 1116, 5, 97, 0, 0, - 924, - 925, + 1116, + 1117, 5, 116, 0, 0, - 925, - 926, + 1117, + 1118, 5, 104, 0, 0, - 926, - 927, + 1118, + 1119, 5, 34, 0, 0, - 927, - 104, + 1119, + 118, 1, 0, 0, 0, - 928, - 929, + 1120, + 1121, 5, 34, 0, 0, - 929, - 930, + 1121, + 1122, 5, 83, 0, 0, - 930, - 931, + 1122, + 1123, 5, 116, 0, 0, - 931, - 932, + 1123, + 1124, 5, 114, 0, 0, - 932, - 933, + 1124, + 1125, 5, 105, 0, 0, - 933, - 934, + 1125, + 1126, 5, 110, 0, 0, - 934, - 935, + 1126, + 1127, 5, 103, 0, 0, - 935, - 936, + 1127, + 1128, 5, - 71, + 77, 0, 0, - 936, - 937, + 1128, + 1129, 5, - 114, + 97, 0, 0, - 937, - 938, + 1129, + 1130, 5, - 101, + 116, 0, 0, - 938, - 939, + 1130, + 1131, 5, - 97, + 99, 0, 0, - 939, - 940, + 1131, + 1132, 5, - 116, + 104, 0, 0, - 940, - 941, + 1132, + 1133, 5, 101, 0, 0, - 941, - 942, + 1133, + 1134, 5, - 114, + 115, 0, 0, - 942, - 943, + 1134, + 1135, 5, - 84, + 34, 0, 0, - 943, - 944, - 5, - 104, + 1135, + 120, + 1, 0, 0, - 944, - 945, + 0, + 1136, + 1137, 5, - 97, + 34, 0, 0, - 945, - 946, + 1137, + 1138, 5, - 110, + 84, 0, 0, - 946, - 947, + 1138, + 1139, 5, - 69, + 105, 0, 0, - 947, - 948, + 1139, + 1140, 5, - 113, + 109, 0, 0, - 948, - 949, + 1140, + 1141, 5, - 117, + 101, 0, 0, - 949, - 950, + 1141, + 1142, 5, - 97, + 115, 0, 0, - 950, - 951, + 1142, + 1143, 5, - 108, + 116, 0, 0, - 951, - 952, + 1143, + 1144, 5, - 115, + 97, 0, 0, - 952, - 953, + 1144, + 1145, 5, - 34, - 0, + 109, 0, - 953, - 106, - 1, 0, + 1145, + 1146, + 5, + 112, 0, 0, - 954, - 955, + 1146, + 1147, 5, - 34, + 69, 0, 0, - 955, - 956, + 1147, + 1148, 5, - 83, + 113, 0, 0, - 956, - 957, + 1148, + 1149, 5, - 116, + 117, 0, 0, - 957, - 958, + 1149, + 1150, 5, - 114, + 97, 0, 0, - 958, - 959, + 1150, + 1151, 5, - 105, + 108, 0, 0, - 959, - 960, + 1151, + 1152, 5, - 110, + 115, 0, 0, - 960, - 961, + 1152, + 1153, 5, - 103, + 34, 0, 0, - 961, - 962, - 5, - 71, + 1153, + 122, + 1, 0, 0, - 962, - 963, + 0, + 1154, + 1155, 5, - 114, + 34, 0, 0, - 963, - 964, + 1155, + 1156, 5, - 101, + 84, 0, 0, - 964, - 965, + 1156, + 1157, 5, - 97, + 105, 0, 0, - 965, - 966, + 1157, + 1158, 5, - 116, + 109, 0, 0, - 966, - 967, + 1158, + 1159, 5, 101, 0, 0, - 967, - 968, + 1159, + 1160, 5, - 114, + 115, 0, 0, - 968, - 969, + 1160, + 1161, 5, - 84, + 116, 0, 0, - 969, - 970, + 1161, + 1162, 5, - 104, + 97, 0, 0, - 970, - 971, + 1162, + 1163, 5, - 97, + 109, 0, 0, - 971, - 972, + 1163, + 1164, 5, - 110, + 112, 0, 0, - 972, - 973, + 1164, + 1165, 5, 69, 0, 0, - 973, - 974, + 1165, + 1166, 5, 113, 0, 0, - 974, - 975, + 1166, + 1167, 5, 117, 0, 0, - 975, - 976, + 1167, + 1168, 5, 97, 0, 0, - 976, - 977, + 1168, + 1169, 5, 108, 0, 0, - 977, - 978, + 1169, + 1170, 5, 115, 0, 0, - 978, - 979, + 1170, + 1171, 5, 80, 0, 0, - 979, - 980, + 1171, + 1172, 5, 97, 0, 0, - 980, - 981, + 1172, + 1173, 5, 116, 0, 0, - 981, - 982, + 1173, + 1174, 5, 104, 0, 0, - 982, - 983, + 1174, + 1175, 5, 34, 0, 0, - 983, - 108, + 1175, + 124, 1, 0, 0, 0, - 984, - 985, + 1176, + 1177, 5, 34, 0, 0, - 985, - 986, + 1177, + 1178, 5, - 83, + 84, 0, 0, - 986, - 987, + 1178, + 1179, + 5, + 105, + 0, + 0, + 1179, + 1180, + 5, + 109, + 0, + 0, + 1180, + 1181, + 5, + 101, + 0, + 0, + 1181, + 1182, + 5, + 115, + 0, + 0, + 1182, + 1183, 5, 116, 0, 0, - 987, - 988, + 1183, + 1184, 5, - 114, + 97, 0, 0, - 988, - 989, + 1184, + 1185, 5, - 105, + 109, 0, 0, - 989, - 990, + 1185, + 1186, 5, - 110, + 112, 0, 0, - 990, - 991, + 1186, + 1187, 5, - 103, + 71, 0, 0, - 991, - 992, + 1187, + 1188, 5, - 76, + 114, 0, 0, - 992, - 993, + 1188, + 1189, 5, 101, 0, 0, - 993, - 994, + 1189, + 1190, 5, - 115, + 97, 0, 0, - 994, - 995, + 1190, + 1191, 5, - 115, + 116, 0, 0, - 995, - 996, + 1191, + 1192, + 5, + 101, + 0, + 0, + 1192, + 1193, + 5, + 114, + 0, + 0, + 1193, + 1194, 5, 84, 0, 0, - 996, - 997, + 1194, + 1195, 5, 104, 0, 0, - 997, - 998, + 1195, + 1196, 5, 97, 0, 0, - 998, - 999, + 1196, + 1197, 5, 110, 0, 0, - 999, - 1000, + 1197, + 1198, 5, 34, 0, 0, - 1000, - 110, + 1198, + 126, 1, 0, 0, 0, - 1001, - 1002, + 1199, + 1200, 5, 34, 0, 0, - 1002, - 1003, + 1200, + 1201, 5, - 83, + 84, 0, 0, - 1003, - 1004, + 1201, + 1202, + 5, + 105, + 0, + 0, + 1202, + 1203, + 5, + 109, + 0, + 0, + 1203, + 1204, + 5, + 101, + 0, + 0, + 1204, + 1205, + 5, + 115, + 0, + 0, + 1205, + 1206, 5, 116, 0, 0, - 1004, - 1005, + 1206, + 1207, 5, - 114, + 97, 0, 0, - 1005, - 1006, + 1207, + 1208, 5, - 105, + 109, 0, 0, - 1006, - 1007, + 1208, + 1209, 5, - 110, + 112, 0, 0, - 1007, - 1008, + 1209, + 1210, 5, - 103, + 71, 0, 0, - 1008, - 1009, + 1210, + 1211, 5, - 76, + 114, 0, 0, - 1009, - 1010, + 1211, + 1212, 5, 101, 0, 0, - 1010, - 1011, + 1212, + 1213, 5, - 115, + 97, 0, 0, - 1011, - 1012, + 1213, + 1214, 5, - 115, + 116, 0, 0, - 1012, - 1013, + 1214, + 1215, + 5, + 101, + 0, + 0, + 1215, + 1216, + 5, + 114, + 0, + 0, + 1216, + 1217, 5, 84, 0, 0, - 1013, - 1014, + 1217, + 1218, 5, 104, 0, 0, - 1014, - 1015, + 1218, + 1219, 5, 97, 0, 0, - 1015, - 1016, + 1219, + 1220, 5, 110, 0, 0, - 1016, - 1017, + 1220, + 1221, 5, 80, 0, 0, - 1017, - 1018, + 1221, + 1222, 5, 97, 0, 0, - 1018, - 1019, + 1222, + 1223, 5, 116, 0, 0, - 1019, - 1020, + 1223, + 1224, 5, 104, 0, 0, - 1020, - 1021, + 1224, + 1225, 5, 34, 0, 0, - 1021, - 112, + 1225, + 128, 1, 0, 0, 0, - 1022, - 1023, + 1226, + 1227, 5, 34, 0, 0, - 1023, - 1024, + 1227, + 1228, 5, - 83, + 84, 0, 0, - 1024, - 1025, + 1228, + 1229, + 5, + 105, + 0, + 0, + 1229, + 1230, + 5, + 109, + 0, + 0, + 1230, + 1231, + 5, + 101, + 0, + 0, + 1231, + 1232, + 5, + 115, + 0, + 0, + 1232, + 1233, 5, 116, 0, 0, - 1025, - 1026, + 1233, + 1234, 5, - 114, + 97, 0, 0, - 1026, - 1027, + 1234, + 1235, 5, - 105, + 109, 0, 0, - 1027, - 1028, + 1235, + 1236, 5, - 110, + 112, 0, 0, - 1028, - 1029, + 1236, + 1237, 5, - 103, + 71, 0, 0, - 1029, - 1030, + 1237, + 1238, 5, - 76, + 114, 0, 0, - 1030, - 1031, + 1238, + 1239, 5, 101, 0, 0, - 1031, - 1032, + 1239, + 1240, 5, - 115, + 97, 0, 0, - 1032, - 1033, + 1240, + 1241, 5, - 115, + 116, 0, 0, - 1033, - 1034, + 1241, + 1242, + 5, + 101, + 0, + 0, + 1242, + 1243, + 5, + 114, + 0, + 0, + 1243, + 1244, 5, 84, 0, 0, - 1034, - 1035, + 1244, + 1245, 5, 104, 0, 0, - 1035, - 1036, + 1245, + 1246, 5, 97, 0, 0, - 1036, - 1037, + 1246, + 1247, 5, 110, 0, 0, - 1037, - 1038, + 1247, + 1248, 5, 69, 0, 0, - 1038, - 1039, + 1248, + 1249, 5, 113, 0, 0, - 1039, - 1040, + 1249, + 1250, 5, 117, 0, 0, - 1040, - 1041, + 1250, + 1251, 5, 97, 0, 0, - 1041, - 1042, + 1251, + 1252, 5, 108, 0, 0, - 1042, - 1043, + 1252, + 1253, 5, 115, 0, 0, - 1043, - 1044, + 1253, + 1254, 5, 34, 0, 0, - 1044, - 114, + 1254, + 130, 1, 0, 0, 0, - 1045, - 1046, + 1255, + 1256, 5, 34, 0, 0, - 1046, - 1047, + 1256, + 1257, 5, - 83, + 84, 0, 0, - 1047, - 1048, + 1257, + 1258, + 5, + 105, + 0, + 0, + 1258, + 1259, + 5, + 109, + 0, + 0, + 1259, + 1260, + 5, + 101, + 0, + 0, + 1260, + 1261, + 5, + 115, + 0, + 0, + 1261, + 1262, 5, 116, 0, 0, - 1048, - 1049, + 1262, + 1263, 5, - 114, + 97, 0, 0, - 1049, - 1050, + 1263, + 1264, 5, - 105, + 109, 0, 0, - 1050, - 1051, + 1264, + 1265, 5, - 110, + 112, 0, 0, - 1051, - 1052, + 1265, + 1266, 5, - 103, + 71, 0, 0, - 1052, - 1053, + 1266, + 1267, + 5, + 114, + 0, + 0, + 1267, + 1268, + 5, + 101, + 0, + 0, + 1268, + 1269, 5, - 76, + 97, 0, 0, - 1053, - 1054, + 1269, + 1270, 5, - 101, + 116, 0, 0, - 1054, - 1055, + 1270, + 1271, 5, - 115, + 101, 0, 0, - 1055, - 1056, + 1271, + 1272, 5, - 115, + 114, 0, 0, - 1056, - 1057, + 1272, + 1273, 5, 84, 0, 0, - 1057, - 1058, + 1273, + 1274, 5, 104, 0, 0, - 1058, - 1059, + 1274, + 1275, 5, 97, 0, 0, - 1059, - 1060, + 1275, + 1276, 5, 110, 0, 0, - 1060, - 1061, + 1276, + 1277, 5, 69, 0, 0, - 1061, - 1062, + 1277, + 1278, 5, 113, 0, 0, - 1062, - 1063, + 1278, + 1279, 5, 117, 0, 0, - 1063, - 1064, + 1279, + 1280, 5, 97, 0, 0, - 1064, - 1065, + 1280, + 1281, 5, 108, 0, 0, - 1065, - 1066, + 1281, + 1282, 5, 115, 0, 0, - 1066, - 1067, + 1282, + 1283, 5, 80, 0, 0, - 1067, - 1068, + 1283, + 1284, 5, 97, 0, 0, - 1068, - 1069, + 1284, + 1285, 5, 116, 0, 0, - 1069, - 1070, + 1285, + 1286, 5, 104, 0, 0, - 1070, - 1071, + 1286, + 1287, 5, 34, 0, 0, - 1071, - 116, + 1287, + 132, 1, 0, 0, 0, - 1072, - 1073, + 1288, + 1289, 5, 34, 0, 0, - 1073, - 1074, + 1289, + 1290, 5, - 83, + 84, 0, 0, - 1074, - 1075, + 1290, + 1291, + 5, + 105, + 0, + 0, + 1291, + 1292, + 5, + 109, + 0, + 0, + 1292, + 1293, + 5, + 101, + 0, + 0, + 1293, + 1294, + 5, + 115, + 0, + 0, + 1294, + 1295, 5, 116, 0, 0, - 1075, - 1076, + 1295, + 1296, 5, - 114, + 97, 0, 0, - 1076, - 1077, + 1296, + 1297, 5, - 105, + 109, 0, 0, - 1077, - 1078, + 1297, + 1298, 5, - 110, + 112, 0, 0, - 1078, - 1079, + 1298, + 1299, 5, - 103, + 76, 0, 0, - 1079, - 1080, + 1299, + 1300, 5, - 77, + 101, 0, 0, - 1080, - 1081, + 1300, + 1301, 5, - 97, + 115, 0, 0, - 1081, - 1082, + 1301, + 1302, 5, - 116, + 115, 0, 0, - 1082, - 1083, + 1302, + 1303, 5, - 99, + 84, 0, 0, - 1083, - 1084, + 1303, + 1304, 5, 104, 0, 0, - 1084, - 1085, + 1304, + 1305, 5, - 101, + 97, 0, 0, - 1085, - 1086, + 1305, + 1306, 5, - 115, + 110, 0, 0, - 1086, - 1087, + 1306, + 1307, 5, 34, 0, 0, - 1087, - 118, + 1307, + 134, 1, 0, 0, 0, - 1088, - 1089, + 1308, + 1309, 5, 34, 0, 0, - 1089, - 1090, + 1309, + 1310, 5, 84, 0, 0, - 1090, - 1091, + 1310, + 1311, 5, 105, 0, 0, - 1091, - 1092, + 1311, + 1312, 5, 109, 0, 0, - 1092, - 1093, + 1312, + 1313, 5, 101, 0, 0, - 1093, - 1094, + 1313, + 1314, 5, 115, 0, 0, - 1094, - 1095, + 1314, + 1315, + 5, + 116, + 0, + 0, + 1315, + 1316, + 5, + 97, + 0, + 0, + 1316, + 1317, + 5, + 109, + 0, + 0, + 1317, + 1318, + 5, + 112, + 0, + 0, + 1318, + 1319, + 5, + 76, + 0, + 0, + 1319, + 1320, + 5, + 101, + 0, + 0, + 1320, + 1321, 5, - 116, + 115, 0, 0, - 1095, - 1096, + 1321, + 1322, 5, - 97, + 115, 0, 0, - 1096, - 1097, + 1322, + 1323, 5, - 109, + 84, 0, 0, - 1097, - 1098, + 1323, + 1324, 5, - 112, + 104, 0, 0, - 1098, - 1099, + 1324, + 1325, 5, - 69, + 97, 0, 0, - 1099, - 1100, + 1325, + 1326, 5, - 113, + 110, 0, 0, - 1100, - 1101, + 1326, + 1327, 5, - 117, + 80, 0, 0, - 1101, - 1102, + 1327, + 1328, 5, 97, 0, 0, - 1102, - 1103, + 1328, + 1329, 5, - 108, + 116, 0, 0, - 1103, - 1104, + 1329, + 1330, 5, - 115, + 104, 0, 0, - 1104, - 1105, + 1330, + 1331, 5, 34, 0, 0, - 1105, - 120, + 1331, + 136, 1, 0, 0, 0, - 1106, - 1107, + 1332, + 1333, 5, 34, 0, 0, - 1107, - 1108, + 1333, + 1334, 5, 84, 0, 0, - 1108, - 1109, + 1334, + 1335, 5, 105, 0, 0, - 1109, - 1110, + 1335, + 1336, 5, 109, 0, 0, - 1110, - 1111, + 1336, + 1337, 5, 101, 0, 0, - 1111, - 1112, + 1337, + 1338, 5, 115, 0, 0, - 1112, - 1113, + 1338, + 1339, 5, 116, 0, 0, - 1113, - 1114, + 1339, + 1340, 5, 97, 0, 0, - 1114, - 1115, + 1340, + 1341, 5, 109, 0, 0, - 1115, - 1116, + 1341, + 1342, 5, 112, 0, 0, - 1116, - 1117, + 1342, + 1343, 5, - 69, + 76, 0, 0, - 1117, - 1118, + 1343, + 1344, 5, - 113, + 101, 0, 0, - 1118, - 1119, + 1344, + 1345, 5, - 117, + 115, 0, 0, - 1119, - 1120, + 1345, + 1346, + 5, + 115, + 0, + 0, + 1346, + 1347, + 5, + 84, + 0, + 0, + 1347, + 1348, + 5, + 104, + 0, + 0, + 1348, + 1349, 5, 97, 0, 0, - 1120, - 1121, + 1349, + 1350, 5, - 108, + 110, 0, 0, - 1121, - 1122, + 1350, + 1351, 5, - 115, + 69, 0, 0, - 1122, - 1123, + 1351, + 1352, 5, - 80, + 113, 0, 0, - 1123, - 1124, + 1352, + 1353, + 5, + 117, + 0, + 0, + 1353, + 1354, 5, 97, 0, 0, - 1124, - 1125, + 1354, + 1355, 5, - 116, + 108, 0, 0, - 1125, - 1126, + 1355, + 1356, 5, - 104, + 115, 0, 0, - 1126, - 1127, + 1356, + 1357, 5, 34, 0, 0, - 1127, - 122, + 1357, + 138, 1, 0, 0, 0, - 1128, - 1129, + 1358, + 1359, 5, 34, 0, 0, - 1129, - 1130, + 1359, + 1360, 5, 84, 0, 0, - 1130, - 1131, + 1360, + 1361, 5, 105, 0, 0, - 1131, - 1132, + 1361, + 1362, 5, 109, 0, 0, - 1132, - 1133, + 1362, + 1363, + 5, + 101, + 0, + 0, + 1363, + 1364, + 5, + 115, + 0, + 0, + 1364, + 1365, + 5, + 116, + 0, + 0, + 1365, + 1366, + 5, + 97, + 0, + 0, + 1366, + 1367, + 5, + 109, + 0, + 0, + 1367, + 1368, + 5, + 112, + 0, + 0, + 1368, + 1369, + 5, + 76, + 0, + 0, + 1369, + 1370, 5, 101, 0, 0, - 1133, - 1134, + 1370, + 1371, 5, 115, 0, 0, - 1134, - 1135, + 1371, + 1372, 5, - 116, + 115, 0, 0, - 1135, - 1136, + 1372, + 1373, 5, - 97, + 84, 0, 0, - 1136, - 1137, + 1373, + 1374, 5, - 109, + 104, 0, 0, - 1137, - 1138, + 1374, + 1375, 5, - 112, + 97, 0, 0, - 1138, - 1139, + 1375, + 1376, 5, - 71, + 110, 0, 0, - 1139, - 1140, + 1376, + 1377, 5, - 114, + 69, 0, 0, - 1140, - 1141, + 1377, + 1378, 5, - 101, + 113, 0, 0, - 1141, - 1142, + 1378, + 1379, 5, - 97, + 117, 0, 0, - 1142, - 1143, + 1379, + 1380, 5, - 116, + 97, 0, 0, - 1143, - 1144, + 1380, + 1381, 5, - 101, + 108, 0, 0, - 1144, - 1145, + 1381, + 1382, 5, - 114, + 115, 0, 0, - 1145, - 1146, + 1382, + 1383, 5, - 84, + 80, 0, 0, - 1146, - 1147, + 1383, + 1384, 5, - 104, + 97, 0, 0, - 1147, - 1148, + 1384, + 1385, 5, - 97, + 116, 0, 0, - 1148, - 1149, + 1385, + 1386, 5, - 110, + 104, 0, 0, - 1149, - 1150, + 1386, + 1387, 5, 34, 0, 0, - 1150, - 124, + 1387, + 140, 1, 0, 0, 0, - 1151, - 1152, + 1388, + 1389, 5, 34, 0, 0, - 1152, - 1153, - 5, - 84, - 0, - 0, - 1153, - 1154, - 5, - 105, - 0, - 0, - 1154, - 1155, + 1389, + 1390, 5, - 109, + 83, 0, 0, - 1155, - 1156, + 1390, + 1391, 5, 101, 0, 0, - 1156, - 1157, + 1391, + 1392, 5, - 115, + 99, 0, 0, - 1157, - 1158, + 1392, + 1393, 5, - 116, + 111, 0, 0, - 1158, - 1159, + 1393, + 1394, 5, - 97, + 110, 0, 0, - 1159, - 1160, + 1394, + 1395, 5, - 109, + 100, 0, 0, - 1160, - 1161, + 1395, + 1396, 5, - 112, + 115, 0, 0, - 1161, - 1162, + 1396, + 1397, 5, - 71, + 80, 0, 0, - 1162, - 1163, + 1397, + 1398, 5, - 114, + 97, 0, 0, - 1163, - 1164, + 1398, + 1399, 5, - 101, + 116, 0, 0, - 1164, - 1165, + 1399, + 1400, 5, - 97, + 104, 0, 0, - 1165, - 1166, + 1400, + 1401, 5, - 116, - 0, + 34, 0, - 1166, - 1167, - 5, - 101, 0, + 1401, + 142, + 1, 0, - 1167, - 1168, - 5, - 114, 0, 0, - 1168, - 1169, + 1402, + 1403, 5, - 84, + 34, 0, 0, - 1169, - 1170, + 1403, + 1404, 5, - 104, + 83, 0, 0, - 1170, - 1171, + 1404, + 1405, 5, - 97, + 101, 0, 0, - 1171, - 1172, + 1405, + 1406, 5, - 110, + 99, 0, 0, - 1172, - 1173, + 1406, + 1407, 5, - 80, + 111, 0, 0, - 1173, - 1174, + 1407, + 1408, 5, - 97, + 110, 0, 0, - 1174, - 1175, + 1408, + 1409, 5, - 116, + 100, 0, 0, - 1175, - 1176, + 1409, + 1410, 5, - 104, + 115, 0, 0, - 1176, - 1177, + 1410, + 1411, 5, 34, 0, 0, - 1177, - 126, + 1411, + 144, 1, 0, 0, 0, - 1178, - 1179, + 1412, + 1413, 5, 34, 0, 0, - 1179, - 1180, + 1413, + 1414, 5, 84, 0, 0, - 1180, - 1181, + 1414, + 1415, 5, 105, 0, 0, - 1181, - 1182, + 1415, + 1416, 5, 109, 0, 0, - 1182, - 1183, + 1416, + 1417, 5, 101, 0, 0, - 1183, - 1184, + 1417, + 1418, 5, 115, 0, 0, - 1184, - 1185, + 1418, + 1419, 5, 116, 0, 0, - 1185, - 1186, + 1419, + 1420, 5, 97, 0, 0, - 1186, - 1187, + 1420, + 1421, 5, 109, 0, 0, - 1187, - 1188, + 1421, + 1422, 5, 112, 0, 0, - 1188, - 1189, + 1422, + 1423, 5, - 71, + 80, 0, 0, - 1189, - 1190, + 1423, + 1424, 5, - 114, + 97, 0, 0, - 1190, - 1191, + 1424, + 1425, 5, - 101, + 116, 0, 0, - 1191, - 1192, + 1425, + 1426, 5, - 97, + 104, 0, 0, - 1192, - 1193, + 1426, + 1427, 5, - 116, - 0, + 34, 0, - 1193, - 1194, - 5, - 101, 0, + 1427, + 146, + 1, 0, - 1194, - 1195, - 5, - 114, 0, 0, - 1195, - 1196, + 1428, + 1429, 5, - 84, + 34, 0, 0, - 1196, - 1197, + 1429, + 1430, 5, - 104, + 84, 0, 0, - 1197, - 1198, + 1430, + 1431, 5, - 97, + 105, 0, 0, - 1198, - 1199, + 1431, + 1432, 5, - 110, + 109, 0, 0, - 1199, - 1200, + 1432, + 1433, 5, - 69, + 101, 0, 0, - 1200, - 1201, + 1433, + 1434, 5, - 113, + 115, 0, 0, - 1201, - 1202, + 1434, + 1435, 5, - 117, + 116, 0, 0, - 1202, - 1203, + 1435, + 1436, 5, 97, 0, 0, - 1203, - 1204, + 1436, + 1437, 5, - 108, + 109, 0, 0, - 1204, - 1205, + 1437, + 1438, 5, - 115, + 112, 0, 0, - 1205, - 1206, + 1438, + 1439, 5, 34, 0, 0, - 1206, - 128, + 1439, + 148, 1, 0, 0, 0, - 1207, - 1208, + 1440, + 1441, 5, 34, 0, 0, - 1208, - 1209, + 1441, + 1442, 5, 84, 0, 0, - 1209, - 1210, + 1442, + 1443, 5, 105, 0, 0, - 1210, - 1211, + 1443, + 1444, 5, 109, 0, 0, - 1211, - 1212, + 1444, + 1445, 5, 101, 0, 0, - 1212, - 1213, - 5, - 115, - 0, - 0, - 1213, - 1214, - 5, - 116, - 0, - 0, - 1214, - 1215, - 5, - 97, - 0, - 0, - 1215, - 1216, - 5, - 109, - 0, - 0, - 1216, - 1217, - 5, - 112, - 0, - 0, - 1217, - 1218, - 5, - 71, - 0, - 0, - 1218, - 1219, + 1445, + 1446, 5, - 114, + 111, 0, 0, - 1219, - 1220, + 1446, + 1447, 5, - 101, + 117, 0, 0, - 1220, - 1221, + 1447, + 1448, 5, - 97, + 116, 0, 0, - 1221, - 1222, + 1448, + 1449, 5, - 116, + 83, 0, 0, - 1222, - 1223, + 1449, + 1450, 5, 101, 0, 0, - 1223, - 1224, + 1450, + 1451, 5, - 114, + 99, 0, 0, - 1224, - 1225, + 1451, + 1452, 5, - 84, + 111, 0, 0, - 1225, - 1226, + 1452, + 1453, 5, - 104, + 110, 0, 0, - 1226, - 1227, + 1453, + 1454, 5, - 97, + 100, 0, 0, - 1227, - 1228, + 1454, + 1455, 5, - 110, + 115, 0, 0, - 1228, - 1229, + 1455, + 1456, 5, - 69, + 34, 0, 0, - 1229, - 1230, + 1456, + 150, + 1, + 0, + 0, + 0, + 1457, + 1458, 5, - 113, + 34, 0, 0, - 1230, - 1231, + 1458, + 1459, 5, - 117, + 84, 0, 0, - 1231, - 1232, + 1459, + 1460, 5, - 97, + 105, 0, 0, - 1232, - 1233, + 1460, + 1461, 5, - 108, + 109, 0, 0, - 1233, - 1234, + 1461, + 1462, 5, - 115, + 101, 0, 0, - 1234, - 1235, + 1462, + 1463, 5, - 80, + 111, 0, 0, - 1235, - 1236, + 1463, + 1464, 5, - 97, + 117, 0, 0, - 1236, - 1237, + 1464, + 1465, 5, 116, 0, 0, - 1237, - 1238, + 1465, + 1466, 5, - 104, + 83, 0, 0, - 1238, - 1239, + 1466, + 1467, 5, - 34, - 0, + 101, 0, - 1239, - 130, - 1, 0, + 1467, + 1468, + 5, + 99, 0, 0, - 1240, - 1241, + 1468, + 1469, 5, - 34, + 111, 0, 0, - 1241, - 1242, + 1469, + 1470, 5, - 84, + 110, 0, 0, - 1242, - 1243, + 1470, + 1471, 5, - 105, + 100, 0, 0, - 1243, - 1244, + 1471, + 1472, 5, - 109, + 115, 0, 0, - 1244, - 1245, + 1472, + 1473, 5, - 101, + 80, 0, 0, - 1245, - 1246, + 1473, + 1474, 5, - 115, + 97, 0, 0, - 1246, - 1247, + 1474, + 1475, 5, 116, 0, 0, - 1247, - 1248, + 1475, + 1476, 5, - 97, + 104, 0, 0, - 1248, - 1249, + 1476, + 1477, 5, - 109, + 34, 0, 0, - 1249, - 1250, + 1477, + 152, + 1, + 0, + 0, + 0, + 1478, + 1479, 5, - 112, + 34, 0, 0, - 1250, - 1251, + 1479, + 1480, 5, - 76, + 72, 0, 0, - 1251, - 1252, + 1480, + 1481, 5, 101, 0, 0, - 1252, - 1253, + 1481, + 1482, 5, - 115, + 97, 0, 0, - 1253, - 1254, + 1482, + 1483, 5, - 115, + 114, 0, 0, - 1254, - 1255, + 1483, + 1484, 5, - 84, + 116, 0, 0, - 1255, - 1256, + 1484, + 1485, 5, - 104, + 98, 0, 0, - 1256, - 1257, + 1485, + 1486, 5, - 97, + 101, 0, 0, - 1257, - 1258, + 1486, + 1487, 5, - 110, + 97, 0, 0, - 1258, - 1259, + 1487, + 1488, 5, - 34, - 0, + 116, 0, - 1259, - 132, - 1, 0, + 1488, + 1489, + 5, + 83, 0, 0, - 1260, - 1261, + 1489, + 1490, 5, - 34, + 101, 0, 0, - 1261, - 1262, + 1490, + 1491, 5, - 84, + 99, 0, 0, - 1262, - 1263, + 1491, + 1492, 5, - 105, + 111, 0, 0, - 1263, - 1264, + 1492, + 1493, 5, - 109, + 110, 0, 0, - 1264, - 1265, + 1493, + 1494, 5, - 101, + 100, 0, 0, - 1265, - 1266, + 1494, + 1495, 5, 115, 0, 0, - 1266, - 1267, + 1495, + 1496, 5, - 116, - 0, + 34, 0, - 1267, - 1268, - 5, - 97, 0, + 1496, + 154, + 1, 0, - 1268, - 1269, - 5, - 109, 0, 0, - 1269, - 1270, + 1497, + 1498, 5, - 112, + 34, 0, 0, - 1270, - 1271, + 1498, + 1499, 5, - 76, + 72, 0, 0, - 1271, - 1272, + 1499, + 1500, 5, 101, 0, 0, - 1272, - 1273, + 1500, + 1501, 5, - 115, + 97, 0, 0, - 1273, - 1274, + 1501, + 1502, 5, - 115, + 114, 0, 0, - 1274, - 1275, + 1502, + 1503, 5, - 84, + 116, 0, 0, - 1275, - 1276, + 1503, + 1504, 5, - 104, + 98, 0, 0, - 1276, - 1277, + 1504, + 1505, 5, - 97, + 101, 0, 0, - 1277, - 1278, + 1505, + 1506, 5, - 110, + 97, 0, 0, - 1278, - 1279, + 1506, + 1507, 5, - 80, + 116, 0, 0, - 1279, - 1280, + 1507, + 1508, 5, - 97, + 83, 0, 0, - 1280, - 1281, + 1508, + 1509, 5, - 116, + 101, 0, 0, - 1281, - 1282, + 1509, + 1510, 5, - 104, + 99, 0, 0, - 1282, - 1283, + 1510, + 1511, 5, - 34, - 0, + 111, 0, - 1283, - 134, - 1, 0, + 1511, + 1512, + 5, + 110, 0, 0, - 1284, - 1285, + 1512, + 1513, 5, - 34, + 100, 0, 0, - 1285, - 1286, + 1513, + 1514, 5, - 84, + 115, 0, 0, - 1286, - 1287, + 1514, + 1515, 5, - 105, + 80, 0, 0, - 1287, - 1288, + 1515, + 1516, 5, - 109, + 97, 0, 0, - 1288, - 1289, + 1516, + 1517, 5, - 101, + 116, 0, 0, - 1289, - 1290, + 1517, + 1518, 5, - 115, + 104, 0, 0, - 1290, - 1291, + 1518, + 1519, 5, - 116, + 34, 0, 0, - 1291, - 1292, - 5, - 97, + 1519, + 156, + 1, 0, 0, - 1292, - 1293, + 0, + 1520, + 1521, 5, - 109, + 34, 0, 0, - 1293, - 1294, + 1521, + 1522, 5, - 112, + 80, 0, 0, - 1294, - 1295, + 1522, + 1523, 5, - 76, + 114, 0, 0, - 1295, - 1296, + 1523, + 1524, 5, - 101, + 111, 0, 0, - 1296, - 1297, + 1524, + 1525, 5, - 115, + 99, 0, 0, - 1297, - 1298, + 1525, + 1526, 5, - 115, + 101, 0, 0, - 1298, - 1299, + 1526, + 1527, 5, - 84, + 115, 0, 0, - 1299, - 1300, + 1527, + 1528, 5, - 104, + 115, 0, 0, - 1300, - 1301, + 1528, + 1529, 5, - 97, + 111, 0, 0, - 1301, - 1302, + 1529, + 1530, 5, - 110, + 114, 0, 0, - 1302, - 1303, + 1530, + 1531, 5, - 69, + 67, 0, 0, - 1303, - 1304, + 1531, + 1532, 5, - 113, + 111, 0, 0, - 1304, - 1305, + 1532, + 1533, 5, - 117, + 110, 0, 0, - 1305, - 1306, + 1533, + 1534, 5, - 97, + 102, 0, 0, - 1306, - 1307, + 1534, + 1535, 5, - 108, + 105, 0, 0, - 1307, - 1308, + 1535, + 1536, 5, - 115, + 103, 0, 0, - 1308, - 1309, + 1536, + 1537, 5, 34, 0, 0, - 1309, - 136, + 1537, + 158, 1, 0, 0, 0, - 1310, - 1311, + 1538, + 1539, 5, 34, 0, 0, - 1311, - 1312, + 1539, + 1540, 5, - 84, + 77, 0, 0, - 1312, - 1313, + 1540, + 1541, 5, - 105, + 111, 0, 0, - 1313, - 1314, + 1541, + 1542, 5, - 109, + 100, 0, 0, - 1314, - 1315, + 1542, + 1543, 5, 101, 0, 0, - 1315, - 1316, + 1543, + 1544, 5, - 115, + 34, 0, 0, - 1316, - 1317, - 5, - 116, + 1544, + 160, + 1, 0, 0, - 1317, - 1318, + 0, + 1545, + 1546, 5, - 97, + 34, 0, 0, - 1318, - 1319, + 1546, + 1547, 5, - 109, + 73, 0, 0, - 1319, - 1320, + 1547, + 1548, 5, - 112, + 78, 0, 0, - 1320, - 1321, + 1548, + 1549, 5, 76, 0, 0, - 1321, - 1322, + 1549, + 1550, 5, - 101, + 73, 0, 0, - 1322, - 1323, + 1550, + 1551, 5, - 115, + 78, 0, 0, - 1323, - 1324, + 1551, + 1552, 5, - 115, + 69, 0, 0, - 1324, - 1325, + 1552, + 1553, 5, - 84, + 34, 0, 0, - 1325, - 1326, - 5, - 104, + 1553, + 162, + 1, 0, 0, - 1326, - 1327, + 0, + 1554, + 1555, 5, - 97, + 34, 0, 0, - 1327, - 1328, + 1555, + 1556, 5, - 110, + 68, 0, 0, - 1328, - 1329, + 1556, + 1557, 5, - 69, + 73, 0, 0, - 1329, - 1330, + 1557, + 1558, 5, - 113, + 83, 0, 0, - 1330, - 1331, + 1558, + 1559, 5, - 117, + 84, 0, 0, - 1331, - 1332, + 1559, + 1560, 5, - 97, + 82, 0, 0, - 1332, - 1333, + 1560, + 1561, 5, - 108, + 73, 0, 0, - 1333, - 1334, + 1561, + 1562, 5, - 115, + 66, 0, 0, - 1334, - 1335, + 1562, + 1563, 5, - 80, + 85, 0, 0, - 1335, - 1336, + 1563, + 1564, 5, - 97, + 84, 0, 0, - 1336, - 1337, + 1564, + 1565, 5, - 116, + 69, 0, 0, - 1337, - 1338, + 1565, + 1566, 5, - 104, + 68, 0, 0, - 1338, - 1339, + 1566, + 1567, 5, 34, 0, 0, - 1339, - 138, + 1567, + 164, 1, 0, 0, 0, - 1340, - 1341, + 1568, + 1569, 5, 34, 0, 0, - 1341, - 1342, + 1569, + 1570, 5, - 83, + 69, 0, 0, - 1342, - 1343, + 1570, + 1571, + 5, + 120, + 0, + 0, + 1571, + 1572, 5, 101, 0, 0, - 1343, - 1344, + 1572, + 1573, 5, 99, 0, 0, - 1344, - 1345, + 1573, + 1574, 5, - 111, + 117, 0, 0, - 1345, - 1346, + 1574, + 1575, 5, - 110, + 116, 0, 0, - 1346, - 1347, + 1575, + 1576, 5, - 100, + 105, 0, 0, - 1347, - 1348, + 1576, + 1577, 5, - 115, + 111, 0, 0, - 1348, - 1349, + 1577, + 1578, 5, - 80, + 110, 0, 0, - 1349, - 1350, + 1578, + 1579, 5, - 97, + 84, 0, 0, - 1350, - 1351, + 1579, + 1580, 5, - 116, + 121, 0, 0, - 1351, - 1352, + 1580, + 1581, 5, - 104, + 112, 0, 0, - 1352, - 1353, + 1581, + 1582, + 5, + 101, + 0, + 0, + 1582, + 1583, 5, 34, 0, 0, - 1353, - 140, + 1583, + 166, 1, 0, 0, 0, - 1354, - 1355, + 1584, + 1585, 5, 34, 0, 0, - 1355, - 1356, + 1585, + 1586, 5, 83, 0, 0, - 1356, - 1357, + 1586, + 1587, 5, - 101, + 84, 0, 0, - 1357, - 1358, + 1587, + 1588, 5, - 99, + 65, 0, 0, - 1358, - 1359, + 1588, + 1589, 5, - 111, + 78, 0, 0, - 1359, - 1360, + 1589, + 1590, 5, - 110, + 68, 0, 0, - 1360, - 1361, + 1590, + 1591, 5, - 100, + 65, 0, 0, - 1361, - 1362, + 1591, + 1592, 5, - 115, + 82, 0, 0, - 1362, - 1363, + 1592, + 1593, + 5, + 68, + 0, + 0, + 1593, + 1594, 5, 34, 0, 0, - 1363, - 142, + 1594, + 168, 1, 0, 0, 0, - 1364, - 1365, + 1595, + 1596, 5, 34, 0, 0, - 1365, - 1366, + 1596, + 1597, 5, - 84, + 73, 0, 0, - 1366, - 1367, + 1597, + 1598, 5, - 105, + 116, 0, 0, - 1367, - 1368, + 1598, + 1599, 5, - 109, + 101, 0, 0, - 1368, - 1369, + 1599, + 1600, 5, - 101, + 109, 0, 0, - 1369, - 1370, + 1600, + 1601, 5, - 115, + 80, 0, 0, - 1370, - 1371, + 1601, + 1602, 5, - 116, + 114, 0, 0, - 1371, - 1372, + 1602, + 1603, 5, - 97, + 111, 0, 0, - 1372, - 1373, + 1603, + 1604, 5, - 109, + 99, 0, 0, - 1373, - 1374, + 1604, + 1605, 5, - 112, + 101, 0, 0, - 1374, - 1375, + 1605, + 1606, 5, - 80, + 115, 0, 0, - 1375, - 1376, + 1606, + 1607, 5, - 97, + 115, 0, 0, - 1376, - 1377, + 1607, + 1608, 5, - 116, + 111, 0, 0, - 1377, - 1378, + 1608, + 1609, 5, - 104, + 114, 0, 0, - 1378, - 1379, + 1609, + 1610, 5, 34, 0, 0, - 1379, - 144, + 1610, + 170, 1, 0, 0, 0, - 1380, - 1381, + 1611, + 1612, 5, 34, 0, 0, - 1381, - 1382, - 5, - 84, - 0, - 0, - 1382, - 1383, + 1612, + 1613, 5, - 105, + 73, 0, 0, - 1383, - 1384, + 1613, + 1614, 5, - 109, + 116, 0, 0, - 1384, - 1385, + 1614, + 1615, 5, 101, 0, 0, - 1385, - 1386, + 1615, + 1616, 5, - 115, + 114, 0, 0, - 1386, - 1387, + 1616, + 1617, 5, - 116, + 97, 0, 0, - 1387, - 1388, + 1617, + 1618, 5, - 97, + 116, 0, 0, - 1388, - 1389, + 1618, + 1619, 5, - 109, + 111, 0, 0, - 1389, - 1390, + 1619, + 1620, 5, - 112, + 114, 0, 0, - 1390, - 1391, + 1620, + 1621, 5, 34, 0, 0, - 1391, - 146, + 1621, + 172, 1, 0, 0, 0, - 1392, - 1393, + 1622, + 1623, 5, 34, 0, 0, - 1393, - 1394, - 5, - 84, - 0, - 0, - 1394, - 1395, + 1623, + 1624, 5, - 105, + 73, 0, 0, - 1395, - 1396, + 1624, + 1625, 5, - 109, + 116, 0, 0, - 1396, - 1397, + 1625, + 1626, 5, 101, 0, 0, - 1397, - 1398, + 1626, + 1627, 5, - 111, + 109, 0, 0, - 1398, - 1399, + 1627, + 1628, 5, - 117, + 83, 0, 0, - 1399, - 1400, + 1628, + 1629, 5, - 116, + 101, 0, 0, - 1400, - 1401, + 1629, + 1630, 5, - 83, + 108, 0, 0, - 1401, - 1402, + 1630, + 1631, 5, 101, 0, 0, - 1402, - 1403, + 1631, + 1632, 5, 99, 0, 0, - 1403, - 1404, - 5, - 111, - 0, - 0, - 1404, - 1405, + 1632, + 1633, 5, - 110, + 116, 0, 0, - 1405, - 1406, + 1633, + 1634, 5, - 100, + 111, 0, 0, - 1406, - 1407, + 1634, + 1635, 5, - 115, + 114, 0, 0, - 1407, - 1408, + 1635, + 1636, 5, 34, 0, 0, - 1408, - 148, + 1636, + 174, 1, 0, 0, 0, - 1409, - 1410, + 1637, + 1638, 5, 34, 0, 0, - 1410, - 1411, + 1638, + 1639, 5, - 84, + 77, 0, 0, - 1411, - 1412, + 1639, + 1640, 5, - 105, + 97, 0, 0, - 1412, - 1413, + 1640, + 1641, 5, - 109, + 120, 0, 0, - 1413, - 1414, + 1641, + 1642, 5, - 101, + 67, 0, 0, - 1414, - 1415, + 1642, + 1643, 5, 111, 0, 0, - 1415, - 1416, + 1643, + 1644, 5, - 117, + 110, 0, 0, - 1416, - 1417, + 1644, + 1645, 5, - 116, + 99, 0, 0, - 1417, - 1418, + 1645, + 1646, 5, - 83, + 117, 0, 0, - 1418, - 1419, + 1646, + 1647, 5, - 101, + 114, 0, 0, - 1419, - 1420, + 1647, + 1648, 5, - 99, + 114, 0, 0, - 1420, - 1421, + 1648, + 1649, 5, - 111, + 101, 0, 0, - 1421, - 1422, + 1649, + 1650, 5, 110, 0, 0, - 1422, - 1423, + 1650, + 1651, 5, - 100, + 99, 0, 0, - 1423, - 1424, + 1651, + 1652, 5, - 115, + 121, 0, 0, - 1424, - 1425, + 1652, + 1653, 5, 80, 0, 0, - 1425, - 1426, + 1653, + 1654, 5, 97, 0, 0, - 1426, - 1427, + 1654, + 1655, 5, 116, 0, 0, - 1427, - 1428, + 1655, + 1656, 5, 104, 0, 0, - 1428, - 1429, + 1656, + 1657, 5, 34, 0, 0, - 1429, - 150, + 1657, + 176, 1, 0, 0, 0, - 1430, - 1431, + 1658, + 1659, 5, 34, 0, 0, - 1431, - 1432, + 1659, + 1660, 5, - 72, + 77, 0, 0, - 1432, - 1433, + 1660, + 1661, 5, - 101, + 97, 0, 0, - 1433, - 1434, + 1661, + 1662, 5, - 97, + 120, 0, 0, - 1434, - 1435, + 1662, + 1663, 5, - 114, + 67, 0, 0, - 1435, - 1436, + 1663, + 1664, 5, - 116, + 111, 0, 0, - 1436, - 1437, + 1664, + 1665, 5, - 98, + 110, 0, 0, - 1437, - 1438, + 1665, + 1666, + 5, + 99, + 0, + 0, + 1666, + 1667, + 5, + 117, + 0, + 0, + 1667, + 1668, + 5, + 114, + 0, + 0, + 1668, + 1669, + 5, + 114, + 0, + 0, + 1669, + 1670, 5, 101, 0, 0, - 1438, - 1439, + 1670, + 1671, 5, - 97, + 110, 0, 0, - 1439, - 1440, + 1671, + 1672, 5, - 116, + 99, 0, 0, - 1440, - 1441, + 1672, + 1673, + 5, + 121, + 0, + 0, + 1673, + 1674, + 5, + 34, + 0, + 0, + 1674, + 178, + 1, + 0, + 0, + 0, + 1675, + 1676, + 5, + 34, + 0, + 0, + 1676, + 1677, 5, - 83, + 82, 0, 0, - 1441, - 1442, + 1677, + 1678, 5, 101, 0, 0, - 1442, - 1443, + 1678, + 1679, 5, - 99, + 115, 0, 0, - 1443, - 1444, + 1679, + 1680, 5, 111, 0, 0, - 1444, - 1445, + 1680, + 1681, 5, - 110, + 117, 0, 0, - 1445, - 1446, + 1681, + 1682, 5, - 100, + 114, 0, 0, - 1446, - 1447, + 1682, + 1683, 5, - 115, + 99, 0, 0, - 1447, - 1448, + 1683, + 1684, + 5, + 101, + 0, + 0, + 1684, + 1685, 5, 34, 0, 0, - 1448, - 152, + 1685, + 180, 1, 0, 0, 0, - 1449, - 1450, + 1686, + 1687, 5, 34, 0, 0, - 1450, - 1451, + 1687, + 1688, 5, - 72, + 73, 0, 0, - 1451, - 1452, + 1688, + 1689, 5, - 101, + 110, 0, 0, - 1452, - 1453, + 1689, + 1690, 5, - 97, + 112, 0, 0, - 1453, - 1454, + 1690, + 1691, 5, - 114, + 117, 0, 0, - 1454, - 1455, + 1691, + 1692, 5, 116, 0, 0, - 1455, - 1456, + 1692, + 1693, 5, - 98, + 80, 0, 0, - 1456, - 1457, + 1693, + 1694, 5, - 101, + 97, 0, 0, - 1457, - 1458, + 1694, + 1695, 5, - 97, + 116, 0, 0, - 1458, - 1459, + 1695, + 1696, 5, - 116, + 104, 0, 0, - 1459, - 1460, + 1696, + 1697, 5, - 83, + 34, 0, 0, - 1460, - 1461, + 1697, + 182, + 1, + 0, + 0, + 0, + 1698, + 1699, 5, - 101, + 34, 0, 0, - 1461, - 1462, + 1699, + 1700, 5, - 99, + 79, 0, 0, - 1462, - 1463, + 1700, + 1701, 5, - 111, + 117, 0, 0, - 1463, - 1464, + 1701, + 1702, 5, - 110, + 116, 0, 0, - 1464, - 1465, + 1702, + 1703, 5, - 100, + 112, 0, 0, - 1465, - 1466, + 1703, + 1704, 5, - 115, + 117, 0, 0, - 1466, - 1467, + 1704, + 1705, + 5, + 116, + 0, + 0, + 1705, + 1706, 5, 80, 0, 0, - 1467, - 1468, + 1706, + 1707, 5, 97, 0, 0, - 1468, - 1469, + 1707, + 1708, 5, 116, 0, 0, - 1469, - 1470, + 1708, + 1709, 5, 104, 0, 0, - 1470, - 1471, + 1709, + 1710, 5, 34, 0, 0, - 1471, - 154, + 1710, + 184, 1, 0, 0, 0, - 1472, - 1473, + 1711, + 1712, 5, 34, 0, 0, - 1473, - 1474, - 5, - 80, - 0, - 0, - 1474, - 1475, - 5, - 114, - 0, - 0, - 1475, - 1476, + 1712, + 1713, 5, - 111, + 73, 0, 0, - 1476, - 1477, + 1713, + 1714, 5, - 99, + 116, 0, 0, - 1477, - 1478, + 1714, + 1715, 5, 101, 0, 0, - 1478, - 1479, + 1715, + 1716, 5, - 115, + 109, 0, 0, - 1479, - 1480, + 1716, + 1717, 5, 115, 0, 0, - 1480, - 1481, - 5, - 111, - 0, - 0, - 1481, - 1482, - 5, - 114, - 0, - 0, - 1482, - 1483, + 1717, + 1718, 5, - 67, - 0, + 34, 0, - 1483, - 1484, - 5, - 111, 0, + 1718, + 186, + 1, 0, - 1484, - 1485, - 5, - 110, 0, 0, - 1485, - 1486, + 1719, + 1720, 5, - 102, + 34, 0, 0, - 1486, - 1487, + 1720, + 1721, 5, - 105, + 73, 0, 0, - 1487, - 1488, + 1721, + 1722, 5, - 103, + 116, 0, 0, - 1488, - 1489, + 1722, + 1723, 5, - 34, - 0, + 101, 0, - 1489, - 156, - 1, 0, + 1723, + 1724, + 5, + 109, 0, 0, - 1490, - 1491, + 1724, + 1725, 5, - 34, + 115, 0, 0, - 1491, - 1492, + 1725, + 1726, 5, - 77, + 80, 0, 0, - 1492, - 1493, + 1726, + 1727, 5, - 111, + 97, 0, 0, - 1493, - 1494, + 1727, + 1728, 5, - 100, + 116, 0, 0, - 1494, - 1495, + 1728, + 1729, 5, - 101, + 104, 0, 0, - 1495, - 1496, + 1729, + 1730, 5, 34, 0, 0, - 1496, - 158, + 1730, + 188, 1, 0, 0, 0, - 1497, - 1498, + 1731, + 1732, 5, 34, 0, 0, - 1498, - 1499, + 1732, + 1733, 5, - 73, + 82, 0, 0, - 1499, - 1500, + 1733, + 1734, 5, - 78, + 101, 0, 0, - 1500, - 1501, + 1734, + 1735, 5, - 76, + 115, 0, 0, - 1501, - 1502, + 1735, + 1736, 5, - 73, + 117, 0, 0, - 1502, - 1503, + 1736, + 1737, 5, - 78, + 108, 0, 0, - 1503, - 1504, + 1737, + 1738, 5, - 69, + 116, 0, 0, - 1504, - 1505, + 1738, + 1739, 5, - 34, - 0, - 0, - 1505, - 160, - 1, - 0, + 80, 0, 0, - 1506, - 1507, + 1739, + 1740, 5, - 34, + 97, 0, 0, - 1507, - 1508, + 1740, + 1741, 5, - 68, + 116, 0, 0, - 1508, - 1509, + 1741, + 1742, 5, - 73, + 104, 0, 0, - 1509, - 1510, + 1742, + 1743, 5, - 83, + 34, 0, 0, - 1510, - 1511, - 5, - 84, + 1743, + 190, + 1, 0, 0, - 1511, - 1512, + 0, + 1744, + 1745, 5, - 82, + 34, 0, 0, - 1512, - 1513, + 1745, + 1746, 5, - 73, + 82, 0, 0, - 1513, - 1514, + 1746, + 1747, 5, - 66, + 101, 0, 0, - 1514, - 1515, + 1747, + 1748, 5, - 85, + 115, 0, 0, - 1515, - 1516, + 1748, + 1749, 5, - 84, + 117, 0, 0, - 1516, - 1517, + 1749, + 1750, 5, - 69, + 108, 0, 0, - 1517, - 1518, + 1750, + 1751, 5, - 68, + 116, 0, 0, - 1518, - 1519, + 1751, + 1752, 5, 34, 0, 0, - 1519, - 162, + 1752, + 192, 1, 0, 0, 0, - 1520, - 1521, + 1753, + 1754, 5, 34, 0, 0, - 1521, - 1522, - 5, - 69, - 0, - 0, - 1522, - 1523, - 5, - 120, - 0, - 0, - 1523, - 1524, - 5, - 101, - 0, - 0, - 1524, - 1525, + 1754, + 1755, 5, - 99, + 80, 0, 0, - 1525, - 1526, + 1755, + 1756, 5, - 117, + 97, 0, 0, - 1526, - 1527, + 1756, + 1757, 5, - 116, + 114, 0, 0, - 1527, - 1528, + 1757, + 1758, 5, - 105, + 97, 0, 0, - 1528, - 1529, + 1758, + 1759, 5, - 111, + 109, 0, 0, - 1529, - 1530, + 1759, + 1760, 5, - 110, + 101, 0, 0, - 1530, - 1531, + 1760, + 1761, 5, - 84, + 116, 0, 0, - 1531, - 1532, + 1761, + 1762, 5, - 121, + 101, 0, 0, - 1532, - 1533, + 1762, + 1763, 5, - 112, + 114, 0, 0, - 1533, - 1534, + 1763, + 1764, 5, - 101, + 115, 0, 0, - 1534, - 1535, + 1764, + 1765, 5, 34, 0, 0, - 1535, - 164, + 1765, + 194, 1, 0, 0, 0, - 1536, - 1537, + 1766, + 1767, 5, 34, 0, 0, - 1537, - 1538, + 1767, + 1768, 5, - 83, + 67, 0, 0, - 1538, - 1539, + 1768, + 1769, 5, - 84, + 114, 0, 0, - 1539, - 1540, + 1769, + 1770, 5, - 65, + 101, 0, 0, - 1540, - 1541, + 1770, + 1771, 5, - 78, + 100, 0, 0, - 1541, - 1542, + 1771, + 1772, 5, - 68, + 101, 0, 0, - 1542, - 1543, + 1772, + 1773, 5, - 65, + 110, 0, 0, - 1543, - 1544, + 1773, + 1774, 5, - 82, + 116, 0, 0, - 1544, - 1545, + 1774, + 1775, 5, - 68, + 105, 0, 0, - 1545, - 1546, + 1775, + 1776, 5, - 34, - 0, - 0, - 1546, - 166, - 1, - 0, + 97, 0, 0, - 1547, - 1548, + 1776, + 1777, 5, - 34, + 108, 0, 0, - 1548, - 1549, + 1777, + 1778, 5, - 73, + 115, 0, 0, - 1549, - 1550, + 1778, + 1779, 5, - 116, - 0, + 34, 0, - 1550, - 1551, - 5, - 101, 0, + 1779, + 196, + 1, 0, - 1551, - 1552, - 5, - 109, 0, 0, - 1552, - 1553, + 1780, + 1781, 5, - 80, + 34, 0, 0, - 1553, - 1554, + 1781, + 1782, 5, - 114, + 82, 0, 0, - 1554, - 1555, + 1782, + 1783, 5, 111, 0, 0, - 1555, - 1556, + 1783, + 1784, 5, - 99, + 108, 0, 0, - 1556, - 1557, + 1784, + 1785, 5, 101, 0, 0, - 1557, - 1558, - 5, - 115, - 0, - 0, - 1558, - 1559, + 1785, + 1786, 5, - 115, + 65, 0, 0, - 1559, - 1560, + 1786, + 1787, 5, - 111, + 114, 0, 0, - 1560, - 1561, + 1787, + 1788, 5, - 114, + 110, 0, 0, - 1561, - 1562, + 1788, + 1789, 5, 34, 0, 0, - 1562, - 168, + 1789, + 198, 1, 0, 0, 0, - 1563, - 1564, + 1790, + 1791, 5, 34, 0, 0, - 1564, - 1565, + 1791, + 1792, 5, - 73, + 82, 0, 0, - 1565, - 1566, + 1792, + 1793, 5, - 116, + 111, 0, 0, - 1566, - 1567, + 1793, + 1794, + 5, + 108, + 0, + 0, + 1794, + 1795, 5, 101, 0, 0, - 1567, - 1568, + 1795, + 1796, + 5, + 65, + 0, + 0, + 1796, + 1797, 5, 114, 0, 0, - 1568, - 1569, + 1797, + 1798, 5, - 97, + 110, 0, 0, - 1569, - 1570, + 1798, + 1799, 5, - 116, + 46, 0, 0, - 1570, - 1571, + 1799, + 1800, 5, - 111, + 36, 0, 0, - 1571, - 1572, + 1800, + 1801, 5, - 114, + 34, + 0, + 0, + 1801, + 200, + 1, + 0, 0, 0, - 1572, - 1573, + 1802, + 1803, 5, 34, 0, 0, - 1573, - 170, - 1, - 0, + 1803, + 1804, + 5, + 82, 0, 0, - 1574, - 1575, + 1804, + 1805, 5, - 34, + 101, 0, 0, - 1575, - 1576, + 1805, + 1806, 5, - 73, + 115, 0, 0, - 1576, - 1577, + 1806, + 1807, 5, - 116, + 117, 0, 0, - 1577, - 1578, + 1807, + 1808, 5, - 101, + 108, 0, 0, - 1578, - 1579, + 1808, + 1809, 5, - 109, + 116, 0, 0, - 1579, - 1580, + 1809, + 1810, 5, 83, 0, 0, - 1580, - 1581, + 1810, + 1811, 5, 101, 0, 0, - 1581, - 1582, + 1811, + 1812, 5, 108, 0, 0, - 1582, - 1583, + 1812, + 1813, 5, 101, 0, 0, - 1583, - 1584, + 1813, + 1814, 5, 99, 0, 0, - 1584, - 1585, + 1814, + 1815, 5, 116, 0, 0, - 1585, - 1586, + 1815, + 1816, 5, 111, 0, 0, - 1586, - 1587, + 1816, + 1817, 5, 114, 0, 0, - 1587, - 1588, + 1817, + 1818, 5, 34, 0, 0, - 1588, - 172, + 1818, + 202, 1, 0, 0, 0, - 1589, - 1590, + 1819, + 1820, 5, 34, 0, 0, - 1590, - 1591, + 1820, + 1821, 5, - 77, + 73, 0, 0, - 1591, - 1592, + 1821, + 1822, 5, - 97, + 116, 0, 0, - 1592, - 1593, + 1822, + 1823, 5, - 120, + 101, 0, 0, - 1593, - 1594, + 1823, + 1824, 5, - 67, + 109, 0, 0, - 1594, - 1595, + 1824, + 1825, 5, - 111, + 82, 0, 0, - 1595, - 1596, + 1825, + 1826, 5, - 110, + 101, 0, 0, - 1596, - 1597, + 1826, + 1827, 5, - 99, + 97, 0, 0, - 1597, - 1598, + 1827, + 1828, 5, - 117, + 100, 0, 0, - 1598, - 1599, + 1828, + 1829, 5, - 114, + 101, 0, 0, - 1599, - 1600, + 1829, + 1830, 5, 114, 0, 0, - 1600, - 1601, + 1830, + 1831, 5, - 101, + 34, 0, 0, - 1601, - 1602, - 5, - 110, + 1831, + 204, + 1, 0, 0, - 1602, - 1603, + 0, + 1832, + 1833, 5, - 99, + 34, 0, 0, - 1603, - 1604, + 1833, + 1834, 5, - 121, + 82, 0, 0, - 1604, - 1605, + 1834, + 1835, 5, - 80, + 101, 0, 0, - 1605, - 1606, + 1835, + 1836, 5, 97, 0, 0, - 1606, - 1607, + 1836, + 1837, 5, - 116, + 100, 0, 0, - 1607, - 1608, + 1837, + 1838, 5, - 104, + 101, 0, 0, - 1608, - 1609, + 1838, + 1839, 5, - 34, + 114, 0, 0, - 1609, - 174, - 1, + 1839, + 1840, + 5, + 67, + 0, 0, + 1840, + 1841, + 5, + 111, 0, 0, - 1610, - 1611, + 1841, + 1842, 5, - 34, + 110, 0, 0, - 1611, - 1612, + 1842, + 1843, 5, - 77, + 102, 0, 0, - 1612, - 1613, + 1843, + 1844, 5, - 97, + 105, 0, 0, - 1613, - 1614, + 1844, + 1845, 5, - 120, + 103, 0, 0, - 1614, - 1615, + 1845, + 1846, 5, - 67, + 34, 0, 0, - 1615, - 1616, + 1846, + 206, + 1, + 0, + 0, + 0, + 1847, + 1848, + 5, + 34, + 0, + 0, + 1848, + 1849, 5, - 111, + 73, 0, 0, - 1616, - 1617, + 1849, + 1850, 5, 110, 0, 0, - 1617, - 1618, + 1850, + 1851, 5, - 99, + 112, 0, 0, - 1618, - 1619, + 1851, + 1852, 5, 117, 0, 0, - 1619, - 1620, - 5, - 114, - 0, - 0, - 1620, - 1621, + 1852, + 1853, 5, - 114, + 116, 0, 0, - 1621, - 1622, + 1853, + 1854, 5, - 101, + 84, 0, 0, - 1622, - 1623, + 1854, + 1855, 5, - 110, + 121, 0, 0, - 1623, - 1624, + 1855, + 1856, 5, - 99, + 112, 0, 0, - 1624, - 1625, + 1856, + 1857, 5, - 121, + 101, 0, 0, - 1625, - 1626, + 1857, + 1858, 5, 34, 0, 0, - 1626, - 176, + 1858, + 208, 1, 0, 0, 0, - 1627, - 1628, + 1859, + 1860, 5, 34, 0, 0, - 1628, - 1629, + 1860, + 1861, 5, - 82, + 67, 0, 0, - 1629, - 1630, + 1861, + 1862, 5, - 101, + 83, 0, 0, - 1630, - 1631, + 1862, + 1863, 5, - 115, + 86, 0, 0, - 1631, - 1632, + 1863, + 1864, 5, - 111, + 72, 0, 0, - 1632, - 1633, + 1864, + 1865, 5, - 117, + 101, 0, 0, - 1633, - 1634, + 1865, + 1866, 5, - 114, + 97, 0, 0, - 1634, - 1635, + 1866, + 1867, 5, - 99, + 100, 0, 0, - 1635, - 1636, + 1867, + 1868, 5, 101, 0, 0, - 1636, - 1637, - 5, - 34, - 0, - 0, - 1637, - 178, - 1, - 0, - 0, - 0, - 1638, - 1639, + 1868, + 1869, 5, - 34, + 114, 0, 0, - 1639, - 1640, + 1869, + 1870, 5, - 73, + 76, 0, 0, - 1640, - 1641, + 1870, + 1871, 5, - 110, + 111, 0, 0, - 1641, - 1642, + 1871, + 1872, 5, - 112, + 99, 0, 0, - 1642, - 1643, + 1872, + 1873, 5, - 117, + 97, 0, 0, - 1643, - 1644, + 1873, + 1874, 5, 116, 0, 0, - 1644, - 1645, - 5, - 80, - 0, - 0, - 1645, - 1646, + 1874, + 1875, 5, - 97, + 105, 0, 0, - 1646, - 1647, + 1875, + 1876, 5, - 116, + 111, 0, 0, - 1647, - 1648, + 1876, + 1877, 5, - 104, + 110, 0, 0, - 1648, - 1649, + 1877, + 1878, 5, 34, 0, 0, - 1649, - 180, + 1878, + 210, 1, 0, 0, 0, - 1650, - 1651, + 1879, + 1880, 5, 34, 0, 0, - 1651, - 1652, + 1880, + 1881, 5, - 79, + 67, 0, 0, - 1652, - 1653, + 1881, + 1882, 5, - 117, + 83, 0, 0, - 1653, - 1654, + 1882, + 1883, 5, - 116, + 86, 0, 0, - 1654, - 1655, + 1883, + 1884, 5, - 112, + 72, 0, 0, - 1655, - 1656, + 1884, + 1885, 5, - 117, + 101, 0, 0, - 1656, - 1657, + 1885, + 1886, 5, - 116, + 97, 0, 0, - 1657, - 1658, + 1886, + 1887, 5, - 80, + 100, 0, 0, - 1658, - 1659, + 1887, + 1888, 5, - 97, + 101, 0, 0, - 1659, - 1660, + 1888, + 1889, 5, - 116, + 114, 0, 0, - 1660, - 1661, + 1889, + 1890, 5, - 104, + 115, 0, 0, - 1661, - 1662, + 1890, + 1891, 5, 34, 0, 0, - 1662, - 182, + 1891, + 212, 1, 0, 0, 0, - 1663, - 1664, + 1892, + 1893, 5, 34, 0, 0, - 1664, - 1665, - 5, - 73, - 0, - 0, - 1665, - 1666, + 1893, + 1894, 5, - 116, + 77, 0, 0, - 1666, - 1667, + 1894, + 1895, 5, - 101, + 97, 0, 0, - 1667, - 1668, + 1895, + 1896, 5, - 109, + 120, 0, 0, - 1668, - 1669, + 1896, + 1897, 5, - 115, + 73, 0, 0, - 1669, - 1670, + 1897, + 1898, 5, - 80, + 116, 0, 0, - 1670, - 1671, + 1898, + 1899, 5, - 97, + 101, 0, 0, - 1671, - 1672, + 1899, + 1900, 5, - 116, + 109, 0, 0, - 1672, - 1673, + 1900, + 1901, 5, - 104, + 115, 0, 0, - 1673, - 1674, + 1901, + 1902, 5, 34, 0, 0, - 1674, - 184, + 1902, + 214, 1, 0, 0, 0, - 1675, - 1676, + 1903, + 1904, 5, 34, 0, 0, - 1676, - 1677, + 1904, + 1905, 5, - 82, + 77, 0, 0, - 1677, - 1678, + 1905, + 1906, 5, - 101, + 97, 0, 0, - 1678, - 1679, + 1906, + 1907, 5, - 115, + 120, 0, 0, - 1679, - 1680, + 1907, + 1908, 5, - 117, + 73, 0, 0, - 1680, - 1681, + 1908, + 1909, 5, - 108, + 116, 0, 0, - 1681, - 1682, + 1909, + 1910, 5, - 116, + 101, 0, 0, - 1682, - 1683, + 1910, + 1911, + 5, + 109, + 0, + 0, + 1911, + 1912, + 5, + 115, + 0, + 0, + 1912, + 1913, 5, 80, 0, 0, - 1683, - 1684, + 1913, + 1914, 5, 97, 0, 0, - 1684, - 1685, + 1914, + 1915, 5, 116, 0, 0, - 1685, - 1686, + 1915, + 1916, 5, 104, 0, 0, - 1686, - 1687, + 1916, + 1917, 5, 34, 0, 0, - 1687, - 186, + 1917, + 216, 1, 0, 0, 0, - 1688, - 1689, + 1918, + 1919, 5, 34, 0, 0, - 1689, - 1690, + 1919, + 1920, 5, - 82, + 84, 0, 0, - 1690, - 1691, + 1920, + 1921, 5, - 101, + 111, 0, 0, - 1691, - 1692, + 1921, + 1922, 5, - 115, + 108, 0, 0, - 1692, - 1693, + 1922, + 1923, 5, - 117, + 101, 0, 0, - 1693, - 1694, + 1923, + 1924, 5, - 108, + 114, 0, 0, - 1694, - 1695, + 1924, + 1925, 5, - 116, + 97, 0, 0, - 1695, - 1696, + 1925, + 1926, 5, - 34, - 0, + 116, 0, - 1696, - 188, - 1, 0, + 1926, + 1927, + 5, + 101, 0, 0, - 1697, - 1698, + 1927, + 1928, 5, - 34, + 100, 0, 0, - 1698, - 1699, + 1928, + 1929, 5, - 80, + 70, 0, 0, - 1699, - 1700, + 1929, + 1930, 5, 97, 0, 0, - 1700, - 1701, + 1930, + 1931, 5, - 114, + 105, 0, 0, - 1701, - 1702, + 1931, + 1932, 5, - 97, + 108, 0, 0, - 1702, - 1703, + 1932, + 1933, 5, - 109, + 117, 0, 0, - 1703, - 1704, + 1933, + 1934, + 5, + 114, + 0, + 0, + 1934, + 1935, 5, 101, 0, 0, - 1704, - 1705, + 1935, + 1936, 5, - 116, + 67, + 0, + 0, + 1936, + 1937, + 5, + 111, 0, 0, - 1705, - 1706, + 1937, + 1938, 5, - 101, + 117, 0, 0, - 1706, - 1707, + 1938, + 1939, 5, - 114, + 110, 0, 0, - 1707, - 1708, + 1939, + 1940, 5, - 115, + 116, 0, 0, - 1708, - 1709, + 1940, + 1941, 5, 34, 0, 0, - 1709, - 190, + 1941, + 218, 1, 0, 0, 0, - 1710, - 1711, + 1942, + 1943, 5, 34, 0, 0, - 1711, - 1712, + 1943, + 1944, 5, - 82, + 84, 0, 0, - 1712, - 1713, + 1944, + 1945, 5, - 101, + 111, 0, 0, - 1713, - 1714, + 1945, + 1946, 5, - 115, + 108, 0, 0, - 1714, - 1715, + 1946, + 1947, 5, - 117, + 101, 0, 0, - 1715, - 1716, + 1947, + 1948, 5, - 108, + 114, 0, 0, - 1716, - 1717, + 1948, + 1949, 5, - 116, + 97, 0, 0, - 1717, - 1718, + 1949, + 1950, 5, - 83, + 116, 0, 0, - 1718, - 1719, + 1950, + 1951, 5, 101, 0, 0, - 1719, - 1720, + 1951, + 1952, 5, - 108, + 100, 0, 0, - 1720, - 1721, + 1952, + 1953, 5, - 101, + 70, 0, 0, - 1721, - 1722, + 1953, + 1954, 5, - 99, + 97, 0, 0, - 1722, - 1723, + 1954, + 1955, 5, - 116, + 105, 0, 0, - 1723, - 1724, + 1955, + 1956, 5, - 111, + 108, 0, 0, - 1724, - 1725, + 1956, + 1957, 5, - 114, + 117, 0, 0, - 1725, - 1726, + 1957, + 1958, 5, - 34, - 0, - 0, - 1726, - 192, - 1, - 0, + 114, 0, 0, - 1727, - 1728, + 1958, + 1959, 5, - 34, + 101, 0, 0, - 1728, - 1729, + 1959, + 1960, 5, - 73, + 67, 0, 0, - 1729, - 1730, + 1960, + 1961, 5, - 116, + 111, 0, 0, - 1730, - 1731, + 1961, + 1962, 5, - 101, + 117, 0, 0, - 1731, - 1732, + 1962, + 1963, 5, - 109, + 110, 0, 0, - 1732, - 1733, + 1963, + 1964, 5, - 82, + 116, 0, 0, - 1733, - 1734, + 1964, + 1965, 5, - 101, + 80, 0, 0, - 1734, - 1735, + 1965, + 1966, 5, 97, 0, 0, - 1735, - 1736, - 5, - 100, - 0, - 0, - 1736, - 1737, + 1966, + 1967, 5, - 101, + 116, 0, 0, - 1737, - 1738, + 1967, + 1968, 5, - 114, + 104, 0, 0, - 1738, - 1739, + 1968, + 1969, 5, 34, 0, 0, - 1739, - 194, + 1969, + 220, 1, 0, 0, 0, - 1740, - 1741, + 1970, + 1971, 5, 34, 0, 0, - 1741, - 1742, + 1971, + 1972, 5, - 82, + 84, 0, 0, - 1742, - 1743, + 1972, + 1973, 5, - 101, + 111, 0, 0, - 1743, - 1744, + 1973, + 1974, 5, - 97, + 108, 0, 0, - 1744, - 1745, + 1974, + 1975, 5, - 100, + 101, 0, 0, - 1745, - 1746, + 1975, + 1976, 5, - 101, + 114, 0, 0, - 1746, - 1747, + 1976, + 1977, 5, - 114, + 97, 0, 0, - 1747, - 1748, + 1977, + 1978, 5, - 67, + 116, 0, 0, - 1748, - 1749, + 1978, + 1979, 5, - 111, + 101, 0, 0, - 1749, - 1750, + 1979, + 1980, + 5, + 100, + 0, + 0, + 1980, + 1981, 5, - 110, + 70, 0, 0, - 1750, - 1751, + 1981, + 1982, 5, - 102, + 97, 0, 0, - 1751, - 1752, + 1982, + 1983, 5, 105, 0, 0, - 1752, - 1753, + 1983, + 1984, 5, - 103, + 108, 0, 0, - 1753, - 1754, + 1984, + 1985, 5, - 34, + 117, 0, 0, - 1754, - 196, - 1, + 1985, + 1986, + 5, + 114, + 0, 0, + 1986, + 1987, + 5, + 101, 0, 0, - 1755, - 1756, + 1987, + 1988, 5, - 34, + 80, 0, 0, - 1756, - 1757, + 1988, + 1989, 5, - 73, + 101, 0, 0, - 1757, - 1758, + 1989, + 1990, 5, - 110, + 114, 0, 0, - 1758, - 1759, + 1990, + 1991, 5, - 112, + 99, 0, 0, - 1759, - 1760, + 1991, + 1992, 5, - 117, + 101, 0, 0, - 1760, - 1761, + 1992, + 1993, 5, - 116, + 110, 0, 0, - 1761, - 1762, + 1993, + 1994, 5, - 84, + 116, 0, 0, - 1762, - 1763, + 1994, + 1995, 5, - 121, + 97, 0, 0, - 1763, - 1764, + 1995, + 1996, 5, - 112, + 103, 0, 0, - 1764, - 1765, + 1996, + 1997, 5, 101, 0, 0, - 1765, - 1766, + 1997, + 1998, 5, 34, 0, 0, - 1766, - 198, + 1998, + 222, 1, 0, 0, 0, - 1767, - 1768, + 1999, + 2000, 5, 34, 0, 0, - 1768, - 1769, + 2000, + 2001, 5, - 67, + 84, 0, 0, - 1769, - 1770, + 2001, + 2002, 5, - 83, + 111, 0, 0, - 1770, - 1771, + 2002, + 2003, 5, - 86, + 108, 0, 0, - 1771, - 1772, + 2003, + 2004, 5, - 72, + 101, 0, 0, - 1772, - 1773, + 2004, + 2005, 5, - 101, + 114, 0, 0, - 1773, - 1774, + 2005, + 2006, 5, 97, 0, 0, - 1774, - 1775, + 2006, + 2007, 5, - 100, + 116, 0, 0, - 1775, - 1776, + 2007, + 2008, 5, 101, 0, 0, - 1776, - 1777, + 2008, + 2009, 5, - 114, + 100, 0, 0, - 1777, - 1778, + 2009, + 2010, 5, - 76, + 70, 0, 0, - 1778, - 1779, + 2010, + 2011, 5, - 111, + 97, 0, 0, - 1779, - 1780, + 2011, + 2012, 5, - 99, + 105, 0, 0, - 1780, - 1781, + 2012, + 2013, 5, - 97, + 108, 0, 0, - 1781, - 1782, + 2013, + 2014, 5, - 116, + 117, 0, 0, - 1782, - 1783, + 2014, + 2015, 5, - 105, + 114, 0, 0, - 1783, - 1784, + 2015, + 2016, 5, - 111, + 101, 0, 0, - 1784, - 1785, + 2016, + 2017, 5, - 110, + 80, 0, 0, - 1785, - 1786, + 2017, + 2018, 5, - 34, - 0, + 101, 0, - 1786, - 200, - 1, 0, + 2018, + 2019, + 5, + 114, 0, 0, - 1787, - 1788, + 2019, + 2020, 5, - 34, + 99, 0, 0, - 1788, - 1789, + 2020, + 2021, 5, - 67, + 101, 0, 0, - 1789, - 1790, + 2021, + 2022, 5, - 83, + 110, 0, 0, - 1790, - 1791, + 2022, + 2023, 5, - 86, + 116, 0, 0, - 1791, - 1792, + 2023, + 2024, 5, - 72, + 97, 0, 0, - 1792, - 1793, + 2024, + 2025, 5, - 101, + 103, 0, 0, - 1793, - 1794, + 2025, + 2026, 5, - 97, + 101, 0, 0, - 1794, - 1795, + 2026, + 2027, 5, - 100, + 80, 0, 0, - 1795, - 1796, + 2027, + 2028, 5, - 101, + 97, 0, 0, - 1796, - 1797, + 2028, + 2029, 5, - 114, + 116, 0, 0, - 1797, - 1798, + 2029, + 2030, 5, - 115, + 104, 0, 0, - 1798, - 1799, + 2030, + 2031, 5, 34, 0, 0, - 1799, - 202, + 2031, + 224, 1, 0, 0, 0, - 1800, - 1801, + 2032, + 2033, 5, 34, 0, 0, - 1801, - 1802, + 2033, + 2034, 5, - 77, + 76, 0, 0, - 1802, - 1803, + 2034, + 2035, 5, 97, 0, 0, - 1803, - 1804, - 5, - 120, - 0, - 0, - 1804, - 1805, - 5, - 73, - 0, - 0, - 1805, - 1806, + 2035, + 2036, 5, - 116, + 98, 0, 0, - 1806, - 1807, + 2036, + 2037, 5, 101, 0, 0, - 1807, - 1808, - 5, - 109, - 0, - 0, - 1808, - 1809, + 2037, + 2038, 5, - 115, + 108, 0, 0, - 1809, - 1810, + 2038, + 2039, 5, 34, 0, 0, - 1810, - 204, + 2039, + 226, 1, 0, 0, 0, - 1811, - 1812, + 2040, + 2041, 5, 34, 0, 0, - 1812, - 1813, + 2041, + 2042, 5, - 77, + 82, 0, 0, - 1813, - 1814, + 2042, + 2043, 5, - 97, + 101, 0, 0, - 1814, - 1815, + 2043, + 2044, 5, - 120, + 115, 0, 0, - 1815, - 1816, + 2044, + 2045, 5, - 73, + 117, 0, 0, - 1816, - 1817, + 2045, + 2046, 5, - 116, + 108, 0, 0, - 1817, - 1818, + 2046, + 2047, 5, - 101, + 116, 0, 0, - 1818, - 1819, + 2047, + 2048, 5, - 109, + 87, 0, 0, - 1819, - 1820, + 2048, + 2049, 5, - 115, + 114, 0, 0, - 1820, - 1821, + 2049, + 2050, 5, - 80, + 105, 0, 0, - 1821, - 1822, + 2050, + 2051, 5, - 97, + 116, 0, 0, - 1822, - 1823, + 2051, + 2052, 5, - 116, + 101, 0, 0, - 1823, - 1824, + 2052, + 2053, 5, - 104, + 114, 0, 0, - 1824, - 1825, + 2053, + 2054, 5, 34, 0, 0, - 1825, - 206, + 2054, + 228, 1, 0, 0, 0, - 1826, - 1827, + 2055, + 2056, 5, 34, 0, 0, - 1827, - 1828, - 5, - 84, - 0, - 0, - 1828, - 1829, - 5, - 111, - 0, - 0, - 1829, - 1830, + 2056, + 2057, 5, - 108, + 78, 0, 0, - 1830, - 1831, + 2057, + 2058, 5, 101, 0, 0, - 1831, - 1832, - 5, - 114, - 0, - 0, - 1832, - 1833, + 2058, + 2059, 5, - 97, + 120, 0, 0, - 1833, - 1834, + 2059, + 2060, 5, 116, 0, 0, - 1834, - 1835, + 2060, + 2061, 5, - 101, - 0, + 34, 0, - 1835, - 1836, - 5, - 100, 0, + 2061, + 230, + 1, 0, - 1836, - 1837, - 5, - 70, 0, 0, - 1837, - 1838, + 2062, + 2063, 5, - 97, + 34, 0, 0, - 1838, - 1839, + 2063, + 2064, 5, - 105, + 69, 0, 0, - 1839, - 1840, + 2064, + 2065, 5, - 108, + 110, 0, 0, - 1840, - 1841, + 2065, + 2066, 5, - 117, + 100, 0, 0, - 1841, - 1842, + 2066, + 2067, 5, - 114, + 34, 0, 0, - 1842, - 1843, + 2067, + 232, + 1, + 0, + 0, + 0, + 2068, + 2069, 5, - 101, + 34, 0, 0, - 1843, - 1844, + 2069, + 2070, 5, 67, 0, 0, - 1844, - 1845, + 2070, + 2071, 5, - 111, + 97, 0, 0, - 1845, - 1846, + 2071, + 2072, 5, 117, 0, 0, - 1846, - 1847, + 2072, + 2073, 5, - 110, + 115, 0, 0, - 1847, - 1848, + 2073, + 2074, 5, - 116, + 101, 0, 0, - 1848, - 1849, + 2074, + 2075, 5, 34, 0, 0, - 1849, - 208, + 2075, + 234, 1, 0, 0, 0, - 1850, - 1851, + 2076, + 2077, 5, 34, 0, 0, - 1851, - 1852, + 2077, + 2078, 5, - 84, + 67, 0, 0, - 1852, - 1853, + 2078, + 2079, 5, - 111, + 97, 0, 0, - 1853, - 1854, + 2079, + 2080, 5, - 108, + 117, 0, 0, - 1854, - 1855, + 2080, + 2081, + 5, + 115, + 0, + 0, + 2081, + 2082, 5, 101, 0, 0, - 1855, - 1856, + 2082, + 2083, 5, - 114, + 80, 0, 0, - 1856, - 1857, + 2083, + 2084, 5, 97, 0, 0, - 1857, - 1858, + 2084, + 2085, 5, 116, 0, 0, - 1858, - 1859, + 2085, + 2086, 5, - 101, + 104, 0, 0, - 1859, - 1860, + 2086, + 2087, 5, - 100, - 0, + 34, 0, - 1860, - 1861, - 5, - 70, 0, + 2087, + 236, + 1, 0, - 1861, - 1862, - 5, - 97, 0, 0, - 1862, - 1863, + 2088, + 2089, 5, - 105, + 34, 0, 0, - 1863, - 1864, + 2089, + 2090, 5, - 108, + 69, 0, 0, - 1864, - 1865, + 2090, + 2091, 5, - 117, + 114, 0, 0, - 1865, - 1866, + 2091, + 2092, 5, 114, 0, 0, - 1866, - 1867, + 2092, + 2093, 5, - 101, + 111, 0, 0, - 1867, - 1868, + 2093, + 2094, 5, - 67, + 114, 0, 0, - 1868, - 1869, + 2094, + 2095, 5, - 111, - 0, + 34, 0, - 1869, - 1870, - 5, - 117, 0, + 2095, + 238, + 1, 0, - 1870, - 1871, - 5, - 110, 0, 0, - 1871, - 1872, + 2096, + 2097, 5, - 116, + 34, 0, 0, - 1872, - 1873, + 2097, + 2098, 5, - 80, + 69, 0, 0, - 1873, - 1874, + 2098, + 2099, 5, - 97, + 114, 0, 0, - 1874, - 1875, + 2099, + 2100, 5, - 116, + 114, 0, 0, - 1875, - 1876, + 2100, + 2101, 5, - 104, + 111, 0, 0, - 1876, - 1877, + 2101, + 2102, 5, - 34, - 0, - 0, - 1877, - 210, - 1, - 0, + 114, 0, 0, - 1878, - 1879, + 2102, + 2103, 5, - 34, + 80, 0, 0, - 1879, - 1880, + 2103, + 2104, 5, - 84, + 97, 0, 0, - 1880, - 1881, + 2104, + 2105, 5, - 111, + 116, 0, 0, - 1881, - 1882, + 2105, + 2106, 5, - 108, + 104, 0, 0, - 1882, - 1883, + 2106, + 2107, 5, - 101, + 34, 0, 0, - 1883, - 1884, - 5, - 114, + 2107, + 240, + 1, + 0, 0, 0, - 1884, - 1885, + 2108, + 2109, 5, - 97, + 34, 0, 0, - 1885, - 1886, + 2109, + 2110, 5, - 116, + 82, 0, 0, - 1886, - 1887, + 2110, + 2111, 5, 101, 0, 0, - 1887, - 1888, + 2111, + 2112, 5, - 100, + 116, 0, 0, - 1888, - 1889, + 2112, + 2113, 5, - 70, + 114, 0, 0, - 1889, - 1890, + 2113, + 2114, 5, - 97, + 121, 0, 0, - 1890, - 1891, + 2114, + 2115, 5, - 105, - 0, + 34, 0, - 1891, - 1892, - 5, - 108, 0, + 2115, + 242, + 1, 0, - 1892, - 1893, - 5, - 117, 0, 0, - 1893, - 1894, + 2116, + 2117, 5, - 114, + 34, 0, 0, - 1894, - 1895, + 2117, + 2118, 5, - 101, + 69, 0, 0, - 1895, - 1896, + 2118, + 2119, 5, - 80, + 114, 0, 0, - 1896, - 1897, + 2119, + 2120, 5, - 101, + 114, 0, 0, - 1897, - 1898, + 2120, + 2121, 5, - 114, + 111, 0, 0, - 1898, - 1899, + 2121, + 2122, 5, - 99, + 114, 0, 0, - 1899, - 1900, + 2122, + 2123, 5, - 101, + 69, 0, 0, - 1900, - 1901, + 2123, + 2124, 5, - 110, + 113, 0, 0, - 1901, - 1902, + 2124, + 2125, 5, - 116, + 117, 0, 0, - 1902, - 1903, + 2125, + 2126, 5, 97, 0, 0, - 1903, - 1904, + 2126, + 2127, 5, - 103, + 108, 0, 0, - 1904, - 1905, + 2127, + 2128, 5, - 101, + 115, 0, 0, - 1905, - 1906, + 2128, + 2129, 5, 34, 0, 0, - 1906, - 212, + 2129, + 244, 1, 0, 0, 0, - 1907, - 1908, + 2130, + 2131, 5, 34, 0, 0, - 1908, - 1909, + 2131, + 2132, 5, - 84, + 73, 0, 0, - 1909, - 1910, + 2132, + 2133, 5, - 111, + 110, 0, 0, - 1910, - 1911, + 2133, + 2134, 5, - 108, + 116, 0, 0, - 1911, - 1912, + 2134, + 2135, 5, 101, 0, 0, - 1912, - 1913, + 2135, + 2136, 5, 114, 0, 0, - 1913, - 1914, + 2136, + 2137, 5, - 97, + 118, 0, 0, - 1914, - 1915, + 2137, + 2138, 5, - 116, + 97, 0, 0, - 1915, - 1916, + 2138, + 2139, 5, - 101, + 108, 0, 0, - 1916, - 1917, + 2139, + 2140, 5, - 100, + 83, 0, 0, - 1917, - 1918, + 2140, + 2141, 5, - 70, + 101, 0, 0, - 1918, - 1919, + 2141, + 2142, 5, - 97, + 99, 0, 0, - 1919, - 1920, + 2142, + 2143, 5, - 105, + 111, 0, 0, - 1920, - 1921, + 2143, + 2144, 5, - 108, + 110, 0, 0, - 1921, - 1922, + 2144, + 2145, 5, - 117, + 100, 0, 0, - 1922, - 1923, + 2145, + 2146, 5, - 114, + 115, 0, 0, - 1923, - 1924, + 2146, + 2147, 5, - 101, - 0, + 34, 0, - 1924, - 1925, - 5, - 80, 0, + 2147, + 246, + 1, 0, - 1925, - 1926, - 5, - 101, 0, 0, - 1926, - 1927, + 2148, + 2149, 5, - 114, + 34, 0, 0, - 1927, - 1928, + 2149, + 2150, 5, - 99, + 77, 0, 0, - 1928, - 1929, + 2150, + 2151, 5, - 101, + 97, 0, 0, - 1929, - 1930, + 2151, + 2152, 5, - 110, + 120, 0, 0, - 1930, - 1931, + 2152, + 2153, 5, - 116, + 65, 0, 0, - 1931, - 1932, + 2153, + 2154, 5, - 97, + 116, 0, 0, - 1932, - 1933, + 2154, + 2155, 5, - 103, + 116, 0, 0, - 1933, - 1934, + 2155, + 2156, 5, 101, 0, 0, - 1934, - 1935, + 2156, + 2157, 5, - 80, + 109, 0, 0, - 1935, - 1936, + 2157, + 2158, 5, - 97, + 112, 0, 0, - 1936, - 1937, + 2158, + 2159, 5, 116, 0, 0, - 1937, - 1938, + 2159, + 2160, 5, - 104, + 115, 0, 0, - 1938, - 1939, + 2160, + 2161, 5, 34, 0, 0, - 1939, - 214, + 2161, + 248, 1, 0, 0, 0, - 1940, - 1941, + 2162, + 2163, 5, 34, 0, 0, - 1941, - 1942, + 2163, + 2164, 5, - 76, + 66, 0, 0, - 1942, - 1943, + 2164, + 2165, 5, 97, 0, 0, - 1943, - 1944, + 2165, + 2166, 5, - 98, + 99, 0, 0, - 1944, - 1945, + 2166, + 2167, 5, - 101, + 107, 0, 0, - 1945, - 1946, + 2167, + 2168, 5, - 108, + 111, 0, 0, - 1946, - 1947, + 2168, + 2169, 5, - 34, - 0, - 0, - 1947, - 216, - 1, - 0, + 102, 0, 0, - 1948, - 1949, + 2169, + 2170, 5, - 34, + 102, 0, 0, - 1949, - 1950, + 2170, + 2171, 5, - 78, + 82, 0, 0, - 1950, - 1951, + 2171, + 2172, 5, - 101, + 97, 0, 0, - 1951, - 1952, + 2172, + 2173, 5, - 120, + 116, 0, 0, - 1952, - 1953, + 2173, + 2174, 5, - 116, + 101, 0, 0, - 1953, - 1954, + 2174, + 2175, 5, 34, 0, 0, - 1954, - 218, + 2175, + 250, 1, 0, 0, 0, - 1955, - 1956, + 2176, + 2177, 5, 34, 0, 0, - 1956, - 1957, + 2177, + 2178, 5, - 69, + 77, 0, 0, - 1957, - 1958, + 2178, + 2179, 5, - 110, + 97, 0, 0, - 1958, - 1959, + 2179, + 2180, 5, - 100, + 120, 0, 0, - 1959, - 1960, + 2180, + 2181, 5, - 34, - 0, - 0, - 1960, - 220, - 1, - 0, + 68, 0, 0, - 1961, - 1962, + 2181, + 2182, 5, - 34, + 101, 0, 0, - 1962, - 1963, + 2182, + 2183, 5, - 67, + 108, 0, 0, - 1963, - 1964, + 2183, + 2184, 5, 97, 0, 0, - 1964, - 1965, + 2184, + 2185, 5, - 117, + 121, 0, 0, - 1965, - 1966, + 2185, + 2186, 5, - 115, + 83, 0, 0, - 1966, - 1967, + 2186, + 2187, 5, 101, 0, 0, - 1967, - 1968, + 2187, + 2188, 5, - 34, - 0, + 99, 0, - 1968, - 222, - 1, 0, + 2188, + 2189, + 5, + 111, 0, 0, - 1969, - 1970, + 2189, + 2190, 5, - 34, + 110, 0, 0, - 1970, - 1971, + 2190, + 2191, 5, - 67, + 100, 0, 0, - 1971, - 1972, + 2191, + 2192, 5, - 97, + 115, 0, 0, - 1972, - 1973, + 2192, + 2193, 5, - 117, + 34, 0, 0, - 1973, - 1974, + 2193, + 252, + 1, + 0, + 0, + 0, + 2194, + 2195, 5, - 115, + 34, 0, 0, - 1974, - 1975, + 2195, + 2196, 5, - 101, + 74, 0, 0, - 1975, - 1976, + 2196, + 2197, 5, - 80, + 105, 0, 0, - 1976, - 1977, + 2197, + 2198, 5, - 97, + 116, 0, 0, - 1977, - 1978, + 2198, + 2199, 5, 116, 0, 0, - 1978, - 1979, + 2199, + 2200, 5, - 104, + 101, 0, 0, - 1979, - 1980, + 2200, + 2201, 5, - 34, + 114, 0, 0, - 1980, - 224, - 1, + 2201, + 2202, + 5, + 83, + 0, 0, + 2202, + 2203, + 5, + 116, 0, 0, - 1981, - 1982, + 2203, + 2204, 5, - 34, + 114, 0, 0, - 1982, - 1983, + 2204, + 2205, 5, - 69, + 97, 0, 0, - 1983, - 1984, + 2205, + 2206, 5, - 114, + 116, 0, 0, - 1984, - 1985, + 2206, + 2207, 5, - 114, + 101, 0, 0, - 1985, - 1986, + 2207, + 2208, 5, - 111, + 103, 0, 0, - 1986, - 1987, + 2208, + 2209, 5, - 114, + 121, 0, 0, - 1987, - 1988, + 2209, + 2210, 5, 34, 0, 0, - 1988, - 226, + 2210, + 254, 1, 0, 0, 0, - 1989, - 1990, + 2211, + 2212, 5, 34, 0, 0, - 1990, - 1991, + 2212, + 2213, 5, - 69, + 70, 0, 0, - 1991, - 1992, + 2213, + 2214, 5, - 114, + 85, 0, 0, - 1992, - 1993, + 2214, + 2215, 5, - 114, + 76, 0, 0, - 1993, - 1994, + 2215, + 2216, 5, - 111, + 76, 0, 0, - 1994, - 1995, + 2216, + 2217, 5, - 114, + 34, 0, 0, - 1995, - 1996, + 2217, + 256, + 1, + 0, + 0, + 0, + 2218, + 2219, 5, - 80, + 34, 0, 0, - 1996, - 1997, + 2219, + 2220, 5, - 97, + 78, 0, 0, - 1997, - 1998, + 2220, + 2221, 5, - 116, + 79, 0, 0, - 1998, - 1999, + 2221, + 2222, 5, - 104, + 78, 0, 0, - 1999, - 2000, + 2222, + 2223, + 5, + 69, + 0, + 0, + 2223, + 2224, 5, 34, 0, 0, - 2000, - 228, + 2224, + 258, 1, 0, 0, 0, - 2001, - 2002, + 2225, + 2226, 5, 34, 0, 0, - 2002, - 2003, + 2226, + 2227, 5, - 82, + 67, 0, 0, - 2003, - 2004, + 2227, + 2228, 5, - 101, + 97, 0, 0, - 2004, - 2005, + 2228, + 2229, 5, 116, 0, 0, - 2005, - 2006, + 2229, + 2230, 5, - 114, + 99, 0, 0, - 2006, - 2007, + 2230, + 2231, 5, - 121, + 104, 0, 0, - 2007, - 2008, + 2231, + 2232, 5, 34, 0, 0, - 2008, - 230, + 2232, + 260, 1, 0, 0, 0, - 2009, - 2010, + 2233, + 2234, 5, 34, 0, 0, - 2010, - 2011, + 2234, + 2235, 5, - 69, + 81, 0, 0, - 2011, - 2012, + 2235, + 2236, 5, - 114, + 117, 0, 0, - 2012, - 2013, + 2236, + 2237, + 5, + 101, + 0, + 0, + 2237, + 2238, 5, 114, 0, 0, - 2013, - 2014, + 2238, + 2239, 5, - 111, + 121, 0, 0, - 2014, - 2015, + 2239, + 2240, 5, - 114, + 76, + 0, + 0, + 2240, + 2241, + 5, + 97, 0, 0, - 2015, - 2016, + 2241, + 2242, 5, - 69, + 110, 0, 0, - 2016, - 2017, + 2242, + 2243, 5, - 113, + 103, 0, 0, - 2017, - 2018, + 2243, + 2244, 5, 117, 0, 0, - 2018, - 2019, + 2244, + 2245, 5, 97, 0, 0, - 2019, - 2020, + 2245, + 2246, 5, - 108, + 103, 0, 0, - 2020, - 2021, + 2246, + 2247, 5, - 115, + 101, 0, 0, - 2021, - 2022, + 2247, + 2248, 5, 34, 0, 0, - 2022, - 232, + 2248, + 262, 1, 0, 0, 0, - 2023, - 2024, + 2249, + 2250, 5, 34, 0, 0, - 2024, - 2025, + 2250, + 2251, 5, - 73, + 74, 0, 0, - 2025, - 2026, + 2251, + 2252, 5, - 110, + 83, 0, 0, - 2026, - 2027, + 2252, + 2253, 5, - 116, + 79, 0, 0, - 2027, - 2028, + 2253, + 2254, 5, - 101, + 78, 0, 0, - 2028, - 2029, + 2254, + 2255, 5, - 114, + 80, 0, 0, - 2029, - 2030, + 2255, + 2256, 5, - 118, + 97, 0, 0, - 2030, - 2031, + 2256, + 2257, 5, - 97, + 116, 0, 0, - 2031, - 2032, + 2257, + 2258, 5, - 108, + 104, 0, 0, - 2032, - 2033, + 2258, + 2259, 5, - 83, + 34, 0, 0, - 2033, - 2034, + 2259, + 264, + 1, + 0, + 0, + 0, + 2260, + 2261, 5, - 101, + 34, 0, 0, - 2034, - 2035, + 2261, + 2262, 5, - 99, + 74, 0, 0, - 2035, - 2036, + 2262, + 2263, 5, - 111, + 83, 0, 0, - 2036, - 2037, + 2263, + 2264, 5, - 110, + 79, 0, 0, - 2037, - 2038, + 2264, + 2265, 5, - 100, + 78, 0, 0, - 2038, - 2039, + 2265, + 2266, 5, - 115, + 97, 0, 0, - 2039, - 2040, + 2266, + 2267, + 5, + 116, + 0, + 0, + 2267, + 2268, + 5, + 97, + 0, + 0, + 2268, + 2269, 5, 34, 0, 0, - 2040, - 234, + 2269, + 266, 1, 0, 0, 0, - 2041, - 2042, + 2270, + 2271, 5, 34, 0, 0, - 2042, - 2043, + 2271, + 2272, 5, - 77, + 65, 0, 0, - 2043, - 2044, + 2272, + 2273, 5, - 97, + 115, 0, 0, - 2044, - 2045, + 2273, + 2274, 5, - 120, + 115, 0, 0, - 2045, - 2046, + 2274, + 2275, 5, - 65, + 105, 0, 0, - 2046, - 2047, + 2275, + 2276, 5, - 116, + 103, 0, 0, - 2047, - 2048, + 2276, + 2277, 5, - 116, + 110, 0, 0, - 2048, - 2049, + 2277, + 2278, 5, - 101, + 34, 0, 0, - 2049, - 2050, + 2278, + 268, + 1, + 0, + 0, + 0, + 2279, + 2280, 5, - 109, + 34, 0, 0, - 2050, - 2051, + 2280, + 2281, 5, - 112, + 79, 0, 0, - 2051, - 2052, + 2281, + 2282, 5, - 116, + 117, 0, 0, - 2052, - 2053, + 2282, + 2283, 5, - 115, + 116, 0, 0, - 2053, - 2054, + 2283, + 2284, 5, - 34, + 112, 0, 0, - 2054, - 236, - 1, + 2284, + 2285, + 5, + 117, + 0, 0, + 2285, + 2286, + 5, + 116, 0, 0, - 2055, - 2056, + 2286, + 2287, 5, 34, 0, 0, - 2056, - 2057, - 5, - 66, + 2287, + 270, + 1, 0, 0, - 2057, - 2058, + 0, + 2288, + 2289, 5, - 97, + 34, 0, 0, - 2058, - 2059, + 2289, + 2290, 5, - 99, + 65, 0, 0, - 2059, - 2060, + 2290, + 2291, 5, - 107, + 114, 0, 0, - 2060, - 2061, + 2291, + 2292, 5, - 111, + 103, 0, 0, - 2061, - 2062, + 2292, + 2293, 5, - 102, + 117, 0, 0, - 2062, - 2063, + 2293, + 2294, 5, - 102, + 109, 0, 0, - 2063, - 2064, + 2294, + 2295, 5, - 82, + 101, 0, 0, - 2064, - 2065, + 2295, + 2296, 5, - 97, + 110, 0, 0, - 2065, - 2066, + 2296, + 2297, 5, 116, 0, 0, - 2066, - 2067, + 2297, + 2298, 5, - 101, + 115, 0, 0, - 2067, - 2068, + 2298, + 2299, 5, 34, 0, 0, - 2068, - 238, + 2299, + 272, 1, 0, 0, 0, - 2069, - 2070, + 2300, + 2301, 5, 34, 0, 0, - 2070, - 2071, + 2301, + 2302, 5, - 77, + 83, 0, 0, - 2071, - 2072, + 2302, + 2303, 5, - 97, + 116, 0, 0, - 2072, - 2073, + 2303, + 2304, 5, - 120, + 97, 0, 0, - 2073, - 2074, + 2304, + 2305, 5, - 68, + 116, 0, 0, - 2074, - 2075, + 2305, + 2306, 5, 101, 0, 0, - 2075, - 2076, + 2306, + 2307, 5, - 108, + 115, 0, 0, - 2076, - 2077, + 2307, + 2308, 5, - 97, + 46, 0, 0, - 2077, - 2078, + 2308, + 2309, 5, - 121, + 65, 0, 0, - 2078, - 2079, + 2309, + 2310, 5, - 83, + 76, 0, 0, - 2079, - 2080, + 2310, + 2311, 5, - 101, + 76, 0, 0, - 2080, - 2081, + 2311, + 2312, 5, - 99, + 34, 0, 0, - 2081, - 2082, + 2312, + 274, + 1, + 0, + 0, + 0, + 2313, + 2314, 5, - 111, + 34, 0, 0, - 2082, - 2083, + 2314, + 2315, 5, - 110, + 83, 0, 0, - 2083, - 2084, + 2315, + 2316, 5, - 100, + 116, 0, 0, - 2084, - 2085, + 2316, + 2317, 5, - 115, + 97, 0, 0, - 2085, - 2086, + 2317, + 2318, 5, - 34, + 116, 0, 0, - 2086, - 240, - 1, + 2318, + 2319, + 5, + 101, 0, 0, + 2319, + 2320, + 5, + 115, 0, - 2087, - 2088, + 0, + 2320, + 2321, 5, - 34, + 46, 0, 0, - 2088, - 2089, + 2321, + 2322, 5, - 74, + 68, 0, 0, - 2089, - 2090, + 2322, + 2323, 5, - 105, + 97, 0, 0, - 2090, - 2091, + 2323, + 2324, 5, 116, 0, 0, - 2091, - 2092, + 2324, + 2325, 5, - 116, + 97, 0, 0, - 2092, - 2093, + 2325, + 2326, 5, - 101, + 76, 0, 0, - 2093, - 2094, + 2326, + 2327, 5, - 114, + 105, 0, 0, - 2094, - 2095, + 2327, + 2328, 5, - 83, + 109, + 0, + 0, + 2328, + 2329, + 5, + 105, + 0, + 0, + 2329, + 2330, + 5, + 116, + 0, + 0, + 2330, + 2331, + 5, + 69, 0, 0, - 2095, - 2096, + 2331, + 2332, 5, - 116, + 120, 0, 0, - 2096, - 2097, + 2332, + 2333, 5, - 114, + 99, 0, 0, - 2097, - 2098, + 2333, + 2334, 5, - 97, + 101, 0, 0, - 2098, - 2099, + 2334, + 2335, 5, - 116, + 101, 0, 0, - 2099, - 2100, + 2335, + 2336, 5, - 101, + 100, 0, 0, - 2100, - 2101, + 2336, + 2337, 5, - 103, + 101, 0, 0, - 2101, - 2102, + 2337, + 2338, 5, - 121, + 100, 0, 0, - 2102, - 2103, + 2338, + 2339, 5, 34, 0, 0, - 2103, - 242, + 2339, + 276, 1, 0, 0, 0, - 2104, - 2105, + 2340, + 2341, 5, 34, 0, 0, - 2105, - 2106, + 2341, + 2342, 5, - 70, + 83, 0, 0, - 2106, - 2107, + 2342, + 2343, 5, - 85, + 116, 0, 0, - 2107, - 2108, + 2343, + 2344, 5, - 76, + 97, 0, 0, - 2108, - 2109, + 2344, + 2345, 5, - 76, + 116, 0, 0, - 2109, - 2110, + 2345, + 2346, 5, - 34, + 101, 0, 0, - 2110, - 244, - 1, + 2346, + 2347, + 5, + 115, 0, 0, + 2347, + 2348, + 5, + 46, 0, - 2111, - 2112, + 0, + 2348, + 2349, 5, - 34, + 72, 0, 0, - 2112, - 2113, + 2349, + 2350, 5, - 78, + 101, 0, 0, - 2113, - 2114, + 2350, + 2351, 5, - 79, + 97, 0, 0, - 2114, - 2115, + 2351, + 2352, 5, - 78, + 114, 0, 0, - 2115, - 2116, + 2352, + 2353, 5, - 69, + 116, 0, 0, - 2116, - 2117, + 2353, + 2354, 5, - 34, + 98, 0, 0, - 2117, - 246, - 1, + 2354, + 2355, + 5, + 101, 0, 0, + 2355, + 2356, + 5, + 97, 0, - 2118, - 2119, + 0, + 2356, + 2357, 5, - 34, + 116, 0, 0, - 2119, - 2120, + 2357, + 2358, 5, - 67, + 84, 0, 0, - 2120, - 2121, + 2358, + 2359, 5, - 97, + 105, 0, 0, - 2121, - 2122, + 2359, + 2360, 5, - 116, + 109, 0, 0, - 2122, - 2123, + 2360, + 2361, 5, - 99, + 101, 0, 0, - 2123, - 2124, + 2361, + 2362, 5, - 104, + 111, 0, 0, - 2124, - 2125, + 2362, + 2363, + 5, + 117, + 0, + 0, + 2363, + 2364, + 5, + 116, + 0, + 0, + 2364, + 2365, 5, 34, 0, 0, - 2125, - 248, + 2365, + 278, 1, 0, 0, 0, - 2126, - 2127, + 2366, + 2367, 5, 34, 0, 0, - 2127, - 2128, + 2367, + 2368, 5, 83, 0, 0, - 2128, - 2129, + 2368, + 2369, 5, 116, 0, 0, - 2129, - 2130, + 2369, + 2370, 5, 97, 0, 0, - 2130, - 2131, + 2370, + 2371, 5, 116, 0, 0, - 2131, - 2132, + 2371, + 2372, 5, 101, 0, 0, - 2132, - 2133, + 2372, + 2373, 5, 115, 0, 0, - 2133, - 2134, + 2373, + 2374, + 5, + 46, + 0, + 0, + 2374, + 2375, + 5, + 84, + 0, + 0, + 2375, + 2376, + 5, + 105, + 0, + 0, + 2376, + 2377, + 5, + 109, + 0, + 0, + 2377, + 2378, 5, - 46, + 101, 0, 0, - 2134, - 2135, + 2378, + 2379, 5, - 65, + 111, 0, 0, - 2135, - 2136, + 2379, + 2380, 5, - 76, + 117, 0, 0, - 2136, - 2137, + 2380, + 2381, 5, - 76, + 116, 0, 0, - 2137, - 2138, + 2381, + 2382, 5, 34, 0, 0, - 2138, - 250, + 2382, + 280, 1, 0, 0, 0, - 2139, - 2140, + 2383, + 2384, 5, 34, 0, 0, - 2140, - 2141, + 2384, + 2385, 5, 83, 0, 0, - 2141, - 2142, + 2385, + 2386, 5, 116, 0, 0, - 2142, - 2143, + 2386, + 2387, 5, 97, 0, 0, - 2143, - 2144, + 2387, + 2388, 5, 116, 0, 0, - 2144, - 2145, + 2388, + 2389, 5, 101, 0, 0, - 2145, - 2146, + 2389, + 2390, 5, 115, 0, 0, - 2146, - 2147, + 2390, + 2391, 5, 46, 0, 0, - 2147, - 2148, + 2391, + 2392, 5, - 68, + 84, 0, 0, - 2148, - 2149, + 2392, + 2393, 5, 97, 0, 0, - 2149, - 2150, - 5, - 116, - 0, - 0, - 2150, - 2151, + 2393, + 2394, 5, - 97, + 115, 0, 0, - 2151, - 2152, + 2394, + 2395, 5, - 76, + 107, 0, 0, - 2152, - 2153, + 2395, + 2396, 5, - 105, + 70, 0, 0, - 2153, - 2154, + 2396, + 2397, 5, - 109, + 97, 0, 0, - 2154, - 2155, + 2397, + 2398, 5, 105, 0, 0, - 2155, - 2156, - 5, - 116, - 0, - 0, - 2156, - 2157, - 5, - 69, - 0, - 0, - 2157, - 2158, - 5, - 120, - 0, - 0, - 2158, - 2159, - 5, - 99, - 0, - 0, - 2159, - 2160, - 5, - 101, - 0, - 0, - 2160, - 2161, - 5, - 101, - 0, - 0, - 2161, - 2162, + 2398, + 2399, 5, - 100, + 108, 0, 0, - 2162, - 2163, + 2399, + 2400, 5, 101, 0, 0, - 2163, - 2164, + 2400, + 2401, 5, 100, 0, 0, - 2164, - 2165, + 2401, + 2402, 5, 34, 0, 0, - 2165, - 252, + 2402, + 282, 1, 0, 0, 0, - 2166, - 2167, + 2403, + 2404, 5, 34, 0, 0, - 2167, - 2168, + 2404, + 2405, 5, 83, 0, 0, - 2168, - 2169, + 2405, + 2406, 5, 116, 0, 0, - 2169, - 2170, + 2406, + 2407, 5, 97, 0, 0, - 2170, - 2171, + 2407, + 2408, 5, 116, 0, 0, - 2171, - 2172, + 2408, + 2409, 5, 101, 0, 0, - 2172, - 2173, + 2409, + 2410, 5, 115, 0, 0, - 2173, - 2174, + 2410, + 2411, 5, 46, 0, 0, - 2174, - 2175, + 2411, + 2412, 5, - 72, + 80, 0, 0, - 2175, - 2176, + 2412, + 2413, 5, 101, 0, 0, - 2176, - 2177, - 5, - 97, - 0, - 0, - 2177, - 2178, + 2413, + 2414, 5, 114, 0, 0, - 2178, - 2179, - 5, - 116, - 0, - 0, - 2179, - 2180, - 5, - 98, - 0, - 0, - 2180, - 2181, - 5, - 101, - 0, - 0, - 2181, - 2182, - 5, - 97, - 0, - 0, - 2182, - 2183, + 2414, + 2415, 5, - 116, + 109, 0, 0, - 2183, - 2184, + 2415, + 2416, 5, - 84, + 105, 0, 0, - 2184, - 2185, + 2416, + 2417, 5, - 105, + 115, 0, 0, - 2185, - 2186, + 2417, + 2418, 5, - 109, + 115, 0, 0, - 2186, - 2187, + 2418, + 2419, 5, - 101, + 105, 0, 0, - 2187, - 2188, + 2419, + 2420, 5, 111, 0, 0, - 2188, - 2189, + 2420, + 2421, 5, - 117, + 110, 0, 0, - 2189, - 2190, + 2421, + 2422, 5, - 116, + 115, 0, 0, - 2190, - 2191, + 2422, + 2423, 5, 34, 0, 0, - 2191, - 254, + 2423, + 284, 1, 0, 0, 0, - 2192, - 2193, + 2424, + 2425, 5, 34, 0, 0, - 2193, - 2194, + 2425, + 2426, 5, 83, 0, 0, - 2194, - 2195, + 2426, + 2427, 5, 116, 0, 0, - 2195, - 2196, + 2427, + 2428, 5, 97, 0, 0, - 2196, - 2197, + 2428, + 2429, 5, 116, 0, 0, - 2197, - 2198, + 2429, + 2430, 5, 101, 0, 0, - 2198, - 2199, + 2430, + 2431, 5, 115, 0, 0, - 2199, - 2200, + 2431, + 2432, 5, 46, 0, 0, - 2200, - 2201, - 5, - 84, - 0, - 0, - 2201, - 2202, - 5, - 105, - 0, - 0, - 2202, - 2203, + 2432, + 2433, 5, - 109, + 82, 0, 0, - 2203, - 2204, + 2433, + 2434, 5, 101, 0, 0, - 2204, - 2205, + 2434, + 2435, 5, - 111, + 115, 0, 0, - 2205, - 2206, + 2435, + 2436, 5, 117, 0, 0, - 2206, - 2207, - 5, - 116, - 0, - 0, - 2207, - 2208, - 5, - 34, - 0, - 0, - 2208, - 256, - 1, - 0, - 0, - 0, - 2209, - 2210, + 2436, + 2437, 5, - 34, + 108, 0, 0, - 2210, - 2211, + 2437, + 2438, 5, - 83, + 116, 0, 0, - 2211, - 2212, + 2438, + 2439, 5, - 116, + 80, 0, 0, - 2212, - 2213, + 2439, + 2440, 5, 97, 0, 0, - 2213, - 2214, + 2440, + 2441, 5, 116, 0, 0, - 2214, - 2215, - 5, - 101, - 0, - 0, - 2215, - 2216, + 2441, + 2442, 5, - 115, + 104, 0, 0, - 2216, - 2217, + 2442, + 2443, 5, - 46, + 77, 0, 0, - 2217, - 2218, + 2443, + 2444, 5, - 84, + 97, 0, 0, - 2218, - 2219, + 2444, + 2445, 5, - 97, + 116, 0, 0, - 2219, - 2220, + 2445, + 2446, 5, - 115, + 99, 0, 0, - 2220, - 2221, + 2446, + 2447, 5, - 107, + 104, 0, 0, - 2221, - 2222, + 2447, + 2448, 5, 70, 0, 0, - 2222, - 2223, + 2448, + 2449, 5, 97, 0, 0, - 2223, - 2224, + 2449, + 2450, 5, 105, 0, 0, - 2224, - 2225, + 2450, + 2451, 5, 108, 0, 0, - 2225, - 2226, + 2451, + 2452, 5, - 101, + 117, 0, 0, - 2226, - 2227, + 2452, + 2453, 5, - 100, + 114, 0, 0, - 2227, - 2228, + 2453, + 2454, + 5, + 101, + 0, + 0, + 2454, + 2455, 5, 34, 0, 0, - 2228, - 258, + 2455, + 286, 1, 0, 0, 0, - 2229, - 2230, + 2456, + 2457, 5, 34, 0, 0, - 2230, - 2231, + 2457, + 2458, 5, 83, 0, 0, - 2231, - 2232, + 2458, + 2459, 5, 116, 0, 0, - 2232, - 2233, + 2459, + 2460, 5, 97, 0, 0, - 2233, - 2234, + 2460, + 2461, 5, 116, 0, 0, - 2234, - 2235, + 2461, + 2462, 5, 101, 0, 0, - 2235, - 2236, + 2462, + 2463, 5, 115, 0, 0, - 2236, - 2237, + 2463, + 2464, 5, 46, 0, 0, - 2237, - 2238, + 2464, + 2465, 5, 80, 0, 0, - 2238, - 2239, + 2465, + 2466, 5, - 101, + 97, 0, 0, - 2239, - 2240, + 2466, + 2467, 5, 114, 0, 0, - 2240, - 2241, + 2467, + 2468, 5, - 109, + 97, 0, 0, - 2241, - 2242, + 2468, + 2469, 5, - 105, + 109, 0, 0, - 2242, - 2243, + 2469, + 2470, 5, - 115, + 101, 0, 0, - 2243, - 2244, + 2470, + 2471, 5, - 115, + 116, 0, 0, - 2244, - 2245, + 2471, + 2472, 5, - 105, + 101, 0, 0, - 2245, - 2246, + 2472, + 2473, 5, - 111, + 114, 0, 0, - 2246, - 2247, + 2473, + 2474, 5, - 110, + 80, 0, 0, - 2247, - 2248, + 2474, + 2475, 5, - 115, + 97, 0, 0, - 2248, - 2249, + 2475, + 2476, 5, - 34, - 0, + 116, 0, - 2249, - 260, - 1, 0, + 2476, + 2477, + 5, + 104, 0, 0, - 2250, - 2251, + 2477, + 2478, 5, - 34, + 70, 0, 0, - 2251, - 2252, + 2478, + 2479, 5, - 83, + 97, 0, 0, - 2252, - 2253, + 2479, + 2480, 5, - 116, + 105, 0, 0, - 2253, - 2254, + 2480, + 2481, 5, - 97, + 108, 0, 0, - 2254, - 2255, + 2481, + 2482, 5, - 116, + 117, 0, 0, - 2255, - 2256, + 2482, + 2483, 5, - 101, + 114, 0, 0, - 2256, - 2257, + 2483, + 2484, 5, - 115, + 101, 0, 0, - 2257, - 2258, + 2484, + 2485, 5, - 46, + 34, 0, 0, - 2258, - 2259, - 5, - 82, + 2485, + 288, + 1, 0, 0, - 2259, - 2260, + 0, + 2486, + 2487, 5, - 101, + 34, 0, 0, - 2260, - 2261, + 2487, + 2488, 5, - 115, + 83, 0, 0, - 2261, - 2262, + 2488, + 2489, 5, - 117, + 116, 0, 0, - 2262, - 2263, + 2489, + 2490, 5, - 108, + 97, 0, 0, - 2263, - 2264, + 2490, + 2491, 5, 116, 0, 0, - 2264, - 2265, + 2491, + 2492, 5, - 80, + 101, 0, 0, - 2265, - 2266, + 2492, + 2493, 5, - 97, + 115, 0, 0, - 2266, - 2267, + 2493, + 2494, 5, - 116, + 46, 0, 0, - 2267, - 2268, + 2494, + 2495, 5, - 104, + 66, 0, 0, - 2268, - 2269, + 2495, + 2496, 5, - 77, + 114, 0, 0, - 2269, - 2270, + 2496, + 2497, 5, 97, 0, 0, - 2270, - 2271, + 2497, + 2498, 5, - 116, + 110, 0, 0, - 2271, - 2272, + 2498, + 2499, 5, 99, 0, 0, - 2272, - 2273, + 2499, + 2500, 5, 104, 0, 0, - 2273, - 2274, + 2500, + 2501, 5, 70, 0, 0, - 2274, - 2275, + 2501, + 2502, 5, 97, 0, 0, - 2275, - 2276, + 2502, + 2503, 5, 105, 0, 0, - 2276, - 2277, + 2503, + 2504, 5, 108, 0, 0, - 2277, - 2278, - 5, - 117, - 0, - 0, - 2278, - 2279, + 2504, + 2505, 5, - 114, + 101, 0, 0, - 2279, - 2280, + 2505, + 2506, 5, - 101, + 100, 0, 0, - 2280, - 2281, + 2506, + 2507, 5, 34, 0, 0, - 2281, - 262, + 2507, + 290, 1, 0, 0, 0, - 2282, - 2283, + 2508, + 2509, 5, 34, 0, 0, - 2283, - 2284, + 2509, + 2510, 5, 83, 0, 0, - 2284, - 2285, + 2510, + 2511, 5, 116, 0, 0, - 2285, - 2286, + 2511, + 2512, 5, 97, 0, 0, - 2286, - 2287, + 2512, + 2513, 5, 116, 0, 0, - 2287, - 2288, + 2513, + 2514, 5, 101, 0, 0, - 2288, - 2289, + 2514, + 2515, 5, 115, 0, 0, - 2289, - 2290, + 2515, + 2516, 5, 46, 0, 0, - 2290, - 2291, + 2516, + 2517, 5, - 80, + 78, 0, 0, - 2291, - 2292, + 2517, + 2518, 5, - 97, + 111, 0, 0, - 2292, - 2293, + 2518, + 2519, 5, - 114, + 67, 0, 0, - 2293, - 2294, + 2519, + 2520, 5, - 97, + 104, 0, 0, - 2294, - 2295, + 2520, + 2521, 5, - 109, + 111, 0, 0, - 2295, - 2296, + 2521, + 2522, 5, - 101, + 105, 0, 0, - 2296, - 2297, + 2522, + 2523, 5, - 116, + 99, 0, 0, - 2297, - 2298, + 2523, + 2524, 5, 101, 0, 0, - 2298, - 2299, - 5, - 114, - 0, - 0, - 2299, - 2300, + 2524, + 2525, 5, - 80, + 77, 0, 0, - 2300, - 2301, + 2525, + 2526, 5, 97, 0, 0, - 2301, - 2302, + 2526, + 2527, 5, 116, 0, 0, - 2302, - 2303, - 5, - 104, - 0, - 0, - 2303, - 2304, - 5, - 70, - 0, - 0, - 2304, - 2305, - 5, - 97, - 0, - 0, - 2305, - 2306, - 5, - 105, - 0, - 0, - 2306, - 2307, + 2527, + 2528, 5, - 108, + 99, 0, 0, - 2307, - 2308, + 2528, + 2529, 5, - 117, + 104, 0, 0, - 2308, - 2309, + 2529, + 2530, 5, - 114, + 101, 0, 0, - 2309, - 2310, + 2530, + 2531, 5, - 101, + 100, 0, 0, - 2310, - 2311, + 2531, + 2532, 5, 34, 0, 0, - 2311, - 264, + 2532, + 292, 1, 0, 0, 0, - 2312, - 2313, + 2533, + 2534, 5, 34, 0, 0, - 2313, - 2314, + 2534, + 2535, 5, 83, 0, 0, - 2314, - 2315, + 2535, + 2536, 5, 116, 0, 0, - 2315, - 2316, + 2536, + 2537, 5, 97, 0, 0, - 2316, - 2317, + 2537, + 2538, 5, 116, 0, 0, - 2317, - 2318, + 2538, + 2539, 5, 101, 0, 0, - 2318, - 2319, + 2539, + 2540, 5, 115, 0, 0, - 2319, - 2320, + 2540, + 2541, 5, 46, 0, 0, - 2320, - 2321, + 2541, + 2542, 5, - 66, + 73, 0, 0, - 2321, - 2322, + 2542, + 2543, + 5, + 110, + 0, + 0, + 2543, + 2544, + 5, + 116, + 0, + 0, + 2544, + 2545, 5, 114, 0, 0, - 2322, - 2323, + 2545, + 2546, 5, - 97, + 105, 0, 0, - 2323, - 2324, + 2546, + 2547, 5, 110, 0, 0, - 2324, - 2325, + 2547, + 2548, 5, - 99, + 115, 0, 0, - 2325, - 2326, + 2548, + 2549, 5, - 104, + 105, 0, 0, - 2326, - 2327, + 2549, + 2550, + 5, + 99, + 0, + 0, + 2550, + 2551, 5, 70, 0, 0, - 2327, - 2328, + 2551, + 2552, 5, 97, 0, 0, - 2328, - 2329, + 2552, + 2553, 5, 105, 0, 0, - 2329, - 2330, + 2553, + 2554, + 5, + 108, + 0, + 0, + 2554, + 2555, 5, - 108, + 117, 0, 0, - 2330, - 2331, + 2555, + 2556, 5, - 101, + 114, 0, 0, - 2331, - 2332, + 2556, + 2557, 5, - 100, + 101, 0, 0, - 2332, - 2333, + 2557, + 2558, 5, 34, 0, 0, - 2333, - 266, + 2558, + 294, 1, 0, 0, 0, - 2334, - 2335, + 2559, + 2560, 5, 34, 0, 0, - 2335, - 2336, + 2560, + 2561, 5, 83, 0, 0, - 2336, - 2337, + 2561, + 2562, 5, 116, 0, 0, - 2337, - 2338, + 2562, + 2563, 5, 97, 0, 0, - 2338, - 2339, + 2563, + 2564, 5, 116, 0, 0, - 2339, - 2340, + 2564, + 2565, 5, 101, 0, 0, - 2340, - 2341, + 2565, + 2566, 5, 115, 0, 0, - 2341, - 2342, + 2566, + 2567, 5, 46, 0, 0, - 2342, - 2343, + 2567, + 2568, 5, - 78, + 69, 0, 0, - 2343, - 2344, + 2568, + 2569, 5, - 111, + 120, 0, 0, - 2344, - 2345, + 2569, + 2570, 5, - 67, + 99, 0, 0, - 2345, - 2346, + 2570, + 2571, 5, - 104, + 101, 0, 0, - 2346, - 2347, + 2571, + 2572, 5, - 111, + 101, 0, 0, - 2347, - 2348, + 2572, + 2573, 5, - 105, + 100, 0, 0, - 2348, - 2349, + 2573, + 2574, 5, - 99, + 84, 0, 0, - 2349, - 2350, + 2574, + 2575, 5, - 101, + 111, 0, 0, - 2350, - 2351, + 2575, + 2576, 5, - 77, + 108, 0, 0, - 2351, - 2352, + 2576, + 2577, 5, - 97, + 101, 0, 0, - 2352, - 2353, + 2577, + 2578, 5, - 116, + 114, 0, 0, - 2353, - 2354, + 2578, + 2579, 5, - 99, + 97, 0, 0, - 2354, - 2355, + 2579, + 2580, 5, - 104, + 116, 0, 0, - 2355, - 2356, + 2580, + 2581, 5, 101, 0, 0, - 2356, - 2357, + 2581, + 2582, 5, 100, 0, 0, - 2357, - 2358, + 2582, + 2583, 5, - 34, - 0, + 70, 0, - 2358, - 268, - 1, 0, + 2583, + 2584, + 5, + 97, 0, 0, - 2359, - 2360, + 2584, + 2585, 5, - 34, + 105, 0, 0, - 2360, - 2361, + 2585, + 2586, 5, - 83, + 108, 0, 0, - 2361, - 2362, + 2586, + 2587, 5, - 116, + 117, 0, 0, - 2362, - 2363, + 2587, + 2588, 5, - 97, + 114, 0, 0, - 2363, - 2364, + 2588, + 2589, 5, - 116, + 101, 0, 0, - 2364, - 2365, + 2589, + 2590, 5, - 101, + 84, 0, 0, - 2365, - 2366, + 2590, + 2591, 5, - 115, + 104, 0, 0, - 2366, - 2367, + 2591, + 2592, 5, - 46, + 114, 0, 0, - 2367, - 2368, + 2592, + 2593, 5, - 73, + 101, 0, 0, - 2368, - 2369, + 2593, + 2594, 5, - 110, + 115, 0, 0, - 2369, - 2370, + 2594, + 2595, 5, - 116, + 104, 0, 0, - 2370, - 2371, + 2595, + 2596, 5, - 114, + 111, 0, 0, - 2371, - 2372, + 2596, + 2597, 5, - 105, + 108, 0, 0, - 2372, - 2373, + 2597, + 2598, 5, - 110, + 100, 0, 0, - 2373, - 2374, + 2598, + 2599, 5, - 115, + 34, 0, 0, - 2374, - 2375, + 2599, + 296, + 1, + 0, + 0, + 0, + 2600, + 2601, 5, - 105, + 34, 0, 0, - 2375, - 2376, + 2601, + 2602, 5, - 99, + 83, 0, 0, - 2376, - 2377, + 2602, + 2603, 5, - 70, + 116, 0, 0, - 2377, - 2378, + 2603, + 2604, 5, 97, 0, 0, - 2378, - 2379, + 2604, + 2605, 5, - 105, + 116, 0, 0, - 2379, - 2380, + 2605, + 2606, 5, - 108, + 101, 0, 0, - 2380, - 2381, + 2606, + 2607, 5, - 117, + 115, 0, 0, - 2381, - 2382, + 2607, + 2608, 5, - 114, + 46, 0, 0, - 2382, - 2383, + 2608, + 2609, 5, - 101, + 73, 0, 0, - 2383, - 2384, + 2609, + 2610, 5, - 34, - 0, + 116, 0, - 2384, - 270, - 1, 0, + 2610, + 2611, + 5, + 101, 0, 0, - 2385, - 2386, + 2611, + 2612, 5, - 34, + 109, 0, 0, - 2386, - 2387, + 2612, + 2613, 5, - 83, + 82, 0, 0, - 2387, - 2388, + 2613, + 2614, 5, - 116, + 101, 0, 0, - 2388, - 2389, + 2614, + 2615, 5, 97, 0, 0, - 2389, - 2390, + 2615, + 2616, 5, - 116, + 100, 0, 0, - 2390, - 2391, + 2616, + 2617, 5, 101, 0, 0, - 2391, - 2392, - 5, - 115, - 0, - 0, - 2392, - 2393, + 2617, + 2618, 5, - 46, + 114, 0, 0, - 2393, - 2394, + 2618, + 2619, 5, - 69, + 70, 0, 0, - 2394, - 2395, + 2619, + 2620, 5, - 120, + 97, 0, 0, - 2395, - 2396, + 2620, + 2621, 5, - 99, + 105, 0, 0, - 2396, - 2397, + 2621, + 2622, 5, - 101, + 108, 0, 0, - 2397, - 2398, + 2622, + 2623, 5, 101, 0, 0, - 2398, - 2399, + 2623, + 2624, 5, 100, 0, 0, - 2399, - 2400, + 2624, + 2625, 5, - 84, + 34, 0, 0, - 2400, - 2401, - 5, - 111, + 2625, + 298, + 1, 0, 0, - 2401, - 2402, + 0, + 2626, + 2627, 5, - 108, + 34, 0, 0, - 2402, - 2403, + 2627, + 2628, 5, - 101, + 83, 0, 0, - 2403, - 2404, + 2628, + 2629, 5, - 114, + 116, 0, 0, - 2404, - 2405, + 2629, + 2630, 5, 97, 0, 0, - 2405, - 2406, + 2630, + 2631, 5, 116, 0, 0, - 2406, - 2407, + 2631, + 2632, 5, 101, 0, 0, - 2407, - 2408, + 2632, + 2633, 5, - 100, + 115, 0, 0, - 2408, - 2409, + 2633, + 2634, 5, - 70, + 46, 0, 0, - 2409, - 2410, + 2634, + 2635, 5, - 97, + 82, 0, 0, - 2410, - 2411, + 2635, + 2636, 5, - 105, + 101, 0, 0, - 2411, - 2412, + 2636, + 2637, 5, - 108, + 115, 0, 0, - 2412, - 2413, + 2637, + 2638, 5, 117, 0, 0, - 2413, - 2414, + 2638, + 2639, 5, - 114, + 108, 0, 0, - 2414, - 2415, + 2639, + 2640, 5, - 101, + 116, 0, 0, - 2415, - 2416, + 2640, + 2641, 5, - 84, + 87, 0, 0, - 2416, - 2417, + 2641, + 2642, 5, - 104, + 114, 0, 0, - 2417, - 2418, + 2642, + 2643, 5, - 114, + 105, 0, 0, - 2418, - 2419, + 2643, + 2644, + 5, + 116, + 0, + 0, + 2644, + 2645, 5, 101, 0, 0, - 2419, - 2420, + 2645, + 2646, 5, - 115, + 114, 0, 0, - 2420, - 2421, + 2646, + 2647, 5, - 104, + 70, 0, 0, - 2421, - 2422, + 2647, + 2648, 5, - 111, + 97, 0, 0, - 2422, - 2423, + 2648, + 2649, + 5, + 105, + 0, + 0, + 2649, + 2650, 5, 108, 0, 0, - 2423, - 2424, + 2650, + 2651, + 5, + 101, + 0, + 0, + 2651, + 2652, 5, 100, 0, 0, - 2424, - 2425, + 2652, + 2653, 5, 34, 0, 0, - 2425, - 272, + 2653, + 300, 1, 0, 0, 0, - 2426, - 2427, + 2654, + 2655, 5, 34, 0, 0, - 2427, - 2428, + 2655, + 2656, 5, 83, 0, 0, - 2428, - 2429, + 2656, + 2657, 5, 116, 0, 0, - 2429, - 2430, + 2657, + 2658, 5, 97, 0, 0, - 2430, - 2431, + 2658, + 2659, 5, 116, 0, 0, - 2431, - 2432, + 2659, + 2660, 5, 101, 0, 0, - 2432, - 2433, + 2660, + 2661, 5, 115, 0, 0, - 2433, - 2434, + 2661, + 2662, 5, 46, 0, 0, - 2434, - 2435, + 2662, + 2663, 5, - 73, + 81, 0, 0, - 2435, - 2436, + 2663, + 2664, 5, - 116, + 117, 0, 0, - 2436, - 2437, + 2664, + 2665, 5, 101, 0, 0, - 2437, - 2438, + 2665, + 2666, 5, - 109, + 114, 0, 0, - 2438, - 2439, + 2666, + 2667, 5, - 82, + 121, 0, 0, - 2439, - 2440, + 2667, + 2668, 5, - 101, + 69, 0, 0, - 2440, - 2441, + 2668, + 2669, + 5, + 118, + 0, + 0, + 2669, + 2670, 5, 97, 0, 0, - 2441, - 2442, + 2670, + 2671, 5, - 100, + 108, 0, 0, - 2442, - 2443, + 2671, + 2672, 5, - 101, + 117, + 0, + 0, + 2672, + 2673, + 5, + 97, + 0, + 0, + 2673, + 2674, + 5, + 116, + 0, + 0, + 2674, + 2675, + 5, + 105, 0, 0, - 2443, - 2444, + 2675, + 2676, 5, - 114, + 111, 0, 0, - 2444, - 2445, + 2676, + 2677, 5, - 70, + 110, 0, 0, - 2445, - 2446, + 2677, + 2678, 5, - 97, + 69, 0, 0, - 2446, - 2447, + 2678, + 2679, 5, - 105, + 114, 0, 0, - 2447, - 2448, + 2679, + 2680, 5, - 108, + 114, 0, 0, - 2448, - 2449, + 2680, + 2681, 5, - 101, + 111, 0, 0, - 2449, - 2450, + 2681, + 2682, 5, - 100, + 114, 0, 0, - 2450, - 2451, + 2682, + 2683, 5, 34, 0, 0, - 2451, - 274, + 2683, + 302, 1, 0, 0, 0, - 2452, - 2453, + 2684, + 2685, 5, 34, 0, 0, - 2453, - 2454, + 2685, + 2686, 5, 83, 0, 0, - 2454, - 2455, + 2686, + 2687, 5, 116, 0, 0, - 2455, - 2456, + 2687, + 2688, 5, 97, 0, 0, - 2456, - 2457, + 2688, + 2689, 5, 116, 0, 0, - 2457, - 2458, + 2689, + 2690, 5, 101, 0, 0, - 2458, - 2459, + 2690, + 2691, 5, 115, 0, 0, - 2459, - 2460, + 2691, + 2692, 5, 46, 0, 0, - 2460, - 2461, + 2692, + 2693, 5, 82, 0, 0, - 2461, - 2462, + 2693, + 2694, 5, - 101, + 117, 0, 0, - 2462, - 2463, + 2694, + 2695, 5, - 115, + 110, 0, 0, - 2463, - 2464, + 2695, + 2696, 5, - 117, + 116, 0, 0, - 2464, - 2465, + 2696, + 2697, 5, - 108, + 105, 0, 0, - 2465, - 2466, + 2697, + 2698, 5, - 116, + 109, 0, 0, - 2466, - 2467, + 2698, + 2699, 5, - 87, + 101, 0, 0, - 2467, - 2468, + 2699, + 2700, 5, - 114, + 34, 0, 0, - 2468, - 2469, - 5, - 105, + 2700, + 304, + 1, 0, 0, - 2469, - 2470, + 0, + 2701, + 2706, 5, - 116, + 34, 0, 0, - 2470, - 2471, - 5, - 101, + 2702, + 2705, + 3, + 319, + 159, 0, + 2703, + 2705, + 3, + 325, + 162, 0, - 2471, - 2472, - 5, - 114, + 2704, + 2702, + 1, 0, 0, - 2472, - 2473, + 0, + 2704, + 2703, + 1, + 0, + 0, + 0, + 2705, + 2708, + 1, + 0, + 0, + 0, + 2706, + 2704, + 1, + 0, + 0, + 0, + 2706, + 2707, + 1, + 0, + 0, + 0, + 2707, + 2709, + 1, + 0, + 0, + 0, + 2708, + 2706, + 1, + 0, + 0, + 0, + 2709, + 2710, 5, - 70, + 46, 0, 0, - 2473, - 2474, + 2710, + 2711, 5, - 97, + 36, 0, 0, - 2474, - 2475, + 2711, + 2712, 5, - 105, + 34, 0, 0, - 2475, - 2476, + 2712, + 306, + 1, + 0, + 0, + 0, + 2713, + 2714, 5, - 108, + 34, 0, 0, - 2476, - 2477, + 2714, + 2715, 5, - 101, + 36, 0, 0, - 2477, - 2478, + 2715, + 2716, 5, - 100, + 36, 0, 0, - 2478, - 2479, + 2716, + 2721, + 1, + 0, + 0, + 0, + 2717, + 2720, + 3, + 319, + 159, + 0, + 2718, + 2720, + 3, + 325, + 162, + 0, + 2719, + 2717, + 1, + 0, + 0, + 0, + 2719, + 2718, + 1, + 0, + 0, + 0, + 2720, + 2723, + 1, + 0, + 0, + 0, + 2721, + 2719, + 1, + 0, + 0, + 0, + 2721, + 2722, + 1, + 0, + 0, + 0, + 2722, + 2724, + 1, + 0, + 0, + 0, + 2723, + 2721, + 1, + 0, + 0, + 0, + 2724, + 2725, 5, 34, 0, 0, - 2479, - 276, + 2725, + 308, 1, 0, 0, 0, - 2480, - 2481, + 2726, + 2727, 5, 34, 0, 0, - 2481, - 2482, + 2727, + 2728, 5, - 83, + 36, 0, 0, - 2482, - 2483, + 2728, + 2742, 5, - 116, + 34, 0, 0, - 2483, - 2484, + 2729, + 2730, 5, - 97, + 34, 0, 0, - 2484, - 2485, + 2730, + 2731, 5, - 116, + 36, + 0, + 0, + 2731, + 2732, + 1, + 0, + 0, + 0, + 2732, + 2737, + 7, + 0, + 0, + 0, + 2733, + 2736, + 3, + 319, + 159, + 0, + 2734, + 2736, + 3, + 325, + 162, + 0, + 2735, + 2733, + 1, + 0, + 0, + 0, + 2735, + 2734, + 1, + 0, + 0, + 0, + 2736, + 2739, + 1, + 0, + 0, + 0, + 2737, + 2735, + 1, + 0, 0, 0, - 2485, - 2486, - 5, - 101, + 2737, + 2738, + 1, + 0, 0, 0, - 2486, - 2487, - 5, - 115, + 2738, + 2740, + 1, 0, 0, - 2487, - 2488, - 5, - 46, 0, + 2739, + 2737, + 1, 0, - 2488, - 2489, - 5, - 82, 0, 0, - 2489, - 2490, + 2740, + 2742, 5, - 117, + 34, 0, 0, - 2490, - 2491, - 5, - 110, + 2741, + 2726, + 1, 0, 0, - 2491, - 2492, - 5, - 116, + 0, + 2741, + 2729, + 1, 0, 0, - 2492, - 2493, - 5, - 105, 0, + 2742, + 310, + 1, 0, - 2493, - 2494, - 5, - 109, 0, 0, - 2494, - 2495, + 2743, + 2744, 5, - 101, + 34, 0, 0, - 2495, - 2496, + 2744, + 2745, 5, - 34, + 36, 0, 0, - 2496, - 278, + 2745, + 2746, 1, 0, 0, 0, - 2497, - 2502, - 5, - 34, + 2746, + 2751, + 7, + 1, 0, 0, - 2498, - 2501, + 2747, + 2750, 3, - 287, - 143, + 319, + 159, 0, - 2499, - 2501, + 2748, + 2750, 3, - 293, - 146, + 325, + 162, 0, - 2500, - 2498, + 2749, + 2747, 1, 0, 0, 0, - 2500, - 2499, + 2749, + 2748, 1, 0, 0, 0, - 2501, - 2504, + 2750, + 2753, 1, 0, 0, 0, - 2502, - 2500, + 2751, + 2749, 1, 0, 0, 0, - 2502, - 2503, + 2751, + 2752, 1, 0, 0, 0, - 2503, - 2505, + 2752, + 2754, 1, 0, 0, 0, - 2504, - 2502, + 2753, + 2751, 1, 0, 0, 0, - 2505, - 2506, + 2754, + 2755, 5, - 46, + 34, 0, 0, - 2506, - 2507, - 5, - 36, + 2755, + 312, + 1, 0, 0, - 2507, - 2508, + 0, + 2756, + 2757, 5, 34, 0, 0, - 2508, - 280, - 1, + 2757, + 2758, + 5, + 83, + 0, 0, + 2758, + 2759, + 5, + 116, 0, 0, - 2509, - 2510, + 2759, + 2760, 5, - 34, + 97, 0, 0, - 2510, - 2511, + 2760, + 2761, 5, - 36, + 116, 0, 0, - 2511, - 2512, + 2761, + 2762, 5, - 36, + 101, 0, 0, - 2512, - 2517, + 2762, + 2763, + 5, + 115, + 0, + 0, + 2763, + 2764, + 5, + 46, + 0, + 0, + 2764, + 2767, 1, 0, 0, 0, - 2513, - 2516, + 2765, + 2768, 3, - 287, - 143, + 319, + 159, 0, - 2514, - 2516, + 2766, + 2768, 3, - 293, - 146, + 325, + 162, 0, - 2515, - 2513, + 2767, + 2765, 1, 0, 0, 0, - 2515, - 2514, + 2767, + 2766, 1, 0, 0, 0, - 2516, - 2519, + 2768, + 2769, 1, 0, 0, 0, - 2517, - 2515, + 2769, + 2767, 1, 0, 0, 0, - 2517, - 2518, + 2769, + 2770, 1, 0, 0, 0, - 2518, - 2520, + 2770, + 2771, 1, 0, 0, 0, - 2519, - 2517, + 2771, + 2776, + 5, + 40, + 0, + 0, + 2772, + 2775, + 3, + 319, + 159, + 0, + 2773, + 2775, + 3, + 325, + 162, + 0, + 2774, + 2772, 1, 0, 0, 0, - 2520, - 2521, - 5, - 34, + 2774, + 2773, + 1, 0, 0, - 2521, - 282, + 0, + 2775, + 2778, 1, 0, 0, 0, - 2522, - 2523, + 2776, + 2774, + 1, + 0, + 0, + 0, + 2776, + 2777, + 1, + 0, + 0, + 0, + 2777, + 2779, + 1, + 0, + 0, + 0, + 2778, + 2776, + 1, + 0, + 0, + 0, + 2779, + 2780, 5, - 34, + 41, 0, 0, - 2523, - 2524, + 2780, + 2781, 5, - 36, + 34, 0, 0, - 2524, - 2529, + 2781, + 314, 1, 0, 0, 0, - 2525, - 2528, + 2782, + 2787, 3, - 287, - 143, + 327, + 163, 0, - 2526, - 2528, + 2783, + 2786, 3, - 293, - 146, + 319, + 159, 0, - 2527, - 2525, + 2784, + 2786, + 3, + 325, + 162, + 0, + 2785, + 2783, 1, 0, 0, 0, - 2527, - 2526, + 2785, + 2784, 1, 0, 0, 0, - 2528, - 2531, + 2786, + 2789, 1, 0, 0, 0, - 2529, - 2527, + 2787, + 2785, 1, 0, 0, 0, - 2529, - 2530, + 2787, + 2788, 1, 0, 0, 0, - 2530, - 2532, + 2788, + 2790, 1, 0, 0, 0, - 2531, - 2529, + 2789, + 2787, 1, 0, 0, 0, - 2532, - 2533, - 5, - 34, - 0, + 2790, + 2791, + 3, + 329, + 164, 0, - 2533, - 284, + 2791, + 316, 1, 0, 0, 0, - 2534, - 2539, + 2792, + 2797, 5, 34, 0, 0, - 2535, - 2538, + 2793, + 2796, 3, - 287, - 143, + 319, + 159, 0, - 2536, - 2538, + 2794, + 2796, 3, - 293, - 146, + 325, + 162, 0, - 2537, - 2535, + 2795, + 2793, 1, 0, 0, 0, - 2537, - 2536, + 2795, + 2794, 1, 0, 0, 0, - 2538, - 2541, + 2796, + 2799, 1, 0, 0, 0, - 2539, - 2537, + 2797, + 2795, 1, 0, 0, 0, - 2539, - 2540, + 2797, + 2798, 1, 0, 0, 0, - 2540, - 2542, + 2798, + 2800, 1, 0, 0, 0, - 2541, - 2539, + 2799, + 2797, 1, 0, 0, 0, - 2542, - 2543, + 2800, + 2801, 5, 34, 0, 0, - 2543, - 286, + 2801, + 318, 1, 0, 0, 0, - 2544, - 2547, + 2802, + 2805, 5, 92, 0, 0, - 2545, - 2548, + 2803, + 2806, 7, + 2, 0, 0, - 0, - 2546, - 2548, + 2804, + 2806, 3, - 289, - 144, + 321, + 160, 0, - 2547, - 2545, + 2805, + 2803, 1, 0, 0, 0, - 2547, - 2546, + 2805, + 2804, 1, 0, 0, 0, - 2548, - 288, + 2806, + 320, 1, 0, 0, 0, - 2549, - 2550, + 2807, + 2808, 5, 117, 0, 0, - 2550, - 2551, + 2808, + 2809, 3, - 291, - 145, + 323, + 161, 0, - 2551, - 2552, + 2809, + 2810, 3, - 291, - 145, + 323, + 161, 0, - 2552, - 2553, + 2810, + 2811, 3, - 291, - 145, + 323, + 161, 0, - 2553, - 2554, + 2811, + 2812, 3, - 291, - 145, + 323, + 161, 0, - 2554, - 290, + 2812, + 322, 1, 0, 0, 0, - 2555, - 2556, + 2813, + 2814, 7, - 1, + 3, 0, 0, - 2556, - 292, + 2814, + 324, 1, 0, 0, 0, - 2557, - 2558, + 2815, + 2816, 8, - 2, + 4, 0, 0, - 2558, - 294, + 2816, + 326, 1, 0, 0, 0, - 2559, - 2568, + 2817, + 2818, + 5, + 34, + 0, + 0, + 2818, + 2819, + 5, + 123, + 0, + 0, + 2819, + 2820, + 5, + 37, + 0, + 0, + 2820, + 328, + 1, + 0, + 0, + 0, + 2821, + 2822, + 5, + 37, + 0, + 0, + 2822, + 2823, + 5, + 125, + 0, + 0, + 2823, + 2824, + 5, + 34, + 0, + 0, + 2824, + 330, + 1, + 0, + 0, + 0, + 2825, + 2834, 5, 48, 0, 0, - 2560, - 2564, + 2826, + 2830, 7, - 3, + 5, 0, 0, - 2561, - 2563, + 2827, + 2829, 7, - 4, + 6, 0, 0, - 2562, - 2561, + 2828, + 2827, 1, 0, 0, 0, - 2563, - 2566, + 2829, + 2832, 1, 0, 0, 0, - 2564, - 2562, + 2830, + 2828, 1, 0, 0, 0, - 2564, - 2565, + 2830, + 2831, 1, 0, 0, 0, - 2565, - 2568, + 2831, + 2834, 1, 0, 0, 0, - 2566, - 2564, + 2832, + 2830, 1, 0, 0, 0, - 2567, - 2559, + 2833, + 2825, 1, 0, 0, 0, - 2567, - 2560, + 2833, + 2826, 1, 0, 0, 0, - 2568, - 296, + 2834, + 332, 1, 0, 0, 0, - 2569, - 2571, + 2835, + 2837, 5, 45, 0, 0, - 2570, - 2569, + 2836, + 2835, 1, 0, 0, 0, - 2570, - 2571, + 2836, + 2837, 1, 0, 0, 0, - 2571, - 2572, + 2837, + 2838, 1, 0, 0, 0, - 2572, - 2579, + 2838, + 2845, 3, - 295, - 147, + 331, + 165, 0, - 2573, - 2575, + 2839, + 2841, 5, 46, 0, 0, - 2574, - 2576, + 2840, + 2842, 7, - 4, + 6, 0, 0, - 2575, - 2574, + 2841, + 2840, 1, 0, 0, 0, - 2576, - 2577, + 2842, + 2843, 1, 0, 0, 0, - 2577, - 2575, + 2843, + 2841, 1, 0, 0, 0, - 2577, - 2578, + 2843, + 2844, 1, 0, 0, 0, - 2578, - 2580, + 2844, + 2846, 1, 0, 0, 0, - 2579, - 2573, + 2845, + 2839, 1, 0, 0, 0, - 2579, - 2580, + 2845, + 2846, 1, 0, 0, 0, - 2580, - 2582, + 2846, + 2848, 1, 0, 0, 0, - 2581, - 2583, + 2847, + 2849, 3, - 299, - 149, + 335, + 167, 0, - 2582, - 2581, + 2848, + 2847, 1, 0, 0, 0, - 2582, - 2583, + 2848, + 2849, 1, 0, 0, 0, - 2583, - 298, + 2849, + 334, 1, 0, 0, 0, - 2584, - 2586, + 2850, + 2852, + 7, 7, - 5, 0, 0, - 2585, - 2587, + 2851, + 2853, 7, - 6, + 8, 0, 0, - 2586, - 2585, + 2852, + 2851, 1, 0, 0, 0, - 2586, - 2587, + 2852, + 2853, 1, 0, 0, 0, - 2587, - 2588, + 2853, + 2854, 1, 0, 0, 0, - 2588, - 2589, + 2854, + 2855, 3, - 295, - 147, + 331, + 165, 0, - 2589, - 300, + 2855, + 336, 1, 0, 0, 0, - 2590, - 2592, - 7, + 2856, + 2858, 7, + 9, 0, 0, - 2591, - 2590, + 2857, + 2856, 1, 0, 0, 0, - 2592, - 2593, + 2858, + 2859, 1, 0, 0, 0, - 2593, - 2591, + 2859, + 2857, 1, 0, 0, 0, - 2593, - 2594, + 2859, + 2860, 1, 0, 0, 0, - 2594, - 2595, + 2860, + 2861, 1, 0, 0, 0, - 2595, - 2596, + 2861, + 2862, 6, - 150, + 168, 0, 0, - 2596, - 302, + 2862, + 338, 1, 0, 0, 0, - 18, + 27, 0, - 2500, - 2502, - 2515, - 2517, - 2527, - 2529, - 2537, - 2539, - 2547, - 2564, - 2567, - 2570, - 2577, - 2579, - 2582, - 2586, - 2593, + 2704, + 2706, + 2719, + 2721, + 2735, + 2737, + 2741, + 2749, + 2751, + 2767, + 2769, + 2774, + 2776, + 2785, + 2787, + 2795, + 2797, + 2805, + 2830, + 2833, + 2836, + 2843, + 2845, + 2848, + 2852, + 2859, 1, 6, 0, @@ -21305,128 +23543,144 @@ class ASLLexer(Lexer): PARALLEL = 22 MAP = 23 CHOICES = 24 - VARIABLE = 25 - DEFAULT = 26 - BRANCHES = 27 - AND = 28 - BOOLEANEQUALS = 29 - BOOLEANQUALSPATH = 30 - ISBOOLEAN = 31 - ISNULL = 32 - ISNUMERIC = 33 - ISPRESENT = 34 - ISSTRING = 35 - ISTIMESTAMP = 36 - NOT = 37 - NUMERICEQUALS = 38 - NUMERICEQUALSPATH = 39 - NUMERICGREATERTHAN = 40 - NUMERICGREATERTHANPATH = 41 - NUMERICGREATERTHANEQUALS = 42 - NUMERICGREATERTHANEQUALSPATH = 43 - NUMERICLESSTHAN = 44 - NUMERICLESSTHANPATH = 45 - NUMERICLESSTHANEQUALS = 46 - NUMERICLESSTHANEQUALSPATH = 47 - OR = 48 - STRINGEQUALS = 49 - STRINGEQUALSPATH = 50 - STRINGGREATERTHAN = 51 - STRINGGREATERTHANPATH = 52 - STRINGGREATERTHANEQUALS = 53 - STRINGGREATERTHANEQUALSPATH = 54 - STRINGLESSTHAN = 55 - STRINGLESSTHANPATH = 56 - STRINGLESSTHANEQUALS = 57 - STRINGLESSTHANEQUALSPATH = 58 - STRINGMATCHES = 59 - TIMESTAMPEQUALS = 60 - TIMESTAMPEQUALSPATH = 61 - TIMESTAMPGREATERTHAN = 62 - TIMESTAMPGREATERTHANPATH = 63 - TIMESTAMPGREATERTHANEQUALS = 64 - TIMESTAMPGREATERTHANEQUALSPATH = 65 - TIMESTAMPLESSTHAN = 66 - TIMESTAMPLESSTHANPATH = 67 - TIMESTAMPLESSTHANEQUALS = 68 - TIMESTAMPLESSTHANEQUALSPATH = 69 - SECONDSPATH = 70 - SECONDS = 71 - TIMESTAMPPATH = 72 - TIMESTAMP = 73 - TIMEOUTSECONDS = 74 - TIMEOUTSECONDSPATH = 75 - HEARTBEATSECONDS = 76 - HEARTBEATSECONDSPATH = 77 - PROCESSORCONFIG = 78 - MODE = 79 - INLINE = 80 - DISTRIBUTED = 81 - EXECUTIONTYPE = 82 - STANDARD = 83 - ITEMPROCESSOR = 84 - ITERATOR = 85 - ITEMSELECTOR = 86 - MAXCONCURRENCYPATH = 87 - MAXCONCURRENCY = 88 - RESOURCE = 89 - INPUTPATH = 90 - OUTPUTPATH = 91 - ITEMSPATH = 92 - RESULTPATH = 93 - RESULT = 94 - PARAMETERS = 95 - RESULTSELECTOR = 96 - ITEMREADER = 97 - READERCONFIG = 98 - INPUTTYPE = 99 - CSVHEADERLOCATION = 100 - CSVHEADERS = 101 - MAXITEMS = 102 - MAXITEMSPATH = 103 - TOLERATEDFAILURECOUNT = 104 - TOLERATEDFAILURECOUNTPATH = 105 - TOLERATEDFAILUREPERCENTAGE = 106 - TOLERATEDFAILUREPERCENTAGEPATH = 107 - LABEL = 108 - NEXT = 109 - END = 110 - CAUSE = 111 - CAUSEPATH = 112 - ERROR = 113 - ERRORPATH = 114 - RETRY = 115 - ERROREQUALS = 116 - INTERVALSECONDS = 117 - MAXATTEMPTS = 118 - BACKOFFRATE = 119 - MAXDELAYSECONDS = 120 - JITTERSTRATEGY = 121 - FULL = 122 - NONE = 123 - CATCH = 124 - ERRORNAMEStatesALL = 125 - ERRORNAMEStatesDataLimitExceeded = 126 - ERRORNAMEStatesHeartbeatTimeout = 127 - ERRORNAMEStatesTimeout = 128 - ERRORNAMEStatesTaskFailed = 129 - ERRORNAMEStatesPermissions = 130 - ERRORNAMEStatesResultPathMatchFailure = 131 - ERRORNAMEStatesParameterPathFailure = 132 - ERRORNAMEStatesBranchFailed = 133 - ERRORNAMEStatesNoChoiceMatched = 134 - ERRORNAMEStatesIntrinsicFailure = 135 - ERRORNAMEStatesExceedToleratedFailureThreshold = 136 - ERRORNAMEStatesItemReaderFailed = 137 - ERRORNAMEStatesResultWriterFailed = 138 - ERRORNAMEStatesRuntime = 139 - STRINGDOLLAR = 140 - STRINGPATHCONTEXTOBJ = 141 - STRINGPATH = 142 - STRING = 143 - INT = 144 - NUMBER = 145 - WS = 146 + CONDITION = 25 + VARIABLE = 26 + DEFAULT = 27 + BRANCHES = 28 + AND = 29 + BOOLEANEQUALS = 30 + BOOLEANQUALSPATH = 31 + ISBOOLEAN = 32 + ISNULL = 33 + ISNUMERIC = 34 + ISPRESENT = 35 + ISSTRING = 36 + ISTIMESTAMP = 37 + NOT = 38 + NUMERICEQUALS = 39 + NUMERICEQUALSPATH = 40 + NUMERICGREATERTHAN = 41 + NUMERICGREATERTHANPATH = 42 + NUMERICGREATERTHANEQUALS = 43 + NUMERICGREATERTHANEQUALSPATH = 44 + NUMERICLESSTHAN = 45 + NUMERICLESSTHANPATH = 46 + NUMERICLESSTHANEQUALS = 47 + NUMERICLESSTHANEQUALSPATH = 48 + OR = 49 + STRINGEQUALS = 50 + STRINGEQUALSPATH = 51 + STRINGGREATERTHAN = 52 + STRINGGREATERTHANPATH = 53 + STRINGGREATERTHANEQUALS = 54 + STRINGGREATERTHANEQUALSPATH = 55 + STRINGLESSTHAN = 56 + STRINGLESSTHANPATH = 57 + STRINGLESSTHANEQUALS = 58 + STRINGLESSTHANEQUALSPATH = 59 + STRINGMATCHES = 60 + TIMESTAMPEQUALS = 61 + TIMESTAMPEQUALSPATH = 62 + TIMESTAMPGREATERTHAN = 63 + TIMESTAMPGREATERTHANPATH = 64 + TIMESTAMPGREATERTHANEQUALS = 65 + TIMESTAMPGREATERTHANEQUALSPATH = 66 + TIMESTAMPLESSTHAN = 67 + TIMESTAMPLESSTHANPATH = 68 + TIMESTAMPLESSTHANEQUALS = 69 + TIMESTAMPLESSTHANEQUALSPATH = 70 + SECONDSPATH = 71 + SECONDS = 72 + TIMESTAMPPATH = 73 + TIMESTAMP = 74 + TIMEOUTSECONDS = 75 + TIMEOUTSECONDSPATH = 76 + HEARTBEATSECONDS = 77 + HEARTBEATSECONDSPATH = 78 + PROCESSORCONFIG = 79 + MODE = 80 + INLINE = 81 + DISTRIBUTED = 82 + EXECUTIONTYPE = 83 + STANDARD = 84 + ITEMPROCESSOR = 85 + ITERATOR = 86 + ITEMSELECTOR = 87 + MAXCONCURRENCYPATH = 88 + MAXCONCURRENCY = 89 + RESOURCE = 90 + INPUTPATH = 91 + OUTPUTPATH = 92 + ITEMS = 93 + ITEMSPATH = 94 + RESULTPATH = 95 + RESULT = 96 + PARAMETERS = 97 + CREDENTIALS = 98 + ROLEARN = 99 + ROLEARNPATH = 100 + RESULTSELECTOR = 101 + ITEMREADER = 102 + READERCONFIG = 103 + INPUTTYPE = 104 + CSVHEADERLOCATION = 105 + CSVHEADERS = 106 + MAXITEMS = 107 + MAXITEMSPATH = 108 + TOLERATEDFAILURECOUNT = 109 + TOLERATEDFAILURECOUNTPATH = 110 + TOLERATEDFAILUREPERCENTAGE = 111 + TOLERATEDFAILUREPERCENTAGEPATH = 112 + LABEL = 113 + RESULTWRITER = 114 + NEXT = 115 + END = 116 + CAUSE = 117 + CAUSEPATH = 118 + ERROR = 119 + ERRORPATH = 120 + RETRY = 121 + ERROREQUALS = 122 + INTERVALSECONDS = 123 + MAXATTEMPTS = 124 + BACKOFFRATE = 125 + MAXDELAYSECONDS = 126 + JITTERSTRATEGY = 127 + FULL = 128 + NONE = 129 + CATCH = 130 + QUERYLANGUAGE = 131 + JSONPATH = 132 + JSONATA = 133 + ASSIGN = 134 + OUTPUT = 135 + ARGUMENTS = 136 + ERRORNAMEStatesALL = 137 + ERRORNAMEStatesDataLimitExceeded = 138 + ERRORNAMEStatesHeartbeatTimeout = 139 + ERRORNAMEStatesTimeout = 140 + ERRORNAMEStatesTaskFailed = 141 + ERRORNAMEStatesPermissions = 142 + ERRORNAMEStatesResultPathMatchFailure = 143 + ERRORNAMEStatesParameterPathFailure = 144 + ERRORNAMEStatesBranchFailed = 145 + ERRORNAMEStatesNoChoiceMatched = 146 + ERRORNAMEStatesIntrinsicFailure = 147 + ERRORNAMEStatesExceedToleratedFailureThreshold = 148 + ERRORNAMEStatesItemReaderFailed = 149 + ERRORNAMEStatesResultWriterFailed = 150 + ERRORNAMEStatesQueryEvaluationError = 151 + ERRORNAMEStatesRuntime = 152 + STRINGDOLLAR = 153 + STRINGPATHCONTEXTOBJ = 154 + STRINGPATH = 155 + STRINGVAR = 156 + STRINGINTRINSICFUNC = 157 + STRINGJSONATA = 158 + STRING = 159 + INT = 160 + NUMBER = 161 + WS = 162 channelNames = ["DEFAULT_TOKEN_CHANNEL", "HIDDEN"] @@ -21458,6 +23712,7 @@ class ASLLexer(Lexer): "'\"Parallel\"'", "'\"Map\"'", "'\"Choices\"'", + "'\"Condition\"'", "'\"Variable\"'", "'\"Default\"'", "'\"Branches\"'", @@ -21525,10 +23780,14 @@ class ASLLexer(Lexer): "'\"Resource\"'", "'\"InputPath\"'", "'\"OutputPath\"'", + "'\"Items\"'", "'\"ItemsPath\"'", "'\"ResultPath\"'", "'\"Result\"'", "'\"Parameters\"'", + "'\"Credentials\"'", + "'\"RoleArn\"'", + "'\"RoleArn.$\"'", "'\"ResultSelector\"'", "'\"ItemReader\"'", "'\"ReaderConfig\"'", @@ -21542,6 +23801,7 @@ class ASLLexer(Lexer): "'\"ToleratedFailurePercentage\"'", "'\"ToleratedFailurePercentagePath\"'", "'\"Label\"'", + "'\"ResultWriter\"'", "'\"Next\"'", "'\"End\"'", "'\"Cause\"'", @@ -21558,6 +23818,12 @@ class ASLLexer(Lexer): "'\"FULL\"'", "'\"NONE\"'", "'\"Catch\"'", + "'\"QueryLanguage\"'", + "'\"JSONPath\"'", + "'\"JSONata\"'", + "'\"Assign\"'", + "'\"Output\"'", + "'\"Arguments\"'", "'\"States.ALL\"'", "'\"States.DataLimitExceeded\"'", "'\"States.HeartbeatTimeout\"'", @@ -21572,6 +23838,7 @@ class ASLLexer(Lexer): "'\"States.ExceedToleratedFailureThreshold\"'", "'\"States.ItemReaderFailed\"'", "'\"States.ResultWriterFailed\"'", + "'\"States.QueryEvaluationError\"'", "'\"States.Runtime\"'", ] @@ -21601,6 +23868,7 @@ class ASLLexer(Lexer): "PARALLEL", "MAP", "CHOICES", + "CONDITION", "VARIABLE", "DEFAULT", "BRANCHES", @@ -21668,10 +23936,14 @@ class ASLLexer(Lexer): "RESOURCE", "INPUTPATH", "OUTPUTPATH", + "ITEMS", "ITEMSPATH", "RESULTPATH", "RESULT", "PARAMETERS", + "CREDENTIALS", + "ROLEARN", + "ROLEARNPATH", "RESULTSELECTOR", "ITEMREADER", "READERCONFIG", @@ -21685,6 +23957,7 @@ class ASLLexer(Lexer): "TOLERATEDFAILUREPERCENTAGE", "TOLERATEDFAILUREPERCENTAGEPATH", "LABEL", + "RESULTWRITER", "NEXT", "END", "CAUSE", @@ -21701,6 +23974,12 @@ class ASLLexer(Lexer): "FULL", "NONE", "CATCH", + "QUERYLANGUAGE", + "JSONPATH", + "JSONATA", + "ASSIGN", + "OUTPUT", + "ARGUMENTS", "ERRORNAMEStatesALL", "ERRORNAMEStatesDataLimitExceeded", "ERRORNAMEStatesHeartbeatTimeout", @@ -21715,10 +23994,14 @@ class ASLLexer(Lexer): "ERRORNAMEStatesExceedToleratedFailureThreshold", "ERRORNAMEStatesItemReaderFailed", "ERRORNAMEStatesResultWriterFailed", + "ERRORNAMEStatesQueryEvaluationError", "ERRORNAMEStatesRuntime", "STRINGDOLLAR", "STRINGPATHCONTEXTOBJ", "STRINGPATH", + "STRINGVAR", + "STRINGINTRINSICFUNC", + "STRINGJSONATA", "STRING", "INT", "NUMBER", @@ -21750,6 +24033,7 @@ class ASLLexer(Lexer): "PARALLEL", "MAP", "CHOICES", + "CONDITION", "VARIABLE", "DEFAULT", "BRANCHES", @@ -21817,10 +24101,14 @@ class ASLLexer(Lexer): "RESOURCE", "INPUTPATH", "OUTPUTPATH", + "ITEMS", "ITEMSPATH", "RESULTPATH", "RESULT", "PARAMETERS", + "CREDENTIALS", + "ROLEARN", + "ROLEARNPATH", "RESULTSELECTOR", "ITEMREADER", "READERCONFIG", @@ -21834,6 +24122,7 @@ class ASLLexer(Lexer): "TOLERATEDFAILUREPERCENTAGE", "TOLERATEDFAILUREPERCENTAGEPATH", "LABEL", + "RESULTWRITER", "NEXT", "END", "CAUSE", @@ -21850,6 +24139,12 @@ class ASLLexer(Lexer): "FULL", "NONE", "CATCH", + "QUERYLANGUAGE", + "JSONPATH", + "JSONATA", + "ASSIGN", + "OUTPUT", + "ARGUMENTS", "ERRORNAMEStatesALL", "ERRORNAMEStatesDataLimitExceeded", "ERRORNAMEStatesHeartbeatTimeout", @@ -21864,15 +24159,21 @@ class ASLLexer(Lexer): "ERRORNAMEStatesExceedToleratedFailureThreshold", "ERRORNAMEStatesItemReaderFailed", "ERRORNAMEStatesResultWriterFailed", + "ERRORNAMEStatesQueryEvaluationError", "ERRORNAMEStatesRuntime", "STRINGDOLLAR", "STRINGPATHCONTEXTOBJ", "STRINGPATH", + "STRINGVAR", + "STRINGINTRINSICFUNC", + "STRINGJSONATA", "STRING", "ESC", "UNICODE", "HEX", "SAFECODEPOINT", + "LJSONATA", + "RJSONATA", "INT", "NUMBER", "EXP", @@ -21883,7 +24184,7 @@ class ASLLexer(Lexer): def __init__(self, input=None, output: TextIO = sys.stdout): super().__init__(input, output) - self.checkVersion("4.13.1") + self.checkVersion("4.13.2") self._interp = LexerATNSimulator( self, self.atn, self.decisionsToDFA, PredictionContextCache() ) diff --git a/moto/stepfunctions/parser/asl/antlr/runtime/ASLLexer.tokens b/moto/stepfunctions/parser/asl/antlr/runtime/ASLLexer.tokens deleted file mode 100644 index 7f35b74e8fff..000000000000 --- a/moto/stepfunctions/parser/asl/antlr/runtime/ASLLexer.tokens +++ /dev/null @@ -1,259 +0,0 @@ -COMMA=1 -COLON=2 -LBRACK=3 -RBRACK=4 -LBRACE=5 -RBRACE=6 -TRUE=7 -FALSE=8 -NULL=9 -COMMENT=10 -STATES=11 -STARTAT=12 -NEXTSTATE=13 -VERSION=14 -TYPE=15 -TASK=16 -CHOICE=17 -FAIL=18 -SUCCEED=19 -PASS=20 -WAIT=21 -PARALLEL=22 -MAP=23 -CHOICES=24 -VARIABLE=25 -DEFAULT=26 -BRANCHES=27 -AND=28 -BOOLEANEQUALS=29 -BOOLEANQUALSPATH=30 -ISBOOLEAN=31 -ISNULL=32 -ISNUMERIC=33 -ISPRESENT=34 -ISSTRING=35 -ISTIMESTAMP=36 -NOT=37 -NUMERICEQUALS=38 -NUMERICEQUALSPATH=39 -NUMERICGREATERTHAN=40 -NUMERICGREATERTHANPATH=41 -NUMERICGREATERTHANEQUALS=42 -NUMERICGREATERTHANEQUALSPATH=43 -NUMERICLESSTHAN=44 -NUMERICLESSTHANPATH=45 -NUMERICLESSTHANEQUALS=46 -NUMERICLESSTHANEQUALSPATH=47 -OR=48 -STRINGEQUALS=49 -STRINGEQUALSPATH=50 -STRINGGREATERTHAN=51 -STRINGGREATERTHANPATH=52 -STRINGGREATERTHANEQUALS=53 -STRINGGREATERTHANEQUALSPATH=54 -STRINGLESSTHAN=55 -STRINGLESSTHANPATH=56 -STRINGLESSTHANEQUALS=57 -STRINGLESSTHANEQUALSPATH=58 -STRINGMATCHES=59 -TIMESTAMPEQUALS=60 -TIMESTAMPEQUALSPATH=61 -TIMESTAMPGREATERTHAN=62 -TIMESTAMPGREATERTHANPATH=63 -TIMESTAMPGREATERTHANEQUALS=64 -TIMESTAMPGREATERTHANEQUALSPATH=65 -TIMESTAMPLESSTHAN=66 -TIMESTAMPLESSTHANPATH=67 -TIMESTAMPLESSTHANEQUALS=68 -TIMESTAMPLESSTHANEQUALSPATH=69 -SECONDSPATH=70 -SECONDS=71 -TIMESTAMPPATH=72 -TIMESTAMP=73 -TIMEOUTSECONDS=74 -TIMEOUTSECONDSPATH=75 -HEARTBEATSECONDS=76 -HEARTBEATSECONDSPATH=77 -PROCESSORCONFIG=78 -MODE=79 -INLINE=80 -DISTRIBUTED=81 -EXECUTIONTYPE=82 -STANDARD=83 -ITEMPROCESSOR=84 -ITERATOR=85 -ITEMSELECTOR=86 -MAXCONCURRENCY=87 -RESOURCE=88 -INPUTPATH=89 -OUTPUTPATH=90 -ITEMSPATH=91 -RESULTPATH=92 -RESULT=93 -PARAMETERS=94 -RESULTSELECTOR=95 -ITEMREADER=96 -READERCONFIG=97 -INPUTTYPE=98 -CSVHEADERLOCATION=99 -CSVHEADERS=100 -MAXITEMS=101 -MAXITEMSPATH=102 -NEXT=103 -END=104 -CAUSE=105 -ERROR=106 -RETRY=107 -ERROREQUALS=108 -INTERVALSECONDS=109 -MAXATTEMPTS=110 -BACKOFFRATE=111 -CATCH=112 -ERRORNAMEStatesALL=113 -ERRORNAMEStatesHeartbeatTimeout=114 -ERRORNAMEStatesTimeout=115 -ERRORNAMEStatesTaskFailed=116 -ERRORNAMEStatesPermissions=117 -ERRORNAMEStatesResultPathMatchFailure=118 -ERRORNAMEStatesParameterPathFailure=119 -ERRORNAMEStatesBranchFailed=120 -ERRORNAMEStatesNoChoiceMatched=121 -ERRORNAMEStatesIntrinsicFailure=122 -ERRORNAMEStatesExceedToleratedFailureThreshold=123 -ERRORNAMEStatesItemReaderFailed=124 -ERRORNAMEStatesResultWriterFailed=125 -ERRORNAMEStatesRuntime=126 -STRINGDOLLAR=127 -STRINGPATHCONTEXTOBJ=128 -STRINGPATH=129 -STRING=130 -INT=131 -NUMBER=132 -WS=133 -','=1 -':'=2 -'['=3 -']'=4 -'{'=5 -'}'=6 -'true'=7 -'false'=8 -'null'=9 -'"Comment"'=10 -'"States"'=11 -'"StartAt"'=12 -'"NextState"'=13 -'"Version"'=14 -'"Type"'=15 -'"Task"'=16 -'"Choice"'=17 -'"Fail"'=18 -'"Succeed"'=19 -'"Pass"'=20 -'"Wait"'=21 -'"Parallel"'=22 -'"Map"'=23 -'"Choices"'=24 -'"Variable"'=25 -'"Default"'=26 -'"Branches"'=27 -'"And"'=28 -'"BooleanEquals"'=29 -'"BooleanEqualsPath"'=30 -'"IsBoolean"'=31 -'"IsNull"'=32 -'"IsNumeric"'=33 -'"IsPresent"'=34 -'"IsString"'=35 -'"IsTimestamp"'=36 -'"Not"'=37 -'"NumericEquals"'=38 -'"NumericEqualsPath"'=39 -'"NumericGreaterThan"'=40 -'"NumericGreaterThanPath"'=41 -'"NumericGreaterThanEquals"'=42 -'"NumericGreaterThanEqualsPath"'=43 -'"NumericLessThan"'=44 -'"NumericLessThanPath"'=45 -'"NumericLessThanEquals"'=46 -'"NumericLessThanEqualsPath"'=47 -'"Or"'=48 -'"StringEquals"'=49 -'"StringEqualsPath"'=50 -'"StringGreaterThan"'=51 -'"StringGreaterThanPath"'=52 -'"StringGreaterThanEquals"'=53 -'"StringGreaterThanEqualsPath"'=54 -'"StringLessThan"'=55 -'"StringLessThanPath"'=56 -'"StringLessThanEquals"'=57 -'"StringLessThanEqualsPath"'=58 -'"StringMatches"'=59 -'"TimestampEquals"'=60 -'"TimestampEqualsPath"'=61 -'"TimestampGreaterThan"'=62 -'"TimestampGreaterThanPath"'=63 -'"TimestampGreaterThanEquals"'=64 -'"TimestampGreaterThanEqualsPath"'=65 -'"TimestampLessThan"'=66 -'"TimestampLessThanPath"'=67 -'"TimestampLessThanEquals"'=68 -'"TimestampLessThanEqualsPath"'=69 -'"SecondsPath"'=70 -'"Seconds"'=71 -'"TimestampPath"'=72 -'"Timestamp"'=73 -'"TimeoutSeconds"'=74 -'"TimeoutSecondsPath"'=75 -'"HeartbeatSeconds"'=76 -'"HeartbeatSecondsPath"'=77 -'"ProcessorConfig"'=78 -'"Mode"'=79 -'"INLINE"'=80 -'"DISTRIBUTED"'=81 -'"ExecutionType"'=82 -'"STANDARD"'=83 -'"ItemProcessor"'=84 -'"Iterator"'=85 -'"ItemSelector"'=86 -'"MaxConcurrency"'=87 -'"Resource"'=88 -'"InputPath"'=89 -'"OutputPath"'=90 -'"ItemsPath"'=91 -'"ResultPath"'=92 -'"Result"'=93 -'"Parameters"'=94 -'"ResultSelector"'=95 -'"ItemReader"'=96 -'"ReaderConfig"'=97 -'"InputType"'=98 -'"CSVHeaderLocation"'=99 -'"CSVHeaders"'=100 -'"MaxItems"'=101 -'"MaxItemsPath"'=102 -'"Next"'=103 -'"End"'=104 -'"Cause"'=105 -'"Error"'=106 -'"Retry"'=107 -'"ErrorEquals"'=108 -'"IntervalSeconds"'=109 -'"MaxAttempts"'=110 -'"BackoffRate"'=111 -'"Catch"'=112 -'"States.ALL"'=113 -'"States.HeartbeatTimeout"'=114 -'"States.Timeout"'=115 -'"States.TaskFailed"'=116 -'"States.Permissions"'=117 -'"States.ResultPathMatchFailure"'=118 -'"States.ParameterPathFailure"'=119 -'"States.BranchFailed"'=120 -'"States.NoChoiceMatched"'=121 -'"States.IntrinsicFailure"'=122 -'"States.ExceedToleratedFailureThreshold"'=123 -'"States.ItemReaderFailed"'=124 -'"States.ResultWriterFailed"'=125 -'"States.Runtime"'=126 diff --git a/moto/stepfunctions/parser/asl/antlr/runtime/ASLParser.interp b/moto/stepfunctions/parser/asl/antlr/runtime/ASLParser.interp deleted file mode 100644 index d3ff6e4683a4..000000000000 --- a/moto/stepfunctions/parser/asl/antlr/runtime/ASLParser.interp +++ /dev/null @@ -1,364 +0,0 @@ -token literal names: -null -',' -':' -'[' -']' -'{' -'}' -'true' -'false' -'null' -'"Comment"' -'"States"' -'"StartAt"' -'"NextState"' -'"Version"' -'"Type"' -'"Task"' -'"Choice"' -'"Fail"' -'"Succeed"' -'"Pass"' -'"Wait"' -'"Parallel"' -'"Map"' -'"Choices"' -'"Variable"' -'"Default"' -'"Branches"' -'"And"' -'"BooleanEquals"' -'"BooleanEqualsPath"' -'"IsBoolean"' -'"IsNull"' -'"IsNumeric"' -'"IsPresent"' -'"IsString"' -'"IsTimestamp"' -'"Not"' -'"NumericEquals"' -'"NumericEqualsPath"' -'"NumericGreaterThan"' -'"NumericGreaterThanPath"' -'"NumericGreaterThanEquals"' -'"NumericGreaterThanEqualsPath"' -'"NumericLessThan"' -'"NumericLessThanPath"' -'"NumericLessThanEquals"' -'"NumericLessThanEqualsPath"' -'"Or"' -'"StringEquals"' -'"StringEqualsPath"' -'"StringGreaterThan"' -'"StringGreaterThanPath"' -'"StringGreaterThanEquals"' -'"StringGreaterThanEqualsPath"' -'"StringLessThan"' -'"StringLessThanPath"' -'"StringLessThanEquals"' -'"StringLessThanEqualsPath"' -'"StringMatches"' -'"TimestampEquals"' -'"TimestampEqualsPath"' -'"TimestampGreaterThan"' -'"TimestampGreaterThanPath"' -'"TimestampGreaterThanEquals"' -'"TimestampGreaterThanEqualsPath"' -'"TimestampLessThan"' -'"TimestampLessThanPath"' -'"TimestampLessThanEquals"' -'"TimestampLessThanEqualsPath"' -'"SecondsPath"' -'"Seconds"' -'"TimestampPath"' -'"Timestamp"' -'"TimeoutSeconds"' -'"TimeoutSecondsPath"' -'"HeartbeatSeconds"' -'"HeartbeatSecondsPath"' -'"ProcessorConfig"' -'"Mode"' -'"INLINE"' -'"DISTRIBUTED"' -'"ExecutionType"' -'"STANDARD"' -'"ItemProcessor"' -'"Iterator"' -'"ItemSelector"' -'"MaxConcurrency"' -'"Resource"' -'"InputPath"' -'"OutputPath"' -'"ItemsPath"' -'"ResultPath"' -'"Result"' -'"Parameters"' -'"ResultSelector"' -'"ItemReader"' -'"ReaderConfig"' -'"InputType"' -'"CSVHeaderLocation"' -'"CSVHeaders"' -'"MaxItems"' -'"MaxItemsPath"' -'"Next"' -'"End"' -'"Cause"' -'"Error"' -'"Retry"' -'"ErrorEquals"' -'"IntervalSeconds"' -'"MaxAttempts"' -'"BackoffRate"' -'"Catch"' -'"States.ALL"' -'"States.HeartbeatTimeout"' -'"States.Timeout"' -'"States.TaskFailed"' -'"States.Permissions"' -'"States.ResultPathMatchFailure"' -'"States.ParameterPathFailure"' -'"States.BranchFailed"' -'"States.NoChoiceMatched"' -'"States.IntrinsicFailure"' -'"States.ExceedToleratedFailureThreshold"' -'"States.ItemReaderFailed"' -'"States.ResultWriterFailed"' -'"States.Runtime"' -null -null -null -null -null -null -null - -token symbolic names: -null -COMMA -COLON -LBRACK -RBRACK -LBRACE -RBRACE -TRUE -FALSE -NULL -COMMENT -STATES -STARTAT -NEXTSTATE -VERSION -TYPE -TASK -CHOICE -FAIL -SUCCEED -PASS -WAIT -PARALLEL -MAP -CHOICES -VARIABLE -DEFAULT -BRANCHES -AND -BOOLEANEQUALS -BOOLEANQUALSPATH -ISBOOLEAN -ISNULL -ISNUMERIC -ISPRESENT -ISSTRING -ISTIMESTAMP -NOT -NUMERICEQUALS -NUMERICEQUALSPATH -NUMERICGREATERTHAN -NUMERICGREATERTHANPATH -NUMERICGREATERTHANEQUALS -NUMERICGREATERTHANEQUALSPATH -NUMERICLESSTHAN -NUMERICLESSTHANPATH -NUMERICLESSTHANEQUALS -NUMERICLESSTHANEQUALSPATH -OR -STRINGEQUALS -STRINGEQUALSPATH -STRINGGREATERTHAN -STRINGGREATERTHANPATH -STRINGGREATERTHANEQUALS -STRINGGREATERTHANEQUALSPATH -STRINGLESSTHAN -STRINGLESSTHANPATH -STRINGLESSTHANEQUALS -STRINGLESSTHANEQUALSPATH -STRINGMATCHES -TIMESTAMPEQUALS -TIMESTAMPEQUALSPATH -TIMESTAMPGREATERTHAN -TIMESTAMPGREATERTHANPATH -TIMESTAMPGREATERTHANEQUALS -TIMESTAMPGREATERTHANEQUALSPATH -TIMESTAMPLESSTHAN -TIMESTAMPLESSTHANPATH -TIMESTAMPLESSTHANEQUALS -TIMESTAMPLESSTHANEQUALSPATH -SECONDSPATH -SECONDS -TIMESTAMPPATH -TIMESTAMP -TIMEOUTSECONDS -TIMEOUTSECONDSPATH -HEARTBEATSECONDS -HEARTBEATSECONDSPATH -PROCESSORCONFIG -MODE -INLINE -DISTRIBUTED -EXECUTIONTYPE -STANDARD -ITEMPROCESSOR -ITERATOR -ITEMSELECTOR -MAXCONCURRENCY -RESOURCE -INPUTPATH -OUTPUTPATH -ITEMSPATH -RESULTPATH -RESULT -PARAMETERS -RESULTSELECTOR -ITEMREADER -READERCONFIG -INPUTTYPE -CSVHEADERLOCATION -CSVHEADERS -MAXITEMS -MAXITEMSPATH -NEXT -END -CAUSE -ERROR -RETRY -ERROREQUALS -INTERVALSECONDS -MAXATTEMPTS -BACKOFFRATE -CATCH -ERRORNAMEStatesALL -ERRORNAMEStatesHeartbeatTimeout -ERRORNAMEStatesTimeout -ERRORNAMEStatesTaskFailed -ERRORNAMEStatesPermissions -ERRORNAMEStatesResultPathMatchFailure -ERRORNAMEStatesParameterPathFailure -ERRORNAMEStatesBranchFailed -ERRORNAMEStatesNoChoiceMatched -ERRORNAMEStatesIntrinsicFailure -ERRORNAMEStatesExceedToleratedFailureThreshold -ERRORNAMEStatesItemReaderFailed -ERRORNAMEStatesResultWriterFailed -ERRORNAMEStatesRuntime -STRINGDOLLAR -STRINGPATHCONTEXTOBJ -STRINGPATH -STRING -INT -NUMBER -WS - -rule names: -program_decl -top_layer_stmt -startat_decl -comment_decl -version_decl -state_stmt -states_decl -state_name -state_decl -state_decl_body -type_decl -next_decl -resource_decl -input_path_decl -result_decl -result_path_decl -output_path_decl -end_decl -default_decl -error_decl -cause_decl -seconds_decl -seconds_path_decl -timestamp_decl -timestamp_path_decl -items_path_decl -max_concurrency_decl -parameters_decl -timeout_seconds_decl -timeout_seconds_path_decl -heartbeat_seconds_decl -heartbeat_seconds_path_decl -payload_tmpl_decl -payload_binding -intrinsic_func -payload_arr_decl -payload_value_decl -payload_value_lit -result_selector_decl -state_type -choices_decl -choice_rule -comparison_variable_stmt -comparison_composite_stmt -comparison_composite -variable_decl -comparison_func -branches_decl -item_processor_decl -item_processor_item -processor_config_decl -processor_config_field -mode_decl -mode_type -execution_decl -execution_type -iterator_decl -iterator_decl_item -item_selector_decl -item_reader_decl -items_reader_field -reader_config_decl -reader_config_field -input_type_decl -csv_header_location_decl -csv_headers_decl -max_items_decl -max_items_path_decl -retry_decl -retrier_decl -retrier_stmt -error_equals_decl -interval_seconds_decl -max_attempts_decl -backoff_rate_decl -catch_decl -catcher_decl -catcher_stmt -comparison_op -choice_operator -states_error_name -error_name -json_obj_decl -json_binding -json_arr_decl -json_value_decl -keyword_or_string - - -atn: -[4, 1, 133, 793, 2, 0, 7, 0, 2, 1, 7, 1, 2, 2, 7, 2, 2, 3, 7, 3, 2, 4, 7, 4, 2, 5, 7, 5, 2, 6, 7, 6, 2, 7, 7, 7, 2, 8, 7, 8, 2, 9, 7, 9, 2, 10, 7, 10, 2, 11, 7, 11, 2, 12, 7, 12, 2, 13, 7, 13, 2, 14, 7, 14, 2, 15, 7, 15, 2, 16, 7, 16, 2, 17, 7, 17, 2, 18, 7, 18, 2, 19, 7, 19, 2, 20, 7, 20, 2, 21, 7, 21, 2, 22, 7, 22, 2, 23, 7, 23, 2, 24, 7, 24, 2, 25, 7, 25, 2, 26, 7, 26, 2, 27, 7, 27, 2, 28, 7, 28, 2, 29, 7, 29, 2, 30, 7, 30, 2, 31, 7, 31, 2, 32, 7, 32, 2, 33, 7, 33, 2, 34, 7, 34, 2, 35, 7, 35, 2, 36, 7, 36, 2, 37, 7, 37, 2, 38, 7, 38, 2, 39, 7, 39, 2, 40, 7, 40, 2, 41, 7, 41, 2, 42, 7, 42, 2, 43, 7, 43, 2, 44, 7, 44, 2, 45, 7, 45, 2, 46, 7, 46, 2, 47, 7, 47, 2, 48, 7, 48, 2, 49, 7, 49, 2, 50, 7, 50, 2, 51, 7, 51, 2, 52, 7, 52, 2, 53, 7, 53, 2, 54, 7, 54, 2, 55, 7, 55, 2, 56, 7, 56, 2, 57, 7, 57, 2, 58, 7, 58, 2, 59, 7, 59, 2, 60, 7, 60, 2, 61, 7, 61, 2, 62, 7, 62, 2, 63, 7, 63, 2, 64, 7, 64, 2, 65, 7, 65, 2, 66, 7, 66, 2, 67, 7, 67, 2, 68, 7, 68, 2, 69, 7, 69, 2, 70, 7, 70, 2, 71, 7, 71, 2, 72, 7, 72, 2, 73, 7, 73, 2, 74, 7, 74, 2, 75, 7, 75, 2, 76, 7, 76, 2, 77, 7, 77, 2, 78, 7, 78, 2, 79, 7, 79, 2, 80, 7, 80, 2, 81, 7, 81, 2, 82, 7, 82, 2, 83, 7, 83, 2, 84, 7, 84, 2, 85, 7, 85, 2, 86, 7, 86, 1, 0, 1, 0, 1, 0, 1, 0, 5, 0, 179, 8, 0, 10, 0, 12, 0, 182, 9, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 191, 8, 1, 1, 2, 1, 2, 1, 2, 1, 2, 1, 3, 1, 3, 1, 3, 1, 3, 1, 4, 1, 4, 1, 4, 1, 4, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 1, 5, 3, 5, 237, 8, 5, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 1, 6, 5, 6, 245, 8, 6, 10, 6, 12, 6, 248, 9, 6, 1, 6, 1, 6, 1, 7, 1, 7, 1, 8, 1, 8, 1, 8, 1, 8, 1, 9, 1, 9, 1, 9, 1, 9, 5, 9, 262, 8, 9, 10, 9, 12, 9, 265, 9, 9, 1, 9, 1, 9, 1, 10, 1, 10, 1, 10, 1, 10, 1, 11, 1, 11, 1, 11, 1, 11, 1, 12, 1, 12, 1, 12, 1, 12, 1, 13, 1, 13, 1, 13, 1, 13, 3, 13, 285, 8, 13, 1, 14, 1, 14, 1, 14, 1, 14, 1, 15, 1, 15, 1, 15, 1, 15, 3, 15, 295, 8, 15, 1, 16, 1, 16, 1, 16, 1, 16, 3, 16, 301, 8, 16, 1, 17, 1, 17, 1, 17, 1, 17, 1, 18, 1, 18, 1, 18, 1, 18, 1, 19, 1, 19, 1, 19, 1, 19, 1, 20, 1, 20, 1, 20, 1, 20, 1, 21, 1, 21, 1, 21, 1, 21, 1, 22, 1, 22, 1, 22, 1, 22, 1, 23, 1, 23, 1, 23, 1, 23, 1, 24, 1, 24, 1, 24, 1, 24, 1, 25, 1, 25, 1, 25, 1, 25, 1, 26, 1, 26, 1, 26, 1, 26, 1, 27, 1, 27, 1, 27, 1, 27, 1, 28, 1, 28, 1, 28, 1, 28, 1, 29, 1, 29, 1, 29, 1, 29, 1, 30, 1, 30, 1, 30, 1, 30, 1, 31, 1, 31, 1, 31, 1, 31, 1, 32, 1, 32, 1, 32, 1, 32, 5, 32, 367, 8, 32, 10, 32, 12, 32, 370, 9, 32, 1, 32, 1, 32, 1, 32, 1, 32, 3, 32, 376, 8, 32, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 1, 33, 3, 33, 391, 8, 33, 1, 34, 1, 34, 1, 35, 1, 35, 1, 35, 1, 35, 5, 35, 399, 8, 35, 10, 35, 12, 35, 402, 9, 35, 1, 35, 1, 35, 1, 35, 1, 35, 3, 35, 408, 8, 35, 1, 36, 1, 36, 1, 36, 1, 36, 3, 36, 414, 8, 36, 1, 37, 1, 37, 1, 37, 1, 37, 1, 37, 3, 37, 421, 8, 37, 1, 38, 1, 38, 1, 38, 1, 38, 1, 39, 1, 39, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 1, 40, 5, 40, 435, 8, 40, 10, 40, 12, 40, 438, 9, 40, 1, 40, 1, 40, 1, 41, 1, 41, 1, 41, 1, 41, 4, 41, 446, 8, 41, 11, 41, 12, 41, 447, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 1, 41, 5, 41, 456, 8, 41, 10, 41, 12, 41, 459, 9, 41, 1, 41, 1, 41, 3, 41, 463, 8, 41, 1, 42, 1, 42, 1, 42, 3, 42, 468, 8, 42, 1, 43, 1, 43, 3, 43, 472, 8, 43, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 1, 44, 5, 44, 481, 8, 44, 10, 44, 12, 44, 484, 9, 44, 1, 44, 1, 44, 3, 44, 488, 8, 44, 1, 45, 1, 45, 1, 45, 1, 45, 1, 46, 1, 46, 1, 46, 1, 46, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 1, 47, 5, 47, 504, 8, 47, 10, 47, 12, 47, 507, 9, 47, 1, 47, 1, 47, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 1, 48, 5, 48, 517, 8, 48, 10, 48, 12, 48, 520, 9, 48, 1, 48, 1, 48, 1, 49, 1, 49, 1, 49, 1, 49, 3, 49, 528, 8, 49, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 1, 50, 5, 50, 536, 8, 50, 10, 50, 12, 50, 539, 9, 50, 1, 50, 1, 50, 1, 51, 1, 51, 3, 51, 545, 8, 51, 1, 52, 1, 52, 1, 52, 1, 52, 1, 53, 1, 53, 1, 54, 1, 54, 1, 54, 1, 54, 1, 55, 1, 55, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 1, 56, 5, 56, 565, 8, 56, 10, 56, 12, 56, 568, 9, 56, 1, 56, 1, 56, 1, 57, 1, 57, 1, 57, 3, 57, 575, 8, 57, 1, 58, 1, 58, 1, 58, 1, 58, 1, 59, 1, 59, 1, 59, 1, 59, 1, 59, 1, 59, 5, 59, 587, 8, 59, 10, 59, 12, 59, 590, 9, 59, 1, 59, 1, 59, 1, 60, 1, 60, 1, 60, 3, 60, 597, 8, 60, 1, 61, 1, 61, 1, 61, 1, 61, 1, 61, 1, 61, 5, 61, 605, 8, 61, 10, 61, 12, 61, 608, 9, 61, 1, 61, 1, 61, 1, 62, 1, 62, 1, 62, 1, 62, 1, 62, 3, 62, 617, 8, 62, 1, 63, 1, 63, 1, 63, 1, 63, 1, 64, 1, 64, 1, 64, 1, 64, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 1, 65, 5, 65, 633, 8, 65, 10, 65, 12, 65, 636, 9, 65, 1, 65, 1, 65, 1, 66, 1, 66, 1, 66, 1, 66, 1, 67, 1, 67, 1, 67, 1, 67, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 1, 68, 5, 68, 654, 8, 68, 10, 68, 12, 68, 657, 9, 68, 3, 68, 659, 8, 68, 1, 68, 1, 68, 1, 69, 1, 69, 1, 69, 1, 69, 5, 69, 667, 8, 69, 10, 69, 12, 69, 670, 9, 69, 1, 69, 1, 69, 1, 70, 1, 70, 1, 70, 1, 70, 3, 70, 678, 8, 70, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 1, 71, 5, 71, 686, 8, 71, 10, 71, 12, 71, 689, 9, 71, 1, 71, 1, 71, 1, 72, 1, 72, 1, 72, 1, 72, 1, 73, 1, 73, 1, 73, 1, 73, 1, 74, 1, 74, 1, 74, 1, 74, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 1, 75, 5, 75, 711, 8, 75, 10, 75, 12, 75, 714, 9, 75, 3, 75, 716, 8, 75, 1, 75, 1, 75, 1, 76, 1, 76, 1, 76, 1, 76, 5, 76, 724, 8, 76, 10, 76, 12, 76, 727, 9, 76, 1, 76, 1, 76, 1, 77, 1, 77, 1, 77, 3, 77, 734, 8, 77, 1, 78, 1, 78, 1, 79, 1, 79, 1, 80, 1, 80, 1, 81, 1, 81, 3, 81, 744, 8, 81, 1, 82, 1, 82, 1, 82, 1, 82, 5, 82, 750, 8, 82, 10, 82, 12, 82, 753, 9, 82, 1, 82, 1, 82, 1, 82, 1, 82, 3, 82, 759, 8, 82, 1, 83, 1, 83, 1, 83, 1, 83, 1, 84, 1, 84, 1, 84, 1, 84, 5, 84, 769, 8, 84, 10, 84, 12, 84, 772, 9, 84, 1, 84, 1, 84, 1, 84, 1, 84, 3, 84, 778, 8, 84, 1, 85, 1, 85, 1, 85, 1, 85, 1, 85, 1, 85, 1, 85, 1, 85, 1, 85, 3, 85, 789, 8, 85, 1, 86, 1, 86, 1, 86, 0, 0, 87, 0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 0, 8, 1, 0, 7, 8, 1, 0, 16, 23, 1, 0, 80, 81, 1, 0, 131, 132, 3, 0, 29, 36, 38, 47, 49, 69, 3, 0, 28, 28, 37, 37, 48, 48, 1, 0, 113, 126, 2, 0, 10, 13, 15, 130, 813, 0, 174, 1, 0, 0, 0, 2, 190, 1, 0, 0, 0, 4, 192, 1, 0, 0, 0, 6, 196, 1, 0, 0, 0, 8, 200, 1, 0, 0, 0, 10, 236, 1, 0, 0, 0, 12, 238, 1, 0, 0, 0, 14, 251, 1, 0, 0, 0, 16, 253, 1, 0, 0, 0, 18, 257, 1, 0, 0, 0, 20, 268, 1, 0, 0, 0, 22, 272, 1, 0, 0, 0, 24, 276, 1, 0, 0, 0, 26, 280, 1, 0, 0, 0, 28, 286, 1, 0, 0, 0, 30, 290, 1, 0, 0, 0, 32, 296, 1, 0, 0, 0, 34, 302, 1, 0, 0, 0, 36, 306, 1, 0, 0, 0, 38, 310, 1, 0, 0, 0, 40, 314, 1, 0, 0, 0, 42, 318, 1, 0, 0, 0, 44, 322, 1, 0, 0, 0, 46, 326, 1, 0, 0, 0, 48, 330, 1, 0, 0, 0, 50, 334, 1, 0, 0, 0, 52, 338, 1, 0, 0, 0, 54, 342, 1, 0, 0, 0, 56, 346, 1, 0, 0, 0, 58, 350, 1, 0, 0, 0, 60, 354, 1, 0, 0, 0, 62, 358, 1, 0, 0, 0, 64, 375, 1, 0, 0, 0, 66, 390, 1, 0, 0, 0, 68, 392, 1, 0, 0, 0, 70, 407, 1, 0, 0, 0, 72, 413, 1, 0, 0, 0, 74, 420, 1, 0, 0, 0, 76, 422, 1, 0, 0, 0, 78, 426, 1, 0, 0, 0, 80, 428, 1, 0, 0, 0, 82, 462, 1, 0, 0, 0, 84, 467, 1, 0, 0, 0, 86, 471, 1, 0, 0, 0, 88, 473, 1, 0, 0, 0, 90, 489, 1, 0, 0, 0, 92, 493, 1, 0, 0, 0, 94, 497, 1, 0, 0, 0, 96, 510, 1, 0, 0, 0, 98, 527, 1, 0, 0, 0, 100, 529, 1, 0, 0, 0, 102, 544, 1, 0, 0, 0, 104, 546, 1, 0, 0, 0, 106, 550, 1, 0, 0, 0, 108, 552, 1, 0, 0, 0, 110, 556, 1, 0, 0, 0, 112, 558, 1, 0, 0, 0, 114, 574, 1, 0, 0, 0, 116, 576, 1, 0, 0, 0, 118, 580, 1, 0, 0, 0, 120, 596, 1, 0, 0, 0, 122, 598, 1, 0, 0, 0, 124, 616, 1, 0, 0, 0, 126, 618, 1, 0, 0, 0, 128, 622, 1, 0, 0, 0, 130, 626, 1, 0, 0, 0, 132, 639, 1, 0, 0, 0, 134, 643, 1, 0, 0, 0, 136, 647, 1, 0, 0, 0, 138, 662, 1, 0, 0, 0, 140, 677, 1, 0, 0, 0, 142, 679, 1, 0, 0, 0, 144, 692, 1, 0, 0, 0, 146, 696, 1, 0, 0, 0, 148, 700, 1, 0, 0, 0, 150, 704, 1, 0, 0, 0, 152, 719, 1, 0, 0, 0, 154, 733, 1, 0, 0, 0, 156, 735, 1, 0, 0, 0, 158, 737, 1, 0, 0, 0, 160, 739, 1, 0, 0, 0, 162, 743, 1, 0, 0, 0, 164, 758, 1, 0, 0, 0, 166, 760, 1, 0, 0, 0, 168, 777, 1, 0, 0, 0, 170, 788, 1, 0, 0, 0, 172, 790, 1, 0, 0, 0, 174, 175, 5, 5, 0, 0, 175, 180, 3, 2, 1, 0, 176, 177, 5, 1, 0, 0, 177, 179, 3, 2, 1, 0, 178, 176, 1, 0, 0, 0, 179, 182, 1, 0, 0, 0, 180, 178, 1, 0, 0, 0, 180, 181, 1, 0, 0, 0, 181, 183, 1, 0, 0, 0, 182, 180, 1, 0, 0, 0, 183, 184, 5, 6, 0, 0, 184, 1, 1, 0, 0, 0, 185, 191, 3, 6, 3, 0, 186, 191, 3, 8, 4, 0, 187, 191, 3, 4, 2, 0, 188, 191, 3, 12, 6, 0, 189, 191, 3, 56, 28, 0, 190, 185, 1, 0, 0, 0, 190, 186, 1, 0, 0, 0, 190, 187, 1, 0, 0, 0, 190, 188, 1, 0, 0, 0, 190, 189, 1, 0, 0, 0, 191, 3, 1, 0, 0, 0, 192, 193, 5, 12, 0, 0, 193, 194, 5, 2, 0, 0, 194, 195, 3, 172, 86, 0, 195, 5, 1, 0, 0, 0, 196, 197, 5, 10, 0, 0, 197, 198, 5, 2, 0, 0, 198, 199, 3, 172, 86, 0, 199, 7, 1, 0, 0, 0, 200, 201, 5, 14, 0, 0, 201, 202, 5, 2, 0, 0, 202, 203, 3, 172, 86, 0, 203, 9, 1, 0, 0, 0, 204, 237, 3, 6, 3, 0, 205, 237, 3, 20, 10, 0, 206, 237, 3, 26, 13, 0, 207, 237, 3, 24, 12, 0, 208, 237, 3, 22, 11, 0, 209, 237, 3, 28, 14, 0, 210, 237, 3, 30, 15, 0, 211, 237, 3, 32, 16, 0, 212, 237, 3, 34, 17, 0, 213, 237, 3, 36, 18, 0, 214, 237, 3, 80, 40, 0, 215, 237, 3, 38, 19, 0, 216, 237, 3, 40, 20, 0, 217, 237, 3, 42, 21, 0, 218, 237, 3, 44, 22, 0, 219, 237, 3, 46, 23, 0, 220, 237, 3, 48, 24, 0, 221, 237, 3, 50, 25, 0, 222, 237, 3, 96, 48, 0, 223, 237, 3, 112, 56, 0, 224, 237, 3, 116, 58, 0, 225, 237, 3, 118, 59, 0, 226, 237, 3, 52, 26, 0, 227, 237, 3, 56, 28, 0, 228, 237, 3, 58, 29, 0, 229, 237, 3, 60, 30, 0, 230, 237, 3, 62, 31, 0, 231, 237, 3, 94, 47, 0, 232, 237, 3, 54, 27, 0, 233, 237, 3, 136, 68, 0, 234, 237, 3, 150, 75, 0, 235, 237, 3, 76, 38, 0, 236, 204, 1, 0, 0, 0, 236, 205, 1, 0, 0, 0, 236, 206, 1, 0, 0, 0, 236, 207, 1, 0, 0, 0, 236, 208, 1, 0, 0, 0, 236, 209, 1, 0, 0, 0, 236, 210, 1, 0, 0, 0, 236, 211, 1, 0, 0, 0, 236, 212, 1, 0, 0, 0, 236, 213, 1, 0, 0, 0, 236, 214, 1, 0, 0, 0, 236, 215, 1, 0, 0, 0, 236, 216, 1, 0, 0, 0, 236, 217, 1, 0, 0, 0, 236, 218, 1, 0, 0, 0, 236, 219, 1, 0, 0, 0, 236, 220, 1, 0, 0, 0, 236, 221, 1, 0, 0, 0, 236, 222, 1, 0, 0, 0, 236, 223, 1, 0, 0, 0, 236, 224, 1, 0, 0, 0, 236, 225, 1, 0, 0, 0, 236, 226, 1, 0, 0, 0, 236, 227, 1, 0, 0, 0, 236, 228, 1, 0, 0, 0, 236, 229, 1, 0, 0, 0, 236, 230, 1, 0, 0, 0, 236, 231, 1, 0, 0, 0, 236, 232, 1, 0, 0, 0, 236, 233, 1, 0, 0, 0, 236, 234, 1, 0, 0, 0, 236, 235, 1, 0, 0, 0, 237, 11, 1, 0, 0, 0, 238, 239, 5, 11, 0, 0, 239, 240, 5, 2, 0, 0, 240, 241, 5, 5, 0, 0, 241, 246, 3, 16, 8, 0, 242, 243, 5, 1, 0, 0, 243, 245, 3, 16, 8, 0, 244, 242, 1, 0, 0, 0, 245, 248, 1, 0, 0, 0, 246, 244, 1, 0, 0, 0, 246, 247, 1, 0, 0, 0, 247, 249, 1, 0, 0, 0, 248, 246, 1, 0, 0, 0, 249, 250, 5, 6, 0, 0, 250, 13, 1, 0, 0, 0, 251, 252, 3, 172, 86, 0, 252, 15, 1, 0, 0, 0, 253, 254, 3, 14, 7, 0, 254, 255, 5, 2, 0, 0, 255, 256, 3, 18, 9, 0, 256, 17, 1, 0, 0, 0, 257, 258, 5, 5, 0, 0, 258, 263, 3, 10, 5, 0, 259, 260, 5, 1, 0, 0, 260, 262, 3, 10, 5, 0, 261, 259, 1, 0, 0, 0, 262, 265, 1, 0, 0, 0, 263, 261, 1, 0, 0, 0, 263, 264, 1, 0, 0, 0, 264, 266, 1, 0, 0, 0, 265, 263, 1, 0, 0, 0, 266, 267, 5, 6, 0, 0, 267, 19, 1, 0, 0, 0, 268, 269, 5, 15, 0, 0, 269, 270, 5, 2, 0, 0, 270, 271, 3, 78, 39, 0, 271, 21, 1, 0, 0, 0, 272, 273, 5, 103, 0, 0, 273, 274, 5, 2, 0, 0, 274, 275, 3, 172, 86, 0, 275, 23, 1, 0, 0, 0, 276, 277, 5, 88, 0, 0, 277, 278, 5, 2, 0, 0, 278, 279, 3, 172, 86, 0, 279, 25, 1, 0, 0, 0, 280, 281, 5, 89, 0, 0, 281, 284, 5, 2, 0, 0, 282, 285, 5, 9, 0, 0, 283, 285, 3, 172, 86, 0, 284, 282, 1, 0, 0, 0, 284, 283, 1, 0, 0, 0, 285, 27, 1, 0, 0, 0, 286, 287, 5, 93, 0, 0, 287, 288, 5, 2, 0, 0, 288, 289, 3, 170, 85, 0, 289, 29, 1, 0, 0, 0, 290, 291, 5, 92, 0, 0, 291, 294, 5, 2, 0, 0, 292, 295, 5, 9, 0, 0, 293, 295, 3, 172, 86, 0, 294, 292, 1, 0, 0, 0, 294, 293, 1, 0, 0, 0, 295, 31, 1, 0, 0, 0, 296, 297, 5, 90, 0, 0, 297, 300, 5, 2, 0, 0, 298, 301, 5, 9, 0, 0, 299, 301, 3, 172, 86, 0, 300, 298, 1, 0, 0, 0, 300, 299, 1, 0, 0, 0, 301, 33, 1, 0, 0, 0, 302, 303, 5, 104, 0, 0, 303, 304, 5, 2, 0, 0, 304, 305, 7, 0, 0, 0, 305, 35, 1, 0, 0, 0, 306, 307, 5, 26, 0, 0, 307, 308, 5, 2, 0, 0, 308, 309, 3, 172, 86, 0, 309, 37, 1, 0, 0, 0, 310, 311, 5, 106, 0, 0, 311, 312, 5, 2, 0, 0, 312, 313, 3, 172, 86, 0, 313, 39, 1, 0, 0, 0, 314, 315, 5, 105, 0, 0, 315, 316, 5, 2, 0, 0, 316, 317, 3, 172, 86, 0, 317, 41, 1, 0, 0, 0, 318, 319, 5, 71, 0, 0, 319, 320, 5, 2, 0, 0, 320, 321, 5, 131, 0, 0, 321, 43, 1, 0, 0, 0, 322, 323, 5, 70, 0, 0, 323, 324, 5, 2, 0, 0, 324, 325, 3, 172, 86, 0, 325, 45, 1, 0, 0, 0, 326, 327, 5, 73, 0, 0, 327, 328, 5, 2, 0, 0, 328, 329, 3, 172, 86, 0, 329, 47, 1, 0, 0, 0, 330, 331, 5, 72, 0, 0, 331, 332, 5, 2, 0, 0, 332, 333, 3, 172, 86, 0, 333, 49, 1, 0, 0, 0, 334, 335, 5, 91, 0, 0, 335, 336, 5, 2, 0, 0, 336, 337, 3, 172, 86, 0, 337, 51, 1, 0, 0, 0, 338, 339, 5, 87, 0, 0, 339, 340, 5, 2, 0, 0, 340, 341, 5, 131, 0, 0, 341, 53, 1, 0, 0, 0, 342, 343, 5, 94, 0, 0, 343, 344, 5, 2, 0, 0, 344, 345, 3, 64, 32, 0, 345, 55, 1, 0, 0, 0, 346, 347, 5, 74, 0, 0, 347, 348, 5, 2, 0, 0, 348, 349, 5, 131, 0, 0, 349, 57, 1, 0, 0, 0, 350, 351, 5, 75, 0, 0, 351, 352, 5, 2, 0, 0, 352, 353, 5, 129, 0, 0, 353, 59, 1, 0, 0, 0, 354, 355, 5, 76, 0, 0, 355, 356, 5, 2, 0, 0, 356, 357, 5, 131, 0, 0, 357, 61, 1, 0, 0, 0, 358, 359, 5, 77, 0, 0, 359, 360, 5, 2, 0, 0, 360, 361, 5, 129, 0, 0, 361, 63, 1, 0, 0, 0, 362, 363, 5, 5, 0, 0, 363, 368, 3, 66, 33, 0, 364, 365, 5, 1, 0, 0, 365, 367, 3, 66, 33, 0, 366, 364, 1, 0, 0, 0, 367, 370, 1, 0, 0, 0, 368, 366, 1, 0, 0, 0, 368, 369, 1, 0, 0, 0, 369, 371, 1, 0, 0, 0, 370, 368, 1, 0, 0, 0, 371, 372, 5, 6, 0, 0, 372, 376, 1, 0, 0, 0, 373, 374, 5, 5, 0, 0, 374, 376, 5, 6, 0, 0, 375, 362, 1, 0, 0, 0, 375, 373, 1, 0, 0, 0, 376, 65, 1, 0, 0, 0, 377, 378, 5, 127, 0, 0, 378, 379, 5, 2, 0, 0, 379, 391, 5, 129, 0, 0, 380, 381, 5, 127, 0, 0, 381, 382, 5, 2, 0, 0, 382, 391, 5, 128, 0, 0, 383, 384, 5, 127, 0, 0, 384, 385, 5, 2, 0, 0, 385, 391, 3, 68, 34, 0, 386, 387, 3, 172, 86, 0, 387, 388, 5, 2, 0, 0, 388, 389, 3, 72, 36, 0, 389, 391, 1, 0, 0, 0, 390, 377, 1, 0, 0, 0, 390, 380, 1, 0, 0, 0, 390, 383, 1, 0, 0, 0, 390, 386, 1, 0, 0, 0, 391, 67, 1, 0, 0, 0, 392, 393, 5, 130, 0, 0, 393, 69, 1, 0, 0, 0, 394, 395, 5, 3, 0, 0, 395, 400, 3, 72, 36, 0, 396, 397, 5, 1, 0, 0, 397, 399, 3, 72, 36, 0, 398, 396, 1, 0, 0, 0, 399, 402, 1, 0, 0, 0, 400, 398, 1, 0, 0, 0, 400, 401, 1, 0, 0, 0, 401, 403, 1, 0, 0, 0, 402, 400, 1, 0, 0, 0, 403, 404, 5, 4, 0, 0, 404, 408, 1, 0, 0, 0, 405, 406, 5, 3, 0, 0, 406, 408, 5, 4, 0, 0, 407, 394, 1, 0, 0, 0, 407, 405, 1, 0, 0, 0, 408, 71, 1, 0, 0, 0, 409, 414, 3, 66, 33, 0, 410, 414, 3, 70, 35, 0, 411, 414, 3, 64, 32, 0, 412, 414, 3, 74, 37, 0, 413, 409, 1, 0, 0, 0, 413, 410, 1, 0, 0, 0, 413, 411, 1, 0, 0, 0, 413, 412, 1, 0, 0, 0, 414, 73, 1, 0, 0, 0, 415, 421, 5, 132, 0, 0, 416, 421, 5, 131, 0, 0, 417, 421, 7, 0, 0, 0, 418, 421, 5, 9, 0, 0, 419, 421, 3, 172, 86, 0, 420, 415, 1, 0, 0, 0, 420, 416, 1, 0, 0, 0, 420, 417, 1, 0, 0, 0, 420, 418, 1, 0, 0, 0, 420, 419, 1, 0, 0, 0, 421, 75, 1, 0, 0, 0, 422, 423, 5, 95, 0, 0, 423, 424, 5, 2, 0, 0, 424, 425, 3, 64, 32, 0, 425, 77, 1, 0, 0, 0, 426, 427, 7, 1, 0, 0, 427, 79, 1, 0, 0, 0, 428, 429, 5, 24, 0, 0, 429, 430, 5, 2, 0, 0, 430, 431, 5, 3, 0, 0, 431, 436, 3, 82, 41, 0, 432, 433, 5, 1, 0, 0, 433, 435, 3, 82, 41, 0, 434, 432, 1, 0, 0, 0, 435, 438, 1, 0, 0, 0, 436, 434, 1, 0, 0, 0, 436, 437, 1, 0, 0, 0, 437, 439, 1, 0, 0, 0, 438, 436, 1, 0, 0, 0, 439, 440, 5, 4, 0, 0, 440, 81, 1, 0, 0, 0, 441, 442, 5, 5, 0, 0, 442, 445, 3, 84, 42, 0, 443, 444, 5, 1, 0, 0, 444, 446, 3, 84, 42, 0, 445, 443, 1, 0, 0, 0, 446, 447, 1, 0, 0, 0, 447, 445, 1, 0, 0, 0, 447, 448, 1, 0, 0, 0, 448, 449, 1, 0, 0, 0, 449, 450, 5, 6, 0, 0, 450, 463, 1, 0, 0, 0, 451, 452, 5, 5, 0, 0, 452, 457, 3, 86, 43, 0, 453, 454, 5, 1, 0, 0, 454, 456, 3, 86, 43, 0, 455, 453, 1, 0, 0, 0, 456, 459, 1, 0, 0, 0, 457, 455, 1, 0, 0, 0, 457, 458, 1, 0, 0, 0, 458, 460, 1, 0, 0, 0, 459, 457, 1, 0, 0, 0, 460, 461, 5, 6, 0, 0, 461, 463, 1, 0, 0, 0, 462, 441, 1, 0, 0, 0, 462, 451, 1, 0, 0, 0, 463, 83, 1, 0, 0, 0, 464, 468, 3, 90, 45, 0, 465, 468, 3, 92, 46, 0, 466, 468, 3, 22, 11, 0, 467, 464, 1, 0, 0, 0, 467, 465, 1, 0, 0, 0, 467, 466, 1, 0, 0, 0, 468, 85, 1, 0, 0, 0, 469, 472, 3, 88, 44, 0, 470, 472, 3, 22, 11, 0, 471, 469, 1, 0, 0, 0, 471, 470, 1, 0, 0, 0, 472, 87, 1, 0, 0, 0, 473, 474, 3, 158, 79, 0, 474, 487, 5, 2, 0, 0, 475, 488, 3, 82, 41, 0, 476, 477, 5, 3, 0, 0, 477, 482, 3, 82, 41, 0, 478, 479, 5, 1, 0, 0, 479, 481, 3, 82, 41, 0, 480, 478, 1, 0, 0, 0, 481, 484, 1, 0, 0, 0, 482, 480, 1, 0, 0, 0, 482, 483, 1, 0, 0, 0, 483, 485, 1, 0, 0, 0, 484, 482, 1, 0, 0, 0, 485, 486, 5, 4, 0, 0, 486, 488, 1, 0, 0, 0, 487, 475, 1, 0, 0, 0, 487, 476, 1, 0, 0, 0, 488, 89, 1, 0, 0, 0, 489, 490, 5, 25, 0, 0, 490, 491, 5, 2, 0, 0, 491, 492, 3, 172, 86, 0, 492, 91, 1, 0, 0, 0, 493, 494, 3, 156, 78, 0, 494, 495, 5, 2, 0, 0, 495, 496, 3, 170, 85, 0, 496, 93, 1, 0, 0, 0, 497, 498, 5, 27, 0, 0, 498, 499, 5, 2, 0, 0, 499, 500, 5, 3, 0, 0, 500, 505, 3, 0, 0, 0, 501, 502, 5, 1, 0, 0, 502, 504, 3, 0, 0, 0, 503, 501, 1, 0, 0, 0, 504, 507, 1, 0, 0, 0, 505, 503, 1, 0, 0, 0, 505, 506, 1, 0, 0, 0, 506, 508, 1, 0, 0, 0, 507, 505, 1, 0, 0, 0, 508, 509, 5, 4, 0, 0, 509, 95, 1, 0, 0, 0, 510, 511, 5, 84, 0, 0, 511, 512, 5, 2, 0, 0, 512, 513, 5, 5, 0, 0, 513, 518, 3, 98, 49, 0, 514, 515, 5, 1, 0, 0, 515, 517, 3, 98, 49, 0, 516, 514, 1, 0, 0, 0, 517, 520, 1, 0, 0, 0, 518, 516, 1, 0, 0, 0, 518, 519, 1, 0, 0, 0, 519, 521, 1, 0, 0, 0, 520, 518, 1, 0, 0, 0, 521, 522, 5, 6, 0, 0, 522, 97, 1, 0, 0, 0, 523, 528, 3, 100, 50, 0, 524, 528, 3, 4, 2, 0, 525, 528, 3, 12, 6, 0, 526, 528, 3, 6, 3, 0, 527, 523, 1, 0, 0, 0, 527, 524, 1, 0, 0, 0, 527, 525, 1, 0, 0, 0, 527, 526, 1, 0, 0, 0, 528, 99, 1, 0, 0, 0, 529, 530, 5, 78, 0, 0, 530, 531, 5, 2, 0, 0, 531, 532, 5, 5, 0, 0, 532, 537, 3, 102, 51, 0, 533, 534, 5, 1, 0, 0, 534, 536, 3, 102, 51, 0, 535, 533, 1, 0, 0, 0, 536, 539, 1, 0, 0, 0, 537, 535, 1, 0, 0, 0, 537, 538, 1, 0, 0, 0, 538, 540, 1, 0, 0, 0, 539, 537, 1, 0, 0, 0, 540, 541, 5, 6, 0, 0, 541, 101, 1, 0, 0, 0, 542, 545, 3, 104, 52, 0, 543, 545, 3, 108, 54, 0, 544, 542, 1, 0, 0, 0, 544, 543, 1, 0, 0, 0, 545, 103, 1, 0, 0, 0, 546, 547, 5, 79, 0, 0, 547, 548, 5, 2, 0, 0, 548, 549, 3, 106, 53, 0, 549, 105, 1, 0, 0, 0, 550, 551, 7, 2, 0, 0, 551, 107, 1, 0, 0, 0, 552, 553, 5, 82, 0, 0, 553, 554, 5, 2, 0, 0, 554, 555, 3, 110, 55, 0, 555, 109, 1, 0, 0, 0, 556, 557, 5, 83, 0, 0, 557, 111, 1, 0, 0, 0, 558, 559, 5, 85, 0, 0, 559, 560, 5, 2, 0, 0, 560, 561, 5, 5, 0, 0, 561, 566, 3, 114, 57, 0, 562, 563, 5, 1, 0, 0, 563, 565, 3, 114, 57, 0, 564, 562, 1, 0, 0, 0, 565, 568, 1, 0, 0, 0, 566, 564, 1, 0, 0, 0, 566, 567, 1, 0, 0, 0, 567, 569, 1, 0, 0, 0, 568, 566, 1, 0, 0, 0, 569, 570, 5, 6, 0, 0, 570, 113, 1, 0, 0, 0, 571, 575, 3, 4, 2, 0, 572, 575, 3, 12, 6, 0, 573, 575, 3, 6, 3, 0, 574, 571, 1, 0, 0, 0, 574, 572, 1, 0, 0, 0, 574, 573, 1, 0, 0, 0, 575, 115, 1, 0, 0, 0, 576, 577, 5, 86, 0, 0, 577, 578, 5, 2, 0, 0, 578, 579, 3, 64, 32, 0, 579, 117, 1, 0, 0, 0, 580, 581, 5, 96, 0, 0, 581, 582, 5, 2, 0, 0, 582, 583, 5, 5, 0, 0, 583, 588, 3, 120, 60, 0, 584, 585, 5, 1, 0, 0, 585, 587, 3, 120, 60, 0, 586, 584, 1, 0, 0, 0, 587, 590, 1, 0, 0, 0, 588, 586, 1, 0, 0, 0, 588, 589, 1, 0, 0, 0, 589, 591, 1, 0, 0, 0, 590, 588, 1, 0, 0, 0, 591, 592, 5, 6, 0, 0, 592, 119, 1, 0, 0, 0, 593, 597, 3, 24, 12, 0, 594, 597, 3, 54, 27, 0, 595, 597, 3, 122, 61, 0, 596, 593, 1, 0, 0, 0, 596, 594, 1, 0, 0, 0, 596, 595, 1, 0, 0, 0, 597, 121, 1, 0, 0, 0, 598, 599, 5, 97, 0, 0, 599, 600, 5, 2, 0, 0, 600, 601, 5, 5, 0, 0, 601, 606, 3, 124, 62, 0, 602, 603, 5, 1, 0, 0, 603, 605, 3, 124, 62, 0, 604, 602, 1, 0, 0, 0, 605, 608, 1, 0, 0, 0, 606, 604, 1, 0, 0, 0, 606, 607, 1, 0, 0, 0, 607, 609, 1, 0, 0, 0, 608, 606, 1, 0, 0, 0, 609, 610, 5, 6, 0, 0, 610, 123, 1, 0, 0, 0, 611, 617, 3, 126, 63, 0, 612, 617, 3, 128, 64, 0, 613, 617, 3, 130, 65, 0, 614, 617, 3, 132, 66, 0, 615, 617, 3, 134, 67, 0, 616, 611, 1, 0, 0, 0, 616, 612, 1, 0, 0, 0, 616, 613, 1, 0, 0, 0, 616, 614, 1, 0, 0, 0, 616, 615, 1, 0, 0, 0, 617, 125, 1, 0, 0, 0, 618, 619, 5, 98, 0, 0, 619, 620, 5, 2, 0, 0, 620, 621, 3, 172, 86, 0, 621, 127, 1, 0, 0, 0, 622, 623, 5, 99, 0, 0, 623, 624, 5, 2, 0, 0, 624, 625, 3, 172, 86, 0, 625, 129, 1, 0, 0, 0, 626, 627, 5, 100, 0, 0, 627, 628, 5, 2, 0, 0, 628, 629, 5, 3, 0, 0, 629, 634, 3, 172, 86, 0, 630, 631, 5, 1, 0, 0, 631, 633, 3, 172, 86, 0, 632, 630, 1, 0, 0, 0, 633, 636, 1, 0, 0, 0, 634, 632, 1, 0, 0, 0, 634, 635, 1, 0, 0, 0, 635, 637, 1, 0, 0, 0, 636, 634, 1, 0, 0, 0, 637, 638, 5, 4, 0, 0, 638, 131, 1, 0, 0, 0, 639, 640, 5, 101, 0, 0, 640, 641, 5, 2, 0, 0, 641, 642, 5, 131, 0, 0, 642, 133, 1, 0, 0, 0, 643, 644, 5, 102, 0, 0, 644, 645, 5, 2, 0, 0, 645, 646, 5, 129, 0, 0, 646, 135, 1, 0, 0, 0, 647, 648, 5, 107, 0, 0, 648, 649, 5, 2, 0, 0, 649, 658, 5, 3, 0, 0, 650, 655, 3, 138, 69, 0, 651, 652, 5, 1, 0, 0, 652, 654, 3, 138, 69, 0, 653, 651, 1, 0, 0, 0, 654, 657, 1, 0, 0, 0, 655, 653, 1, 0, 0, 0, 655, 656, 1, 0, 0, 0, 656, 659, 1, 0, 0, 0, 657, 655, 1, 0, 0, 0, 658, 650, 1, 0, 0, 0, 658, 659, 1, 0, 0, 0, 659, 660, 1, 0, 0, 0, 660, 661, 5, 4, 0, 0, 661, 137, 1, 0, 0, 0, 662, 663, 5, 5, 0, 0, 663, 668, 3, 140, 70, 0, 664, 665, 5, 1, 0, 0, 665, 667, 3, 140, 70, 0, 666, 664, 1, 0, 0, 0, 667, 670, 1, 0, 0, 0, 668, 666, 1, 0, 0, 0, 668, 669, 1, 0, 0, 0, 669, 671, 1, 0, 0, 0, 670, 668, 1, 0, 0, 0, 671, 672, 5, 6, 0, 0, 672, 139, 1, 0, 0, 0, 673, 678, 3, 142, 71, 0, 674, 678, 3, 144, 72, 0, 675, 678, 3, 146, 73, 0, 676, 678, 3, 148, 74, 0, 677, 673, 1, 0, 0, 0, 677, 674, 1, 0, 0, 0, 677, 675, 1, 0, 0, 0, 677, 676, 1, 0, 0, 0, 678, 141, 1, 0, 0, 0, 679, 680, 5, 108, 0, 0, 680, 681, 5, 2, 0, 0, 681, 682, 5, 3, 0, 0, 682, 687, 3, 162, 81, 0, 683, 684, 5, 1, 0, 0, 684, 686, 3, 162, 81, 0, 685, 683, 1, 0, 0, 0, 686, 689, 1, 0, 0, 0, 687, 685, 1, 0, 0, 0, 687, 688, 1, 0, 0, 0, 688, 690, 1, 0, 0, 0, 689, 687, 1, 0, 0, 0, 690, 691, 5, 4, 0, 0, 691, 143, 1, 0, 0, 0, 692, 693, 5, 109, 0, 0, 693, 694, 5, 2, 0, 0, 694, 695, 5, 131, 0, 0, 695, 145, 1, 0, 0, 0, 696, 697, 5, 110, 0, 0, 697, 698, 5, 2, 0, 0, 698, 699, 5, 131, 0, 0, 699, 147, 1, 0, 0, 0, 700, 701, 5, 111, 0, 0, 701, 702, 5, 2, 0, 0, 702, 703, 7, 3, 0, 0, 703, 149, 1, 0, 0, 0, 704, 705, 5, 112, 0, 0, 705, 706, 5, 2, 0, 0, 706, 715, 5, 3, 0, 0, 707, 712, 3, 152, 76, 0, 708, 709, 5, 1, 0, 0, 709, 711, 3, 152, 76, 0, 710, 708, 1, 0, 0, 0, 711, 714, 1, 0, 0, 0, 712, 710, 1, 0, 0, 0, 712, 713, 1, 0, 0, 0, 713, 716, 1, 0, 0, 0, 714, 712, 1, 0, 0, 0, 715, 707, 1, 0, 0, 0, 715, 716, 1, 0, 0, 0, 716, 717, 1, 0, 0, 0, 717, 718, 5, 4, 0, 0, 718, 151, 1, 0, 0, 0, 719, 720, 5, 5, 0, 0, 720, 725, 3, 154, 77, 0, 721, 722, 5, 1, 0, 0, 722, 724, 3, 154, 77, 0, 723, 721, 1, 0, 0, 0, 724, 727, 1, 0, 0, 0, 725, 723, 1, 0, 0, 0, 725, 726, 1, 0, 0, 0, 726, 728, 1, 0, 0, 0, 727, 725, 1, 0, 0, 0, 728, 729, 5, 6, 0, 0, 729, 153, 1, 0, 0, 0, 730, 734, 3, 142, 71, 0, 731, 734, 3, 30, 15, 0, 732, 734, 3, 22, 11, 0, 733, 730, 1, 0, 0, 0, 733, 731, 1, 0, 0, 0, 733, 732, 1, 0, 0, 0, 734, 155, 1, 0, 0, 0, 735, 736, 7, 4, 0, 0, 736, 157, 1, 0, 0, 0, 737, 738, 7, 5, 0, 0, 738, 159, 1, 0, 0, 0, 739, 740, 7, 6, 0, 0, 740, 161, 1, 0, 0, 0, 741, 744, 3, 160, 80, 0, 742, 744, 3, 172, 86, 0, 743, 741, 1, 0, 0, 0, 743, 742, 1, 0, 0, 0, 744, 163, 1, 0, 0, 0, 745, 746, 5, 5, 0, 0, 746, 751, 3, 166, 83, 0, 747, 748, 5, 1, 0, 0, 748, 750, 3, 166, 83, 0, 749, 747, 1, 0, 0, 0, 750, 753, 1, 0, 0, 0, 751, 749, 1, 0, 0, 0, 751, 752, 1, 0, 0, 0, 752, 754, 1, 0, 0, 0, 753, 751, 1, 0, 0, 0, 754, 755, 5, 6, 0, 0, 755, 759, 1, 0, 0, 0, 756, 757, 5, 5, 0, 0, 757, 759, 5, 6, 0, 0, 758, 745, 1, 0, 0, 0, 758, 756, 1, 0, 0, 0, 759, 165, 1, 0, 0, 0, 760, 761, 3, 172, 86, 0, 761, 762, 5, 2, 0, 0, 762, 763, 3, 170, 85, 0, 763, 167, 1, 0, 0, 0, 764, 765, 5, 3, 0, 0, 765, 770, 3, 170, 85, 0, 766, 767, 5, 1, 0, 0, 767, 769, 3, 170, 85, 0, 768, 766, 1, 0, 0, 0, 769, 772, 1, 0, 0, 0, 770, 768, 1, 0, 0, 0, 770, 771, 1, 0, 0, 0, 771, 773, 1, 0, 0, 0, 772, 770, 1, 0, 0, 0, 773, 774, 5, 4, 0, 0, 774, 778, 1, 0, 0, 0, 775, 776, 5, 3, 0, 0, 776, 778, 5, 4, 0, 0, 777, 764, 1, 0, 0, 0, 777, 775, 1, 0, 0, 0, 778, 169, 1, 0, 0, 0, 779, 789, 5, 132, 0, 0, 780, 789, 5, 131, 0, 0, 781, 789, 5, 7, 0, 0, 782, 789, 5, 8, 0, 0, 783, 789, 5, 9, 0, 0, 784, 789, 3, 166, 83, 0, 785, 789, 3, 168, 84, 0, 786, 789, 3, 164, 82, 0, 787, 789, 3, 172, 86, 0, 788, 779, 1, 0, 0, 0, 788, 780, 1, 0, 0, 0, 788, 781, 1, 0, 0, 0, 788, 782, 1, 0, 0, 0, 788, 783, 1, 0, 0, 0, 788, 784, 1, 0, 0, 0, 788, 785, 1, 0, 0, 0, 788, 786, 1, 0, 0, 0, 788, 787, 1, 0, 0, 0, 789, 171, 1, 0, 0, 0, 790, 791, 7, 7, 0, 0, 791, 173, 1, 0, 0, 0, 50, 180, 190, 236, 246, 263, 284, 294, 300, 368, 375, 390, 400, 407, 413, 420, 436, 447, 457, 462, 467, 471, 482, 487, 505, 518, 527, 537, 544, 566, 574, 588, 596, 606, 616, 634, 655, 658, 668, 677, 687, 712, 715, 725, 733, 743, 751, 758, 770, 777, 788] \ No newline at end of file diff --git a/moto/stepfunctions/parser/asl/antlr/runtime/ASLParser.py b/moto/stepfunctions/parser/asl/antlr/runtime/ASLParser.py index e993ac5f0ef9..f0e97eba3ed6 100644 --- a/moto/stepfunctions/parser/asl/antlr/runtime/ASLParser.py +++ b/moto/stepfunctions/parser/asl/antlr/runtime/ASLParser.py @@ -1,4 +1,4 @@ -# Generated from ASLParser.g4 by ANTLR 4.13.1 +# Generated from ASLParser.g4 by ANTLR 4.13.2 # encoding: utf-8 import sys from typing import TextIO @@ -23,8 +23,8 @@ def serializedATN(): return [ 4, 1, - 146, - 880, + 162, + 1259, 2, 0, 7, @@ -417,6 +417,90 @@ def serializedATN(): 97, 7, 97, + 2, + 98, + 7, + 98, + 2, + 99, + 7, + 99, + 2, + 100, + 7, + 100, + 2, + 101, + 7, + 101, + 2, + 102, + 7, + 102, + 2, + 103, + 7, + 103, + 2, + 104, + 7, + 104, + 2, + 105, + 7, + 105, + 2, + 106, + 7, + 106, + 2, + 107, + 7, + 107, + 2, + 108, + 7, + 108, + 2, + 109, + 7, + 109, + 2, + 110, + 7, + 110, + 2, + 111, + 7, + 111, + 2, + 112, + 7, + 112, + 2, + 113, + 7, + 113, + 2, + 114, + 7, + 114, + 2, + 115, + 7, + 115, + 2, + 116, + 7, + 116, + 2, + 117, + 7, + 117, + 2, + 118, + 7, + 118, 1, 0, 1, @@ -433,14 +517,14 @@ def serializedATN(): 1, 5, 1, - 204, + 246, 8, 1, 10, 1, 12, 1, - 207, + 249, 9, 1, 1, @@ -457,9 +541,11 @@ def serializedATN(): 2, 1, 2, + 1, + 2, 3, 2, - 216, + 259, 8, 2, 1, @@ -495,82 +581,73 @@ def serializedATN(): 1, 6, 1, - 6, - 1, - 6, - 1, - 6, + 7, 1, - 6, + 7, 1, - 6, + 7, 1, - 6, + 7, 1, - 6, + 7, 1, - 6, + 7, 1, - 6, + 7, 1, - 6, + 7, 1, - 6, + 7, 1, - 6, + 7, 1, - 6, + 7, 1, - 6, + 7, 1, - 6, + 7, 1, - 6, + 7, 1, - 6, + 7, 1, - 6, + 7, 1, - 6, + 7, 1, - 6, + 7, 1, - 6, + 7, 1, - 6, + 7, 1, - 6, + 7, 1, - 6, + 7, 1, - 6, + 7, 1, - 6, + 7, 1, - 6, + 7, 1, - 6, + 7, 1, - 6, + 7, 1, - 6, + 7, 1, - 6, + 7, 1, - 6, + 7, 1, - 6, + 7, 1, - 6, + 7, 1, - 6, + 7, 1, - 6, - 3, - 6, - 270, - 8, - 6, + 7, 1, 7, 1, @@ -583,30 +660,53 @@ def serializedATN(): 7, 1, 7, - 5, + 1, 7, - 278, - 8, + 1, 7, - 10, + 1, 7, - 12, + 1, 7, - 281, - 9, + 1, 7, 1, 7, 1, 7, + 3, + 7, + 324, + 8, + 7, 1, 8, 1, 8, 1, - 9, + 8, + 1, + 8, + 1, + 8, 1, + 8, + 5, + 8, + 332, + 8, + 8, + 10, + 8, + 12, + 8, + 335, 9, + 8, + 1, + 8, + 1, + 8, 1, 9, 1, @@ -619,26 +719,26 @@ def serializedATN(): 10, 1, 10, - 5, - 10, - 295, - 8, - 10, - 10, - 10, - 12, - 10, - 298, - 9, - 10, 1, - 10, + 11, 1, - 10, + 11, 1, 11, 1, 11, + 5, + 11, + 349, + 8, + 11, + 10, + 11, + 12, + 11, + 352, + 9, + 11, 1, 11, 1, @@ -667,11 +767,6 @@ def serializedATN(): 14, 1, 14, - 3, - 14, - 318, - 8, - 14, 1, 15, 1, @@ -681,17 +776,34 @@ def serializedATN(): 1, 15, 1, - 16, + 15, 1, - 16, + 15, 1, - 16, + 15, 1, - 16, + 15, + 1, + 15, + 1, + 15, 3, - 16, - 328, + 15, + 378, + 8, + 15, + 3, + 15, + 380, 8, + 15, + 1, + 16, + 1, + 16, + 1, + 16, + 1, 16, 1, 17, @@ -703,7 +815,7 @@ def serializedATN(): 17, 3, 17, - 334, + 390, 8, 17, 1, @@ -715,6 +827,28 @@ def serializedATN(): 1, 18, 1, + 18, + 1, + 18, + 1, + 18, + 1, + 18, + 1, + 18, + 1, + 18, + 3, + 18, + 402, + 8, + 18, + 3, + 18, + 404, + 8, + 18, + 1, 19, 1, 19, @@ -744,7 +878,7 @@ def serializedATN(): 21, 3, 21, - 354, + 420, 8, 21, 1, @@ -756,6 +890,27 @@ def serializedATN(): 1, 22, 1, + 22, + 1, + 22, + 1, + 22, + 1, + 22, + 1, + 22, + 1, + 22, + 1, + 22, + 1, + 22, + 3, + 22, + 434, + 8, + 22, + 1, 23, 1, 23, @@ -769,7 +924,7 @@ def serializedATN(): 23, 3, 23, - 366, + 442, 8, 23, 1, @@ -781,6 +936,31 @@ def serializedATN(): 1, 24, 1, + 24, + 1, + 24, + 1, + 24, + 1, + 24, + 1, + 24, + 1, + 24, + 1, + 24, + 1, + 24, + 3, + 24, + 456, + 8, + 24, + 1, + 25, + 1, + 25, + 1, 25, 1, 25, @@ -788,6 +968,11 @@ def serializedATN(): 25, 1, 25, + 3, + 25, + 464, + 8, + 25, 1, 26, 1, @@ -797,6 +982,19 @@ def serializedATN(): 1, 26, 1, + 26, + 1, + 26, + 3, + 26, + 472, + 8, + 26, + 1, + 27, + 1, + 27, + 1, 27, 1, 27, @@ -804,6 +1002,13 @@ def serializedATN(): 27, 1, 27, + 3, + 27, + 480, + 8, + 27, + 1, + 28, 1, 28, 1, @@ -813,6 +1018,17 @@ def serializedATN(): 1, 28, 1, + 28, + 3, + 28, + 488, + 8, + 28, + 1, + 29, + 1, + 29, + 1, 29, 1, 29, @@ -820,6 +1036,15 @@ def serializedATN(): 29, 1, 29, + 3, + 29, + 496, + 8, + 29, + 1, + 30, + 1, + 30, 1, 30, 1, @@ -829,6 +1054,21 @@ def serializedATN(): 1, 30, 1, + 30, + 1, + 30, + 1, + 30, + 3, + 30, + 507, + 8, + 30, + 1, + 31, + 1, + 31, + 1, 31, 1, 31, @@ -836,6 +1076,15 @@ def serializedATN(): 31, 1, 31, + 3, + 31, + 515, + 8, + 31, + 1, + 32, + 1, + 32, 1, 32, 1, @@ -844,6 +1093,11 @@ def serializedATN(): 32, 1, 32, + 3, + 32, + 523, + 8, + 32, 1, 33, 1, @@ -861,6 +1115,10 @@ def serializedATN(): 1, 34, 1, + 34, + 1, + 34, + 1, 35, 1, 35, @@ -869,24 +1127,41 @@ def serializedATN(): 1, 35, 1, - 36, + 35, 1, - 36, + 35, 1, - 36, + 35, 1, - 36, - 5, - 36, - 420, + 35, + 1, + 35, + 1, + 35, + 1, + 35, + 1, + 35, + 1, + 35, + 1, + 35, + 1, + 35, + 1, + 35, + 1, + 35, + 1, + 35, + 3, + 35, + 553, 8, + 35, + 1, 36, - 10, - 36, - 12, - 36, - 423, - 9, + 1, 36, 1, 36, @@ -898,7 +1173,7 @@ def serializedATN(): 36, 3, 36, - 429, + 561, 8, 36, 1, @@ -913,23 +1188,9 @@ def serializedATN(): 37, 1, 37, - 1, - 37, - 1, - 37, - 1, - 37, - 1, - 37, - 1, - 37, - 1, - 37, - 1, - 37, 3, 37, - 444, + 569, 8, 37, 1, @@ -937,24 +1198,21 @@ def serializedATN(): 1, 38, 1, - 39, + 38, 1, - 39, + 38, 1, - 39, + 38, 1, - 39, - 5, - 39, - 452, + 38, + 3, + 38, + 577, 8, + 38, + 1, 39, - 10, - 39, - 12, - 39, - 455, - 9, + 1, 39, 1, 39, @@ -966,7 +1224,7 @@ def serializedATN(): 39, 3, 39, - 461, + 585, 8, 39, 1, @@ -974,18 +1232,27 @@ def serializedATN(): 1, 40, 1, - 40, + 41, 1, - 40, - 3, - 40, - 467, - 8, - 40, + 41, 1, 41, 1, 41, + 5, + 41, + 593, + 8, + 41, + 10, + 41, + 12, + 41, + 596, + 9, + 41, + 1, + 41, 1, 41, 1, @@ -994,7 +1261,7 @@ def serializedATN(): 41, 3, 41, - 474, + 602, 8, 41, 1, @@ -1006,86 +1273,91 @@ def serializedATN(): 1, 42, 1, - 43, + 42, 1, - 43, + 42, 1, - 44, + 42, 1, - 44, + 42, 1, - 44, + 42, 1, - 44, + 42, 1, - 44, + 42, 1, - 44, + 42, + 1, + 42, + 1, + 42, + 1, + 42, + 1, + 42, + 3, + 42, + 620, + 8, + 42, + 1, + 43, + 1, + 43, + 1, + 43, + 1, + 43, 5, - 44, - 488, + 43, + 626, 8, - 44, + 43, 10, - 44, + 43, 12, - 44, - 491, + 43, + 629, 9, - 44, - 1, - 44, - 1, - 44, + 43, 1, - 45, + 43, 1, - 45, + 43, 1, - 45, + 43, 1, - 45, - 4, - 45, - 499, + 43, + 3, + 43, + 635, 8, - 45, - 11, - 45, - 12, - 45, - 500, + 43, 1, - 45, + 44, 1, - 45, + 44, 1, - 45, + 44, + 3, + 44, + 640, + 8, + 44, 1, 45, 1, 45, 1, 45, - 5, - 45, - 509, - 8, - 45, - 10, - 45, - 12, - 45, - 512, - 9, - 45, 1, 45, 1, 45, 3, 45, - 516, + 647, 8, 45, 1, @@ -1096,18 +1368,37 @@ def serializedATN(): 46, 1, 46, - 3, - 46, - 522, + 1, + 47, + 1, + 47, + 1, + 47, + 1, + 47, + 1, + 47, + 1, + 47, + 5, + 47, + 659, 8, - 46, + 47, + 10, + 47, + 12, + 47, + 662, + 9, + 47, 1, 47, 1, 47, 3, 47, - 526, + 666, 8, 47, 1, @@ -1115,44 +1406,44 @@ def serializedATN(): 1, 48, 1, - 48, + 49, 1, - 48, + 49, 1, - 48, + 49, 1, - 48, + 49, 1, - 48, + 49, + 1, + 49, 5, - 48, - 535, + 49, + 676, 8, - 48, + 49, 10, - 48, + 49, 12, - 48, - 538, + 49, + 679, 9, - 48, + 49, 1, - 48, + 49, 1, - 48, + 49, 3, - 48, - 542, + 49, + 683, 8, - 48, - 1, 49, 1, - 49, + 50, 1, - 49, + 50, 1, - 49, + 50, 1, 50, 1, @@ -1162,33 +1453,37 @@ def serializedATN(): 1, 50, 1, - 51, + 50, 1, - 51, + 50, 1, - 51, + 50, 1, - 51, + 50, 1, - 51, + 50, 1, - 51, - 5, - 51, - 558, + 50, + 1, + 50, + 1, + 50, + 3, + 50, + 700, 8, - 51, - 10, - 51, - 12, - 51, - 561, - 9, + 50, + 1, 51, 1, 51, 1, 51, + 3, + 51, + 705, + 8, + 51, 1, 52, 1, @@ -1203,20 +1498,29 @@ def serializedATN(): 52, 5, 52, - 571, + 713, 8, 52, 10, 52, 12, 52, - 574, + 716, 9, 52, 1, 52, 1, 52, + 3, + 52, + 720, + 8, + 52, + 1, + 53, + 1, + 53, 1, 53, 1, @@ -1227,7 +1531,7 @@ def serializedATN(): 53, 3, 53, - 582, + 728, 8, 53, 1, @@ -1242,30 +1546,18 @@ def serializedATN(): 54, 1, 54, - 5, + 3, 54, - 590, + 736, 8, 54, - 10, - 54, - 12, - 54, - 593, - 9, - 54, - 1, - 54, - 1, - 54, 1, 55, 1, 55, - 3, + 1, 55, - 599, - 8, + 1, 55, 1, 56, @@ -1276,49 +1568,99 @@ def serializedATN(): 1, 56, 1, + 56, + 1, + 56, + 5, + 56, + 748, + 8, + 56, + 10, + 56, + 12, + 56, + 751, + 9, + 56, + 1, + 56, + 1, + 56, + 3, + 56, + 755, + 8, + 56, + 1, 57, 1, 57, 1, - 58, + 57, + 1, + 57, 1, 58, 1, 58, 1, 58, + 3, + 58, + 764, + 8, + 58, 1, 59, 1, 59, 1, - 60, + 59, 1, - 60, + 59, 1, - 60, + 59, 1, - 60, + 59, + 5, + 59, + 772, + 8, + 59, + 10, + 59, + 12, + 59, + 775, + 9, + 59, 1, - 60, + 59, 1, - 60, - 5, - 60, - 619, + 59, + 3, + 59, + 779, 8, + 59, + 1, 60, - 10, + 1, 60, - 12, + 1, 60, - 622, - 9, + 1, 60, 1, 60, 1, 60, + 3, + 60, + 787, + 8, + 60, 1, 61, 1, @@ -1327,15 +1669,6 @@ def serializedATN(): 61, 1, 61, - 3, - 61, - 630, - 8, - 61, - 1, - 62, - 1, - 62, 1, 62, 1, @@ -1354,14 +1687,14 @@ def serializedATN(): 63, 5, 63, - 642, + 801, 8, 63, 10, 63, 12, 63, - 645, + 804, 9, 63, 1, @@ -1374,41 +1707,66 @@ def serializedATN(): 64, 1, 64, - 3, + 1, 64, - 652, + 4, + 64, + 812, 8, 64, + 11, + 64, + 12, + 64, + 813, 1, - 65, + 64, 1, - 65, + 64, 1, - 65, + 64, 1, - 65, + 64, 1, - 65, + 64, 1, - 65, + 64, 5, - 65, - 660, + 64, + 822, 8, - 65, + 64, 10, - 65, + 64, 12, - 65, - 663, + 64, + 825, 9, + 64, + 1, + 64, + 1, + 64, + 3, + 64, + 829, + 8, + 64, + 1, 65, 1, 65, 1, 65, 1, - 66, + 65, + 1, + 65, + 3, + 65, + 836, + 8, + 65, 1, 66, 1, @@ -1419,7 +1777,7 @@ def serializedATN(): 66, 3, 66, - 672, + 842, 8, 66, 1, @@ -1431,6 +1789,39 @@ def serializedATN(): 1, 67, 1, + 67, + 1, + 67, + 1, + 67, + 5, + 67, + 851, + 8, + 67, + 10, + 67, + 12, + 67, + 854, + 9, + 67, + 1, + 67, + 1, + 67, + 3, + 67, + 858, + 8, + 67, + 1, + 68, + 1, + 68, + 1, + 68, + 1, 68, 1, 68, @@ -1439,6 +1830,15 @@ def serializedATN(): 1, 68, 1, + 68, + 1, + 68, + 3, + 68, + 869, + 8, + 68, + 1, 69, 1, 69, @@ -1450,26 +1850,51 @@ def serializedATN(): 69, 1, 69, - 5, + 1, 69, - 688, - 8, + 1, 69, - 10, + 1, 69, - 12, + 1, 69, - 691, - 9, + 1, + 69, + 1, 69, 1, 69, 1, 69, + 3, + 69, + 885, + 8, + 69, + 1, + 70, + 1, + 70, + 1, + 70, + 1, + 70, 1, 70, 1, 70, + 5, + 70, + 893, + 8, + 70, + 10, + 70, + 12, + 70, + 896, + 9, + 70, 1, 70, 1, @@ -1483,7 +1908,25 @@ def serializedATN(): 1, 71, 1, - 72, + 71, + 1, + 71, + 5, + 71, + 906, + 8, + 71, + 10, + 71, + 12, + 71, + 909, + 9, + 71, + 1, + 71, + 1, + 71, 1, 72, 1, @@ -1491,7 +1934,12 @@ def serializedATN(): 1, 72, 1, - 73, + 72, + 3, + 72, + 917, + 8, + 72, 1, 73, 1, @@ -1499,13 +1947,36 @@ def serializedATN(): 1, 73, 1, - 74, + 73, 1, - 74, + 73, + 1, + 73, + 5, + 73, + 925, + 8, + 73, + 10, + 73, + 12, + 73, + 928, + 9, + 73, + 1, + 73, + 1, + 73, 1, 74, 1, 74, + 3, + 74, + 934, + 8, + 74, 1, 75, 1, @@ -1519,38 +1990,9 @@ def serializedATN(): 1, 76, 1, - 76, - 1, - 76, - 1, - 77, - 1, - 77, - 1, - 77, - 1, - 77, - 1, 77, 1, 77, - 5, - 77, - 729, - 8, - 77, - 10, - 77, - 12, - 77, - 732, - 9, - 77, - 3, - 77, - 734, - 8, - 77, 1, 77, 1, @@ -1560,28 +2002,6 @@ def serializedATN(): 1, 78, 1, - 78, - 1, - 78, - 5, - 78, - 742, - 8, - 78, - 10, - 78, - 12, - 78, - 745, - 9, - 78, - 1, - 78, - 1, - 78, - 1, - 79, - 1, 79, 1, 79, @@ -1593,15 +2013,22 @@ def serializedATN(): 79, 1, 79, - 3, + 5, 79, - 756, + 954, 8, 79, + 10, + 79, + 12, + 79, + 957, + 9, + 79, 1, - 80, + 79, 1, - 80, + 79, 1, 80, 1, @@ -1610,22 +2037,11 @@ def serializedATN(): 80, 1, 80, - 5, + 3, 80, - 764, + 965, 8, 80, - 10, - 80, - 12, - 80, - 767, - 9, - 80, - 1, - 80, - 1, - 80, 1, 81, 1, @@ -1643,6 +2059,26 @@ def serializedATN(): 1, 82, 1, + 82, + 1, + 82, + 5, + 82, + 977, + 8, + 82, + 10, + 82, + 12, + 82, + 980, + 9, + 82, + 1, + 82, + 1, + 82, + 1, 83, 1, 83, @@ -1650,6 +2086,11 @@ def serializedATN(): 83, 1, 83, + 3, + 83, + 988, + 8, + 83, 1, 84, 1, @@ -1659,42 +2100,44 @@ def serializedATN(): 1, 84, 1, - 85, + 84, 1, - 85, + 84, + 5, + 84, + 996, + 8, + 84, + 10, + 84, + 12, + 84, + 999, + 9, + 84, 1, - 85, + 84, + 1, + 84, 1, 85, 1, - 86, + 85, 1, - 86, + 85, 1, - 86, + 85, 1, - 86, + 85, + 3, + 85, + 1008, + 8, + 85, 1, 86, 1, 86, - 5, - 86, - 797, - 8, - 86, - 10, - 86, - 12, - 86, - 800, - 9, - 86, - 3, - 86, - 802, - 8, - 86, 1, 86, 1, @@ -1707,22 +2150,10 @@ def serializedATN(): 87, 1, 87, - 5, - 87, - 810, - 8, - 87, - 10, - 87, - 12, - 87, - 813, - 9, - 87, 1, - 87, + 88, 1, - 87, + 88, 1, 88, 1, @@ -1731,30 +2162,88 @@ def serializedATN(): 88, 1, 88, - 3, + 5, 88, - 821, + 1024, 8, 88, + 10, + 88, + 12, + 88, + 1027, + 9, + 88, + 1, + 88, + 1, + 88, + 1, + 89, + 1, + 89, + 1, + 89, + 1, + 89, 1, 89, 1, 89, + 3, + 89, + 1037, + 8, + 89, + 1, + 90, + 1, + 90, + 1, + 90, + 1, + 90, 1, 90, 1, 90, + 3, + 90, + 1045, + 8, + 90, + 1, + 91, + 1, + 91, + 1, + 91, + 1, + 91, 1, 91, 1, 91, + 3, + 91, + 1053, + 8, + 91, + 1, + 92, + 1, + 92, + 1, + 92, + 1, + 92, 1, 92, 1, 92, 3, 92, - 831, + 1061, 8, 92, 1, @@ -1765,29 +2254,13 @@ def serializedATN(): 93, 1, 93, - 5, + 1, 93, - 837, - 8, - 93, - 10, - 93, - 12, - 93, - 840, - 9, - 93, - 1, - 93, - 1, - 93, - 1, - 93, - 1, + 1, 93, 3, 93, - 846, + 1069, 8, 93, 1, @@ -1799,25 +2272,14 @@ def serializedATN(): 1, 94, 1, - 95, - 1, - 95, - 1, - 95, + 94, 1, - 95, - 5, - 95, - 856, + 94, + 3, + 94, + 1077, 8, - 95, - 10, - 95, - 12, - 95, - 859, - 9, - 95, + 94, 1, 95, 1, @@ -1826,11 +2288,6 @@ def serializedATN(): 95, 1, 95, - 3, - 95, - 865, - 8, - 95, 1, 96, 1, @@ -1843,5704 +2300,8777 @@ def serializedATN(): 96, 1, 96, - 1, + 5, 96, - 1, + 1089, + 8, 96, - 1, + 10, 96, - 3, + 12, 96, - 876, - 8, + 1092, + 9, 96, 1, - 97, + 96, + 1, + 96, 1, 97, 1, 97, - 0, - 0, + 3, + 97, + 1098, + 8, + 97, + 1, 98, - 0, - 2, - 4, - 6, + 1, + 98, + 1, + 98, + 1, + 98, + 1, + 98, + 1, + 98, + 5, + 98, + 1106, 8, + 98, 10, + 98, 12, - 14, - 16, - 18, - 20, - 22, - 24, - 26, - 28, - 30, - 32, - 34, - 36, - 38, - 40, - 42, - 44, - 46, - 48, - 50, - 52, - 54, - 56, - 58, - 60, - 62, - 64, - 66, - 68, - 70, - 72, - 74, - 76, - 78, - 80, - 82, - 84, - 86, - 88, - 90, - 92, - 94, - 96, 98, - 100, - 102, - 104, - 106, - 108, - 110, - 112, - 114, - 116, - 118, - 120, - 122, - 124, - 126, - 128, - 130, - 132, - 134, - 136, - 138, - 140, - 142, - 144, - 146, - 148, - 150, - 152, - 154, - 156, - 158, - 160, - 162, - 164, - 166, - 168, - 170, - 172, - 174, - 176, - 178, - 180, - 182, - 184, - 186, - 188, - 190, - 192, - 194, - 0, + 1109, 9, - 1, - 0, - 7, + 98, + 3, + 98, + 1111, 8, + 98, 1, - 0, - 16, - 23, + 98, 1, - 0, - 80, - 81, + 98, 1, - 0, - 144, - 145, + 99, 1, - 0, - 122, - 123, - 3, - 0, - 29, - 36, - 38, - 47, - 49, - 69, - 3, - 0, - 28, - 28, - 37, - 37, - 48, - 48, + 99, 1, - 0, - 125, - 139, + 99, + 1, + 99, 5, - 0, + 99, + 1119, + 8, + 99, 10, - 13, - 15, - 111, - 113, - 113, - 115, - 125, - 127, - 143, - 905, - 0, - 196, + 99, + 12, + 99, + 1122, + 9, + 99, 1, - 0, - 0, - 0, - 2, - 199, + 99, 1, - 0, - 0, - 0, - 4, - 215, + 99, 1, - 0, - 0, - 0, - 6, - 217, - 1, - 0, - 0, - 0, - 8, - 221, + 100, 1, - 0, - 0, - 0, - 10, - 225, + 100, 1, - 0, - 0, - 0, - 12, - 269, + 100, 1, - 0, - 0, - 0, - 14, - 271, + 100, 1, - 0, - 0, - 0, - 16, - 284, + 100, 1, - 0, - 0, - 0, - 18, - 286, + 100, 1, - 0, - 0, - 0, - 20, - 290, + 100, + 3, + 100, + 1133, + 8, + 100, 1, - 0, - 0, - 0, - 22, - 301, + 101, 1, - 0, - 0, - 0, - 24, - 305, + 101, 1, - 0, - 0, - 0, - 26, - 309, + 101, 1, - 0, - 0, - 0, - 28, - 313, + 101, 1, - 0, - 0, - 0, - 30, - 319, + 101, 1, - 0, - 0, - 0, - 32, - 323, + 101, + 5, + 101, + 1141, + 8, + 101, + 10, + 101, + 12, + 101, + 1144, + 9, + 101, 1, - 0, - 0, - 0, - 34, - 329, + 101, 1, - 0, - 0, - 0, - 36, - 335, + 101, 1, - 0, - 0, - 0, - 38, - 339, + 102, 1, - 0, - 0, - 0, - 40, - 343, + 102, 1, - 0, - 0, - 0, - 42, - 353, + 102, 1, - 0, - 0, - 0, - 44, - 355, + 102, 1, - 0, - 0, - 0, - 46, - 365, + 103, 1, - 0, - 0, - 0, - 48, - 367, + 103, 1, - 0, - 0, - 0, - 50, - 371, + 103, 1, - 0, - 0, - 0, - 52, - 375, + 103, 1, - 0, - 0, - 0, - 54, - 379, + 104, 1, - 0, - 0, - 0, - 56, - 383, + 104, 1, - 0, - 0, - 0, - 58, - 387, + 104, 1, - 0, - 0, - 0, - 60, - 391, + 104, 1, - 0, - 0, - 0, - 62, - 395, + 105, 1, - 0, - 0, - 0, - 64, - 399, + 105, 1, - 0, - 0, - 0, - 66, - 403, + 105, 1, - 0, - 0, - 0, - 68, - 407, + 105, 1, - 0, - 0, - 0, - 70, - 411, + 106, 1, - 0, - 0, - 0, - 72, - 428, + 106, 1, - 0, - 0, - 0, - 74, - 443, + 106, 1, - 0, - 0, - 0, - 76, - 445, + 106, 1, - 0, - 0, - 0, - 78, - 460, + 107, 1, - 0, - 0, - 0, - 80, - 466, + 107, 1, - 0, - 0, - 0, - 82, - 473, + 107, 1, - 0, - 0, - 0, - 84, - 475, + 107, 1, - 0, - 0, - 0, - 86, - 479, + 107, 1, - 0, - 0, - 0, - 88, - 481, + 107, + 5, + 107, + 1174, + 8, + 107, + 10, + 107, + 12, + 107, + 1177, + 9, + 107, + 3, + 107, + 1179, + 8, + 107, 1, - 0, - 0, - 0, - 90, - 515, + 107, 1, - 0, - 0, - 0, - 92, - 521, + 107, 1, - 0, - 0, - 0, - 94, - 525, + 108, 1, - 0, - 0, - 0, - 96, - 527, + 108, 1, - 0, - 0, - 0, - 98, - 543, + 108, 1, - 0, - 0, - 0, - 100, - 547, + 108, + 5, + 108, + 1187, + 8, + 108, + 10, + 108, + 12, + 108, + 1190, + 9, + 108, 1, - 0, - 0, - 0, - 102, - 551, + 108, 1, - 0, - 0, - 0, - 104, - 564, + 108, 1, - 0, - 0, - 0, - 106, - 581, + 109, 1, - 0, - 0, - 0, - 108, - 583, + 109, 1, - 0, - 0, - 0, - 110, - 598, + 109, 1, - 0, - 0, - 0, - 112, - 600, + 109, 1, - 0, - 0, - 0, - 114, - 604, + 109, 1, - 0, - 0, - 0, - 116, - 606, + 109, + 3, + 109, + 1200, + 8, + 109, 1, - 0, - 0, - 0, - 118, - 610, + 110, 1, - 0, - 0, - 0, - 120, - 612, + 110, 1, - 0, - 0, - 0, - 122, - 629, + 111, 1, - 0, - 0, - 0, - 124, - 631, + 111, 1, - 0, - 0, - 0, - 126, - 635, + 112, 1, - 0, - 0, - 0, - 128, - 651, + 112, 1, - 0, - 0, - 0, - 130, - 653, + 113, 1, - 0, - 0, - 0, - 132, - 671, + 113, + 3, + 113, + 1210, + 8, + 113, 1, - 0, - 0, - 0, - 134, - 673, + 114, 1, - 0, - 0, - 0, - 136, - 677, + 114, 1, - 0, - 0, - 0, - 138, - 681, + 114, 1, - 0, - 0, - 0, - 140, - 694, + 114, + 5, + 114, + 1216, + 8, + 114, + 10, + 114, + 12, + 114, + 1219, + 9, + 114, 1, - 0, - 0, - 0, - 142, - 698, + 114, 1, - 0, - 0, - 0, - 144, - 702, + 114, 1, - 0, - 0, - 0, - 146, - 706, + 114, 1, - 0, - 0, - 0, - 148, - 710, + 114, + 3, + 114, + 1225, + 8, + 114, 1, - 0, - 0, - 0, - 150, - 714, + 115, 1, - 0, - 0, - 0, - 152, - 718, + 115, 1, - 0, - 0, - 0, - 154, - 722, + 115, 1, - 0, - 0, - 0, - 156, - 737, + 115, 1, - 0, - 0, - 0, - 158, - 755, + 116, + 1, + 116, + 1, + 116, + 1, + 116, + 5, + 116, + 1235, + 8, + 116, + 10, + 116, + 12, + 116, + 1238, + 9, + 116, + 1, + 116, + 1, + 116, + 1, + 116, + 1, + 116, + 3, + 116, + 1244, + 8, + 116, + 1, + 117, + 1, + 117, + 1, + 117, + 1, + 117, + 1, + 117, + 1, + 117, + 1, + 117, + 1, + 117, + 1, + 117, + 3, + 117, + 1255, + 8, + 117, + 1, + 118, + 1, + 118, 1, + 118, 0, 0, + 119, 0, + 2, + 4, + 6, + 8, + 10, + 12, + 14, + 16, + 18, + 20, + 22, + 24, + 26, + 28, + 30, + 32, + 34, + 36, + 38, + 40, + 42, + 44, + 46, + 48, + 50, + 52, + 54, + 56, + 58, + 60, + 62, + 64, + 66, + 68, + 70, + 72, + 74, + 76, + 78, + 80, + 82, + 84, + 86, + 88, + 90, + 92, + 94, + 96, + 98, + 100, + 102, + 104, + 106, + 108, + 110, + 112, + 114, + 116, + 118, + 120, + 122, + 124, + 126, + 128, + 130, + 132, + 134, + 136, + 138, + 140, + 142, + 144, + 146, + 148, + 150, + 152, + 154, + 156, + 158, 160, - 757, - 1, + 162, + 164, + 166, + 168, + 170, + 172, + 174, + 176, + 178, + 180, + 182, + 184, + 186, + 188, + 190, + 192, + 194, + 196, + 198, + 200, + 202, + 204, + 206, + 208, + 210, + 212, + 214, + 216, + 218, + 220, + 222, + 224, + 226, + 228, + 230, + 232, + 234, + 236, 0, + 10, + 1, 0, + 132, + 133, + 1, 0, - 162, - 770, + 7, + 8, 1, 0, + 16, + 23, + 1, 0, + 81, + 82, + 1, 0, - 164, - 774, + 160, + 161, 1, 0, + 128, + 129, + 3, 0, + 30, + 37, + 39, + 48, + 50, + 70, + 3, 0, - 166, - 778, + 29, + 29, + 38, + 38, + 49, + 49, 1, 0, + 137, + 152, + 6, 0, + 10, + 13, + 15, + 117, + 119, + 119, + 121, + 131, + 134, + 137, + 139, + 159, + 1347, 0, - 168, - 782, + 238, 1, 0, 0, 0, - 170, - 786, + 2, + 241, 1, 0, 0, 0, - 172, - 790, + 4, + 258, 1, 0, 0, 0, - 174, - 805, + 6, + 260, 1, 0, 0, 0, - 176, - 820, + 8, + 264, 1, 0, 0, 0, - 178, - 822, + 10, + 268, 1, 0, 0, 0, - 180, - 824, + 12, + 272, 1, 0, 0, 0, - 182, - 826, + 14, + 323, 1, 0, 0, 0, - 184, - 830, + 16, + 325, 1, 0, 0, 0, - 186, - 845, + 18, + 338, 1, 0, 0, 0, - 188, - 847, + 20, + 340, 1, 0, 0, 0, - 190, - 864, + 22, + 344, 1, 0, 0, 0, - 192, - 875, + 24, + 355, 1, 0, 0, 0, - 194, - 877, + 26, + 359, 1, 0, 0, 0, - 196, - 197, - 3, - 2, + 28, + 363, 1, 0, - 197, - 198, - 5, 0, 0, + 30, + 379, 1, - 198, - 1, + 0, + 0, + 0, + 32, + 381, 1, 0, 0, 0, - 199, - 200, - 5, - 5, + 34, + 385, + 1, 0, 0, - 200, - 205, - 3, - 4, - 2, 0, - 201, - 202, - 5, + 36, + 403, 1, 0, 0, - 202, - 204, - 3, - 4, - 2, 0, - 203, - 201, + 38, + 405, 1, 0, 0, 0, - 204, - 207, + 40, + 409, 1, 0, 0, 0, - 205, - 203, + 42, + 419, 1, 0, 0, 0, - 205, - 206, + 44, + 433, 1, 0, 0, 0, - 206, - 208, + 46, + 441, 1, 0, 0, 0, - 207, - 205, + 48, + 455, 1, 0, 0, 0, - 208, - 209, - 5, - 6, + 50, + 463, + 1, 0, 0, - 209, - 3, + 0, + 52, + 471, 1, 0, 0, 0, - 210, - 216, - 3, - 8, - 4, + 54, + 479, + 1, 0, - 211, - 216, - 3, - 10, - 5, 0, - 212, - 216, - 3, - 6, - 3, 0, - 213, - 216, - 3, - 14, - 7, + 56, + 487, + 1, 0, - 214, - 216, - 3, - 64, - 32, 0, - 215, - 210, + 0, + 58, + 495, 1, 0, 0, 0, - 215, - 211, + 60, + 506, 1, 0, 0, 0, - 215, - 212, + 62, + 514, 1, 0, 0, 0, - 215, - 213, + 64, + 522, 1, 0, 0, 0, - 215, - 214, + 66, + 524, 1, 0, 0, 0, - 216, - 5, + 68, + 528, 1, 0, 0, 0, - 217, - 218, - 5, - 12, + 70, + 552, + 1, 0, 0, - 218, - 219, - 5, - 2, + 0, + 72, + 560, + 1, 0, 0, - 219, - 220, - 3, - 194, - 97, 0, - 220, - 7, + 74, + 568, 1, 0, 0, 0, - 221, - 222, - 5, - 10, + 76, + 576, + 1, 0, 0, - 222, - 223, - 5, - 2, 0, + 78, + 584, + 1, 0, - 223, - 224, - 3, - 194, - 97, 0, - 224, - 9, + 0, + 80, + 586, 1, 0, 0, 0, - 225, - 226, - 5, - 14, + 82, + 601, + 1, 0, 0, - 226, - 227, - 5, - 2, + 0, + 84, + 619, + 1, 0, 0, - 227, - 228, - 3, - 194, - 97, 0, - 228, - 11, + 86, + 634, 1, 0, 0, 0, - 229, - 270, - 3, - 8, - 4, + 88, + 639, + 1, 0, - 230, - 270, - 3, - 22, - 11, 0, - 231, - 270, - 3, - 28, - 14, 0, - 232, - 270, - 3, - 26, - 13, - 0, - 233, - 270, - 3, - 24, - 12, + 90, + 646, + 1, 0, - 234, - 270, - 3, - 30, - 15, 0, - 235, - 270, - 3, - 32, - 16, 0, - 236, - 270, - 3, - 34, - 17, + 92, + 648, + 1, 0, - 237, - 270, - 3, - 36, - 18, 0, - 238, - 270, - 3, - 38, - 19, 0, - 239, - 270, - 3, - 88, - 44, + 94, + 665, + 1, 0, - 240, - 270, - 3, - 40, - 20, 0, - 241, - 270, - 3, - 42, - 21, 0, - 242, - 270, - 3, - 44, - 22, + 96, + 667, + 1, 0, - 243, - 270, - 3, - 46, - 23, 0, - 244, - 270, - 3, - 48, - 24, 0, - 245, - 270, - 3, - 50, - 25, + 98, + 682, + 1, 0, - 246, - 270, - 3, - 52, - 26, 0, - 247, - 270, - 3, - 54, - 27, 0, - 248, - 270, - 3, - 56, - 28, + 100, + 699, + 1, 0, - 249, - 270, - 3, - 104, - 52, 0, - 250, - 270, - 3, - 120, - 60, 0, - 251, - 270, - 3, - 124, - 62, + 102, + 704, + 1, 0, - 252, - 270, - 3, - 126, - 63, 0, - 253, - 270, - 3, - 58, - 29, 0, - 254, - 270, - 3, - 60, - 30, + 104, + 719, + 1, 0, - 255, - 270, - 3, - 64, - 32, 0, - 256, - 270, - 3, - 66, - 33, 0, - 257, - 270, - 3, - 68, - 34, + 106, + 727, + 1, 0, - 258, - 270, - 3, - 70, - 35, 0, - 259, - 270, - 3, - 102, - 51, 0, - 260, - 270, - 3, - 62, - 31, + 108, + 735, + 1, 0, - 261, - 270, - 3, - 154, - 77, 0, - 262, - 270, - 3, - 172, - 86, 0, - 263, - 270, - 3, - 84, - 42, + 110, + 737, + 1, 0, - 264, - 270, - 3, - 144, - 72, 0, - 265, - 270, - 3, - 146, - 73, 0, - 266, - 270, - 3, - 148, - 74, + 112, + 754, + 1, 0, - 267, - 270, - 3, - 150, - 75, 0, - 268, - 270, - 3, - 152, - 76, 0, - 269, - 229, + 114, + 756, 1, 0, 0, 0, - 269, - 230, + 116, + 763, 1, 0, 0, 0, - 269, - 231, + 118, + 778, 1, 0, 0, 0, - 269, - 232, + 120, + 786, 1, 0, 0, 0, - 269, - 233, + 122, + 788, 1, 0, 0, 0, - 269, - 234, + 124, + 792, 1, 0, 0, 0, - 269, - 235, + 126, + 794, 1, 0, 0, 0, - 269, - 236, + 128, + 828, 1, 0, 0, 0, - 269, - 237, + 130, + 835, 1, 0, 0, 0, - 269, - 238, + 132, + 841, 1, 0, 0, 0, - 269, - 239, + 134, + 843, 1, 0, 0, 0, - 269, - 240, + 136, + 868, 1, 0, 0, 0, - 269, - 241, + 138, + 884, 1, 0, 0, 0, - 269, - 242, + 140, + 886, 1, 0, 0, 0, - 269, - 243, + 142, + 899, 1, 0, 0, 0, - 269, - 244, + 144, + 916, 1, 0, 0, 0, - 269, - 245, + 146, + 918, 1, 0, 0, 0, - 269, - 246, + 148, + 933, 1, 0, 0, 0, - 269, - 247, + 150, + 935, 1, 0, 0, 0, - 269, - 248, + 152, + 939, 1, 0, 0, 0, - 269, - 249, + 154, + 941, 1, 0, 0, 0, - 269, - 250, + 156, + 945, 1, 0, 0, 0, - 269, - 251, + 158, + 947, 1, 0, 0, 0, - 269, - 252, + 160, + 964, 1, 0, 0, 0, - 269, - 253, + 162, + 966, 1, 0, 0, 0, - 269, - 254, + 164, + 970, 1, 0, 0, 0, - 269, - 255, + 166, + 987, 1, 0, 0, 0, - 269, - 256, + 168, + 989, 1, 0, 0, 0, - 269, - 257, + 170, + 1007, 1, 0, 0, 0, - 269, - 258, + 172, + 1009, 1, 0, 0, 0, - 269, - 259, + 174, + 1013, 1, 0, 0, 0, - 269, - 260, + 176, + 1017, 1, 0, 0, 0, - 269, - 261, + 178, + 1036, 1, 0, 0, 0, - 269, - 262, + 180, + 1044, 1, 0, 0, 0, - 269, - 263, + 182, + 1052, 1, 0, 0, 0, - 269, - 264, + 184, + 1060, 1, 0, 0, 0, - 269, - 265, + 186, + 1068, 1, 0, 0, 0, - 269, - 266, + 188, + 1076, 1, 0, 0, 0, - 269, - 267, + 190, + 1078, 1, 0, 0, 0, - 269, - 268, + 192, + 1082, 1, 0, 0, 0, - 270, - 13, + 194, + 1097, 1, 0, 0, 0, - 271, - 272, - 5, - 11, - 0, + 196, + 1099, + 1, 0, - 272, - 273, - 5, - 2, 0, 0, - 273, - 274, - 5, - 5, + 198, + 1114, + 1, 0, 0, - 274, - 279, - 3, - 18, - 9, 0, - 275, - 276, - 5, + 200, + 1132, 1, 0, 0, - 276, - 278, - 3, - 18, - 9, 0, - 277, - 275, + 202, + 1134, 1, 0, 0, 0, - 278, - 281, + 204, + 1147, 1, 0, 0, 0, - 279, - 277, + 206, + 1151, 1, 0, 0, 0, - 279, - 280, + 208, + 1155, 1, 0, 0, 0, - 280, - 282, + 210, + 1159, 1, 0, 0, 0, - 281, - 279, + 212, + 1163, 1, 0, 0, 0, - 282, - 283, - 5, - 6, - 0, - 0, - 283, - 15, + 214, + 1167, 1, 0, 0, 0, - 284, - 285, - 3, - 194, - 97, - 0, - 285, - 17, + 216, + 1182, 1, 0, 0, 0, - 286, - 287, - 3, - 16, - 8, - 0, - 287, - 288, - 5, - 2, + 218, + 1199, + 1, 0, 0, - 288, - 289, - 3, - 20, - 10, 0, - 289, - 19, + 220, + 1201, 1, 0, 0, 0, - 290, - 291, - 5, - 5, + 222, + 1203, + 1, 0, 0, - 291, - 296, - 3, - 12, - 6, 0, - 292, - 293, - 5, + 224, + 1205, 1, 0, 0, - 293, - 295, - 3, - 12, - 6, 0, - 294, - 292, + 226, + 1209, 1, 0, 0, 0, - 295, - 298, + 228, + 1224, 1, 0, 0, 0, - 296, - 294, + 230, + 1226, 1, 0, 0, 0, - 296, - 297, + 232, + 1243, 1, 0, 0, 0, - 297, - 299, + 234, + 1254, 1, 0, 0, 0, - 298, - 296, + 236, + 1256, 1, 0, 0, 0, - 299, - 300, + 238, + 239, + 3, + 2, + 1, + 0, + 239, + 240, 5, - 6, 0, 0, - 300, - 21, + 1, + 240, + 1, 1, 0, 0, 0, - 301, - 302, + 241, + 242, + 5, 5, - 15, 0, 0, - 302, - 303, - 5, + 242, + 247, + 3, + 4, 2, 0, + 243, + 244, + 5, + 1, 0, - 303, - 304, + 0, + 244, + 246, 3, - 86, - 43, + 4, + 2, 0, - 304, - 23, + 245, + 243, 1, 0, 0, 0, - 305, - 306, - 5, - 109, + 246, + 249, + 1, 0, 0, - 306, - 307, - 5, - 2, 0, + 247, + 245, + 1, 0, - 307, - 308, - 3, - 194, - 97, 0, - 308, - 25, + 0, + 247, + 248, 1, 0, 0, 0, - 309, - 310, - 5, - 89, + 248, + 250, + 1, 0, 0, - 310, - 311, + 0, + 249, + 247, + 1, + 0, + 0, + 0, + 250, + 251, 5, - 2, + 6, 0, 0, - 311, - 312, + 251, 3, - 194, - 97, - 0, - 312, - 27, 1, 0, 0, 0, - 313, - 314, - 5, - 90, - 0, + 252, + 259, + 3, + 8, + 4, 0, - 314, - 317, + 253, + 259, + 3, + 10, 5, - 2, 0, + 254, + 259, + 3, + 12, + 6, 0, - 315, - 318, - 5, - 9, + 255, + 259, + 3, + 6, + 3, 0, + 256, + 259, + 3, + 16, + 8, 0, - 316, - 318, + 257, + 259, 3, - 194, - 97, + 72, + 36, 0, - 317, - 315, + 258, + 252, 1, 0, 0, 0, - 317, - 316, + 258, + 253, 1, 0, 0, 0, - 318, - 29, + 258, + 254, 1, 0, 0, 0, - 319, - 320, - 5, - 94, + 258, + 255, + 1, 0, 0, - 320, - 321, - 5, - 2, 0, + 258, + 256, + 1, 0, - 321, - 322, - 3, - 192, - 96, 0, - 322, - 31, + 0, + 258, + 257, 1, 0, 0, 0, - 323, - 324, + 259, 5, - 93, + 1, 0, 0, - 324, - 327, + 0, + 260, + 261, 5, - 2, + 12, 0, 0, - 325, - 328, + 261, + 262, 5, - 9, + 2, 0, 0, - 326, - 328, + 262, + 263, 3, - 194, - 97, - 0, - 327, - 325, - 1, - 0, - 0, - 0, - 327, - 326, - 1, - 0, - 0, + 236, + 118, 0, - 328, - 33, + 263, + 7, 1, 0, 0, 0, - 329, - 330, + 264, + 265, 5, - 91, + 10, 0, 0, - 330, - 333, + 265, + 266, 5, 2, 0, 0, - 331, - 334, - 5, - 9, - 0, - 0, - 332, - 334, + 266, + 267, 3, - 194, - 97, + 236, + 118, 0, - 333, - 331, + 267, + 9, 1, 0, 0, 0, - 333, - 332, - 1, + 268, + 269, + 5, + 14, + 0, + 0, + 269, + 270, + 5, + 2, 0, 0, + 270, + 271, + 3, + 236, + 118, 0, - 334, - 35, + 271, + 11, 1, 0, 0, 0, - 335, - 336, + 272, + 273, 5, - 110, + 131, 0, 0, - 336, - 337, + 273, + 274, 5, 2, 0, 0, - 337, - 338, + 274, + 275, 7, 0, 0, 0, - 338, - 37, + 275, + 13, 1, 0, 0, 0, - 339, - 340, - 5, - 26, + 276, + 324, + 3, + 8, + 4, 0, + 277, + 324, + 3, + 12, + 6, 0, - 340, - 341, - 5, - 2, + 278, + 324, + 3, + 24, + 12, 0, + 279, + 324, + 3, + 30, + 15, 0, - 341, - 342, + 280, + 324, 3, - 194, - 97, + 28, + 14, 0, - 342, - 39, - 1, + 281, + 324, + 3, + 26, + 13, 0, + 282, + 324, + 3, + 32, + 16, 0, + 283, + 324, + 3, + 34, + 17, 0, - 343, - 344, - 5, - 113, + 284, + 324, + 3, + 36, + 18, 0, + 285, + 324, + 3, + 38, + 19, 0, - 344, - 345, - 5, - 2, + 286, + 324, + 3, + 40, + 20, 0, + 287, + 324, + 3, + 126, + 63, 0, - 345, - 346, + 288, + 324, 3, - 194, - 97, + 42, + 21, 0, - 346, - 41, - 1, + 289, + 324, + 3, + 44, + 22, 0, + 290, + 324, + 3, + 46, + 23, 0, + 291, + 324, + 3, + 48, + 24, 0, - 347, - 348, - 5, - 114, + 292, + 324, + 3, + 50, + 25, 0, + 293, + 324, + 3, + 52, + 26, 0, - 348, - 349, - 5, - 2, + 294, + 324, + 3, + 54, + 27, 0, + 295, + 324, + 3, + 56, + 28, 0, - 349, - 354, - 5, - 142, + 296, + 324, + 3, + 58, + 29, 0, + 297, + 324, + 3, + 60, + 30, 0, - 350, - 351, - 5, - 114, + 298, + 324, + 3, + 142, + 71, 0, + 299, + 324, + 3, + 158, + 79, 0, - 351, - 352, - 5, - 2, + 300, + 324, + 3, + 162, + 81, 0, + 301, + 324, + 3, + 164, + 82, 0, - 352, - 354, + 302, + 324, 3, - 76, - 38, + 62, + 31, 0, - 353, - 347, - 1, + 303, + 324, + 3, + 64, + 32, 0, + 304, + 324, + 3, + 72, + 36, 0, + 305, + 324, + 3, + 74, + 37, 0, - 353, - 350, - 1, + 306, + 324, + 3, + 76, + 38, 0, + 307, + 324, + 3, + 78, + 39, 0, + 308, + 324, + 3, + 140, + 70, 0, - 354, - 43, - 1, + 309, + 324, + 3, + 66, + 33, 0, + 310, + 324, + 3, + 196, + 98, 0, + 311, + 324, + 3, + 214, + 107, 0, - 355, - 356, - 5, - 111, + 312, + 324, + 3, + 122, + 61, 0, + 313, + 324, + 3, + 182, + 91, 0, - 356, - 357, - 5, - 2, - 0, - 0, - 357, - 358, + 314, + 324, 3, - 194, - 97, + 184, + 92, 0, - 358, - 45, - 1, + 315, + 324, + 3, + 186, + 93, 0, + 316, + 324, + 3, + 188, + 94, 0, + 317, + 324, + 3, + 190, + 95, 0, - 359, - 360, - 5, - 112, + 318, + 324, + 3, + 192, + 96, 0, + 319, + 324, + 3, + 92, + 46, 0, - 360, - 361, - 5, - 2, + 320, + 324, + 3, + 108, + 54, 0, + 321, + 324, + 3, + 110, + 55, 0, - 361, - 366, - 5, - 142, + 322, + 324, + 3, + 68, + 34, 0, + 323, + 276, + 1, 0, - 362, - 363, - 5, - 112, 0, 0, - 363, - 364, - 5, - 2, + 323, + 277, + 1, 0, 0, - 364, - 366, - 3, - 76, - 38, 0, - 365, - 359, + 323, + 278, 1, 0, 0, 0, - 365, - 362, + 323, + 279, 1, 0, 0, 0, - 366, - 47, + 323, + 280, 1, 0, 0, 0, - 367, - 368, - 5, - 71, + 323, + 281, + 1, 0, 0, - 368, - 369, - 5, - 2, 0, + 323, + 282, + 1, 0, - 369, - 370, - 5, - 144, 0, 0, - 370, - 49, + 323, + 283, 1, 0, 0, 0, - 371, - 372, - 5, - 70, - 0, - 0, - 372, - 373, - 5, - 2, + 323, + 284, + 1, 0, 0, - 373, - 374, - 3, - 194, - 97, 0, - 374, - 51, + 323, + 285, 1, 0, 0, 0, - 375, - 376, - 5, - 73, - 0, - 0, - 376, - 377, - 5, - 2, + 323, + 286, + 1, 0, 0, - 377, - 378, - 3, - 194, - 97, 0, - 378, - 53, + 323, + 287, 1, 0, 0, 0, - 379, - 380, - 5, - 72, + 323, + 288, + 1, 0, 0, - 380, - 381, - 5, - 2, + 0, + 323, + 289, + 1, 0, 0, - 381, - 382, - 3, - 194, - 97, 0, - 382, - 55, + 323, + 290, 1, 0, 0, 0, - 383, - 384, - 5, - 92, + 323, + 291, + 1, 0, 0, - 384, - 385, - 5, - 2, 0, + 323, + 292, + 1, 0, - 385, - 386, - 3, - 194, - 97, 0, - 386, - 57, + 0, + 323, + 293, 1, 0, 0, 0, - 387, - 388, - 5, - 88, + 323, + 294, + 1, 0, 0, - 388, - 389, - 5, - 2, 0, + 323, + 295, + 1, 0, - 389, - 390, - 5, - 144, 0, 0, - 390, - 59, + 323, + 296, 1, 0, 0, 0, - 391, - 392, - 5, - 87, + 323, + 297, + 1, 0, 0, - 392, - 393, - 5, - 2, 0, + 323, + 298, + 1, 0, - 393, - 394, - 5, - 142, 0, 0, - 394, - 61, + 323, + 299, 1, 0, 0, 0, - 395, - 396, - 5, - 95, - 0, - 0, - 396, - 397, - 5, - 2, + 323, + 300, + 1, 0, 0, - 397, - 398, - 3, - 72, - 36, 0, - 398, - 63, + 323, + 301, 1, 0, 0, 0, - 399, - 400, - 5, - 74, + 323, + 302, + 1, 0, 0, - 400, - 401, - 5, - 2, 0, + 323, + 303, + 1, 0, - 401, - 402, - 5, - 144, 0, 0, - 402, - 65, + 323, + 304, 1, 0, 0, 0, - 403, - 404, - 5, - 75, + 323, + 305, + 1, 0, 0, - 404, - 405, - 5, - 2, 0, + 323, + 306, + 1, 0, - 405, - 406, - 5, - 142, 0, 0, - 406, - 67, + 323, + 307, 1, 0, 0, 0, - 407, - 408, - 5, - 76, + 323, + 308, + 1, 0, 0, - 408, - 409, - 5, - 2, 0, + 323, + 309, + 1, 0, - 409, - 410, - 5, - 144, 0, 0, - 410, - 69, + 323, + 310, 1, 0, 0, 0, - 411, - 412, - 5, - 77, + 323, + 311, + 1, 0, 0, - 412, - 413, - 5, - 2, 0, + 323, + 312, + 1, 0, - 413, - 414, - 5, - 142, 0, 0, - 414, - 71, + 323, + 313, 1, 0, 0, 0, - 415, - 416, - 5, - 5, + 323, + 314, + 1, 0, 0, - 416, - 421, - 3, - 74, - 37, 0, - 417, - 418, - 5, + 323, + 315, 1, 0, 0, - 418, - 420, - 3, - 74, - 37, 0, - 419, - 417, + 323, + 316, 1, 0, 0, 0, - 420, - 423, + 323, + 317, 1, 0, 0, 0, - 421, - 419, + 323, + 318, 1, 0, 0, 0, - 421, - 422, + 323, + 319, 1, 0, 0, 0, - 422, - 424, + 323, + 320, 1, 0, 0, 0, - 423, - 421, + 323, + 321, 1, 0, 0, 0, - 424, - 425, - 5, - 6, + 323, + 322, + 1, 0, 0, - 425, - 429, + 0, + 324, + 15, 1, 0, 0, 0, - 426, - 427, + 325, + 326, 5, + 11, + 0, + 0, + 326, + 327, 5, + 2, 0, 0, - 427, - 429, + 327, + 328, + 5, 5, - 6, 0, 0, - 428, - 415, + 328, + 333, + 3, + 20, + 10, + 0, + 329, + 330, + 5, 1, 0, 0, + 330, + 332, + 3, + 20, + 10, 0, - 428, - 426, + 331, + 329, 1, 0, 0, 0, - 429, - 73, + 332, + 335, 1, 0, 0, 0, - 430, - 431, - 5, - 140, + 333, + 331, + 1, 0, 0, - 431, - 432, - 5, - 2, 0, + 333, + 334, + 1, 0, - 432, - 444, - 5, - 142, 0, 0, - 433, - 434, - 5, - 140, + 334, + 336, + 1, 0, 0, - 434, - 435, - 5, - 2, 0, + 335, + 333, + 1, 0, - 435, - 444, - 5, - 141, 0, 0, - 436, - 437, + 336, + 337, 5, - 140, + 6, 0, 0, - 437, - 438, - 5, - 2, + 337, + 17, + 1, 0, 0, - 438, - 444, - 3, - 76, - 38, - 0, - 439, - 440, - 3, - 194, - 97, - 0, - 440, - 441, - 5, - 2, 0, - 0, - 441, - 442, + 338, + 339, 3, - 80, - 40, - 0, - 442, - 444, - 1, - 0, - 0, - 0, - 443, - 430, - 1, - 0, - 0, + 236, + 118, 0, - 443, - 433, + 339, + 19, 1, 0, 0, 0, - 443, - 436, - 1, - 0, - 0, + 340, + 341, + 3, + 18, + 9, 0, - 443, - 439, - 1, + 341, + 342, + 5, + 2, 0, 0, + 342, + 343, + 3, + 22, + 11, 0, - 444, - 75, + 343, + 21, 1, 0, 0, 0, - 445, - 446, + 344, + 345, 5, - 143, - 0, - 0, - 446, - 77, - 1, - 0, - 0, - 0, - 447, - 448, 5, - 3, 0, 0, - 448, - 453, + 345, + 350, 3, - 80, - 40, + 14, + 7, 0, - 449, - 450, + 346, + 347, 5, 1, 0, 0, - 450, - 452, + 347, + 349, 3, - 80, - 40, + 14, + 7, 0, - 451, - 449, + 348, + 346, 1, 0, 0, 0, - 452, - 455, + 349, + 352, 1, 0, 0, 0, - 453, - 451, + 350, + 348, 1, 0, 0, 0, - 453, - 454, + 350, + 351, 1, 0, 0, 0, - 454, - 456, + 351, + 353, 1, 0, 0, 0, - 455, - 453, + 352, + 350, 1, 0, 0, 0, - 456, - 457, + 353, + 354, 5, - 4, + 6, 0, 0, - 457, - 461, + 354, + 23, 1, 0, 0, 0, - 458, - 459, + 355, + 356, 5, - 3, + 15, 0, 0, - 459, - 461, + 356, + 357, 5, - 4, - 0, - 0, - 460, - 447, - 1, + 2, 0, 0, + 357, + 358, + 3, + 124, + 62, 0, - 460, - 458, + 358, + 25, 1, 0, 0, 0, - 461, - 79, - 1, + 359, + 360, + 5, + 115, 0, 0, + 360, + 361, + 5, + 2, 0, - 462, - 467, - 3, - 74, - 37, 0, - 463, - 467, + 361, + 362, 3, - 78, - 39, + 236, + 118, 0, - 464, - 467, - 3, - 72, - 36, + 362, + 27, + 1, 0, - 465, - 467, - 3, - 82, - 41, 0, - 466, - 462, - 1, 0, + 363, + 364, + 5, + 90, 0, 0, - 466, - 463, - 1, + 364, + 365, + 5, + 2, 0, 0, + 365, + 366, + 3, + 236, + 118, 0, - 466, - 464, + 366, + 29, 1, 0, 0, 0, - 466, - 465, - 1, - 0, + 367, + 368, + 5, + 91, 0, 0, - 467, - 81, - 1, + 368, + 369, + 5, + 2, 0, 0, + 369, + 380, + 3, + 80, + 40, 0, - 468, - 474, + 370, + 371, 5, - 145, + 91, 0, 0, - 469, - 474, + 371, + 372, 5, - 144, + 2, 0, 0, - 470, - 474, - 7, + 372, + 380, + 5, + 154, 0, 0, + 373, + 374, + 5, + 91, + 0, 0, - 471, - 474, + 374, + 377, + 5, + 2, + 0, + 0, + 375, + 378, 5, 9, 0, 0, - 472, - 474, + 376, + 378, 3, - 194, - 97, + 236, + 118, 0, - 473, - 468, + 377, + 375, 1, 0, 0, 0, - 473, - 469, + 377, + 376, 1, 0, 0, 0, - 473, - 470, + 378, + 380, 1, 0, 0, 0, - 473, - 471, + 379, + 367, 1, 0, 0, 0, - 473, - 472, + 379, + 370, 1, 0, 0, 0, - 474, - 83, + 379, + 373, 1, 0, 0, 0, - 475, - 476, + 380, + 31, + 1, + 0, + 0, + 0, + 381, + 382, 5, 96, 0, 0, - 476, - 477, + 382, + 383, 5, 2, 0, 0, - 477, - 478, + 383, + 384, 3, - 72, - 36, - 0, - 478, - 85, - 1, - 0, - 0, - 0, - 479, - 480, - 7, - 1, - 0, + 234, + 117, 0, - 480, - 87, + 384, + 33, 1, 0, 0, 0, - 481, - 482, + 385, + 386, 5, - 24, + 95, 0, 0, - 482, - 483, + 386, + 389, 5, 2, 0, 0, - 483, - 484, + 387, + 390, 5, - 3, + 9, 0, 0, - 484, - 489, + 388, + 390, 3, - 90, - 45, + 236, + 118, 0, - 485, - 486, - 5, + 389, + 387, 1, 0, 0, - 486, - 488, - 3, - 90, - 45, 0, - 487, - 485, + 389, + 388, 1, 0, 0, 0, - 488, - 491, + 390, + 35, 1, 0, 0, 0, - 489, - 487, - 1, - 0, + 391, + 392, + 5, + 92, 0, 0, - 489, - 490, - 1, + 392, + 393, + 5, + 2, 0, 0, + 393, + 404, + 3, + 80, + 40, 0, - 490, - 492, - 1, + 394, + 395, + 5, + 92, 0, 0, + 395, + 396, + 5, + 2, 0, - 491, - 489, - 1, 0, + 396, + 404, + 5, + 154, 0, 0, - 492, - 493, + 397, + 398, 5, - 4, - 0, + 92, 0, - 493, - 89, - 1, 0, + 398, + 401, + 5, + 2, 0, 0, - 494, - 495, - 5, + 399, + 402, 5, + 9, 0, 0, - 495, - 498, + 400, + 402, 3, - 92, - 46, + 236, + 118, 0, - 496, - 497, - 5, + 401, + 399, 1, 0, 0, - 497, - 499, - 3, - 92, - 46, 0, - 498, - 496, + 401, + 400, 1, 0, 0, 0, - 499, - 500, + 402, + 404, 1, 0, 0, 0, - 500, - 498, + 403, + 391, 1, 0, 0, 0, - 500, - 501, + 403, + 394, 1, 0, 0, 0, - 501, - 502, + 403, + 397, 1, 0, 0, 0, - 502, - 503, - 5, - 6, - 0, - 0, - 503, - 516, + 404, + 37, 1, 0, 0, 0, - 504, - 505, - 5, + 405, + 406, 5, + 116, 0, 0, - 505, - 510, - 3, - 94, - 47, - 0, - 506, - 507, + 406, + 407, 5, - 1, - 0, - 0, - 507, - 509, - 3, - 94, - 47, - 0, - 508, - 506, - 1, - 0, + 2, 0, 0, - 509, - 512, + 407, + 408, + 7, 1, 0, 0, - 0, - 510, - 508, + 408, + 39, 1, 0, 0, 0, - 510, - 511, - 1, - 0, + 409, + 410, + 5, + 27, 0, 0, - 511, - 513, - 1, + 410, + 411, + 5, + 2, 0, 0, + 411, + 412, + 3, + 236, + 118, 0, - 512, - 510, + 412, + 41, 1, 0, 0, 0, - 513, - 514, + 413, + 414, 5, - 6, - 0, - 0, - 514, - 516, - 1, - 0, - 0, - 0, - 515, - 494, - 1, - 0, - 0, + 119, 0, - 515, - 504, - 1, 0, + 414, + 415, + 5, + 2, 0, 0, - 516, - 91, - 1, + 415, + 420, + 5, + 158, 0, 0, + 416, + 417, + 5, + 119, 0, - 517, - 522, - 3, - 98, - 49, 0, - 518, - 522, - 3, - 100, - 50, + 417, + 418, + 5, + 2, 0, - 519, - 522, - 3, - 24, - 12, 0, - 520, - 522, + 418, + 420, 3, - 8, - 4, - 0, - 521, - 517, - 1, - 0, - 0, + 236, + 118, 0, - 521, - 518, + 419, + 413, 1, 0, 0, 0, - 521, - 519, + 419, + 416, 1, 0, 0, 0, - 521, - 520, + 420, + 43, 1, 0, 0, 0, - 522, - 93, - 1, + 421, + 422, + 5, + 120, 0, 0, + 422, + 423, + 5, + 2, 0, - 523, - 526, - 3, - 96, - 48, 0, - 524, - 526, + 423, + 434, 3, - 24, - 12, - 0, - 525, - 523, - 1, - 0, + 80, + 40, 0, + 424, + 425, + 5, + 120, 0, - 525, - 524, - 1, 0, + 425, + 426, + 5, + 2, 0, 0, - 526, - 95, - 1, + 426, + 434, + 5, + 155, 0, 0, + 427, + 428, + 5, + 120, 0, - 527, - 528, - 3, - 180, - 90, 0, - 528, - 541, + 428, + 429, 5, 2, 0, 0, - 529, - 542, - 3, - 90, - 45, - 0, - 530, - 531, + 429, + 434, 5, - 3, - 0, + 154, 0, - 531, - 536, - 3, - 90, - 45, 0, - 532, - 533, + 430, + 431, 5, - 1, + 120, 0, 0, - 533, - 535, - 3, - 90, - 45, + 431, + 432, + 5, + 2, 0, - 534, - 532, - 1, 0, + 432, + 434, + 5, + 157, 0, 0, - 535, - 538, + 433, + 421, 1, 0, 0, 0, - 536, - 534, + 433, + 424, 1, 0, 0, 0, - 536, - 537, + 433, + 427, 1, 0, 0, 0, - 537, - 539, + 433, + 430, 1, 0, 0, 0, - 538, - 536, + 434, + 45, 1, 0, 0, 0, - 539, - 540, + 435, + 436, 5, - 4, + 117, 0, 0, - 540, - 542, - 1, + 436, + 437, + 5, + 2, 0, 0, + 437, + 442, + 5, + 158, + 0, 0, - 541, - 529, + 438, + 439, + 5, + 117, + 0, + 0, + 439, + 440, + 5, + 2, + 0, + 0, + 440, + 442, + 3, + 236, + 118, + 0, + 441, + 435, 1, 0, 0, 0, - 541, - 530, + 441, + 438, 1, 0, 0, 0, - 542, - 97, + 442, + 47, 1, 0, 0, 0, - 543, - 544, + 443, + 444, 5, - 25, + 118, 0, 0, - 544, - 545, + 444, + 445, 5, 2, 0, 0, - 545, - 546, + 445, + 456, 3, - 194, - 97, - 0, - 546, - 99, - 1, - 0, + 80, + 40, 0, + 446, + 447, + 5, + 118, 0, - 547, - 548, - 3, - 178, - 89, 0, - 548, - 549, + 447, + 448, 5, 2, 0, 0, - 549, - 550, - 3, - 192, - 96, - 0, - 550, - 101, - 1, - 0, + 448, + 456, + 5, + 155, 0, 0, - 551, - 552, + 449, + 450, 5, - 27, + 118, 0, 0, - 552, - 553, + 450, + 451, 5, 2, 0, 0, - 553, - 554, + 451, + 456, 5, - 3, - 0, + 154, 0, - 554, - 559, - 3, - 2, - 1, 0, - 555, - 556, + 452, + 453, 5, - 1, + 118, 0, 0, - 556, - 558, - 3, + 453, + 454, + 5, 2, - 1, 0, - 557, - 555, - 1, 0, + 454, + 456, + 5, + 157, 0, 0, - 558, - 561, + 455, + 443, 1, 0, 0, 0, - 559, - 557, + 455, + 446, 1, 0, 0, 0, - 559, - 560, + 455, + 449, 1, 0, 0, 0, - 560, - 562, + 455, + 452, 1, 0, 0, 0, - 561, - 559, + 456, + 49, 1, 0, 0, 0, - 562, - 563, + 457, + 458, 5, - 4, + 72, 0, 0, - 563, - 103, - 1, + 458, + 459, + 5, + 2, 0, 0, + 459, + 464, + 5, + 158, + 0, 0, - 564, - 565, + 460, + 461, 5, - 84, + 72, 0, 0, - 565, - 566, + 461, + 462, 5, 2, 0, 0, - 566, - 567, - 5, + 462, + 464, 5, + 160, 0, 0, - 567, - 572, - 3, - 106, - 53, - 0, - 568, - 569, - 5, + 463, + 457, 1, 0, 0, - 569, - 571, - 3, - 106, - 53, 0, - 570, - 568, + 463, + 460, 1, 0, 0, 0, - 571, - 574, + 464, + 51, 1, 0, 0, 0, - 572, - 570, - 1, + 465, + 466, + 5, + 71, 0, 0, + 466, + 467, + 5, + 2, 0, - 572, - 573, - 1, 0, + 467, + 472, + 3, + 80, + 40, + 0, + 468, + 469, + 5, + 71, 0, 0, - 573, - 575, + 469, + 470, + 5, + 2, + 0, + 0, + 470, + 472, + 3, + 236, + 118, + 0, + 471, + 465, 1, 0, 0, 0, - 574, - 572, + 471, + 468, 1, 0, 0, 0, - 575, - 576, - 5, - 6, - 0, - 0, - 576, - 105, + 472, + 53, 1, 0, 0, 0, - 577, - 582, - 3, - 108, - 54, + 473, + 474, + 5, + 74, 0, - 578, - 582, - 3, - 6, - 3, 0, - 579, - 582, - 3, - 14, - 7, + 474, + 475, + 5, + 2, 0, - 580, - 582, - 3, - 8, - 4, 0, - 581, - 577, - 1, + 475, + 480, + 5, + 158, 0, 0, + 476, + 477, + 5, + 74, + 0, 0, - 581, - 578, - 1, + 477, + 478, + 5, + 2, 0, 0, + 478, + 480, + 3, + 236, + 118, 0, - 581, - 579, + 479, + 473, 1, 0, 0, 0, - 581, - 580, + 479, + 476, 1, 0, 0, 0, - 582, - 107, + 480, + 55, 1, 0, 0, 0, - 583, - 584, + 481, + 482, 5, - 78, + 73, 0, 0, - 584, - 585, + 482, + 483, 5, 2, 0, 0, - 585, - 586, - 5, - 5, - 0, - 0, - 586, - 591, + 483, + 488, 3, - 110, - 55, + 80, + 40, 0, - 587, - 588, + 484, + 485, 5, - 1, - 0, + 73, 0, - 588, - 590, - 3, - 110, - 55, 0, - 589, - 587, - 1, + 485, + 486, + 5, + 2, 0, 0, + 486, + 488, + 3, + 236, + 118, 0, - 590, - 593, + 487, + 481, 1, 0, 0, 0, - 591, - 589, + 487, + 484, 1, 0, 0, 0, - 591, - 592, + 488, + 57, 1, 0, 0, 0, - 592, - 594, - 1, - 0, + 489, + 490, + 5, + 93, 0, 0, - 593, - 591, - 1, + 490, + 491, + 5, + 2, 0, 0, + 491, + 496, + 3, + 118, + 59, 0, - 594, - 595, + 492, + 493, 5, - 6, - 0, + 93, 0, - 595, - 109, - 1, 0, + 493, + 494, + 5, + 2, 0, 0, - 596, - 599, - 3, - 112, - 56, + 494, + 496, + 5, + 158, 0, - 597, - 599, - 3, - 116, - 58, 0, - 598, - 596, + 495, + 489, 1, 0, 0, 0, - 598, - 597, + 495, + 492, 1, 0, 0, 0, - 599, - 111, + 496, + 59, 1, 0, 0, 0, - 600, - 601, + 497, + 498, 5, - 79, + 94, 0, 0, - 601, - 602, + 498, + 499, 5, 2, 0, 0, - 602, - 603, - 3, - 114, - 57, + 499, + 507, + 5, + 154, 0, - 603, - 113, - 1, 0, + 500, + 501, + 5, + 94, 0, 0, - 604, - 605, - 7, + 501, + 502, + 5, 2, 0, 0, - 605, - 115, - 1, - 0, - 0, + 502, + 507, + 3, + 80, + 40, 0, - 606, - 607, + 503, + 504, 5, - 82, + 94, 0, 0, - 607, - 608, + 504, + 505, 5, 2, 0, 0, - 608, - 609, + 505, + 507, 3, + 236, 118, - 59, 0, - 609, - 117, + 506, + 497, 1, 0, 0, 0, - 610, - 611, - 5, - 83, - 0, - 0, - 611, - 119, + 506, + 500, 1, 0, 0, 0, - 612, - 613, - 5, - 85, - 0, + 506, + 503, + 1, 0, - 613, - 614, - 5, - 2, 0, 0, - 614, - 615, - 5, - 5, + 507, + 61, + 1, 0, 0, - 615, - 620, - 3, - 122, - 61, 0, - 616, - 617, + 508, + 509, 5, - 1, + 89, 0, 0, - 617, - 619, - 3, - 122, - 61, + 509, + 510, + 5, + 2, 0, - 618, - 616, - 1, 0, + 510, + 515, + 5, + 158, 0, 0, - 619, - 622, - 1, + 511, + 512, + 5, + 89, 0, 0, + 512, + 513, + 5, + 2, 0, - 620, - 618, - 1, 0, + 513, + 515, + 5, + 160, 0, 0, - 620, - 621, + 514, + 508, 1, 0, 0, 0, - 621, - 623, + 514, + 511, 1, 0, 0, 0, - 622, - 620, + 515, + 63, 1, 0, 0, 0, - 623, - 624, + 516, + 517, 5, - 6, - 0, - 0, - 624, - 121, - 1, - 0, - 0, + 88, 0, - 625, - 630, - 3, - 6, - 3, 0, - 626, - 630, - 3, - 14, - 7, + 517, + 518, + 5, + 2, 0, - 627, - 630, - 3, - 8, - 4, 0, - 628, - 630, + 518, + 523, 3, - 108, - 54, + 80, + 40, 0, - 629, - 625, - 1, + 519, + 520, + 5, + 88, 0, 0, + 520, + 521, + 5, + 2, 0, - 629, - 626, - 1, 0, + 521, + 523, + 5, + 155, 0, 0, - 629, - 627, + 522, + 516, 1, 0, 0, 0, - 629, - 628, + 522, + 519, 1, 0, 0, 0, - 630, - 123, + 523, + 65, 1, 0, 0, 0, - 631, - 632, + 524, + 525, 5, - 86, + 97, 0, 0, - 632, - 633, + 525, + 526, 5, 2, 0, 0, - 633, - 634, + 526, + 527, 3, - 72, - 36, + 82, + 41, 0, - 634, - 125, + 527, + 67, 1, 0, 0, 0, - 635, - 636, + 528, + 529, 5, - 97, + 98, 0, 0, - 636, - 637, + 529, + 530, 5, 2, 0, 0, - 637, - 638, + 530, + 531, 5, 5, 0, 0, - 638, - 643, + 531, + 532, 3, - 128, - 64, + 70, + 35, 0, - 639, - 640, + 532, + 533, 5, - 1, - 0, + 6, 0, - 640, - 642, - 3, - 128, - 64, 0, - 641, - 639, + 533, + 69, 1, 0, 0, 0, - 642, - 645, - 1, - 0, - 0, + 534, + 535, + 5, + 99, 0, - 643, - 641, - 1, 0, + 535, + 536, + 5, + 2, 0, 0, - 643, - 644, - 1, + 536, + 553, + 5, + 158, 0, 0, + 537, + 538, + 5, + 100, 0, - 644, - 646, - 1, 0, + 538, + 539, + 5, + 2, 0, 0, - 645, - 643, - 1, + 539, + 553, + 5, + 155, 0, 0, - 0, - 646, - 647, + 540, + 541, 5, - 6, - 0, - 0, - 647, - 127, - 1, - 0, + 100, 0, 0, - 648, - 652, - 3, - 26, - 13, + 541, + 542, + 5, + 2, 0, - 649, - 652, - 3, - 62, - 31, 0, - 650, - 652, - 3, - 130, - 65, + 542, + 553, + 5, + 154, 0, - 651, - 648, - 1, 0, + 543, + 544, + 5, + 100, 0, 0, - 651, - 649, - 1, + 544, + 545, + 5, + 2, 0, 0, + 545, + 553, + 5, + 157, 0, - 651, - 650, - 1, 0, + 546, + 547, + 5, + 100, 0, 0, - 652, - 129, - 1, + 547, + 548, + 5, + 2, 0, 0, + 548, + 553, + 3, + 80, + 40, 0, - 653, - 654, + 549, + 550, 5, - 98, + 99, 0, 0, - 654, - 655, + 550, + 551, 5, 2, 0, 0, - 655, - 656, - 5, - 5, - 0, - 0, - 656, - 661, + 551, + 553, 3, - 132, - 66, + 236, + 118, 0, - 657, - 658, - 5, + 552, + 534, 1, 0, 0, - 658, - 660, - 3, - 132, - 66, 0, - 659, - 657, + 552, + 537, 1, 0, 0, 0, - 660, - 663, + 552, + 540, 1, 0, 0, 0, - 661, - 659, + 552, + 543, 1, 0, 0, 0, - 661, - 662, + 552, + 546, 1, 0, 0, 0, - 662, - 664, + 552, + 549, 1, 0, 0, 0, - 663, - 661, + 553, + 71, 1, 0, 0, 0, - 664, - 665, + 554, + 555, 5, - 6, - 0, + 75, 0, - 665, - 131, - 1, 0, + 555, + 556, + 5, + 2, 0, 0, - 666, - 672, - 3, - 134, - 67, + 556, + 561, + 5, + 158, 0, - 667, - 672, - 3, - 136, - 68, 0, - 668, - 672, - 3, - 138, - 69, + 557, + 558, + 5, + 75, 0, - 669, - 672, - 3, - 140, - 70, 0, - 670, - 672, - 3, - 142, - 71, + 558, + 559, + 5, + 2, 0, - 671, - 666, - 1, 0, + 559, + 561, + 5, + 160, 0, 0, - 671, - 667, + 560, + 554, 1, 0, 0, 0, - 671, - 668, + 560, + 557, 1, 0, 0, 0, - 671, - 669, + 561, + 73, 1, 0, 0, 0, - 671, - 670, - 1, - 0, + 562, + 563, + 5, + 76, 0, 0, - 672, - 133, - 1, + 563, + 564, + 5, + 2, 0, 0, + 564, + 569, + 3, + 80, + 40, 0, - 673, - 674, + 565, + 566, 5, - 99, + 76, 0, 0, - 674, - 675, + 566, + 567, 5, 2, 0, 0, - 675, - 676, - 3, - 194, - 97, + 567, + 569, + 5, + 155, 0, - 676, - 135, + 0, + 568, + 562, 1, 0, 0, 0, - 677, - 678, - 5, - 100, + 568, + 565, + 1, 0, 0, - 678, - 679, - 5, - 2, 0, - 0, - 679, - 680, - 3, - 194, - 97, - 0, - 680, - 137, + 569, + 75, 1, 0, 0, 0, - 681, - 682, + 570, + 571, 5, - 101, + 77, 0, 0, - 682, - 683, + 571, + 572, 5, 2, 0, 0, - 683, - 684, + 572, + 577, 5, - 3, - 0, + 158, 0, - 684, - 689, - 3, - 194, - 97, 0, - 685, - 686, + 573, + 574, 5, - 1, - 0, - 0, - 686, - 688, - 3, - 194, - 97, - 0, - 687, - 685, - 1, - 0, - 0, - 0, - 688, - 691, - 1, + 77, 0, 0, + 574, + 575, + 5, + 2, 0, - 689, - 687, - 1, 0, + 575, + 577, + 5, + 160, 0, 0, - 689, - 690, + 576, + 570, 1, 0, 0, 0, - 690, - 692, + 576, + 573, 1, 0, 0, 0, - 691, - 689, + 577, + 77, 1, 0, 0, 0, - 692, - 693, + 578, + 579, 5, - 4, + 78, 0, 0, - 693, - 139, - 1, + 579, + 580, + 5, + 2, 0, 0, + 580, + 585, + 3, + 80, + 40, 0, - 694, - 695, + 581, + 582, 5, - 102, + 78, 0, 0, - 695, - 696, + 582, + 583, 5, 2, 0, 0, - 696, - 697, + 583, + 585, 5, - 144, + 155, 0, 0, - 697, - 141, + 584, + 578, 1, 0, 0, 0, - 698, - 699, - 5, - 103, + 584, + 581, + 1, 0, 0, - 699, - 700, - 5, - 2, 0, + 585, + 79, + 1, 0, - 700, - 701, + 0, + 0, + 586, + 587, 5, - 142, + 156, 0, 0, - 701, - 143, + 587, + 81, 1, 0, 0, 0, - 702, - 703, + 588, + 589, 5, - 104, - 0, - 0, - 703, - 704, 5, - 2, 0, 0, - 704, - 705, + 589, + 594, + 3, + 84, + 42, + 0, + 590, + 591, 5, - 144, + 1, 0, 0, - 705, - 145, + 591, + 593, + 3, + 84, + 42, + 0, + 592, + 590, 1, 0, 0, 0, - 706, - 707, - 5, - 105, + 593, + 596, + 1, 0, 0, - 707, - 708, - 5, - 2, 0, + 594, + 592, + 1, 0, - 708, - 709, - 5, - 142, 0, 0, - 709, - 147, + 594, + 595, 1, 0, 0, 0, - 710, - 711, - 5, - 106, + 595, + 597, + 1, 0, 0, - 711, - 712, - 5, - 2, 0, + 596, + 594, + 1, 0, - 712, - 713, + 0, + 0, + 597, + 598, 5, - 145, + 6, 0, 0, - 713, - 149, + 598, + 602, 1, 0, 0, 0, - 714, - 715, + 599, + 600, 5, - 107, - 0, - 0, - 715, - 716, 5, - 2, 0, 0, - 716, - 717, + 600, + 602, 5, - 142, + 6, 0, 0, - 717, - 151, + 601, + 588, 1, 0, 0, 0, - 718, - 719, - 5, - 108, - 0, + 601, + 599, + 1, 0, - 719, - 720, - 5, - 2, 0, 0, - 720, - 721, - 3, - 194, - 97, - 0, - 721, - 153, + 602, + 83, 1, 0, 0, 0, - 722, - 723, + 603, + 604, 5, - 115, + 153, 0, 0, - 723, - 724, + 604, + 605, 5, 2, 0, 0, - 724, - 733, + 605, + 620, 5, - 3, + 155, 0, 0, - 725, - 730, - 3, - 156, - 78, + 606, + 607, + 5, + 153, 0, - 726, - 727, + 0, + 607, + 608, 5, - 1, + 2, 0, 0, - 727, - 729, - 3, - 156, - 78, + 608, + 620, + 5, + 154, 0, - 728, - 726, - 1, 0, + 609, + 610, + 5, + 153, 0, 0, - 729, - 732, - 1, + 610, + 611, + 5, + 2, 0, 0, + 611, + 620, + 5, + 157, 0, - 730, - 728, - 1, 0, + 612, + 613, + 5, + 153, 0, 0, - 730, - 731, - 1, + 613, + 614, + 5, + 2, 0, 0, + 614, + 620, + 3, + 80, + 40, 0, - 731, - 734, + 615, + 616, + 3, + 236, + 118, + 0, + 616, + 617, + 5, + 2, + 0, + 0, + 617, + 618, + 3, + 88, + 44, + 0, + 618, + 620, 1, 0, 0, 0, - 732, - 730, + 619, + 603, 1, 0, 0, 0, - 733, - 725, + 619, + 606, 1, 0, 0, 0, - 733, - 734, + 619, + 609, 1, 0, 0, 0, - 734, - 735, + 619, + 612, 1, 0, 0, 0, - 735, - 736, - 5, - 4, + 619, + 615, + 1, 0, 0, - 736, - 155, + 0, + 620, + 85, 1, 0, 0, 0, - 737, - 738, - 5, + 621, + 622, 5, + 3, 0, 0, - 738, - 743, + 622, + 627, 3, - 158, - 79, + 88, + 44, 0, - 739, - 740, + 623, + 624, 5, 1, 0, 0, - 740, - 742, + 624, + 626, 3, - 158, - 79, + 88, + 44, 0, - 741, - 739, + 625, + 623, 1, 0, 0, 0, - 742, - 745, + 626, + 629, 1, 0, 0, 0, - 743, - 741, + 627, + 625, 1, 0, 0, 0, - 743, - 744, + 627, + 628, 1, 0, 0, 0, - 744, - 746, + 628, + 630, 1, 0, 0, 0, - 745, - 743, + 629, + 627, 1, 0, 0, 0, - 746, - 747, + 630, + 631, 5, - 6, + 4, 0, 0, - 747, - 157, + 631, + 635, 1, 0, 0, 0, - 748, - 756, - 3, - 160, - 80, - 0, - 749, - 756, - 3, - 162, - 81, - 0, - 750, - 756, - 3, - 164, - 82, - 0, - 751, - 756, - 3, - 166, - 83, - 0, - 752, - 756, + 632, + 633, + 5, 3, - 168, - 84, 0, - 753, - 756, - 3, - 170, - 85, 0, - 754, - 756, - 3, - 8, + 633, + 635, + 5, 4, 0, - 755, - 748, + 0, + 634, + 621, 1, 0, 0, 0, - 755, - 749, + 634, + 632, 1, 0, 0, 0, - 755, - 750, + 635, + 87, 1, 0, 0, 0, - 755, - 751, - 1, + 636, + 640, + 3, + 86, + 43, 0, + 637, + 640, + 3, + 82, + 41, 0, + 638, + 640, + 3, + 90, + 45, 0, - 755, - 752, + 639, + 636, 1, 0, 0, 0, - 755, - 753, + 639, + 637, 1, 0, 0, 0, - 755, - 754, + 639, + 638, 1, 0, 0, 0, - 756, - 159, + 640, + 89, 1, 0, 0, 0, - 757, - 758, + 641, + 647, 5, - 116, + 161, 0, 0, - 758, - 759, + 642, + 647, 5, - 2, - 0, + 160, 0, - 759, - 760, - 5, - 3, 0, + 643, + 647, + 7, + 1, 0, - 760, - 765, - 3, - 184, - 92, 0, - 761, - 762, + 644, + 647, 5, - 1, + 9, 0, 0, - 762, - 764, + 645, + 647, 3, - 184, - 92, + 236, + 118, 0, - 763, - 761, + 646, + 641, 1, 0, 0, 0, - 764, - 767, + 646, + 642, 1, 0, 0, 0, - 765, - 763, + 646, + 643, 1, 0, 0, 0, - 765, - 766, + 646, + 644, 1, 0, 0, 0, - 766, - 768, + 646, + 645, 1, 0, 0, 0, - 767, - 765, + 647, + 91, 1, 0, 0, 0, - 768, - 769, + 648, + 649, 5, - 4, + 134, 0, 0, - 769, - 161, + 649, + 650, + 5, + 2, + 0, + 0, + 650, + 651, + 3, + 94, + 47, + 0, + 651, + 93, 1, 0, 0, 0, - 770, - 771, + 652, + 653, + 5, 5, - 117, 0, 0, - 771, - 772, + 653, + 666, 5, - 2, + 6, 0, 0, - 772, - 773, + 654, + 655, + 5, 5, - 144, 0, 0, - 773, - 163, + 655, + 660, + 3, + 96, + 48, + 0, + 656, + 657, + 5, 1, 0, 0, + 657, + 659, + 3, + 96, + 48, 0, - 774, - 775, - 5, - 118, + 658, + 656, + 1, 0, 0, - 775, - 776, - 5, - 2, 0, + 659, + 662, + 1, 0, - 776, - 777, - 5, - 144, 0, 0, - 777, - 165, + 660, + 658, 1, 0, 0, 0, - 778, - 779, - 5, - 119, + 660, + 661, + 1, 0, 0, - 779, - 780, - 5, - 2, 0, + 661, + 663, + 1, 0, - 780, - 781, - 7, - 3, 0, 0, - 781, - 167, + 662, + 660, 1, 0, 0, 0, - 782, - 783, + 663, + 664, 5, - 120, - 0, + 6, 0, - 783, - 784, - 5, - 2, 0, + 664, + 666, + 1, 0, - 784, - 785, - 5, - 144, 0, 0, - 785, - 169, + 665, + 652, 1, 0, 0, 0, - 786, - 787, - 5, - 121, + 665, + 654, + 1, 0, 0, - 787, - 788, - 5, - 2, 0, + 666, + 95, + 1, 0, - 788, - 789, - 7, - 4, 0, 0, - 789, - 171, + 667, + 668, + 3, + 100, + 50, + 0, + 668, + 97, 1, 0, 0, 0, - 790, - 791, + 669, + 670, 5, - 124, - 0, - 0, - 791, - 792, 5, - 2, 0, 0, - 792, - 801, + 670, + 683, 5, - 3, + 6, 0, 0, - 793, - 798, + 671, + 672, + 5, + 5, + 0, + 0, + 672, + 677, 3, - 174, - 87, + 100, + 50, 0, - 794, - 795, + 673, + 674, 5, 1, 0, 0, - 795, - 797, + 674, + 676, 3, - 174, - 87, + 100, + 50, 0, - 796, - 794, + 675, + 673, 1, 0, 0, 0, - 797, - 800, + 676, + 679, 1, 0, 0, 0, - 798, - 796, + 677, + 675, 1, 0, 0, 0, - 798, - 799, + 677, + 678, 1, 0, 0, 0, - 799, - 802, + 678, + 680, 1, 0, 0, 0, - 800, - 798, + 679, + 677, 1, 0, 0, 0, - 801, - 793, + 680, + 681, + 5, + 6, + 0, + 0, + 681, + 683, 1, 0, 0, 0, - 801, - 802, + 682, + 669, 1, 0, 0, 0, - 802, - 803, + 682, + 671, 1, 0, 0, 0, - 803, - 804, + 683, + 99, + 1, + 0, + 0, + 0, + 684, + 685, 5, - 4, + 153, 0, 0, - 804, - 173, - 1, + 685, + 686, + 5, + 2, 0, 0, + 686, + 700, + 5, + 155, + 0, 0, - 805, - 806, + 687, + 688, 5, + 153, + 0, + 0, + 688, + 689, 5, + 2, 0, 0, - 806, - 811, - 3, - 176, - 88, + 689, + 700, + 5, + 154, 0, - 807, - 808, + 0, + 690, + 691, 5, - 1, + 153, 0, 0, - 808, - 810, + 691, + 692, + 5, + 2, + 0, + 0, + 692, + 700, 3, - 176, - 88, + 80, + 40, 0, - 809, - 807, - 1, + 693, + 694, + 5, + 153, 0, 0, + 694, + 695, + 5, + 2, 0, - 810, - 813, - 1, 0, + 695, + 700, + 5, + 157, 0, 0, - 811, - 809, - 1, + 696, + 697, + 5, + 159, 0, 0, + 697, + 698, + 5, + 2, 0, - 811, - 812, + 0, + 698, + 700, + 3, + 102, + 51, + 0, + 699, + 684, 1, 0, 0, 0, - 812, - 814, + 699, + 687, 1, 0, 0, 0, - 813, - 811, + 699, + 690, 1, 0, 0, 0, - 814, - 815, - 5, - 6, + 699, + 693, + 1, 0, 0, - 815, - 175, + 0, + 699, + 696, 1, 0, 0, 0, - 816, - 821, - 3, - 160, - 80, + 700, + 101, + 1, 0, - 817, - 821, + 0, + 0, + 701, + 705, 3, - 32, - 16, + 98, + 49, 0, - 818, - 821, + 702, + 705, 3, - 24, - 12, + 104, + 52, 0, - 819, - 821, + 703, + 705, 3, - 8, - 4, + 106, + 53, 0, - 820, - 816, + 704, + 701, 1, 0, 0, 0, - 820, - 817, + 704, + 702, 1, 0, 0, 0, - 820, - 818, + 704, + 703, 1, 0, 0, 0, - 820, - 819, + 705, + 103, 1, 0, 0, 0, - 821, - 177, - 1, - 0, + 706, + 707, + 5, + 3, 0, 0, - 822, - 823, - 7, + 707, + 720, 5, + 4, 0, 0, - 823, - 179, - 1, - 0, - 0, + 708, + 709, + 5, + 3, 0, - 824, - 825, - 7, - 6, 0, + 709, + 714, + 3, + 102, + 51, 0, - 825, - 181, + 710, + 711, + 5, 1, 0, 0, + 711, + 713, + 3, + 102, + 51, 0, - 826, - 827, - 7, - 7, - 0, - 0, - 827, - 183, + 712, + 710, 1, 0, 0, 0, - 828, - 831, - 3, - 182, - 91, + 713, + 716, + 1, 0, - 829, - 831, - 3, - 194, - 97, 0, - 830, - 828, + 0, + 714, + 712, 1, 0, 0, 0, - 830, - 829, + 714, + 715, 1, 0, 0, 0, - 831, - 185, + 715, + 717, 1, 0, 0, 0, - 832, - 833, - 5, - 5, + 716, + 714, + 1, 0, 0, - 833, - 838, - 3, - 188, - 94, 0, - 834, - 835, + 717, + 718, 5, - 1, - 0, + 4, 0, - 835, - 837, - 3, - 188, - 94, 0, - 836, - 834, + 718, + 720, 1, 0, 0, 0, - 837, - 840, + 719, + 706, 1, 0, 0, 0, - 838, - 836, + 719, + 708, 1, 0, 0, 0, - 838, - 839, + 720, + 105, 1, 0, 0, 0, - 839, - 841, - 1, + 721, + 728, + 5, + 161, 0, 0, + 722, + 728, + 5, + 160, + 0, 0, - 840, - 838, + 723, + 728, + 7, 1, 0, 0, + 724, + 728, + 5, + 9, + 0, 0, - 841, - 842, + 725, + 728, 5, - 6, + 158, 0, 0, - 842, - 846, - 1, + 726, + 728, + 3, + 236, + 118, 0, + 727, + 721, + 1, 0, 0, - 843, - 844, - 5, - 5, 0, + 727, + 722, + 1, 0, - 844, - 846, - 5, - 6, 0, 0, - 845, - 832, + 727, + 723, 1, 0, 0, 0, - 845, - 843, + 727, + 724, 1, 0, 0, 0, - 846, - 187, + 727, + 725, 1, 0, 0, 0, - 847, - 848, - 3, - 194, - 97, - 0, - 848, - 849, - 5, - 2, + 727, + 726, + 1, 0, 0, - 849, - 850, - 3, - 192, - 96, 0, - 850, - 189, + 728, + 107, 1, 0, 0, 0, - 851, - 852, + 729, + 730, 5, - 3, - 0, + 136, 0, - 852, - 857, - 3, - 192, - 96, 0, - 853, - 854, + 730, + 731, 5, - 1, + 2, 0, 0, - 854, - 856, + 731, + 736, 3, - 192, - 96, + 112, + 56, 0, - 855, - 853, - 1, + 732, + 733, + 5, + 136, 0, 0, + 733, + 734, + 5, + 2, 0, - 856, - 859, - 1, 0, + 734, + 736, + 5, + 158, 0, 0, - 857, - 855, + 735, + 729, 1, 0, 0, 0, - 857, - 858, + 735, + 732, 1, 0, 0, 0, - 858, - 860, + 736, + 109, 1, 0, 0, 0, - 859, - 857, - 1, + 737, + 738, + 5, + 135, 0, 0, - 0, - 860, - 861, + 738, + 739, 5, - 4, + 2, 0, 0, - 861, - 865, + 739, + 740, + 3, + 116, + 58, + 0, + 740, + 111, 1, 0, 0, 0, - 862, - 863, + 741, + 742, + 5, 5, - 3, 0, 0, - 863, - 865, + 742, + 755, 5, - 4, + 6, 0, 0, - 864, - 851, + 743, + 744, + 5, + 5, + 0, + 0, + 744, + 749, + 3, + 114, + 57, + 0, + 745, + 746, + 5, 1, 0, 0, + 746, + 748, + 3, + 114, + 57, 0, - 864, - 862, + 747, + 745, 1, 0, 0, 0, - 865, - 191, + 748, + 751, 1, 0, 0, 0, - 866, - 876, - 5, - 145, + 749, + 747, + 1, 0, 0, - 867, - 876, - 5, - 144, 0, + 749, + 750, + 1, 0, - 868, - 876, - 5, - 7, 0, 0, - 869, - 876, + 750, + 752, + 1, + 0, + 0, + 0, + 751, + 749, + 1, + 0, + 0, + 0, + 752, + 753, 5, - 8, + 6, 0, 0, - 870, - 876, + 753, + 755, + 1, + 0, + 0, + 0, + 754, + 741, + 1, + 0, + 0, + 0, + 754, + 743, + 1, + 0, + 0, + 0, + 755, + 113, + 1, + 0, + 0, + 0, + 756, + 757, + 3, + 236, + 118, + 0, + 757, + 758, 5, - 9, + 2, 0, 0, - 871, - 876, + 758, + 759, 3, - 188, - 94, + 116, + 58, 0, - 872, - 876, + 759, + 115, + 1, + 0, + 0, + 0, + 760, + 764, 3, - 190, - 95, + 112, + 56, 0, - 873, - 876, + 761, + 764, 3, - 186, - 93, + 118, + 59, 0, - 874, - 876, + 762, + 764, 3, - 194, - 97, + 120, + 60, 0, - 875, - 866, + 763, + 760, 1, 0, 0, 0, - 875, - 867, + 763, + 761, 1, 0, 0, 0, - 875, - 868, + 763, + 762, 1, 0, 0, 0, - 875, - 869, + 764, + 117, 1, 0, 0, 0, - 875, - 870, - 1, + 765, + 766, + 5, + 3, 0, 0, + 766, + 779, + 5, + 4, 0, - 875, - 871, + 0, + 767, + 768, + 5, + 3, + 0, + 0, + 768, + 773, + 3, + 116, + 58, + 0, + 769, + 770, + 5, 1, 0, 0, + 770, + 772, + 3, + 116, + 58, 0, - 875, - 872, + 771, + 769, 1, 0, 0, 0, - 875, - 873, + 772, + 775, 1, 0, 0, 0, - 875, - 874, + 773, + 771, 1, 0, 0, 0, - 876, - 193, + 773, + 774, 1, 0, 0, 0, - 877, - 878, - 7, - 8, + 774, + 776, + 1, 0, 0, - 878, - 195, + 0, + 775, + 773, 1, 0, 0, 0, - 52, - 205, - 215, - 269, - 279, - 296, - 317, - 327, - 333, - 353, - 365, - 421, - 428, - 443, - 453, - 460, - 466, - 473, - 489, - 500, - 510, - 515, - 521, - 525, - 536, - 541, - 559, - 572, - 581, - 591, - 598, - 620, - 629, - 643, - 651, - 661, - 671, - 689, - 730, - 733, - 743, - 755, + 776, + 777, + 5, + 4, + 0, + 0, + 777, + 779, + 1, + 0, + 0, + 0, + 778, 765, + 1, + 0, + 0, + 0, + 778, + 767, + 1, + 0, + 0, + 0, + 779, + 119, + 1, + 0, + 0, + 0, + 780, + 787, + 5, + 161, + 0, + 0, + 781, + 787, + 5, + 160, + 0, + 0, + 782, + 787, + 7, + 1, + 0, + 0, + 783, + 787, + 5, + 9, + 0, + 0, + 784, + 787, + 5, + 158, + 0, + 0, + 785, + 787, + 3, + 236, + 118, + 0, + 786, + 780, + 1, + 0, + 0, + 0, + 786, + 781, + 1, + 0, + 0, + 0, + 786, + 782, + 1, + 0, + 0, + 0, + 786, + 783, + 1, + 0, + 0, + 0, + 786, + 784, + 1, + 0, + 0, + 0, + 786, + 785, + 1, + 0, + 0, + 0, + 787, + 121, + 1, + 0, + 0, + 0, + 788, + 789, + 5, + 101, + 0, + 0, + 789, + 790, + 5, + 2, + 0, + 0, + 790, + 791, + 3, + 82, + 41, + 0, + 791, + 123, + 1, + 0, + 0, + 0, + 792, + 793, + 7, + 2, + 0, + 0, + 793, + 125, + 1, + 0, + 0, + 0, + 794, + 795, + 5, + 24, + 0, + 0, + 795, + 796, + 5, + 2, + 0, + 0, + 796, + 797, + 5, + 3, + 0, + 0, + 797, + 802, + 3, + 128, + 64, + 0, 798, + 799, + 5, + 1, + 0, + 0, + 799, 801, - 811, - 820, - 830, - 838, - 845, - 857, - 864, - 875, - ] - - -class ASLParser(Parser): - grammarFileName = "ASLParser.g4" - - atn = ATNDeserializer().deserialize(serializedATN()) - - decisionsToDFA = [DFA(ds, i) for i, ds in enumerate(atn.decisionToState)] - - sharedContextCache = PredictionContextCache() - - literalNames = [ - "", - "','", - "':'", - "'['", - "']'", - "'{'", - "'}'", - "'true'", - "'false'", - "'null'", - "'\"Comment\"'", - "'\"States\"'", - "'\"StartAt\"'", - "'\"NextState\"'", - "'\"Version\"'", - "'\"Type\"'", - "'\"Task\"'", - "'\"Choice\"'", - "'\"Fail\"'", - "'\"Succeed\"'", - "'\"Pass\"'", - "'\"Wait\"'", - "'\"Parallel\"'", - "'\"Map\"'", - "'\"Choices\"'", - "'\"Variable\"'", - "'\"Default\"'", - "'\"Branches\"'", - "'\"And\"'", + 3, + 128, + 64, + 0, + 800, + 798, + 1, + 0, + 0, + 0, + 801, + 804, + 1, + 0, + 0, + 0, + 802, + 800, + 1, + 0, + 0, + 0, + 802, + 803, + 1, + 0, + 0, + 0, + 803, + 805, + 1, + 0, + 0, + 0, + 804, + 802, + 1, + 0, + 0, + 0, + 805, + 806, + 5, + 4, + 0, + 0, + 806, + 127, + 1, + 0, + 0, + 0, + 807, + 808, + 5, + 5, + 0, + 0, + 808, + 811, + 3, + 130, + 65, + 0, + 809, + 810, + 5, + 1, + 0, + 0, + 810, + 812, + 3, + 130, + 65, + 0, + 811, + 809, + 1, + 0, + 0, + 0, + 812, + 813, + 1, + 0, + 0, + 0, + 813, + 811, + 1, + 0, + 0, + 0, + 813, + 814, + 1, + 0, + 0, + 0, + 814, + 815, + 1, + 0, + 0, + 0, + 815, + 816, + 5, + 6, + 0, + 0, + 816, + 829, + 1, + 0, + 0, + 0, + 817, + 818, + 5, + 5, + 0, + 0, + 818, + 823, + 3, + 132, + 66, + 0, + 819, + 820, + 5, + 1, + 0, + 0, + 820, + 822, + 3, + 132, + 66, + 0, + 821, + 819, + 1, + 0, + 0, + 0, + 822, + 825, + 1, + 0, + 0, + 0, + 823, + 821, + 1, + 0, + 0, + 0, + 823, + 824, + 1, + 0, + 0, + 0, + 824, + 826, + 1, + 0, + 0, + 0, + 825, + 823, + 1, + 0, + 0, + 0, + 826, + 827, + 5, + 6, + 0, + 0, + 827, + 829, + 1, + 0, + 0, + 0, + 828, + 807, + 1, + 0, + 0, + 0, + 828, + 817, + 1, + 0, + 0, + 0, + 829, + 129, + 1, + 0, + 0, + 0, + 830, + 836, + 3, + 136, + 68, + 0, + 831, + 836, + 3, + 138, + 69, + 0, + 832, + 836, + 3, + 26, + 13, + 0, + 833, + 836, + 3, + 92, + 46, + 0, + 834, + 836, + 3, + 8, + 4, + 0, + 835, + 830, + 1, + 0, + 0, + 0, + 835, + 831, + 1, + 0, + 0, + 0, + 835, + 832, + 1, + 0, + 0, + 0, + 835, + 833, + 1, + 0, + 0, + 0, + 835, + 834, + 1, + 0, + 0, + 0, + 836, + 131, + 1, + 0, + 0, + 0, + 837, + 842, + 3, + 134, + 67, + 0, + 838, + 842, + 3, + 26, + 13, + 0, + 839, + 842, + 3, + 92, + 46, + 0, + 840, + 842, + 3, + 8, + 4, + 0, + 841, + 837, + 1, + 0, + 0, + 0, + 841, + 838, + 1, + 0, + 0, + 0, + 841, + 839, + 1, + 0, + 0, + 0, + 841, + 840, + 1, + 0, + 0, + 0, + 842, + 133, + 1, + 0, + 0, + 0, + 843, + 844, + 3, + 222, + 111, + 0, + 844, + 857, + 5, + 2, + 0, + 0, + 845, + 858, + 3, + 128, + 64, + 0, + 846, + 847, + 5, + 3, + 0, + 0, + 847, + 852, + 3, + 128, + 64, + 0, + 848, + 849, + 5, + 1, + 0, + 0, + 849, + 851, + 3, + 128, + 64, + 0, + 850, + 848, + 1, + 0, + 0, + 0, + 851, + 854, + 1, + 0, + 0, + 0, + 852, + 850, + 1, + 0, + 0, + 0, + 852, + 853, + 1, + 0, + 0, + 0, + 853, + 855, + 1, + 0, + 0, + 0, + 854, + 852, + 1, + 0, + 0, + 0, + 855, + 856, + 5, + 4, + 0, + 0, + 856, + 858, + 1, + 0, + 0, + 0, + 857, + 845, + 1, + 0, + 0, + 0, + 857, + 846, + 1, + 0, + 0, + 0, + 858, + 135, + 1, + 0, + 0, + 0, + 859, + 860, + 5, + 26, + 0, + 0, + 860, + 861, + 5, + 2, + 0, + 0, + 861, + 869, + 5, + 155, + 0, + 0, + 862, + 863, + 5, + 26, + 0, + 0, + 863, + 864, + 5, + 2, + 0, + 0, + 864, + 869, + 3, + 80, + 40, + 0, + 865, + 866, + 5, + 26, + 0, + 0, + 866, + 867, + 5, + 2, + 0, + 0, + 867, + 869, + 5, + 154, + 0, + 0, + 868, + 859, + 1, + 0, + 0, + 0, + 868, + 862, + 1, + 0, + 0, + 0, + 868, + 865, + 1, + 0, + 0, + 0, + 869, + 137, + 1, + 0, + 0, + 0, + 870, + 871, + 5, + 25, + 0, + 0, + 871, + 872, + 5, + 2, + 0, + 0, + 872, + 885, + 7, + 1, + 0, + 0, + 873, + 874, + 5, + 25, + 0, + 0, + 874, + 875, + 5, + 2, + 0, + 0, + 875, + 885, + 5, + 158, + 0, + 0, + 876, + 877, + 3, + 220, + 110, + 0, + 877, + 878, + 5, + 2, + 0, + 0, + 878, + 879, + 3, + 80, + 40, + 0, + 879, + 885, + 1, + 0, + 0, + 0, + 880, + 881, + 3, + 220, + 110, + 0, + 881, + 882, + 5, + 2, + 0, + 0, + 882, + 883, + 3, + 234, + 117, + 0, + 883, + 885, + 1, + 0, + 0, + 0, + 884, + 870, + 1, + 0, + 0, + 0, + 884, + 873, + 1, + 0, + 0, + 0, + 884, + 876, + 1, + 0, + 0, + 0, + 884, + 880, + 1, + 0, + 0, + 0, + 885, + 139, + 1, + 0, + 0, + 0, + 886, + 887, + 5, + 28, + 0, + 0, + 887, + 888, + 5, + 2, + 0, + 0, + 888, + 889, + 5, + 3, + 0, + 0, + 889, + 894, + 3, + 2, + 1, + 0, + 890, + 891, + 5, + 1, + 0, + 0, + 891, + 893, + 3, + 2, + 1, + 0, + 892, + 890, + 1, + 0, + 0, + 0, + 893, + 896, + 1, + 0, + 0, + 0, + 894, + 892, + 1, + 0, + 0, + 0, + 894, + 895, + 1, + 0, + 0, + 0, + 895, + 897, + 1, + 0, + 0, + 0, + 896, + 894, + 1, + 0, + 0, + 0, + 897, + 898, + 5, + 4, + 0, + 0, + 898, + 141, + 1, + 0, + 0, + 0, + 899, + 900, + 5, + 85, + 0, + 0, + 900, + 901, + 5, + 2, + 0, + 0, + 901, + 902, + 5, + 5, + 0, + 0, + 902, + 907, + 3, + 144, + 72, + 0, + 903, + 904, + 5, + 1, + 0, + 0, + 904, + 906, + 3, + 144, + 72, + 0, + 905, + 903, + 1, + 0, + 0, + 0, + 906, + 909, + 1, + 0, + 0, + 0, + 907, + 905, + 1, + 0, + 0, + 0, + 907, + 908, + 1, + 0, + 0, + 0, + 908, + 910, + 1, + 0, + 0, + 0, + 909, + 907, + 1, + 0, + 0, + 0, + 910, + 911, + 5, + 6, + 0, + 0, + 911, + 143, + 1, + 0, + 0, + 0, + 912, + 917, + 3, + 146, + 73, + 0, + 913, + 917, + 3, + 6, + 3, + 0, + 914, + 917, + 3, + 16, + 8, + 0, + 915, + 917, + 3, + 8, + 4, + 0, + 916, + 912, + 1, + 0, + 0, + 0, + 916, + 913, + 1, + 0, + 0, + 0, + 916, + 914, + 1, + 0, + 0, + 0, + 916, + 915, + 1, + 0, + 0, + 0, + 917, + 145, + 1, + 0, + 0, + 0, + 918, + 919, + 5, + 79, + 0, + 0, + 919, + 920, + 5, + 2, + 0, + 0, + 920, + 921, + 5, + 5, + 0, + 0, + 921, + 926, + 3, + 148, + 74, + 0, + 922, + 923, + 5, + 1, + 0, + 0, + 923, + 925, + 3, + 148, + 74, + 0, + 924, + 922, + 1, + 0, + 0, + 0, + 925, + 928, + 1, + 0, + 0, + 0, + 926, + 924, + 1, + 0, + 0, + 0, + 926, + 927, + 1, + 0, + 0, + 0, + 927, + 929, + 1, + 0, + 0, + 0, + 928, + 926, + 1, + 0, + 0, + 0, + 929, + 930, + 5, + 6, + 0, + 0, + 930, + 147, + 1, + 0, + 0, + 0, + 931, + 934, + 3, + 150, + 75, + 0, + 932, + 934, + 3, + 154, + 77, + 0, + 933, + 931, + 1, + 0, + 0, + 0, + 933, + 932, + 1, + 0, + 0, + 0, + 934, + 149, + 1, + 0, + 0, + 0, + 935, + 936, + 5, + 80, + 0, + 0, + 936, + 937, + 5, + 2, + 0, + 0, + 937, + 938, + 3, + 152, + 76, + 0, + 938, + 151, + 1, + 0, + 0, + 0, + 939, + 940, + 7, + 3, + 0, + 0, + 940, + 153, + 1, + 0, + 0, + 0, + 941, + 942, + 5, + 83, + 0, + 0, + 942, + 943, + 5, + 2, + 0, + 0, + 943, + 944, + 3, + 156, + 78, + 0, + 944, + 155, + 1, + 0, + 0, + 0, + 945, + 946, + 5, + 84, + 0, + 0, + 946, + 157, + 1, + 0, + 0, + 0, + 947, + 948, + 5, + 86, + 0, + 0, + 948, + 949, + 5, + 2, + 0, + 0, + 949, + 950, + 5, + 5, + 0, + 0, + 950, + 955, + 3, + 160, + 80, + 0, + 951, + 952, + 5, + 1, + 0, + 0, + 952, + 954, + 3, + 160, + 80, + 0, + 953, + 951, + 1, + 0, + 0, + 0, + 954, + 957, + 1, + 0, + 0, + 0, + 955, + 953, + 1, + 0, + 0, + 0, + 955, + 956, + 1, + 0, + 0, + 0, + 956, + 958, + 1, + 0, + 0, + 0, + 957, + 955, + 1, + 0, + 0, + 0, + 958, + 959, + 5, + 6, + 0, + 0, + 959, + 159, + 1, + 0, + 0, + 0, + 960, + 965, + 3, + 6, + 3, + 0, + 961, + 965, + 3, + 16, + 8, + 0, + 962, + 965, + 3, + 8, + 4, + 0, + 963, + 965, + 3, + 146, + 73, + 0, + 964, + 960, + 1, + 0, + 0, + 0, + 964, + 961, + 1, + 0, + 0, + 0, + 964, + 962, + 1, + 0, + 0, + 0, + 964, + 963, + 1, + 0, + 0, + 0, + 965, + 161, + 1, + 0, + 0, + 0, + 966, + 967, + 5, + 87, + 0, + 0, + 967, + 968, + 5, + 2, + 0, + 0, + 968, + 969, + 3, + 82, + 41, + 0, + 969, + 163, + 1, + 0, + 0, + 0, + 970, + 971, + 5, + 102, + 0, + 0, + 971, + 972, + 5, + 2, + 0, + 0, + 972, + 973, + 5, + 5, + 0, + 0, + 973, + 978, + 3, + 166, + 83, + 0, + 974, + 975, + 5, + 1, + 0, + 0, + 975, + 977, + 3, + 166, + 83, + 0, + 976, + 974, + 1, + 0, + 0, + 0, + 977, + 980, + 1, + 0, + 0, + 0, + 978, + 976, + 1, + 0, + 0, + 0, + 978, + 979, + 1, + 0, + 0, + 0, + 979, + 981, + 1, + 0, + 0, + 0, + 980, + 978, + 1, + 0, + 0, + 0, + 981, + 982, + 5, + 6, + 0, + 0, + 982, + 165, + 1, + 0, + 0, + 0, + 983, + 988, + 3, + 28, + 14, + 0, + 984, + 988, + 3, + 168, + 84, + 0, + 985, + 988, + 3, + 66, + 33, + 0, + 986, + 988, + 3, + 108, + 54, + 0, + 987, + 983, + 1, + 0, + 0, + 0, + 987, + 984, + 1, + 0, + 0, + 0, + 987, + 985, + 1, + 0, + 0, + 0, + 987, + 986, + 1, + 0, + 0, + 0, + 988, + 167, + 1, + 0, + 0, + 0, + 989, + 990, + 5, + 103, + 0, + 0, + 990, + 991, + 5, + 2, + 0, + 0, + 991, + 992, + 5, + 5, + 0, + 0, + 992, + 997, + 3, + 170, + 85, + 0, + 993, + 994, + 5, + 1, + 0, + 0, + 994, + 996, + 3, + 170, + 85, + 0, + 995, + 993, + 1, + 0, + 0, + 0, + 996, + 999, + 1, + 0, + 0, + 0, + 997, + 995, + 1, + 0, + 0, + 0, + 997, + 998, + 1, + 0, + 0, + 0, + 998, + 1000, + 1, + 0, + 0, + 0, + 999, + 997, + 1, + 0, + 0, + 0, + 1000, + 1001, + 5, + 6, + 0, + 0, + 1001, + 169, + 1, + 0, + 0, + 0, + 1002, + 1008, + 3, + 172, + 86, + 0, + 1003, + 1008, + 3, + 174, + 87, + 0, + 1004, + 1008, + 3, + 176, + 88, + 0, + 1005, + 1008, + 3, + 178, + 89, + 0, + 1006, + 1008, + 3, + 180, + 90, + 0, + 1007, + 1002, + 1, + 0, + 0, + 0, + 1007, + 1003, + 1, + 0, + 0, + 0, + 1007, + 1004, + 1, + 0, + 0, + 0, + 1007, + 1005, + 1, + 0, + 0, + 0, + 1007, + 1006, + 1, + 0, + 0, + 0, + 1008, + 171, + 1, + 0, + 0, + 0, + 1009, + 1010, + 5, + 104, + 0, + 0, + 1010, + 1011, + 5, + 2, + 0, + 0, + 1011, + 1012, + 3, + 236, + 118, + 0, + 1012, + 173, + 1, + 0, + 0, + 0, + 1013, + 1014, + 5, + 105, + 0, + 0, + 1014, + 1015, + 5, + 2, + 0, + 0, + 1015, + 1016, + 3, + 236, + 118, + 0, + 1016, + 175, + 1, + 0, + 0, + 0, + 1017, + 1018, + 5, + 106, + 0, + 0, + 1018, + 1019, + 5, + 2, + 0, + 0, + 1019, + 1020, + 5, + 3, + 0, + 0, + 1020, + 1025, + 3, + 236, + 118, + 0, + 1021, + 1022, + 5, + 1, + 0, + 0, + 1022, + 1024, + 3, + 236, + 118, + 0, + 1023, + 1021, + 1, + 0, + 0, + 0, + 1024, + 1027, + 1, + 0, + 0, + 0, + 1025, + 1023, + 1, + 0, + 0, + 0, + 1025, + 1026, + 1, + 0, + 0, + 0, + 1026, + 1028, + 1, + 0, + 0, + 0, + 1027, + 1025, + 1, + 0, + 0, + 0, + 1028, + 1029, + 5, + 4, + 0, + 0, + 1029, + 177, + 1, + 0, + 0, + 0, + 1030, + 1031, + 5, + 107, + 0, + 0, + 1031, + 1032, + 5, + 2, + 0, + 0, + 1032, + 1037, + 5, + 158, + 0, + 0, + 1033, + 1034, + 5, + 107, + 0, + 0, + 1034, + 1035, + 5, + 2, + 0, + 0, + 1035, + 1037, + 5, + 160, + 0, + 0, + 1036, + 1030, + 1, + 0, + 0, + 0, + 1036, + 1033, + 1, + 0, + 0, + 0, + 1037, + 179, + 1, + 0, + 0, + 0, + 1038, + 1039, + 5, + 108, + 0, + 0, + 1039, + 1040, + 5, + 2, + 0, + 0, + 1040, + 1045, + 3, + 80, + 40, + 0, + 1041, + 1042, + 5, + 108, + 0, + 0, + 1042, + 1043, + 5, + 2, + 0, + 0, + 1043, + 1045, + 5, + 155, + 0, + 0, + 1044, + 1038, + 1, + 0, + 0, + 0, + 1044, + 1041, + 1, + 0, + 0, + 0, + 1045, + 181, + 1, + 0, + 0, + 0, + 1046, + 1047, + 5, + 109, + 0, + 0, + 1047, + 1048, + 5, + 2, + 0, + 0, + 1048, + 1053, + 5, + 158, + 0, + 0, + 1049, + 1050, + 5, + 109, + 0, + 0, + 1050, + 1051, + 5, + 2, + 0, + 0, + 1051, + 1053, + 5, + 160, + 0, + 0, + 1052, + 1046, + 1, + 0, + 0, + 0, + 1052, + 1049, + 1, + 0, + 0, + 0, + 1053, + 183, + 1, + 0, + 0, + 0, + 1054, + 1055, + 5, + 110, + 0, + 0, + 1055, + 1056, + 5, + 2, + 0, + 0, + 1056, + 1061, + 3, + 80, + 40, + 0, + 1057, + 1058, + 5, + 110, + 0, + 0, + 1058, + 1059, + 5, + 2, + 0, + 0, + 1059, + 1061, + 5, + 155, + 0, + 0, + 1060, + 1054, + 1, + 0, + 0, + 0, + 1060, + 1057, + 1, + 0, + 0, + 0, + 1061, + 185, + 1, + 0, + 0, + 0, + 1062, + 1063, + 5, + 111, + 0, + 0, + 1063, + 1064, + 5, + 2, + 0, + 0, + 1064, + 1069, + 5, + 158, + 0, + 0, + 1065, + 1066, + 5, + 111, + 0, + 0, + 1066, + 1067, + 5, + 2, + 0, + 0, + 1067, + 1069, + 5, + 161, + 0, + 0, + 1068, + 1062, + 1, + 0, + 0, + 0, + 1068, + 1065, + 1, + 0, + 0, + 0, + 1069, + 187, + 1, + 0, + 0, + 0, + 1070, + 1071, + 5, + 112, + 0, + 0, + 1071, + 1072, + 5, + 2, + 0, + 0, + 1072, + 1077, + 3, + 80, + 40, + 0, + 1073, + 1074, + 5, + 112, + 0, + 0, + 1074, + 1075, + 5, + 2, + 0, + 0, + 1075, + 1077, + 5, + 155, + 0, + 0, + 1076, + 1070, + 1, + 0, + 0, + 0, + 1076, + 1073, + 1, + 0, + 0, + 0, + 1077, + 189, + 1, + 0, + 0, + 0, + 1078, + 1079, + 5, + 113, + 0, + 0, + 1079, + 1080, + 5, + 2, + 0, + 0, + 1080, + 1081, + 3, + 236, + 118, + 0, + 1081, + 191, + 1, + 0, + 0, + 0, + 1082, + 1083, + 5, + 114, + 0, + 0, + 1083, + 1084, + 5, + 2, + 0, + 0, + 1084, + 1085, + 5, + 5, + 0, + 0, + 1085, + 1090, + 3, + 194, + 97, + 0, + 1086, + 1087, + 5, + 1, + 0, + 0, + 1087, + 1089, + 3, + 194, + 97, + 0, + 1088, + 1086, + 1, + 0, + 0, + 0, + 1089, + 1092, + 1, + 0, + 0, + 0, + 1090, + 1088, + 1, + 0, + 0, + 0, + 1090, + 1091, + 1, + 0, + 0, + 0, + 1091, + 1093, + 1, + 0, + 0, + 0, + 1092, + 1090, + 1, + 0, + 0, + 0, + 1093, + 1094, + 5, + 6, + 0, + 0, + 1094, + 193, + 1, + 0, + 0, + 0, + 1095, + 1098, + 3, + 28, + 14, + 0, + 1096, + 1098, + 3, + 66, + 33, + 0, + 1097, + 1095, + 1, + 0, + 0, + 0, + 1097, + 1096, + 1, + 0, + 0, + 0, + 1098, + 195, + 1, + 0, + 0, + 0, + 1099, + 1100, + 5, + 121, + 0, + 0, + 1100, + 1101, + 5, + 2, + 0, + 0, + 1101, + 1110, + 5, + 3, + 0, + 0, + 1102, + 1107, + 3, + 198, + 99, + 0, + 1103, + 1104, + 5, + 1, + 0, + 0, + 1104, + 1106, + 3, + 198, + 99, + 0, + 1105, + 1103, + 1, + 0, + 0, + 0, + 1106, + 1109, + 1, + 0, + 0, + 0, + 1107, + 1105, + 1, + 0, + 0, + 0, + 1107, + 1108, + 1, + 0, + 0, + 0, + 1108, + 1111, + 1, + 0, + 0, + 0, + 1109, + 1107, + 1, + 0, + 0, + 0, + 1110, + 1102, + 1, + 0, + 0, + 0, + 1110, + 1111, + 1, + 0, + 0, + 0, + 1111, + 1112, + 1, + 0, + 0, + 0, + 1112, + 1113, + 5, + 4, + 0, + 0, + 1113, + 197, + 1, + 0, + 0, + 0, + 1114, + 1115, + 5, + 5, + 0, + 0, + 1115, + 1120, + 3, + 200, + 100, + 0, + 1116, + 1117, + 5, + 1, + 0, + 0, + 1117, + 1119, + 3, + 200, + 100, + 0, + 1118, + 1116, + 1, + 0, + 0, + 0, + 1119, + 1122, + 1, + 0, + 0, + 0, + 1120, + 1118, + 1, + 0, + 0, + 0, + 1120, + 1121, + 1, + 0, + 0, + 0, + 1121, + 1123, + 1, + 0, + 0, + 0, + 1122, + 1120, + 1, + 0, + 0, + 0, + 1123, + 1124, + 5, + 6, + 0, + 0, + 1124, + 199, + 1, + 0, + 0, + 0, + 1125, + 1133, + 3, + 202, + 101, + 0, + 1126, + 1133, + 3, + 204, + 102, + 0, + 1127, + 1133, + 3, + 206, + 103, + 0, + 1128, + 1133, + 3, + 208, + 104, + 0, + 1129, + 1133, + 3, + 210, + 105, + 0, + 1130, + 1133, + 3, + 212, + 106, + 0, + 1131, + 1133, + 3, + 8, + 4, + 0, + 1132, + 1125, + 1, + 0, + 0, + 0, + 1132, + 1126, + 1, + 0, + 0, + 0, + 1132, + 1127, + 1, + 0, + 0, + 0, + 1132, + 1128, + 1, + 0, + 0, + 0, + 1132, + 1129, + 1, + 0, + 0, + 0, + 1132, + 1130, + 1, + 0, + 0, + 0, + 1132, + 1131, + 1, + 0, + 0, + 0, + 1133, + 201, + 1, + 0, + 0, + 0, + 1134, + 1135, + 5, + 122, + 0, + 0, + 1135, + 1136, + 5, + 2, + 0, + 0, + 1136, + 1137, + 5, + 3, + 0, + 0, + 1137, + 1142, + 3, + 226, + 113, + 0, + 1138, + 1139, + 5, + 1, + 0, + 0, + 1139, + 1141, + 3, + 226, + 113, + 0, + 1140, + 1138, + 1, + 0, + 0, + 0, + 1141, + 1144, + 1, + 0, + 0, + 0, + 1142, + 1140, + 1, + 0, + 0, + 0, + 1142, + 1143, + 1, + 0, + 0, + 0, + 1143, + 1145, + 1, + 0, + 0, + 0, + 1144, + 1142, + 1, + 0, + 0, + 0, + 1145, + 1146, + 5, + 4, + 0, + 0, + 1146, + 203, + 1, + 0, + 0, + 0, + 1147, + 1148, + 5, + 123, + 0, + 0, + 1148, + 1149, + 5, + 2, + 0, + 0, + 1149, + 1150, + 5, + 160, + 0, + 0, + 1150, + 205, + 1, + 0, + 0, + 0, + 1151, + 1152, + 5, + 124, + 0, + 0, + 1152, + 1153, + 5, + 2, + 0, + 0, + 1153, + 1154, + 5, + 160, + 0, + 0, + 1154, + 207, + 1, + 0, + 0, + 0, + 1155, + 1156, + 5, + 125, + 0, + 0, + 1156, + 1157, + 5, + 2, + 0, + 0, + 1157, + 1158, + 7, + 4, + 0, + 0, + 1158, + 209, + 1, + 0, + 0, + 0, + 1159, + 1160, + 5, + 126, + 0, + 0, + 1160, + 1161, + 5, + 2, + 0, + 0, + 1161, + 1162, + 5, + 160, + 0, + 0, + 1162, + 211, + 1, + 0, + 0, + 0, + 1163, + 1164, + 5, + 127, + 0, + 0, + 1164, + 1165, + 5, + 2, + 0, + 0, + 1165, + 1166, + 7, + 5, + 0, + 0, + 1166, + 213, + 1, + 0, + 0, + 0, + 1167, + 1168, + 5, + 130, + 0, + 0, + 1168, + 1169, + 5, + 2, + 0, + 0, + 1169, + 1178, + 5, + 3, + 0, + 0, + 1170, + 1175, + 3, + 216, + 108, + 0, + 1171, + 1172, + 5, + 1, + 0, + 0, + 1172, + 1174, + 3, + 216, + 108, + 0, + 1173, + 1171, + 1, + 0, + 0, + 0, + 1174, + 1177, + 1, + 0, + 0, + 0, + 1175, + 1173, + 1, + 0, + 0, + 0, + 1175, + 1176, + 1, + 0, + 0, + 0, + 1176, + 1179, + 1, + 0, + 0, + 0, + 1177, + 1175, + 1, + 0, + 0, + 0, + 1178, + 1170, + 1, + 0, + 0, + 0, + 1178, + 1179, + 1, + 0, + 0, + 0, + 1179, + 1180, + 1, + 0, + 0, + 0, + 1180, + 1181, + 5, + 4, + 0, + 0, + 1181, + 215, + 1, + 0, + 0, + 0, + 1182, + 1183, + 5, + 5, + 0, + 0, + 1183, + 1188, + 3, + 218, + 109, + 0, + 1184, + 1185, + 5, + 1, + 0, + 0, + 1185, + 1187, + 3, + 218, + 109, + 0, + 1186, + 1184, + 1, + 0, + 0, + 0, + 1187, + 1190, + 1, + 0, + 0, + 0, + 1188, + 1186, + 1, + 0, + 0, + 0, + 1188, + 1189, + 1, + 0, + 0, + 0, + 1189, + 1191, + 1, + 0, + 0, + 0, + 1190, + 1188, + 1, + 0, + 0, + 0, + 1191, + 1192, + 5, + 6, + 0, + 0, + 1192, + 217, + 1, + 0, + 0, + 0, + 1193, + 1200, + 3, + 202, + 101, + 0, + 1194, + 1200, + 3, + 34, + 17, + 0, + 1195, + 1200, + 3, + 26, + 13, + 0, + 1196, + 1200, + 3, + 92, + 46, + 0, + 1197, + 1200, + 3, + 110, + 55, + 0, + 1198, + 1200, + 3, + 8, + 4, + 0, + 1199, + 1193, + 1, + 0, + 0, + 0, + 1199, + 1194, + 1, + 0, + 0, + 0, + 1199, + 1195, + 1, + 0, + 0, + 0, + 1199, + 1196, + 1, + 0, + 0, + 0, + 1199, + 1197, + 1, + 0, + 0, + 0, + 1199, + 1198, + 1, + 0, + 0, + 0, + 1200, + 219, + 1, + 0, + 0, + 0, + 1201, + 1202, + 7, + 6, + 0, + 0, + 1202, + 221, + 1, + 0, + 0, + 0, + 1203, + 1204, + 7, + 7, + 0, + 0, + 1204, + 223, + 1, + 0, + 0, + 0, + 1205, + 1206, + 7, + 8, + 0, + 0, + 1206, + 225, + 1, + 0, + 0, + 0, + 1207, + 1210, + 3, + 224, + 112, + 0, + 1208, + 1210, + 3, + 236, + 118, + 0, + 1209, + 1207, + 1, + 0, + 0, + 0, + 1209, + 1208, + 1, + 0, + 0, + 0, + 1210, + 227, + 1, + 0, + 0, + 0, + 1211, + 1212, + 5, + 5, + 0, + 0, + 1212, + 1217, + 3, + 230, + 115, + 0, + 1213, + 1214, + 5, + 1, + 0, + 0, + 1214, + 1216, + 3, + 230, + 115, + 0, + 1215, + 1213, + 1, + 0, + 0, + 0, + 1216, + 1219, + 1, + 0, + 0, + 0, + 1217, + 1215, + 1, + 0, + 0, + 0, + 1217, + 1218, + 1, + 0, + 0, + 0, + 1218, + 1220, + 1, + 0, + 0, + 0, + 1219, + 1217, + 1, + 0, + 0, + 0, + 1220, + 1221, + 5, + 6, + 0, + 0, + 1221, + 1225, + 1, + 0, + 0, + 0, + 1222, + 1223, + 5, + 5, + 0, + 0, + 1223, + 1225, + 5, + 6, + 0, + 0, + 1224, + 1211, + 1, + 0, + 0, + 0, + 1224, + 1222, + 1, + 0, + 0, + 0, + 1225, + 229, + 1, + 0, + 0, + 0, + 1226, + 1227, + 3, + 236, + 118, + 0, + 1227, + 1228, + 5, + 2, + 0, + 0, + 1228, + 1229, + 3, + 234, + 117, + 0, + 1229, + 231, + 1, + 0, + 0, + 0, + 1230, + 1231, + 5, + 3, + 0, + 0, + 1231, + 1236, + 3, + 234, + 117, + 0, + 1232, + 1233, + 5, + 1, + 0, + 0, + 1233, + 1235, + 3, + 234, + 117, + 0, + 1234, + 1232, + 1, + 0, + 0, + 0, + 1235, + 1238, + 1, + 0, + 0, + 0, + 1236, + 1234, + 1, + 0, + 0, + 0, + 1236, + 1237, + 1, + 0, + 0, + 0, + 1237, + 1239, + 1, + 0, + 0, + 0, + 1238, + 1236, + 1, + 0, + 0, + 0, + 1239, + 1240, + 5, + 4, + 0, + 0, + 1240, + 1244, + 1, + 0, + 0, + 0, + 1241, + 1242, + 5, + 3, + 0, + 0, + 1242, + 1244, + 5, + 4, + 0, + 0, + 1243, + 1230, + 1, + 0, + 0, + 0, + 1243, + 1241, + 1, + 0, + 0, + 0, + 1244, + 233, + 1, + 0, + 0, + 0, + 1245, + 1255, + 5, + 161, + 0, + 0, + 1246, + 1255, + 5, + 160, + 0, + 0, + 1247, + 1255, + 5, + 7, + 0, + 0, + 1248, + 1255, + 5, + 8, + 0, + 0, + 1249, + 1255, + 5, + 9, + 0, + 0, + 1250, + 1255, + 3, + 230, + 115, + 0, + 1251, + 1255, + 3, + 232, + 116, + 0, + 1252, + 1255, + 3, + 228, + 114, + 0, + 1253, + 1255, + 3, + 236, + 118, + 0, + 1254, + 1245, + 1, + 0, + 0, + 0, + 1254, + 1246, + 1, + 0, + 0, + 0, + 1254, + 1247, + 1, + 0, + 0, + 0, + 1254, + 1248, + 1, + 0, + 0, + 0, + 1254, + 1249, + 1, + 0, + 0, + 0, + 1254, + 1250, + 1, + 0, + 0, + 0, + 1254, + 1251, + 1, + 0, + 0, + 0, + 1254, + 1252, + 1, + 0, + 0, + 0, + 1254, + 1253, + 1, + 0, + 0, + 0, + 1255, + 235, + 1, + 0, + 0, + 0, + 1256, + 1257, + 7, + 9, + 0, + 0, + 1257, + 237, + 1, + 0, + 0, + 0, + 95, + 247, + 258, + 323, + 333, + 350, + 377, + 379, + 389, + 401, + 403, + 419, + 433, + 441, + 455, + 463, + 471, + 479, + 487, + 495, + 506, + 514, + 522, + 552, + 560, + 568, + 576, + 584, + 594, + 601, + 619, + 627, + 634, + 639, + 646, + 660, + 665, + 677, + 682, + 699, + 704, + 714, + 719, + 727, + 735, + 749, + 754, + 763, + 773, + 778, + 786, + 802, + 813, + 823, + 828, + 835, + 841, + 852, + 857, + 868, + 884, + 894, + 907, + 916, + 926, + 933, + 955, + 964, + 978, + 987, + 997, + 1007, + 1025, + 1036, + 1044, + 1052, + 1060, + 1068, + 1076, + 1090, + 1097, + 1107, + 1110, + 1120, + 1132, + 1142, + 1175, + 1178, + 1188, + 1199, + 1209, + 1217, + 1224, + 1236, + 1243, + 1254, + ] + + +class ASLParser(Parser): + grammarFileName = "ASLParser.g4" + + atn = ATNDeserializer().deserialize(serializedATN()) + + decisionsToDFA = [DFA(ds, i) for i, ds in enumerate(atn.decisionToState)] + + sharedContextCache = PredictionContextCache() + + literalNames = [ + "", + "','", + "':'", + "'['", + "']'", + "'{'", + "'}'", + "'true'", + "'false'", + "'null'", + "'\"Comment\"'", + "'\"States\"'", + "'\"StartAt\"'", + "'\"NextState\"'", + "'\"Version\"'", + "'\"Type\"'", + "'\"Task\"'", + "'\"Choice\"'", + "'\"Fail\"'", + "'\"Succeed\"'", + "'\"Pass\"'", + "'\"Wait\"'", + "'\"Parallel\"'", + "'\"Map\"'", + "'\"Choices\"'", + "'\"Condition\"'", + "'\"Variable\"'", + "'\"Default\"'", + "'\"Branches\"'", + "'\"And\"'", "'\"BooleanEquals\"'", "'\"BooleanEqualsPath\"'", "'\"IsBoolean\"'", @@ -7604,10 +11134,14 @@ class ASLParser(Parser): "'\"Resource\"'", "'\"InputPath\"'", "'\"OutputPath\"'", + "'\"Items\"'", "'\"ItemsPath\"'", "'\"ResultPath\"'", "'\"Result\"'", "'\"Parameters\"'", + "'\"Credentials\"'", + "'\"RoleArn\"'", + "'\"RoleArn.$\"'", "'\"ResultSelector\"'", "'\"ItemReader\"'", "'\"ReaderConfig\"'", @@ -7621,6 +11155,7 @@ class ASLParser(Parser): "'\"ToleratedFailurePercentage\"'", "'\"ToleratedFailurePercentagePath\"'", "'\"Label\"'", + "'\"ResultWriter\"'", "'\"Next\"'", "'\"End\"'", "'\"Cause\"'", @@ -7637,6 +11172,12 @@ class ASLParser(Parser): "'\"FULL\"'", "'\"NONE\"'", "'\"Catch\"'", + "'\"QueryLanguage\"'", + "'\"JSONPath\"'", + "'\"JSONata\"'", + "'\"Assign\"'", + "'\"Output\"'", + "'\"Arguments\"'", "'\"States.ALL\"'", "'\"States.DataLimitExceeded\"'", "'\"States.HeartbeatTimeout\"'", @@ -7651,516 +11192,3210 @@ class ASLParser(Parser): "'\"States.ExceedToleratedFailureThreshold\"'", "'\"States.ItemReaderFailed\"'", "'\"States.ResultWriterFailed\"'", + "'\"States.QueryEvaluationError\"'", "'\"States.Runtime\"'", ] - symbolicNames = [ - "", - "COMMA", - "COLON", - "LBRACK", - "RBRACK", - "LBRACE", - "RBRACE", - "TRUE", - "FALSE", - "NULL", - "COMMENT", - "STATES", - "STARTAT", - "NEXTSTATE", - "VERSION", - "TYPE", - "TASK", - "CHOICE", - "FAIL", - "SUCCEED", - "PASS", - "WAIT", - "PARALLEL", - "MAP", - "CHOICES", - "VARIABLE", - "DEFAULT", - "BRANCHES", - "AND", - "BOOLEANEQUALS", - "BOOLEANQUALSPATH", - "ISBOOLEAN", - "ISNULL", - "ISNUMERIC", - "ISPRESENT", - "ISSTRING", - "ISTIMESTAMP", - "NOT", - "NUMERICEQUALS", - "NUMERICEQUALSPATH", - "NUMERICGREATERTHAN", - "NUMERICGREATERTHANPATH", - "NUMERICGREATERTHANEQUALS", - "NUMERICGREATERTHANEQUALSPATH", - "NUMERICLESSTHAN", - "NUMERICLESSTHANPATH", - "NUMERICLESSTHANEQUALS", - "NUMERICLESSTHANEQUALSPATH", - "OR", - "STRINGEQUALS", - "STRINGEQUALSPATH", - "STRINGGREATERTHAN", - "STRINGGREATERTHANPATH", - "STRINGGREATERTHANEQUALS", - "STRINGGREATERTHANEQUALSPATH", - "STRINGLESSTHAN", - "STRINGLESSTHANPATH", - "STRINGLESSTHANEQUALS", - "STRINGLESSTHANEQUALSPATH", - "STRINGMATCHES", - "TIMESTAMPEQUALS", - "TIMESTAMPEQUALSPATH", - "TIMESTAMPGREATERTHAN", - "TIMESTAMPGREATERTHANPATH", - "TIMESTAMPGREATERTHANEQUALS", - "TIMESTAMPGREATERTHANEQUALSPATH", - "TIMESTAMPLESSTHAN", - "TIMESTAMPLESSTHANPATH", - "TIMESTAMPLESSTHANEQUALS", - "TIMESTAMPLESSTHANEQUALSPATH", - "SECONDSPATH", - "SECONDS", - "TIMESTAMPPATH", - "TIMESTAMP", - "TIMEOUTSECONDS", - "TIMEOUTSECONDSPATH", - "HEARTBEATSECONDS", - "HEARTBEATSECONDSPATH", - "PROCESSORCONFIG", - "MODE", - "INLINE", - "DISTRIBUTED", - "EXECUTIONTYPE", - "STANDARD", - "ITEMPROCESSOR", - "ITERATOR", - "ITEMSELECTOR", - "MAXCONCURRENCYPATH", - "MAXCONCURRENCY", - "RESOURCE", - "INPUTPATH", - "OUTPUTPATH", - "ITEMSPATH", - "RESULTPATH", - "RESULT", - "PARAMETERS", - "RESULTSELECTOR", - "ITEMREADER", - "READERCONFIG", - "INPUTTYPE", - "CSVHEADERLOCATION", - "CSVHEADERS", - "MAXITEMS", - "MAXITEMSPATH", - "TOLERATEDFAILURECOUNT", - "TOLERATEDFAILURECOUNTPATH", - "TOLERATEDFAILUREPERCENTAGE", - "TOLERATEDFAILUREPERCENTAGEPATH", - "LABEL", - "NEXT", - "END", - "CAUSE", - "CAUSEPATH", - "ERROR", - "ERRORPATH", - "RETRY", - "ERROREQUALS", - "INTERVALSECONDS", - "MAXATTEMPTS", - "BACKOFFRATE", - "MAXDELAYSECONDS", - "JITTERSTRATEGY", - "FULL", - "NONE", - "CATCH", - "ERRORNAMEStatesALL", - "ERRORNAMEStatesDataLimitExceeded", - "ERRORNAMEStatesHeartbeatTimeout", - "ERRORNAMEStatesTimeout", - "ERRORNAMEStatesTaskFailed", - "ERRORNAMEStatesPermissions", - "ERRORNAMEStatesResultPathMatchFailure", - "ERRORNAMEStatesParameterPathFailure", - "ERRORNAMEStatesBranchFailed", - "ERRORNAMEStatesNoChoiceMatched", - "ERRORNAMEStatesIntrinsicFailure", - "ERRORNAMEStatesExceedToleratedFailureThreshold", - "ERRORNAMEStatesItemReaderFailed", - "ERRORNAMEStatesResultWriterFailed", - "ERRORNAMEStatesRuntime", - "STRINGDOLLAR", - "STRINGPATHCONTEXTOBJ", - "STRINGPATH", - "STRING", - "INT", - "NUMBER", - "WS", - ] + symbolicNames = [ + "", + "COMMA", + "COLON", + "LBRACK", + "RBRACK", + "LBRACE", + "RBRACE", + "TRUE", + "FALSE", + "NULL", + "COMMENT", + "STATES", + "STARTAT", + "NEXTSTATE", + "VERSION", + "TYPE", + "TASK", + "CHOICE", + "FAIL", + "SUCCEED", + "PASS", + "WAIT", + "PARALLEL", + "MAP", + "CHOICES", + "CONDITION", + "VARIABLE", + "DEFAULT", + "BRANCHES", + "AND", + "BOOLEANEQUALS", + "BOOLEANQUALSPATH", + "ISBOOLEAN", + "ISNULL", + "ISNUMERIC", + "ISPRESENT", + "ISSTRING", + "ISTIMESTAMP", + "NOT", + "NUMERICEQUALS", + "NUMERICEQUALSPATH", + "NUMERICGREATERTHAN", + "NUMERICGREATERTHANPATH", + "NUMERICGREATERTHANEQUALS", + "NUMERICGREATERTHANEQUALSPATH", + "NUMERICLESSTHAN", + "NUMERICLESSTHANPATH", + "NUMERICLESSTHANEQUALS", + "NUMERICLESSTHANEQUALSPATH", + "OR", + "STRINGEQUALS", + "STRINGEQUALSPATH", + "STRINGGREATERTHAN", + "STRINGGREATERTHANPATH", + "STRINGGREATERTHANEQUALS", + "STRINGGREATERTHANEQUALSPATH", + "STRINGLESSTHAN", + "STRINGLESSTHANPATH", + "STRINGLESSTHANEQUALS", + "STRINGLESSTHANEQUALSPATH", + "STRINGMATCHES", + "TIMESTAMPEQUALS", + "TIMESTAMPEQUALSPATH", + "TIMESTAMPGREATERTHAN", + "TIMESTAMPGREATERTHANPATH", + "TIMESTAMPGREATERTHANEQUALS", + "TIMESTAMPGREATERTHANEQUALSPATH", + "TIMESTAMPLESSTHAN", + "TIMESTAMPLESSTHANPATH", + "TIMESTAMPLESSTHANEQUALS", + "TIMESTAMPLESSTHANEQUALSPATH", + "SECONDSPATH", + "SECONDS", + "TIMESTAMPPATH", + "TIMESTAMP", + "TIMEOUTSECONDS", + "TIMEOUTSECONDSPATH", + "HEARTBEATSECONDS", + "HEARTBEATSECONDSPATH", + "PROCESSORCONFIG", + "MODE", + "INLINE", + "DISTRIBUTED", + "EXECUTIONTYPE", + "STANDARD", + "ITEMPROCESSOR", + "ITERATOR", + "ITEMSELECTOR", + "MAXCONCURRENCYPATH", + "MAXCONCURRENCY", + "RESOURCE", + "INPUTPATH", + "OUTPUTPATH", + "ITEMS", + "ITEMSPATH", + "RESULTPATH", + "RESULT", + "PARAMETERS", + "CREDENTIALS", + "ROLEARN", + "ROLEARNPATH", + "RESULTSELECTOR", + "ITEMREADER", + "READERCONFIG", + "INPUTTYPE", + "CSVHEADERLOCATION", + "CSVHEADERS", + "MAXITEMS", + "MAXITEMSPATH", + "TOLERATEDFAILURECOUNT", + "TOLERATEDFAILURECOUNTPATH", + "TOLERATEDFAILUREPERCENTAGE", + "TOLERATEDFAILUREPERCENTAGEPATH", + "LABEL", + "RESULTWRITER", + "NEXT", + "END", + "CAUSE", + "CAUSEPATH", + "ERROR", + "ERRORPATH", + "RETRY", + "ERROREQUALS", + "INTERVALSECONDS", + "MAXATTEMPTS", + "BACKOFFRATE", + "MAXDELAYSECONDS", + "JITTERSTRATEGY", + "FULL", + "NONE", + "CATCH", + "QUERYLANGUAGE", + "JSONPATH", + "JSONATA", + "ASSIGN", + "OUTPUT", + "ARGUMENTS", + "ERRORNAMEStatesALL", + "ERRORNAMEStatesDataLimitExceeded", + "ERRORNAMEStatesHeartbeatTimeout", + "ERRORNAMEStatesTimeout", + "ERRORNAMEStatesTaskFailed", + "ERRORNAMEStatesPermissions", + "ERRORNAMEStatesResultPathMatchFailure", + "ERRORNAMEStatesParameterPathFailure", + "ERRORNAMEStatesBranchFailed", + "ERRORNAMEStatesNoChoiceMatched", + "ERRORNAMEStatesIntrinsicFailure", + "ERRORNAMEStatesExceedToleratedFailureThreshold", + "ERRORNAMEStatesItemReaderFailed", + "ERRORNAMEStatesResultWriterFailed", + "ERRORNAMEStatesQueryEvaluationError", + "ERRORNAMEStatesRuntime", + "STRINGDOLLAR", + "STRINGPATHCONTEXTOBJ", + "STRINGPATH", + "STRINGVAR", + "STRINGINTRINSICFUNC", + "STRINGJSONATA", + "STRING", + "INT", + "NUMBER", + "WS", + ] + + RULE_state_machine = 0 + RULE_program_decl = 1 + RULE_top_layer_stmt = 2 + RULE_startat_decl = 3 + RULE_comment_decl = 4 + RULE_version_decl = 5 + RULE_query_language_decl = 6 + RULE_state_stmt = 7 + RULE_states_decl = 8 + RULE_state_name = 9 + RULE_state_decl = 10 + RULE_state_decl_body = 11 + RULE_type_decl = 12 + RULE_next_decl = 13 + RULE_resource_decl = 14 + RULE_input_path_decl = 15 + RULE_result_decl = 16 + RULE_result_path_decl = 17 + RULE_output_path_decl = 18 + RULE_end_decl = 19 + RULE_default_decl = 20 + RULE_error_decl = 21 + RULE_error_path_decl = 22 + RULE_cause_decl = 23 + RULE_cause_path_decl = 24 + RULE_seconds_decl = 25 + RULE_seconds_path_decl = 26 + RULE_timestamp_decl = 27 + RULE_timestamp_path_decl = 28 + RULE_items_decl = 29 + RULE_items_path_decl = 30 + RULE_max_concurrency_decl = 31 + RULE_max_concurrency_path_decl = 32 + RULE_parameters_decl = 33 + RULE_credentials_decl = 34 + RULE_role_arn_decl = 35 + RULE_timeout_seconds_decl = 36 + RULE_timeout_seconds_path_decl = 37 + RULE_heartbeat_seconds_decl = 38 + RULE_heartbeat_seconds_path_decl = 39 + RULE_variable_sample = 40 + RULE_payload_tmpl_decl = 41 + RULE_payload_binding = 42 + RULE_payload_arr_decl = 43 + RULE_payload_value_decl = 44 + RULE_payload_value_lit = 45 + RULE_assign_decl = 46 + RULE_assign_decl_body = 47 + RULE_assign_decl_binding = 48 + RULE_assign_template_value_object = 49 + RULE_assign_template_binding = 50 + RULE_assign_template_value = 51 + RULE_assign_template_value_array = 52 + RULE_assign_template_value_terminal = 53 + RULE_arguments_decl = 54 + RULE_output_decl = 55 + RULE_jsonata_template_value_object = 56 + RULE_jsonata_template_binding = 57 + RULE_jsonata_template_value = 58 + RULE_jsonata_template_value_array = 59 + RULE_jsonata_template_value_terminal = 60 + RULE_result_selector_decl = 61 + RULE_state_type = 62 + RULE_choices_decl = 63 + RULE_choice_rule = 64 + RULE_comparison_variable_stmt = 65 + RULE_comparison_composite_stmt = 66 + RULE_comparison_composite = 67 + RULE_variable_decl = 68 + RULE_comparison_func = 69 + RULE_branches_decl = 70 + RULE_item_processor_decl = 71 + RULE_item_processor_item = 72 + RULE_processor_config_decl = 73 + RULE_processor_config_field = 74 + RULE_mode_decl = 75 + RULE_mode_type = 76 + RULE_execution_decl = 77 + RULE_execution_type = 78 + RULE_iterator_decl = 79 + RULE_iterator_decl_item = 80 + RULE_item_selector_decl = 81 + RULE_item_reader_decl = 82 + RULE_items_reader_field = 83 + RULE_reader_config_decl = 84 + RULE_reader_config_field = 85 + RULE_input_type_decl = 86 + RULE_csv_header_location_decl = 87 + RULE_csv_headers_decl = 88 + RULE_max_items_decl = 89 + RULE_max_items_path_decl = 90 + RULE_tolerated_failure_count_decl = 91 + RULE_tolerated_failure_count_path_decl = 92 + RULE_tolerated_failure_percentage_decl = 93 + RULE_tolerated_failure_percentage_path_decl = 94 + RULE_label_decl = 95 + RULE_result_writer_decl = 96 + RULE_result_writer_field = 97 + RULE_retry_decl = 98 + RULE_retrier_decl = 99 + RULE_retrier_stmt = 100 + RULE_error_equals_decl = 101 + RULE_interval_seconds_decl = 102 + RULE_max_attempts_decl = 103 + RULE_backoff_rate_decl = 104 + RULE_max_delay_seconds_decl = 105 + RULE_jitter_strategy_decl = 106 + RULE_catch_decl = 107 + RULE_catcher_decl = 108 + RULE_catcher_stmt = 109 + RULE_comparison_op = 110 + RULE_choice_operator = 111 + RULE_states_error_name = 112 + RULE_error_name = 113 + RULE_json_obj_decl = 114 + RULE_json_binding = 115 + RULE_json_arr_decl = 116 + RULE_json_value_decl = 117 + RULE_keyword_or_string = 118 + + ruleNames = [ + "state_machine", + "program_decl", + "top_layer_stmt", + "startat_decl", + "comment_decl", + "version_decl", + "query_language_decl", + "state_stmt", + "states_decl", + "state_name", + "state_decl", + "state_decl_body", + "type_decl", + "next_decl", + "resource_decl", + "input_path_decl", + "result_decl", + "result_path_decl", + "output_path_decl", + "end_decl", + "default_decl", + "error_decl", + "error_path_decl", + "cause_decl", + "cause_path_decl", + "seconds_decl", + "seconds_path_decl", + "timestamp_decl", + "timestamp_path_decl", + "items_decl", + "items_path_decl", + "max_concurrency_decl", + "max_concurrency_path_decl", + "parameters_decl", + "credentials_decl", + "role_arn_decl", + "timeout_seconds_decl", + "timeout_seconds_path_decl", + "heartbeat_seconds_decl", + "heartbeat_seconds_path_decl", + "variable_sample", + "payload_tmpl_decl", + "payload_binding", + "payload_arr_decl", + "payload_value_decl", + "payload_value_lit", + "assign_decl", + "assign_decl_body", + "assign_decl_binding", + "assign_template_value_object", + "assign_template_binding", + "assign_template_value", + "assign_template_value_array", + "assign_template_value_terminal", + "arguments_decl", + "output_decl", + "jsonata_template_value_object", + "jsonata_template_binding", + "jsonata_template_value", + "jsonata_template_value_array", + "jsonata_template_value_terminal", + "result_selector_decl", + "state_type", + "choices_decl", + "choice_rule", + "comparison_variable_stmt", + "comparison_composite_stmt", + "comparison_composite", + "variable_decl", + "comparison_func", + "branches_decl", + "item_processor_decl", + "item_processor_item", + "processor_config_decl", + "processor_config_field", + "mode_decl", + "mode_type", + "execution_decl", + "execution_type", + "iterator_decl", + "iterator_decl_item", + "item_selector_decl", + "item_reader_decl", + "items_reader_field", + "reader_config_decl", + "reader_config_field", + "input_type_decl", + "csv_header_location_decl", + "csv_headers_decl", + "max_items_decl", + "max_items_path_decl", + "tolerated_failure_count_decl", + "tolerated_failure_count_path_decl", + "tolerated_failure_percentage_decl", + "tolerated_failure_percentage_path_decl", + "label_decl", + "result_writer_decl", + "result_writer_field", + "retry_decl", + "retrier_decl", + "retrier_stmt", + "error_equals_decl", + "interval_seconds_decl", + "max_attempts_decl", + "backoff_rate_decl", + "max_delay_seconds_decl", + "jitter_strategy_decl", + "catch_decl", + "catcher_decl", + "catcher_stmt", + "comparison_op", + "choice_operator", + "states_error_name", + "error_name", + "json_obj_decl", + "json_binding", + "json_arr_decl", + "json_value_decl", + "keyword_or_string", + ] + + EOF = Token.EOF + COMMA = 1 + COLON = 2 + LBRACK = 3 + RBRACK = 4 + LBRACE = 5 + RBRACE = 6 + TRUE = 7 + FALSE = 8 + NULL = 9 + COMMENT = 10 + STATES = 11 + STARTAT = 12 + NEXTSTATE = 13 + VERSION = 14 + TYPE = 15 + TASK = 16 + CHOICE = 17 + FAIL = 18 + SUCCEED = 19 + PASS = 20 + WAIT = 21 + PARALLEL = 22 + MAP = 23 + CHOICES = 24 + CONDITION = 25 + VARIABLE = 26 + DEFAULT = 27 + BRANCHES = 28 + AND = 29 + BOOLEANEQUALS = 30 + BOOLEANQUALSPATH = 31 + ISBOOLEAN = 32 + ISNULL = 33 + ISNUMERIC = 34 + ISPRESENT = 35 + ISSTRING = 36 + ISTIMESTAMP = 37 + NOT = 38 + NUMERICEQUALS = 39 + NUMERICEQUALSPATH = 40 + NUMERICGREATERTHAN = 41 + NUMERICGREATERTHANPATH = 42 + NUMERICGREATERTHANEQUALS = 43 + NUMERICGREATERTHANEQUALSPATH = 44 + NUMERICLESSTHAN = 45 + NUMERICLESSTHANPATH = 46 + NUMERICLESSTHANEQUALS = 47 + NUMERICLESSTHANEQUALSPATH = 48 + OR = 49 + STRINGEQUALS = 50 + STRINGEQUALSPATH = 51 + STRINGGREATERTHAN = 52 + STRINGGREATERTHANPATH = 53 + STRINGGREATERTHANEQUALS = 54 + STRINGGREATERTHANEQUALSPATH = 55 + STRINGLESSTHAN = 56 + STRINGLESSTHANPATH = 57 + STRINGLESSTHANEQUALS = 58 + STRINGLESSTHANEQUALSPATH = 59 + STRINGMATCHES = 60 + TIMESTAMPEQUALS = 61 + TIMESTAMPEQUALSPATH = 62 + TIMESTAMPGREATERTHAN = 63 + TIMESTAMPGREATERTHANPATH = 64 + TIMESTAMPGREATERTHANEQUALS = 65 + TIMESTAMPGREATERTHANEQUALSPATH = 66 + TIMESTAMPLESSTHAN = 67 + TIMESTAMPLESSTHANPATH = 68 + TIMESTAMPLESSTHANEQUALS = 69 + TIMESTAMPLESSTHANEQUALSPATH = 70 + SECONDSPATH = 71 + SECONDS = 72 + TIMESTAMPPATH = 73 + TIMESTAMP = 74 + TIMEOUTSECONDS = 75 + TIMEOUTSECONDSPATH = 76 + HEARTBEATSECONDS = 77 + HEARTBEATSECONDSPATH = 78 + PROCESSORCONFIG = 79 + MODE = 80 + INLINE = 81 + DISTRIBUTED = 82 + EXECUTIONTYPE = 83 + STANDARD = 84 + ITEMPROCESSOR = 85 + ITERATOR = 86 + ITEMSELECTOR = 87 + MAXCONCURRENCYPATH = 88 + MAXCONCURRENCY = 89 + RESOURCE = 90 + INPUTPATH = 91 + OUTPUTPATH = 92 + ITEMS = 93 + ITEMSPATH = 94 + RESULTPATH = 95 + RESULT = 96 + PARAMETERS = 97 + CREDENTIALS = 98 + ROLEARN = 99 + ROLEARNPATH = 100 + RESULTSELECTOR = 101 + ITEMREADER = 102 + READERCONFIG = 103 + INPUTTYPE = 104 + CSVHEADERLOCATION = 105 + CSVHEADERS = 106 + MAXITEMS = 107 + MAXITEMSPATH = 108 + TOLERATEDFAILURECOUNT = 109 + TOLERATEDFAILURECOUNTPATH = 110 + TOLERATEDFAILUREPERCENTAGE = 111 + TOLERATEDFAILUREPERCENTAGEPATH = 112 + LABEL = 113 + RESULTWRITER = 114 + NEXT = 115 + END = 116 + CAUSE = 117 + CAUSEPATH = 118 + ERROR = 119 + ERRORPATH = 120 + RETRY = 121 + ERROREQUALS = 122 + INTERVALSECONDS = 123 + MAXATTEMPTS = 124 + BACKOFFRATE = 125 + MAXDELAYSECONDS = 126 + JITTERSTRATEGY = 127 + FULL = 128 + NONE = 129 + CATCH = 130 + QUERYLANGUAGE = 131 + JSONPATH = 132 + JSONATA = 133 + ASSIGN = 134 + OUTPUT = 135 + ARGUMENTS = 136 + ERRORNAMEStatesALL = 137 + ERRORNAMEStatesDataLimitExceeded = 138 + ERRORNAMEStatesHeartbeatTimeout = 139 + ERRORNAMEStatesTimeout = 140 + ERRORNAMEStatesTaskFailed = 141 + ERRORNAMEStatesPermissions = 142 + ERRORNAMEStatesResultPathMatchFailure = 143 + ERRORNAMEStatesParameterPathFailure = 144 + ERRORNAMEStatesBranchFailed = 145 + ERRORNAMEStatesNoChoiceMatched = 146 + ERRORNAMEStatesIntrinsicFailure = 147 + ERRORNAMEStatesExceedToleratedFailureThreshold = 148 + ERRORNAMEStatesItemReaderFailed = 149 + ERRORNAMEStatesResultWriterFailed = 150 + ERRORNAMEStatesQueryEvaluationError = 151 + ERRORNAMEStatesRuntime = 152 + STRINGDOLLAR = 153 + STRINGPATHCONTEXTOBJ = 154 + STRINGPATH = 155 + STRINGVAR = 156 + STRINGINTRINSICFUNC = 157 + STRINGJSONATA = 158 + STRING = 159 + INT = 160 + NUMBER = 161 + WS = 162 + + def __init__(self, input: TokenStream, output: TextIO = sys.stdout): + super().__init__(input, output) + self.checkVersion("4.13.2") + self._interp = ParserATNSimulator( + self, self.atn, self.decisionsToDFA, self.sharedContextCache + ) + self._predicates = None + + class State_machineContext(ParserRuleContext): + __slots__ = "parser" + + def __init__( + self, parser, parent: ParserRuleContext = None, invokingState: int = -1 + ): + super().__init__(parent, invokingState) + self.parser = parser + + def program_decl(self): + return self.getTypedRuleContext(ASLParser.Program_declContext, 0) + + def EOF(self): + return self.getToken(ASLParser.EOF, 0) + + def getRuleIndex(self): + return ASLParser.RULE_state_machine + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterState_machine"): + listener.enterState_machine(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitState_machine"): + listener.exitState_machine(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitState_machine"): + return visitor.visitState_machine(self) + else: + return visitor.visitChildren(self) + + def state_machine(self): + localctx = ASLParser.State_machineContext(self, self._ctx, self.state) + self.enterRule(localctx, 0, self.RULE_state_machine) + try: + self.enterOuterAlt(localctx, 1) + self.state = 238 + self.program_decl() + self.state = 239 + self.match(ASLParser.EOF) + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class Program_declContext(ParserRuleContext): + __slots__ = "parser" + + def __init__( + self, parser, parent: ParserRuleContext = None, invokingState: int = -1 + ): + super().__init__(parent, invokingState) + self.parser = parser + + def LBRACE(self): + return self.getToken(ASLParser.LBRACE, 0) + + def top_layer_stmt(self, i: int = None): + if i is None: + return self.getTypedRuleContexts(ASLParser.Top_layer_stmtContext) + else: + return self.getTypedRuleContext(ASLParser.Top_layer_stmtContext, i) + + def RBRACE(self): + return self.getToken(ASLParser.RBRACE, 0) + + def COMMA(self, i: int = None): + if i is None: + return self.getTokens(ASLParser.COMMA) + else: + return self.getToken(ASLParser.COMMA, i) + + def getRuleIndex(self): + return ASLParser.RULE_program_decl + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterProgram_decl"): + listener.enterProgram_decl(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitProgram_decl"): + listener.exitProgram_decl(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitProgram_decl"): + return visitor.visitProgram_decl(self) + else: + return visitor.visitChildren(self) + + def program_decl(self): + localctx = ASLParser.Program_declContext(self, self._ctx, self.state) + self.enterRule(localctx, 2, self.RULE_program_decl) + self._la = 0 # Token type + try: + self.enterOuterAlt(localctx, 1) + self.state = 241 + self.match(ASLParser.LBRACE) + self.state = 242 + self.top_layer_stmt() + self.state = 247 + self._errHandler.sync(self) + _la = self._input.LA(1) + while _la == 1: + self.state = 243 + self.match(ASLParser.COMMA) + self.state = 244 + self.top_layer_stmt() + self.state = 249 + self._errHandler.sync(self) + _la = self._input.LA(1) + + self.state = 250 + self.match(ASLParser.RBRACE) + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class Top_layer_stmtContext(ParserRuleContext): + __slots__ = "parser" + + def __init__( + self, parser, parent: ParserRuleContext = None, invokingState: int = -1 + ): + super().__init__(parent, invokingState) + self.parser = parser + + def comment_decl(self): + return self.getTypedRuleContext(ASLParser.Comment_declContext, 0) + + def version_decl(self): + return self.getTypedRuleContext(ASLParser.Version_declContext, 0) + + def query_language_decl(self): + return self.getTypedRuleContext(ASLParser.Query_language_declContext, 0) + + def startat_decl(self): + return self.getTypedRuleContext(ASLParser.Startat_declContext, 0) + + def states_decl(self): + return self.getTypedRuleContext(ASLParser.States_declContext, 0) + + def timeout_seconds_decl(self): + return self.getTypedRuleContext(ASLParser.Timeout_seconds_declContext, 0) + + def getRuleIndex(self): + return ASLParser.RULE_top_layer_stmt + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterTop_layer_stmt"): + listener.enterTop_layer_stmt(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitTop_layer_stmt"): + listener.exitTop_layer_stmt(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitTop_layer_stmt"): + return visitor.visitTop_layer_stmt(self) + else: + return visitor.visitChildren(self) + + def top_layer_stmt(self): + localctx = ASLParser.Top_layer_stmtContext(self, self._ctx, self.state) + self.enterRule(localctx, 4, self.RULE_top_layer_stmt) + try: + self.state = 258 + self._errHandler.sync(self) + token = self._input.LA(1) + if token in [10]: + self.enterOuterAlt(localctx, 1) + self.state = 252 + self.comment_decl() + pass + elif token in [14]: + self.enterOuterAlt(localctx, 2) + self.state = 253 + self.version_decl() + pass + elif token in [131]: + self.enterOuterAlt(localctx, 3) + self.state = 254 + self.query_language_decl() + pass + elif token in [12]: + self.enterOuterAlt(localctx, 4) + self.state = 255 + self.startat_decl() + pass + elif token in [11]: + self.enterOuterAlt(localctx, 5) + self.state = 256 + self.states_decl() + pass + elif token in [75]: + self.enterOuterAlt(localctx, 6) + self.state = 257 + self.timeout_seconds_decl() + pass + else: + raise NoViableAltException(self) + + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class Startat_declContext(ParserRuleContext): + __slots__ = "parser" + + def __init__( + self, parser, parent: ParserRuleContext = None, invokingState: int = -1 + ): + super().__init__(parent, invokingState) + self.parser = parser + + def STARTAT(self): + return self.getToken(ASLParser.STARTAT, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def keyword_or_string(self): + return self.getTypedRuleContext(ASLParser.Keyword_or_stringContext, 0) + + def getRuleIndex(self): + return ASLParser.RULE_startat_decl + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterStartat_decl"): + listener.enterStartat_decl(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitStartat_decl"): + listener.exitStartat_decl(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitStartat_decl"): + return visitor.visitStartat_decl(self) + else: + return visitor.visitChildren(self) + + def startat_decl(self): + localctx = ASLParser.Startat_declContext(self, self._ctx, self.state) + self.enterRule(localctx, 6, self.RULE_startat_decl) + try: + self.enterOuterAlt(localctx, 1) + self.state = 260 + self.match(ASLParser.STARTAT) + self.state = 261 + self.match(ASLParser.COLON) + self.state = 262 + self.keyword_or_string() + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class Comment_declContext(ParserRuleContext): + __slots__ = "parser" + + def __init__( + self, parser, parent: ParserRuleContext = None, invokingState: int = -1 + ): + super().__init__(parent, invokingState) + self.parser = parser + + def COMMENT(self): + return self.getToken(ASLParser.COMMENT, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def keyword_or_string(self): + return self.getTypedRuleContext(ASLParser.Keyword_or_stringContext, 0) + + def getRuleIndex(self): + return ASLParser.RULE_comment_decl + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterComment_decl"): + listener.enterComment_decl(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitComment_decl"): + listener.exitComment_decl(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitComment_decl"): + return visitor.visitComment_decl(self) + else: + return visitor.visitChildren(self) + + def comment_decl(self): + localctx = ASLParser.Comment_declContext(self, self._ctx, self.state) + self.enterRule(localctx, 8, self.RULE_comment_decl) + try: + self.enterOuterAlt(localctx, 1) + self.state = 264 + self.match(ASLParser.COMMENT) + self.state = 265 + self.match(ASLParser.COLON) + self.state = 266 + self.keyword_or_string() + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class Version_declContext(ParserRuleContext): + __slots__ = "parser" + + def __init__( + self, parser, parent: ParserRuleContext = None, invokingState: int = -1 + ): + super().__init__(parent, invokingState) + self.parser = parser + + def VERSION(self): + return self.getToken(ASLParser.VERSION, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def keyword_or_string(self): + return self.getTypedRuleContext(ASLParser.Keyword_or_stringContext, 0) + + def getRuleIndex(self): + return ASLParser.RULE_version_decl + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterVersion_decl"): + listener.enterVersion_decl(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitVersion_decl"): + listener.exitVersion_decl(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitVersion_decl"): + return visitor.visitVersion_decl(self) + else: + return visitor.visitChildren(self) + + def version_decl(self): + localctx = ASLParser.Version_declContext(self, self._ctx, self.state) + self.enterRule(localctx, 10, self.RULE_version_decl) + try: + self.enterOuterAlt(localctx, 1) + self.state = 268 + self.match(ASLParser.VERSION) + self.state = 269 + self.match(ASLParser.COLON) + self.state = 270 + self.keyword_or_string() + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class Query_language_declContext(ParserRuleContext): + __slots__ = "parser" + + def __init__( + self, parser, parent: ParserRuleContext = None, invokingState: int = -1 + ): + super().__init__(parent, invokingState) + self.parser = parser + + def QUERYLANGUAGE(self): + return self.getToken(ASLParser.QUERYLANGUAGE, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def JSONPATH(self): + return self.getToken(ASLParser.JSONPATH, 0) + + def JSONATA(self): + return self.getToken(ASLParser.JSONATA, 0) + + def getRuleIndex(self): + return ASLParser.RULE_query_language_decl + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterQuery_language_decl"): + listener.enterQuery_language_decl(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitQuery_language_decl"): + listener.exitQuery_language_decl(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitQuery_language_decl"): + return visitor.visitQuery_language_decl(self) + else: + return visitor.visitChildren(self) + + def query_language_decl(self): + localctx = ASLParser.Query_language_declContext(self, self._ctx, self.state) + self.enterRule(localctx, 12, self.RULE_query_language_decl) + self._la = 0 # Token type + try: + self.enterOuterAlt(localctx, 1) + self.state = 272 + self.match(ASLParser.QUERYLANGUAGE) + self.state = 273 + self.match(ASLParser.COLON) + self.state = 274 + _la = self._input.LA(1) + if not (_la == 132 or _la == 133): + self._errHandler.recoverInline(self) + else: + self._errHandler.reportMatch(self) + self.consume() + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class State_stmtContext(ParserRuleContext): + __slots__ = "parser" + + def __init__( + self, parser, parent: ParserRuleContext = None, invokingState: int = -1 + ): + super().__init__(parent, invokingState) + self.parser = parser + + def comment_decl(self): + return self.getTypedRuleContext(ASLParser.Comment_declContext, 0) + + def query_language_decl(self): + return self.getTypedRuleContext(ASLParser.Query_language_declContext, 0) + + def type_decl(self): + return self.getTypedRuleContext(ASLParser.Type_declContext, 0) + + def input_path_decl(self): + return self.getTypedRuleContext(ASLParser.Input_path_declContext, 0) + + def resource_decl(self): + return self.getTypedRuleContext(ASLParser.Resource_declContext, 0) + + def next_decl(self): + return self.getTypedRuleContext(ASLParser.Next_declContext, 0) + + def result_decl(self): + return self.getTypedRuleContext(ASLParser.Result_declContext, 0) + + def result_path_decl(self): + return self.getTypedRuleContext(ASLParser.Result_path_declContext, 0) + + def output_path_decl(self): + return self.getTypedRuleContext(ASLParser.Output_path_declContext, 0) + + def end_decl(self): + return self.getTypedRuleContext(ASLParser.End_declContext, 0) + + def default_decl(self): + return self.getTypedRuleContext(ASLParser.Default_declContext, 0) + + def choices_decl(self): + return self.getTypedRuleContext(ASLParser.Choices_declContext, 0) + + def error_decl(self): + return self.getTypedRuleContext(ASLParser.Error_declContext, 0) + + def error_path_decl(self): + return self.getTypedRuleContext(ASLParser.Error_path_declContext, 0) + + def cause_decl(self): + return self.getTypedRuleContext(ASLParser.Cause_declContext, 0) + + def cause_path_decl(self): + return self.getTypedRuleContext(ASLParser.Cause_path_declContext, 0) + + def seconds_decl(self): + return self.getTypedRuleContext(ASLParser.Seconds_declContext, 0) + + def seconds_path_decl(self): + return self.getTypedRuleContext(ASLParser.Seconds_path_declContext, 0) + + def timestamp_decl(self): + return self.getTypedRuleContext(ASLParser.Timestamp_declContext, 0) + + def timestamp_path_decl(self): + return self.getTypedRuleContext(ASLParser.Timestamp_path_declContext, 0) + + def items_decl(self): + return self.getTypedRuleContext(ASLParser.Items_declContext, 0) + + def items_path_decl(self): + return self.getTypedRuleContext(ASLParser.Items_path_declContext, 0) + + def item_processor_decl(self): + return self.getTypedRuleContext(ASLParser.Item_processor_declContext, 0) + + def iterator_decl(self): + return self.getTypedRuleContext(ASLParser.Iterator_declContext, 0) + + def item_selector_decl(self): + return self.getTypedRuleContext(ASLParser.Item_selector_declContext, 0) + + def item_reader_decl(self): + return self.getTypedRuleContext(ASLParser.Item_reader_declContext, 0) + + def max_concurrency_decl(self): + return self.getTypedRuleContext(ASLParser.Max_concurrency_declContext, 0) + + def max_concurrency_path_decl(self): + return self.getTypedRuleContext( + ASLParser.Max_concurrency_path_declContext, 0 + ) + + def timeout_seconds_decl(self): + return self.getTypedRuleContext(ASLParser.Timeout_seconds_declContext, 0) + + def timeout_seconds_path_decl(self): + return self.getTypedRuleContext( + ASLParser.Timeout_seconds_path_declContext, 0 + ) + + def heartbeat_seconds_decl(self): + return self.getTypedRuleContext(ASLParser.Heartbeat_seconds_declContext, 0) + + def heartbeat_seconds_path_decl(self): + return self.getTypedRuleContext( + ASLParser.Heartbeat_seconds_path_declContext, 0 + ) + + def branches_decl(self): + return self.getTypedRuleContext(ASLParser.Branches_declContext, 0) + + def parameters_decl(self): + return self.getTypedRuleContext(ASLParser.Parameters_declContext, 0) + + def retry_decl(self): + return self.getTypedRuleContext(ASLParser.Retry_declContext, 0) + + def catch_decl(self): + return self.getTypedRuleContext(ASLParser.Catch_declContext, 0) + + def result_selector_decl(self): + return self.getTypedRuleContext(ASLParser.Result_selector_declContext, 0) + + def tolerated_failure_count_decl(self): + return self.getTypedRuleContext( + ASLParser.Tolerated_failure_count_declContext, 0 + ) + + def tolerated_failure_count_path_decl(self): + return self.getTypedRuleContext( + ASLParser.Tolerated_failure_count_path_declContext, 0 + ) + + def tolerated_failure_percentage_decl(self): + return self.getTypedRuleContext( + ASLParser.Tolerated_failure_percentage_declContext, 0 + ) + + def tolerated_failure_percentage_path_decl(self): + return self.getTypedRuleContext( + ASLParser.Tolerated_failure_percentage_path_declContext, 0 + ) + + def label_decl(self): + return self.getTypedRuleContext(ASLParser.Label_declContext, 0) + + def result_writer_decl(self): + return self.getTypedRuleContext(ASLParser.Result_writer_declContext, 0) + + def assign_decl(self): + return self.getTypedRuleContext(ASLParser.Assign_declContext, 0) + + def arguments_decl(self): + return self.getTypedRuleContext(ASLParser.Arguments_declContext, 0) + + def output_decl(self): + return self.getTypedRuleContext(ASLParser.Output_declContext, 0) + + def credentials_decl(self): + return self.getTypedRuleContext(ASLParser.Credentials_declContext, 0) + + def getRuleIndex(self): + return ASLParser.RULE_state_stmt + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterState_stmt"): + listener.enterState_stmt(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitState_stmt"): + listener.exitState_stmt(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitState_stmt"): + return visitor.visitState_stmt(self) + else: + return visitor.visitChildren(self) + + def state_stmt(self): + localctx = ASLParser.State_stmtContext(self, self._ctx, self.state) + self.enterRule(localctx, 14, self.RULE_state_stmt) + try: + self.state = 323 + self._errHandler.sync(self) + token = self._input.LA(1) + if token in [10]: + self.enterOuterAlt(localctx, 1) + self.state = 276 + self.comment_decl() + pass + elif token in [131]: + self.enterOuterAlt(localctx, 2) + self.state = 277 + self.query_language_decl() + pass + elif token in [15]: + self.enterOuterAlt(localctx, 3) + self.state = 278 + self.type_decl() + pass + elif token in [91]: + self.enterOuterAlt(localctx, 4) + self.state = 279 + self.input_path_decl() + pass + elif token in [90]: + self.enterOuterAlt(localctx, 5) + self.state = 280 + self.resource_decl() + pass + elif token in [115]: + self.enterOuterAlt(localctx, 6) + self.state = 281 + self.next_decl() + pass + elif token in [96]: + self.enterOuterAlt(localctx, 7) + self.state = 282 + self.result_decl() + pass + elif token in [95]: + self.enterOuterAlt(localctx, 8) + self.state = 283 + self.result_path_decl() + pass + elif token in [92]: + self.enterOuterAlt(localctx, 9) + self.state = 284 + self.output_path_decl() + pass + elif token in [116]: + self.enterOuterAlt(localctx, 10) + self.state = 285 + self.end_decl() + pass + elif token in [27]: + self.enterOuterAlt(localctx, 11) + self.state = 286 + self.default_decl() + pass + elif token in [24]: + self.enterOuterAlt(localctx, 12) + self.state = 287 + self.choices_decl() + pass + elif token in [119]: + self.enterOuterAlt(localctx, 13) + self.state = 288 + self.error_decl() + pass + elif token in [120]: + self.enterOuterAlt(localctx, 14) + self.state = 289 + self.error_path_decl() + pass + elif token in [117]: + self.enterOuterAlt(localctx, 15) + self.state = 290 + self.cause_decl() + pass + elif token in [118]: + self.enterOuterAlt(localctx, 16) + self.state = 291 + self.cause_path_decl() + pass + elif token in [72]: + self.enterOuterAlt(localctx, 17) + self.state = 292 + self.seconds_decl() + pass + elif token in [71]: + self.enterOuterAlt(localctx, 18) + self.state = 293 + self.seconds_path_decl() + pass + elif token in [74]: + self.enterOuterAlt(localctx, 19) + self.state = 294 + self.timestamp_decl() + pass + elif token in [73]: + self.enterOuterAlt(localctx, 20) + self.state = 295 + self.timestamp_path_decl() + pass + elif token in [93]: + self.enterOuterAlt(localctx, 21) + self.state = 296 + self.items_decl() + pass + elif token in [94]: + self.enterOuterAlt(localctx, 22) + self.state = 297 + self.items_path_decl() + pass + elif token in [85]: + self.enterOuterAlt(localctx, 23) + self.state = 298 + self.item_processor_decl() + pass + elif token in [86]: + self.enterOuterAlt(localctx, 24) + self.state = 299 + self.iterator_decl() + pass + elif token in [87]: + self.enterOuterAlt(localctx, 25) + self.state = 300 + self.item_selector_decl() + pass + elif token in [102]: + self.enterOuterAlt(localctx, 26) + self.state = 301 + self.item_reader_decl() + pass + elif token in [89]: + self.enterOuterAlt(localctx, 27) + self.state = 302 + self.max_concurrency_decl() + pass + elif token in [88]: + self.enterOuterAlt(localctx, 28) + self.state = 303 + self.max_concurrency_path_decl() + pass + elif token in [75]: + self.enterOuterAlt(localctx, 29) + self.state = 304 + self.timeout_seconds_decl() + pass + elif token in [76]: + self.enterOuterAlt(localctx, 30) + self.state = 305 + self.timeout_seconds_path_decl() + pass + elif token in [77]: + self.enterOuterAlt(localctx, 31) + self.state = 306 + self.heartbeat_seconds_decl() + pass + elif token in [78]: + self.enterOuterAlt(localctx, 32) + self.state = 307 + self.heartbeat_seconds_path_decl() + pass + elif token in [28]: + self.enterOuterAlt(localctx, 33) + self.state = 308 + self.branches_decl() + pass + elif token in [97]: + self.enterOuterAlt(localctx, 34) + self.state = 309 + self.parameters_decl() + pass + elif token in [121]: + self.enterOuterAlt(localctx, 35) + self.state = 310 + self.retry_decl() + pass + elif token in [130]: + self.enterOuterAlt(localctx, 36) + self.state = 311 + self.catch_decl() + pass + elif token in [101]: + self.enterOuterAlt(localctx, 37) + self.state = 312 + self.result_selector_decl() + pass + elif token in [109]: + self.enterOuterAlt(localctx, 38) + self.state = 313 + self.tolerated_failure_count_decl() + pass + elif token in [110]: + self.enterOuterAlt(localctx, 39) + self.state = 314 + self.tolerated_failure_count_path_decl() + pass + elif token in [111]: + self.enterOuterAlt(localctx, 40) + self.state = 315 + self.tolerated_failure_percentage_decl() + pass + elif token in [112]: + self.enterOuterAlt(localctx, 41) + self.state = 316 + self.tolerated_failure_percentage_path_decl() + pass + elif token in [113]: + self.enterOuterAlt(localctx, 42) + self.state = 317 + self.label_decl() + pass + elif token in [114]: + self.enterOuterAlt(localctx, 43) + self.state = 318 + self.result_writer_decl() + pass + elif token in [134]: + self.enterOuterAlt(localctx, 44) + self.state = 319 + self.assign_decl() + pass + elif token in [136]: + self.enterOuterAlt(localctx, 45) + self.state = 320 + self.arguments_decl() + pass + elif token in [135]: + self.enterOuterAlt(localctx, 46) + self.state = 321 + self.output_decl() + pass + elif token in [98]: + self.enterOuterAlt(localctx, 47) + self.state = 322 + self.credentials_decl() + pass + else: + raise NoViableAltException(self) + + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class States_declContext(ParserRuleContext): + __slots__ = "parser" + + def __init__( + self, parser, parent: ParserRuleContext = None, invokingState: int = -1 + ): + super().__init__(parent, invokingState) + self.parser = parser + + def STATES(self): + return self.getToken(ASLParser.STATES, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def LBRACE(self): + return self.getToken(ASLParser.LBRACE, 0) + + def state_decl(self, i: int = None): + if i is None: + return self.getTypedRuleContexts(ASLParser.State_declContext) + else: + return self.getTypedRuleContext(ASLParser.State_declContext, i) + + def RBRACE(self): + return self.getToken(ASLParser.RBRACE, 0) + + def COMMA(self, i: int = None): + if i is None: + return self.getTokens(ASLParser.COMMA) + else: + return self.getToken(ASLParser.COMMA, i) + + def getRuleIndex(self): + return ASLParser.RULE_states_decl + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterStates_decl"): + listener.enterStates_decl(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitStates_decl"): + listener.exitStates_decl(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitStates_decl"): + return visitor.visitStates_decl(self) + else: + return visitor.visitChildren(self) + + def states_decl(self): + localctx = ASLParser.States_declContext(self, self._ctx, self.state) + self.enterRule(localctx, 16, self.RULE_states_decl) + self._la = 0 # Token type + try: + self.enterOuterAlt(localctx, 1) + self.state = 325 + self.match(ASLParser.STATES) + self.state = 326 + self.match(ASLParser.COLON) + self.state = 327 + self.match(ASLParser.LBRACE) + self.state = 328 + self.state_decl() + self.state = 333 + self._errHandler.sync(self) + _la = self._input.LA(1) + while _la == 1: + self.state = 329 + self.match(ASLParser.COMMA) + self.state = 330 + self.state_decl() + self.state = 335 + self._errHandler.sync(self) + _la = self._input.LA(1) + + self.state = 336 + self.match(ASLParser.RBRACE) + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class State_nameContext(ParserRuleContext): + __slots__ = "parser" + + def __init__( + self, parser, parent: ParserRuleContext = None, invokingState: int = -1 + ): + super().__init__(parent, invokingState) + self.parser = parser + + def keyword_or_string(self): + return self.getTypedRuleContext(ASLParser.Keyword_or_stringContext, 0) + + def getRuleIndex(self): + return ASLParser.RULE_state_name + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterState_name"): + listener.enterState_name(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitState_name"): + listener.exitState_name(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitState_name"): + return visitor.visitState_name(self) + else: + return visitor.visitChildren(self) + + def state_name(self): + localctx = ASLParser.State_nameContext(self, self._ctx, self.state) + self.enterRule(localctx, 18, self.RULE_state_name) + try: + self.enterOuterAlt(localctx, 1) + self.state = 338 + self.keyword_or_string() + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class State_declContext(ParserRuleContext): + __slots__ = "parser" + + def __init__( + self, parser, parent: ParserRuleContext = None, invokingState: int = -1 + ): + super().__init__(parent, invokingState) + self.parser = parser + + def state_name(self): + return self.getTypedRuleContext(ASLParser.State_nameContext, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def state_decl_body(self): + return self.getTypedRuleContext(ASLParser.State_decl_bodyContext, 0) + + def getRuleIndex(self): + return ASLParser.RULE_state_decl + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterState_decl"): + listener.enterState_decl(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitState_decl"): + listener.exitState_decl(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitState_decl"): + return visitor.visitState_decl(self) + else: + return visitor.visitChildren(self) + + def state_decl(self): + localctx = ASLParser.State_declContext(self, self._ctx, self.state) + self.enterRule(localctx, 20, self.RULE_state_decl) + try: + self.enterOuterAlt(localctx, 1) + self.state = 340 + self.state_name() + self.state = 341 + self.match(ASLParser.COLON) + self.state = 342 + self.state_decl_body() + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class State_decl_bodyContext(ParserRuleContext): + __slots__ = "parser" + + def __init__( + self, parser, parent: ParserRuleContext = None, invokingState: int = -1 + ): + super().__init__(parent, invokingState) + self.parser = parser + + def LBRACE(self): + return self.getToken(ASLParser.LBRACE, 0) + + def state_stmt(self, i: int = None): + if i is None: + return self.getTypedRuleContexts(ASLParser.State_stmtContext) + else: + return self.getTypedRuleContext(ASLParser.State_stmtContext, i) + + def RBRACE(self): + return self.getToken(ASLParser.RBRACE, 0) + + def COMMA(self, i: int = None): + if i is None: + return self.getTokens(ASLParser.COMMA) + else: + return self.getToken(ASLParser.COMMA, i) + + def getRuleIndex(self): + return ASLParser.RULE_state_decl_body + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterState_decl_body"): + listener.enterState_decl_body(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitState_decl_body"): + listener.exitState_decl_body(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitState_decl_body"): + return visitor.visitState_decl_body(self) + else: + return visitor.visitChildren(self) + + def state_decl_body(self): + localctx = ASLParser.State_decl_bodyContext(self, self._ctx, self.state) + self.enterRule(localctx, 22, self.RULE_state_decl_body) + self._la = 0 # Token type + try: + self.enterOuterAlt(localctx, 1) + self.state = 344 + self.match(ASLParser.LBRACE) + self.state = 345 + self.state_stmt() + self.state = 350 + self._errHandler.sync(self) + _la = self._input.LA(1) + while _la == 1: + self.state = 346 + self.match(ASLParser.COMMA) + self.state = 347 + self.state_stmt() + self.state = 352 + self._errHandler.sync(self) + _la = self._input.LA(1) + + self.state = 353 + self.match(ASLParser.RBRACE) + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class Type_declContext(ParserRuleContext): + __slots__ = "parser" + + def __init__( + self, parser, parent: ParserRuleContext = None, invokingState: int = -1 + ): + super().__init__(parent, invokingState) + self.parser = parser + + def TYPE(self): + return self.getToken(ASLParser.TYPE, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def state_type(self): + return self.getTypedRuleContext(ASLParser.State_typeContext, 0) + + def getRuleIndex(self): + return ASLParser.RULE_type_decl + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterType_decl"): + listener.enterType_decl(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitType_decl"): + listener.exitType_decl(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitType_decl"): + return visitor.visitType_decl(self) + else: + return visitor.visitChildren(self) + + def type_decl(self): + localctx = ASLParser.Type_declContext(self, self._ctx, self.state) + self.enterRule(localctx, 24, self.RULE_type_decl) + try: + self.enterOuterAlt(localctx, 1) + self.state = 355 + self.match(ASLParser.TYPE) + self.state = 356 + self.match(ASLParser.COLON) + self.state = 357 + self.state_type() + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class Next_declContext(ParserRuleContext): + __slots__ = "parser" + + def __init__( + self, parser, parent: ParserRuleContext = None, invokingState: int = -1 + ): + super().__init__(parent, invokingState) + self.parser = parser + + def NEXT(self): + return self.getToken(ASLParser.NEXT, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def keyword_or_string(self): + return self.getTypedRuleContext(ASLParser.Keyword_or_stringContext, 0) + + def getRuleIndex(self): + return ASLParser.RULE_next_decl + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterNext_decl"): + listener.enterNext_decl(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitNext_decl"): + listener.exitNext_decl(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitNext_decl"): + return visitor.visitNext_decl(self) + else: + return visitor.visitChildren(self) + + def next_decl(self): + localctx = ASLParser.Next_declContext(self, self._ctx, self.state) + self.enterRule(localctx, 26, self.RULE_next_decl) + try: + self.enterOuterAlt(localctx, 1) + self.state = 359 + self.match(ASLParser.NEXT) + self.state = 360 + self.match(ASLParser.COLON) + self.state = 361 + self.keyword_or_string() + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class Resource_declContext(ParserRuleContext): + __slots__ = "parser" + + def __init__( + self, parser, parent: ParserRuleContext = None, invokingState: int = -1 + ): + super().__init__(parent, invokingState) + self.parser = parser + + def RESOURCE(self): + return self.getToken(ASLParser.RESOURCE, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def keyword_or_string(self): + return self.getTypedRuleContext(ASLParser.Keyword_or_stringContext, 0) + + def getRuleIndex(self): + return ASLParser.RULE_resource_decl + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterResource_decl"): + listener.enterResource_decl(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitResource_decl"): + listener.exitResource_decl(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitResource_decl"): + return visitor.visitResource_decl(self) + else: + return visitor.visitChildren(self) + + def resource_decl(self): + localctx = ASLParser.Resource_declContext(self, self._ctx, self.state) + self.enterRule(localctx, 28, self.RULE_resource_decl) + try: + self.enterOuterAlt(localctx, 1) + self.state = 363 + self.match(ASLParser.RESOURCE) + self.state = 364 + self.match(ASLParser.COLON) + self.state = 365 + self.keyword_or_string() + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class Input_path_declContext(ParserRuleContext): + __slots__ = "parser" + + def __init__( + self, parser, parent: ParserRuleContext = None, invokingState: int = -1 + ): + super().__init__(parent, invokingState) + self.parser = parser + + def getRuleIndex(self): + return ASLParser.RULE_input_path_decl + + def copyFrom(self, ctx: ParserRuleContext): + super().copyFrom(ctx) + + class Input_path_decl_path_context_objectContext(Input_path_declContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Input_path_declContext + super().__init__(parser) + self.copyFrom(ctx) + + def INPUTPATH(self): + return self.getToken(ASLParser.INPUTPATH, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def STRINGPATHCONTEXTOBJ(self): + return self.getToken(ASLParser.STRINGPATHCONTEXTOBJ, 0) + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterInput_path_decl_path_context_object"): + listener.enterInput_path_decl_path_context_object(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitInput_path_decl_path_context_object"): + listener.exitInput_path_decl_path_context_object(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitInput_path_decl_path_context_object"): + return visitor.visitInput_path_decl_path_context_object(self) + else: + return visitor.visitChildren(self) + + class Input_path_decl_varContext(Input_path_declContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Input_path_declContext + super().__init__(parser) + self.copyFrom(ctx) + + def INPUTPATH(self): + return self.getToken(ASLParser.INPUTPATH, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def variable_sample(self): + return self.getTypedRuleContext(ASLParser.Variable_sampleContext, 0) + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterInput_path_decl_var"): + listener.enterInput_path_decl_var(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitInput_path_decl_var"): + listener.exitInput_path_decl_var(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitInput_path_decl_var"): + return visitor.visitInput_path_decl_var(self) + else: + return visitor.visitChildren(self) + + class Input_path_decl_pathContext(Input_path_declContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Input_path_declContext + super().__init__(parser) + self.copyFrom(ctx) + + def INPUTPATH(self): + return self.getToken(ASLParser.INPUTPATH, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def NULL(self): + return self.getToken(ASLParser.NULL, 0) + + def keyword_or_string(self): + return self.getTypedRuleContext(ASLParser.Keyword_or_stringContext, 0) + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterInput_path_decl_path"): + listener.enterInput_path_decl_path(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitInput_path_decl_path"): + listener.exitInput_path_decl_path(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitInput_path_decl_path"): + return visitor.visitInput_path_decl_path(self) + else: + return visitor.visitChildren(self) + + def input_path_decl(self): + localctx = ASLParser.Input_path_declContext(self, self._ctx, self.state) + self.enterRule(localctx, 30, self.RULE_input_path_decl) + try: + self.state = 379 + self._errHandler.sync(self) + la_ = self._interp.adaptivePredict(self._input, 6, self._ctx) + if la_ == 1: + localctx = ASLParser.Input_path_decl_varContext(self, localctx) + self.enterOuterAlt(localctx, 1) + self.state = 367 + self.match(ASLParser.INPUTPATH) + self.state = 368 + self.match(ASLParser.COLON) + self.state = 369 + self.variable_sample() + pass + + elif la_ == 2: + localctx = ASLParser.Input_path_decl_path_context_objectContext( + self, localctx + ) + self.enterOuterAlt(localctx, 2) + self.state = 370 + self.match(ASLParser.INPUTPATH) + self.state = 371 + self.match(ASLParser.COLON) + self.state = 372 + self.match(ASLParser.STRINGPATHCONTEXTOBJ) + pass + + elif la_ == 3: + localctx = ASLParser.Input_path_decl_pathContext(self, localctx) + self.enterOuterAlt(localctx, 3) + self.state = 373 + self.match(ASLParser.INPUTPATH) + self.state = 374 + self.match(ASLParser.COLON) + self.state = 377 + self._errHandler.sync(self) + token = self._input.LA(1) + if token in [9]: + self.state = 375 + self.match(ASLParser.NULL) + pass + elif token in [ + 10, + 11, + 12, + 13, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 119, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 134, + 135, + 136, + 137, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + ]: + self.state = 376 + self.keyword_or_string() + pass + else: + raise NoViableAltException(self) + + pass + + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class Result_declContext(ParserRuleContext): + __slots__ = "parser" + + def __init__( + self, parser, parent: ParserRuleContext = None, invokingState: int = -1 + ): + super().__init__(parent, invokingState) + self.parser = parser + + def RESULT(self): + return self.getToken(ASLParser.RESULT, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def json_value_decl(self): + return self.getTypedRuleContext(ASLParser.Json_value_declContext, 0) + + def getRuleIndex(self): + return ASLParser.RULE_result_decl + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterResult_decl"): + listener.enterResult_decl(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitResult_decl"): + listener.exitResult_decl(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitResult_decl"): + return visitor.visitResult_decl(self) + else: + return visitor.visitChildren(self) + + def result_decl(self): + localctx = ASLParser.Result_declContext(self, self._ctx, self.state) + self.enterRule(localctx, 32, self.RULE_result_decl) + try: + self.enterOuterAlt(localctx, 1) + self.state = 381 + self.match(ASLParser.RESULT) + self.state = 382 + self.match(ASLParser.COLON) + self.state = 383 + self.json_value_decl() + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class Result_path_declContext(ParserRuleContext): + __slots__ = "parser" + + def __init__( + self, parser, parent: ParserRuleContext = None, invokingState: int = -1 + ): + super().__init__(parent, invokingState) + self.parser = parser + + def RESULTPATH(self): + return self.getToken(ASLParser.RESULTPATH, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def NULL(self): + return self.getToken(ASLParser.NULL, 0) + + def keyword_or_string(self): + return self.getTypedRuleContext(ASLParser.Keyword_or_stringContext, 0) + + def getRuleIndex(self): + return ASLParser.RULE_result_path_decl + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterResult_path_decl"): + listener.enterResult_path_decl(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitResult_path_decl"): + listener.exitResult_path_decl(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitResult_path_decl"): + return visitor.visitResult_path_decl(self) + else: + return visitor.visitChildren(self) + + def result_path_decl(self): + localctx = ASLParser.Result_path_declContext(self, self._ctx, self.state) + self.enterRule(localctx, 34, self.RULE_result_path_decl) + try: + self.enterOuterAlt(localctx, 1) + self.state = 385 + self.match(ASLParser.RESULTPATH) + self.state = 386 + self.match(ASLParser.COLON) + self.state = 389 + self._errHandler.sync(self) + token = self._input.LA(1) + if token in [9]: + self.state = 387 + self.match(ASLParser.NULL) + pass + elif token in [ + 10, + 11, + 12, + 13, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 119, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 134, + 135, + 136, + 137, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + ]: + self.state = 388 + self.keyword_or_string() + pass + else: + raise NoViableAltException(self) + + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class Output_path_declContext(ParserRuleContext): + __slots__ = "parser" + + def __init__( + self, parser, parent: ParserRuleContext = None, invokingState: int = -1 + ): + super().__init__(parent, invokingState) + self.parser = parser + + def getRuleIndex(self): + return ASLParser.RULE_output_path_decl + + def copyFrom(self, ctx: ParserRuleContext): + super().copyFrom(ctx) + + class Output_path_decl_path_context_objectContext(Output_path_declContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Output_path_declContext + super().__init__(parser) + self.copyFrom(ctx) + + def OUTPUTPATH(self): + return self.getToken(ASLParser.OUTPUTPATH, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def STRINGPATHCONTEXTOBJ(self): + return self.getToken(ASLParser.STRINGPATHCONTEXTOBJ, 0) + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterOutput_path_decl_path_context_object"): + listener.enterOutput_path_decl_path_context_object(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitOutput_path_decl_path_context_object"): + listener.exitOutput_path_decl_path_context_object(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitOutput_path_decl_path_context_object"): + return visitor.visitOutput_path_decl_path_context_object(self) + else: + return visitor.visitChildren(self) + + class Output_path_decl_varContext(Output_path_declContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Output_path_declContext + super().__init__(parser) + self.copyFrom(ctx) + + def OUTPUTPATH(self): + return self.getToken(ASLParser.OUTPUTPATH, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def variable_sample(self): + return self.getTypedRuleContext(ASLParser.Variable_sampleContext, 0) + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterOutput_path_decl_var"): + listener.enterOutput_path_decl_var(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitOutput_path_decl_var"): + listener.exitOutput_path_decl_var(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitOutput_path_decl_var"): + return visitor.visitOutput_path_decl_var(self) + else: + return visitor.visitChildren(self) + + class Output_path_decl_pathContext(Output_path_declContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Output_path_declContext + super().__init__(parser) + self.copyFrom(ctx) + + def OUTPUTPATH(self): + return self.getToken(ASLParser.OUTPUTPATH, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def NULL(self): + return self.getToken(ASLParser.NULL, 0) + + def keyword_or_string(self): + return self.getTypedRuleContext(ASLParser.Keyword_or_stringContext, 0) + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterOutput_path_decl_path"): + listener.enterOutput_path_decl_path(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitOutput_path_decl_path"): + listener.exitOutput_path_decl_path(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitOutput_path_decl_path"): + return visitor.visitOutput_path_decl_path(self) + else: + return visitor.visitChildren(self) + + def output_path_decl(self): + localctx = ASLParser.Output_path_declContext(self, self._ctx, self.state) + self.enterRule(localctx, 36, self.RULE_output_path_decl) + try: + self.state = 403 + self._errHandler.sync(self) + la_ = self._interp.adaptivePredict(self._input, 9, self._ctx) + if la_ == 1: + localctx = ASLParser.Output_path_decl_varContext(self, localctx) + self.enterOuterAlt(localctx, 1) + self.state = 391 + self.match(ASLParser.OUTPUTPATH) + self.state = 392 + self.match(ASLParser.COLON) + self.state = 393 + self.variable_sample() + pass + + elif la_ == 2: + localctx = ASLParser.Output_path_decl_path_context_objectContext( + self, localctx + ) + self.enterOuterAlt(localctx, 2) + self.state = 394 + self.match(ASLParser.OUTPUTPATH) + self.state = 395 + self.match(ASLParser.COLON) + self.state = 396 + self.match(ASLParser.STRINGPATHCONTEXTOBJ) + pass + + elif la_ == 3: + localctx = ASLParser.Output_path_decl_pathContext(self, localctx) + self.enterOuterAlt(localctx, 3) + self.state = 397 + self.match(ASLParser.OUTPUTPATH) + self.state = 398 + self.match(ASLParser.COLON) + self.state = 401 + self._errHandler.sync(self) + token = self._input.LA(1) + if token in [9]: + self.state = 399 + self.match(ASLParser.NULL) + pass + elif token in [ + 10, + 11, + 12, + 13, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 119, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 134, + 135, + 136, + 137, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + ]: + self.state = 400 + self.keyword_or_string() + pass + else: + raise NoViableAltException(self) + + pass + + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class End_declContext(ParserRuleContext): + __slots__ = "parser" + + def __init__( + self, parser, parent: ParserRuleContext = None, invokingState: int = -1 + ): + super().__init__(parent, invokingState) + self.parser = parser + + def END(self): + return self.getToken(ASLParser.END, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def TRUE(self): + return self.getToken(ASLParser.TRUE, 0) + + def FALSE(self): + return self.getToken(ASLParser.FALSE, 0) + + def getRuleIndex(self): + return ASLParser.RULE_end_decl + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterEnd_decl"): + listener.enterEnd_decl(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitEnd_decl"): + listener.exitEnd_decl(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitEnd_decl"): + return visitor.visitEnd_decl(self) + else: + return visitor.visitChildren(self) + + def end_decl(self): + localctx = ASLParser.End_declContext(self, self._ctx, self.state) + self.enterRule(localctx, 38, self.RULE_end_decl) + self._la = 0 # Token type + try: + self.enterOuterAlt(localctx, 1) + self.state = 405 + self.match(ASLParser.END) + self.state = 406 + self.match(ASLParser.COLON) + self.state = 407 + _la = self._input.LA(1) + if not (_la == 7 or _la == 8): + self._errHandler.recoverInline(self) + else: + self._errHandler.reportMatch(self) + self.consume() + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class Default_declContext(ParserRuleContext): + __slots__ = "parser" + + def __init__( + self, parser, parent: ParserRuleContext = None, invokingState: int = -1 + ): + super().__init__(parent, invokingState) + self.parser = parser + + def DEFAULT(self): + return self.getToken(ASLParser.DEFAULT, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def keyword_or_string(self): + return self.getTypedRuleContext(ASLParser.Keyword_or_stringContext, 0) + + def getRuleIndex(self): + return ASLParser.RULE_default_decl + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterDefault_decl"): + listener.enterDefault_decl(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitDefault_decl"): + listener.exitDefault_decl(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitDefault_decl"): + return visitor.visitDefault_decl(self) + else: + return visitor.visitChildren(self) + + def default_decl(self): + localctx = ASLParser.Default_declContext(self, self._ctx, self.state) + self.enterRule(localctx, 40, self.RULE_default_decl) + try: + self.enterOuterAlt(localctx, 1) + self.state = 409 + self.match(ASLParser.DEFAULT) + self.state = 410 + self.match(ASLParser.COLON) + self.state = 411 + self.keyword_or_string() + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class Error_declContext(ParserRuleContext): + __slots__ = "parser" + + def __init__( + self, parser, parent: ParserRuleContext = None, invokingState: int = -1 + ): + super().__init__(parent, invokingState) + self.parser = parser + + def getRuleIndex(self): + return ASLParser.RULE_error_decl + + def copyFrom(self, ctx: ParserRuleContext): + super().copyFrom(ctx) + + class Error_stringContext(Error_declContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Error_declContext + super().__init__(parser) + self.copyFrom(ctx) + + def ERROR(self): + return self.getToken(ASLParser.ERROR, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def keyword_or_string(self): + return self.getTypedRuleContext(ASLParser.Keyword_or_stringContext, 0) + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterError_string"): + listener.enterError_string(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitError_string"): + listener.exitError_string(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitError_string"): + return visitor.visitError_string(self) + else: + return visitor.visitChildren(self) + + class Error_jsonataContext(Error_declContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Error_declContext + super().__init__(parser) + self.copyFrom(ctx) + + def ERROR(self): + return self.getToken(ASLParser.ERROR, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def STRINGJSONATA(self): + return self.getToken(ASLParser.STRINGJSONATA, 0) + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterError_jsonata"): + listener.enterError_jsonata(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitError_jsonata"): + listener.exitError_jsonata(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitError_jsonata"): + return visitor.visitError_jsonata(self) + else: + return visitor.visitChildren(self) + + def error_decl(self): + localctx = ASLParser.Error_declContext(self, self._ctx, self.state) + self.enterRule(localctx, 42, self.RULE_error_decl) + try: + self.state = 419 + self._errHandler.sync(self) + la_ = self._interp.adaptivePredict(self._input, 10, self._ctx) + if la_ == 1: + localctx = ASLParser.Error_jsonataContext(self, localctx) + self.enterOuterAlt(localctx, 1) + self.state = 413 + self.match(ASLParser.ERROR) + self.state = 414 + self.match(ASLParser.COLON) + self.state = 415 + self.match(ASLParser.STRINGJSONATA) + pass + + elif la_ == 2: + localctx = ASLParser.Error_stringContext(self, localctx) + self.enterOuterAlt(localctx, 2) + self.state = 416 + self.match(ASLParser.ERROR) + self.state = 417 + self.match(ASLParser.COLON) + self.state = 418 + self.keyword_or_string() + pass + + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class Error_path_declContext(ParserRuleContext): + __slots__ = "parser" + + def __init__( + self, parser, parent: ParserRuleContext = None, invokingState: int = -1 + ): + super().__init__(parent, invokingState) + self.parser = parser + + def getRuleIndex(self): + return ASLParser.RULE_error_path_decl + + def copyFrom(self, ctx: ParserRuleContext): + super().copyFrom(ctx) + + class Error_path_decl_intrinsicContext(Error_path_declContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Error_path_declContext + super().__init__(parser) + self.copyFrom(ctx) + + def ERRORPATH(self): + return self.getToken(ASLParser.ERRORPATH, 0) - RULE_state_machine = 0 - RULE_program_decl = 1 - RULE_top_layer_stmt = 2 - RULE_startat_decl = 3 - RULE_comment_decl = 4 - RULE_version_decl = 5 - RULE_state_stmt = 6 - RULE_states_decl = 7 - RULE_state_name = 8 - RULE_state_decl = 9 - RULE_state_decl_body = 10 - RULE_type_decl = 11 - RULE_next_decl = 12 - RULE_resource_decl = 13 - RULE_input_path_decl = 14 - RULE_result_decl = 15 - RULE_result_path_decl = 16 - RULE_output_path_decl = 17 - RULE_end_decl = 18 - RULE_default_decl = 19 - RULE_error_decl = 20 - RULE_error_path_decl = 21 - RULE_cause_decl = 22 - RULE_cause_path_decl = 23 - RULE_seconds_decl = 24 - RULE_seconds_path_decl = 25 - RULE_timestamp_decl = 26 - RULE_timestamp_path_decl = 27 - RULE_items_path_decl = 28 - RULE_max_concurrency_decl = 29 - RULE_max_concurrency_path_decl = 30 - RULE_parameters_decl = 31 - RULE_timeout_seconds_decl = 32 - RULE_timeout_seconds_path_decl = 33 - RULE_heartbeat_seconds_decl = 34 - RULE_heartbeat_seconds_path_decl = 35 - RULE_payload_tmpl_decl = 36 - RULE_payload_binding = 37 - RULE_intrinsic_func = 38 - RULE_payload_arr_decl = 39 - RULE_payload_value_decl = 40 - RULE_payload_value_lit = 41 - RULE_result_selector_decl = 42 - RULE_state_type = 43 - RULE_choices_decl = 44 - RULE_choice_rule = 45 - RULE_comparison_variable_stmt = 46 - RULE_comparison_composite_stmt = 47 - RULE_comparison_composite = 48 - RULE_variable_decl = 49 - RULE_comparison_func = 50 - RULE_branches_decl = 51 - RULE_item_processor_decl = 52 - RULE_item_processor_item = 53 - RULE_processor_config_decl = 54 - RULE_processor_config_field = 55 - RULE_mode_decl = 56 - RULE_mode_type = 57 - RULE_execution_decl = 58 - RULE_execution_type = 59 - RULE_iterator_decl = 60 - RULE_iterator_decl_item = 61 - RULE_item_selector_decl = 62 - RULE_item_reader_decl = 63 - RULE_items_reader_field = 64 - RULE_reader_config_decl = 65 - RULE_reader_config_field = 66 - RULE_input_type_decl = 67 - RULE_csv_header_location_decl = 68 - RULE_csv_headers_decl = 69 - RULE_max_items_decl = 70 - RULE_max_items_path_decl = 71 - RULE_tolerated_failure_count_decl = 72 - RULE_tolerated_failure_count_path_decl = 73 - RULE_tolerated_failure_percentage_decl = 74 - RULE_tolerated_failure_percentage_path_decl = 75 - RULE_label_decl = 76 - RULE_retry_decl = 77 - RULE_retrier_decl = 78 - RULE_retrier_stmt = 79 - RULE_error_equals_decl = 80 - RULE_interval_seconds_decl = 81 - RULE_max_attempts_decl = 82 - RULE_backoff_rate_decl = 83 - RULE_max_delay_seconds_decl = 84 - RULE_jitter_strategy_decl = 85 - RULE_catch_decl = 86 - RULE_catcher_decl = 87 - RULE_catcher_stmt = 88 - RULE_comparison_op = 89 - RULE_choice_operator = 90 - RULE_states_error_name = 91 - RULE_error_name = 92 - RULE_json_obj_decl = 93 - RULE_json_binding = 94 - RULE_json_arr_decl = 95 - RULE_json_value_decl = 96 - RULE_keyword_or_string = 97 + def COLON(self): + return self.getToken(ASLParser.COLON, 0) - ruleNames = [ - "state_machine", - "program_decl", - "top_layer_stmt", - "startat_decl", - "comment_decl", - "version_decl", - "state_stmt", - "states_decl", - "state_name", - "state_decl", - "state_decl_body", - "type_decl", - "next_decl", - "resource_decl", - "input_path_decl", - "result_decl", - "result_path_decl", - "output_path_decl", - "end_decl", - "default_decl", - "error_decl", - "error_path_decl", - "cause_decl", - "cause_path_decl", - "seconds_decl", - "seconds_path_decl", - "timestamp_decl", - "timestamp_path_decl", - "items_path_decl", - "max_concurrency_decl", - "max_concurrency_path_decl", - "parameters_decl", - "timeout_seconds_decl", - "timeout_seconds_path_decl", - "heartbeat_seconds_decl", - "heartbeat_seconds_path_decl", - "payload_tmpl_decl", - "payload_binding", - "intrinsic_func", - "payload_arr_decl", - "payload_value_decl", - "payload_value_lit", - "result_selector_decl", - "state_type", - "choices_decl", - "choice_rule", - "comparison_variable_stmt", - "comparison_composite_stmt", - "comparison_composite", - "variable_decl", - "comparison_func", - "branches_decl", - "item_processor_decl", - "item_processor_item", - "processor_config_decl", - "processor_config_field", - "mode_decl", - "mode_type", - "execution_decl", - "execution_type", - "iterator_decl", - "iterator_decl_item", - "item_selector_decl", - "item_reader_decl", - "items_reader_field", - "reader_config_decl", - "reader_config_field", - "input_type_decl", - "csv_header_location_decl", - "csv_headers_decl", - "max_items_decl", - "max_items_path_decl", - "tolerated_failure_count_decl", - "tolerated_failure_count_path_decl", - "tolerated_failure_percentage_decl", - "tolerated_failure_percentage_path_decl", - "label_decl", - "retry_decl", - "retrier_decl", - "retrier_stmt", - "error_equals_decl", - "interval_seconds_decl", - "max_attempts_decl", - "backoff_rate_decl", - "max_delay_seconds_decl", - "jitter_strategy_decl", - "catch_decl", - "catcher_decl", - "catcher_stmt", - "comparison_op", - "choice_operator", - "states_error_name", - "error_name", - "json_obj_decl", - "json_binding", - "json_arr_decl", - "json_value_decl", - "keyword_or_string", - ] + def STRINGINTRINSICFUNC(self): + return self.getToken(ASLParser.STRINGINTRINSICFUNC, 0) - EOF = Token.EOF - COMMA = 1 - COLON = 2 - LBRACK = 3 - RBRACK = 4 - LBRACE = 5 - RBRACE = 6 - TRUE = 7 - FALSE = 8 - NULL = 9 - COMMENT = 10 - STATES = 11 - STARTAT = 12 - NEXTSTATE = 13 - VERSION = 14 - TYPE = 15 - TASK = 16 - CHOICE = 17 - FAIL = 18 - SUCCEED = 19 - PASS = 20 - WAIT = 21 - PARALLEL = 22 - MAP = 23 - CHOICES = 24 - VARIABLE = 25 - DEFAULT = 26 - BRANCHES = 27 - AND = 28 - BOOLEANEQUALS = 29 - BOOLEANQUALSPATH = 30 - ISBOOLEAN = 31 - ISNULL = 32 - ISNUMERIC = 33 - ISPRESENT = 34 - ISSTRING = 35 - ISTIMESTAMP = 36 - NOT = 37 - NUMERICEQUALS = 38 - NUMERICEQUALSPATH = 39 - NUMERICGREATERTHAN = 40 - NUMERICGREATERTHANPATH = 41 - NUMERICGREATERTHANEQUALS = 42 - NUMERICGREATERTHANEQUALSPATH = 43 - NUMERICLESSTHAN = 44 - NUMERICLESSTHANPATH = 45 - NUMERICLESSTHANEQUALS = 46 - NUMERICLESSTHANEQUALSPATH = 47 - OR = 48 - STRINGEQUALS = 49 - STRINGEQUALSPATH = 50 - STRINGGREATERTHAN = 51 - STRINGGREATERTHANPATH = 52 - STRINGGREATERTHANEQUALS = 53 - STRINGGREATERTHANEQUALSPATH = 54 - STRINGLESSTHAN = 55 - STRINGLESSTHANPATH = 56 - STRINGLESSTHANEQUALS = 57 - STRINGLESSTHANEQUALSPATH = 58 - STRINGMATCHES = 59 - TIMESTAMPEQUALS = 60 - TIMESTAMPEQUALSPATH = 61 - TIMESTAMPGREATERTHAN = 62 - TIMESTAMPGREATERTHANPATH = 63 - TIMESTAMPGREATERTHANEQUALS = 64 - TIMESTAMPGREATERTHANEQUALSPATH = 65 - TIMESTAMPLESSTHAN = 66 - TIMESTAMPLESSTHANPATH = 67 - TIMESTAMPLESSTHANEQUALS = 68 - TIMESTAMPLESSTHANEQUALSPATH = 69 - SECONDSPATH = 70 - SECONDS = 71 - TIMESTAMPPATH = 72 - TIMESTAMP = 73 - TIMEOUTSECONDS = 74 - TIMEOUTSECONDSPATH = 75 - HEARTBEATSECONDS = 76 - HEARTBEATSECONDSPATH = 77 - PROCESSORCONFIG = 78 - MODE = 79 - INLINE = 80 - DISTRIBUTED = 81 - EXECUTIONTYPE = 82 - STANDARD = 83 - ITEMPROCESSOR = 84 - ITERATOR = 85 - ITEMSELECTOR = 86 - MAXCONCURRENCYPATH = 87 - MAXCONCURRENCY = 88 - RESOURCE = 89 - INPUTPATH = 90 - OUTPUTPATH = 91 - ITEMSPATH = 92 - RESULTPATH = 93 - RESULT = 94 - PARAMETERS = 95 - RESULTSELECTOR = 96 - ITEMREADER = 97 - READERCONFIG = 98 - INPUTTYPE = 99 - CSVHEADERLOCATION = 100 - CSVHEADERS = 101 - MAXITEMS = 102 - MAXITEMSPATH = 103 - TOLERATEDFAILURECOUNT = 104 - TOLERATEDFAILURECOUNTPATH = 105 - TOLERATEDFAILUREPERCENTAGE = 106 - TOLERATEDFAILUREPERCENTAGEPATH = 107 - LABEL = 108 - NEXT = 109 - END = 110 - CAUSE = 111 - CAUSEPATH = 112 - ERROR = 113 - ERRORPATH = 114 - RETRY = 115 - ERROREQUALS = 116 - INTERVALSECONDS = 117 - MAXATTEMPTS = 118 - BACKOFFRATE = 119 - MAXDELAYSECONDS = 120 - JITTERSTRATEGY = 121 - FULL = 122 - NONE = 123 - CATCH = 124 - ERRORNAMEStatesALL = 125 - ERRORNAMEStatesDataLimitExceeded = 126 - ERRORNAMEStatesHeartbeatTimeout = 127 - ERRORNAMEStatesTimeout = 128 - ERRORNAMEStatesTaskFailed = 129 - ERRORNAMEStatesPermissions = 130 - ERRORNAMEStatesResultPathMatchFailure = 131 - ERRORNAMEStatesParameterPathFailure = 132 - ERRORNAMEStatesBranchFailed = 133 - ERRORNAMEStatesNoChoiceMatched = 134 - ERRORNAMEStatesIntrinsicFailure = 135 - ERRORNAMEStatesExceedToleratedFailureThreshold = 136 - ERRORNAMEStatesItemReaderFailed = 137 - ERRORNAMEStatesResultWriterFailed = 138 - ERRORNAMEStatesRuntime = 139 - STRINGDOLLAR = 140 - STRINGPATHCONTEXTOBJ = 141 - STRINGPATH = 142 - STRING = 143 - INT = 144 - NUMBER = 145 - WS = 146 + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterError_path_decl_intrinsic"): + listener.enterError_path_decl_intrinsic(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitError_path_decl_intrinsic"): + listener.exitError_path_decl_intrinsic(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitError_path_decl_intrinsic"): + return visitor.visitError_path_decl_intrinsic(self) + else: + return visitor.visitChildren(self) + + class Error_path_decl_pathContext(Error_path_declContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Error_path_declContext + super().__init__(parser) + self.copyFrom(ctx) + + def ERRORPATH(self): + return self.getToken(ASLParser.ERRORPATH, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def STRINGPATH(self): + return self.getToken(ASLParser.STRINGPATH, 0) + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterError_path_decl_path"): + listener.enterError_path_decl_path(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitError_path_decl_path"): + listener.exitError_path_decl_path(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitError_path_decl_path"): + return visitor.visitError_path_decl_path(self) + else: + return visitor.visitChildren(self) + + class Error_path_decl_varContext(Error_path_declContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Error_path_declContext + super().__init__(parser) + self.copyFrom(ctx) + + def ERRORPATH(self): + return self.getToken(ASLParser.ERRORPATH, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def variable_sample(self): + return self.getTypedRuleContext(ASLParser.Variable_sampleContext, 0) + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterError_path_decl_var"): + listener.enterError_path_decl_var(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitError_path_decl_var"): + listener.exitError_path_decl_var(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitError_path_decl_var"): + return visitor.visitError_path_decl_var(self) + else: + return visitor.visitChildren(self) + + class Error_path_decl_contextContext(Error_path_declContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Error_path_declContext + super().__init__(parser) + self.copyFrom(ctx) + + def ERRORPATH(self): + return self.getToken(ASLParser.ERRORPATH, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def STRINGPATHCONTEXTOBJ(self): + return self.getToken(ASLParser.STRINGPATHCONTEXTOBJ, 0) + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterError_path_decl_context"): + listener.enterError_path_decl_context(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitError_path_decl_context"): + listener.exitError_path_decl_context(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitError_path_decl_context"): + return visitor.visitError_path_decl_context(self) + else: + return visitor.visitChildren(self) + + def error_path_decl(self): + localctx = ASLParser.Error_path_declContext(self, self._ctx, self.state) + self.enterRule(localctx, 44, self.RULE_error_path_decl) + try: + self.state = 433 + self._errHandler.sync(self) + la_ = self._interp.adaptivePredict(self._input, 11, self._ctx) + if la_ == 1: + localctx = ASLParser.Error_path_decl_varContext(self, localctx) + self.enterOuterAlt(localctx, 1) + self.state = 421 + self.match(ASLParser.ERRORPATH) + self.state = 422 + self.match(ASLParser.COLON) + self.state = 423 + self.variable_sample() + pass + + elif la_ == 2: + localctx = ASLParser.Error_path_decl_pathContext(self, localctx) + self.enterOuterAlt(localctx, 2) + self.state = 424 + self.match(ASLParser.ERRORPATH) + self.state = 425 + self.match(ASLParser.COLON) + self.state = 426 + self.match(ASLParser.STRINGPATH) + pass + + elif la_ == 3: + localctx = ASLParser.Error_path_decl_contextContext(self, localctx) + self.enterOuterAlt(localctx, 3) + self.state = 427 + self.match(ASLParser.ERRORPATH) + self.state = 428 + self.match(ASLParser.COLON) + self.state = 429 + self.match(ASLParser.STRINGPATHCONTEXTOBJ) + pass + + elif la_ == 4: + localctx = ASLParser.Error_path_decl_intrinsicContext(self, localctx) + self.enterOuterAlt(localctx, 4) + self.state = 430 + self.match(ASLParser.ERRORPATH) + self.state = 431 + self.match(ASLParser.COLON) + self.state = 432 + self.match(ASLParser.STRINGINTRINSICFUNC) + pass - def __init__(self, input: TokenStream, output: TextIO = sys.stdout): - super().__init__(input, output) - self.checkVersion("4.13.1") - self._interp = ParserATNSimulator( - self, self.atn, self.decisionsToDFA, self.sharedContextCache - ) - self._predicates = None + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx - class State_machineContext(ParserRuleContext): + class Cause_declContext(ParserRuleContext): __slots__ = "parser" def __init__( @@ -8169,38 +14404,295 @@ def __init__( super().__init__(parent, invokingState) self.parser = parser - def program_decl(self): - return self.getTypedRuleContext(ASLParser.Program_declContext, 0) + def getRuleIndex(self): + return ASLParser.RULE_cause_decl - def EOF(self): - return self.getToken(ASLParser.EOF, 0) + def copyFrom(self, ctx: ParserRuleContext): + super().copyFrom(ctx) + + class Cause_stringContext(Cause_declContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Cause_declContext + super().__init__(parser) + self.copyFrom(ctx) + + def CAUSE(self): + return self.getToken(ASLParser.CAUSE, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def keyword_or_string(self): + return self.getTypedRuleContext(ASLParser.Keyword_or_stringContext, 0) + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterCause_string"): + listener.enterCause_string(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitCause_string"): + listener.exitCause_string(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitCause_string"): + return visitor.visitCause_string(self) + else: + return visitor.visitChildren(self) + + class Cause_jsonataContext(Cause_declContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Cause_declContext + super().__init__(parser) + self.copyFrom(ctx) + + def CAUSE(self): + return self.getToken(ASLParser.CAUSE, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def STRINGJSONATA(self): + return self.getToken(ASLParser.STRINGJSONATA, 0) + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterCause_jsonata"): + listener.enterCause_jsonata(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitCause_jsonata"): + listener.exitCause_jsonata(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitCause_jsonata"): + return visitor.visitCause_jsonata(self) + else: + return visitor.visitChildren(self) + + def cause_decl(self): + localctx = ASLParser.Cause_declContext(self, self._ctx, self.state) + self.enterRule(localctx, 46, self.RULE_cause_decl) + try: + self.state = 441 + self._errHandler.sync(self) + la_ = self._interp.adaptivePredict(self._input, 12, self._ctx) + if la_ == 1: + localctx = ASLParser.Cause_jsonataContext(self, localctx) + self.enterOuterAlt(localctx, 1) + self.state = 435 + self.match(ASLParser.CAUSE) + self.state = 436 + self.match(ASLParser.COLON) + self.state = 437 + self.match(ASLParser.STRINGJSONATA) + pass + + elif la_ == 2: + localctx = ASLParser.Cause_stringContext(self, localctx) + self.enterOuterAlt(localctx, 2) + self.state = 438 + self.match(ASLParser.CAUSE) + self.state = 439 + self.match(ASLParser.COLON) + self.state = 440 + self.keyword_or_string() + pass + + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class Cause_path_declContext(ParserRuleContext): + __slots__ = "parser" + + def __init__( + self, parser, parent: ParserRuleContext = None, invokingState: int = -1 + ): + super().__init__(parent, invokingState) + self.parser = parser def getRuleIndex(self): - return ASLParser.RULE_state_machine + return ASLParser.RULE_cause_path_decl + + def copyFrom(self, ctx: ParserRuleContext): + super().copyFrom(ctx) + + class Cause_path_decl_pathContext(Cause_path_declContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Cause_path_declContext + super().__init__(parser) + self.copyFrom(ctx) + + def CAUSEPATH(self): + return self.getToken(ASLParser.CAUSEPATH, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def STRINGPATH(self): + return self.getToken(ASLParser.STRINGPATH, 0) def enterRule(self, listener: ParseTreeListener): - if hasattr(listener, "enterState_machine"): - listener.enterState_machine(self) + if hasattr(listener, "enterCause_path_decl_path"): + listener.enterCause_path_decl_path(self) def exitRule(self, listener: ParseTreeListener): - if hasattr(listener, "exitState_machine"): - listener.exitState_machine(self) + if hasattr(listener, "exitCause_path_decl_path"): + listener.exitCause_path_decl_path(self) def accept(self, visitor: ParseTreeVisitor): - if hasattr(visitor, "visitState_machine"): - return visitor.visitState_machine(self) + if hasattr(visitor, "visitCause_path_decl_path"): + return visitor.visitCause_path_decl_path(self) else: return visitor.visitChildren(self) - def state_machine(self): - localctx = ASLParser.State_machineContext(self, self._ctx, self.state) - self.enterRule(localctx, 0, self.RULE_state_machine) + class Cause_path_decl_contextContext(Cause_path_declContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Cause_path_declContext + super().__init__(parser) + self.copyFrom(ctx) + + def CAUSEPATH(self): + return self.getToken(ASLParser.CAUSEPATH, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def STRINGPATHCONTEXTOBJ(self): + return self.getToken(ASLParser.STRINGPATHCONTEXTOBJ, 0) + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterCause_path_decl_context"): + listener.enterCause_path_decl_context(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitCause_path_decl_context"): + listener.exitCause_path_decl_context(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitCause_path_decl_context"): + return visitor.visitCause_path_decl_context(self) + else: + return visitor.visitChildren(self) + + class Cause_path_decl_intrinsicContext(Cause_path_declContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Cause_path_declContext + super().__init__(parser) + self.copyFrom(ctx) + + def CAUSEPATH(self): + return self.getToken(ASLParser.CAUSEPATH, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def STRINGINTRINSICFUNC(self): + return self.getToken(ASLParser.STRINGINTRINSICFUNC, 0) + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterCause_path_decl_intrinsic"): + listener.enterCause_path_decl_intrinsic(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitCause_path_decl_intrinsic"): + listener.exitCause_path_decl_intrinsic(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitCause_path_decl_intrinsic"): + return visitor.visitCause_path_decl_intrinsic(self) + else: + return visitor.visitChildren(self) + + class Cause_path_decl_varContext(Cause_path_declContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Cause_path_declContext + super().__init__(parser) + self.copyFrom(ctx) + + def CAUSEPATH(self): + return self.getToken(ASLParser.CAUSEPATH, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def variable_sample(self): + return self.getTypedRuleContext(ASLParser.Variable_sampleContext, 0) + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterCause_path_decl_var"): + listener.enterCause_path_decl_var(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitCause_path_decl_var"): + listener.exitCause_path_decl_var(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitCause_path_decl_var"): + return visitor.visitCause_path_decl_var(self) + else: + return visitor.visitChildren(self) + + def cause_path_decl(self): + localctx = ASLParser.Cause_path_declContext(self, self._ctx, self.state) + self.enterRule(localctx, 48, self.RULE_cause_path_decl) try: - self.enterOuterAlt(localctx, 1) - self.state = 196 - self.program_decl() - self.state = 197 - self.match(ASLParser.EOF) + self.state = 455 + self._errHandler.sync(self) + la_ = self._interp.adaptivePredict(self._input, 13, self._ctx) + if la_ == 1: + localctx = ASLParser.Cause_path_decl_varContext(self, localctx) + self.enterOuterAlt(localctx, 1) + self.state = 443 + self.match(ASLParser.CAUSEPATH) + self.state = 444 + self.match(ASLParser.COLON) + self.state = 445 + self.variable_sample() + pass + + elif la_ == 2: + localctx = ASLParser.Cause_path_decl_pathContext(self, localctx) + self.enterOuterAlt(localctx, 2) + self.state = 446 + self.match(ASLParser.CAUSEPATH) + self.state = 447 + self.match(ASLParser.COLON) + self.state = 448 + self.match(ASLParser.STRINGPATH) + pass + + elif la_ == 3: + localctx = ASLParser.Cause_path_decl_contextContext(self, localctx) + self.enterOuterAlt(localctx, 3) + self.state = 449 + self.match(ASLParser.CAUSEPATH) + self.state = 450 + self.match(ASLParser.COLON) + self.state = 451 + self.match(ASLParser.STRINGPATHCONTEXTOBJ) + pass + + elif la_ == 4: + localctx = ASLParser.Cause_path_decl_intrinsicContext(self, localctx) + self.enterOuterAlt(localctx, 4) + self.state = 452 + self.match(ASLParser.CAUSEPATH) + self.state = 453 + self.match(ASLParser.COLON) + self.state = 454 + self.match(ASLParser.STRINGINTRINSICFUNC) + pass + except RecognitionException as re: localctx.exception = re self._errHandler.reportError(self, re) @@ -8209,7 +14701,7 @@ def state_machine(self): self.exitRule() return localctx - class Program_declContext(ParserRuleContext): + class Seconds_declContext(ParserRuleContext): __slots__ = "parser" def __init__( @@ -8218,65 +14710,101 @@ def __init__( super().__init__(parent, invokingState) self.parser = parser - def LBRACE(self): - return self.getToken(ASLParser.LBRACE, 0) + def getRuleIndex(self): + return ASLParser.RULE_seconds_decl - def top_layer_stmt(self, i: int = None): - if i is None: - return self.getTypedRuleContexts(ASLParser.Top_layer_stmtContext) - else: - return self.getTypedRuleContext(ASLParser.Top_layer_stmtContext, i) + def copyFrom(self, ctx: ParserRuleContext): + super().copyFrom(ctx) - def RBRACE(self): - return self.getToken(ASLParser.RBRACE, 0) + class Seconds_jsonataContext(Seconds_declContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Seconds_declContext + super().__init__(parser) + self.copyFrom(ctx) - def COMMA(self, i: int = None): - if i is None: - return self.getTokens(ASLParser.COMMA) + def SECONDS(self): + return self.getToken(ASLParser.SECONDS, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def STRINGJSONATA(self): + return self.getToken(ASLParser.STRINGJSONATA, 0) + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterSeconds_jsonata"): + listener.enterSeconds_jsonata(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitSeconds_jsonata"): + listener.exitSeconds_jsonata(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitSeconds_jsonata"): + return visitor.visitSeconds_jsonata(self) else: - return self.getToken(ASLParser.COMMA, i) + return visitor.visitChildren(self) - def getRuleIndex(self): - return ASLParser.RULE_program_decl + class Seconds_intContext(Seconds_declContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Seconds_declContext + super().__init__(parser) + self.copyFrom(ctx) + + def SECONDS(self): + return self.getToken(ASLParser.SECONDS, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def INT(self): + return self.getToken(ASLParser.INT, 0) def enterRule(self, listener: ParseTreeListener): - if hasattr(listener, "enterProgram_decl"): - listener.enterProgram_decl(self) + if hasattr(listener, "enterSeconds_int"): + listener.enterSeconds_int(self) def exitRule(self, listener: ParseTreeListener): - if hasattr(listener, "exitProgram_decl"): - listener.exitProgram_decl(self) + if hasattr(listener, "exitSeconds_int"): + listener.exitSeconds_int(self) def accept(self, visitor: ParseTreeVisitor): - if hasattr(visitor, "visitProgram_decl"): - return visitor.visitProgram_decl(self) + if hasattr(visitor, "visitSeconds_int"): + return visitor.visitSeconds_int(self) else: return visitor.visitChildren(self) - def program_decl(self): - localctx = ASLParser.Program_declContext(self, self._ctx, self.state) - self.enterRule(localctx, 2, self.RULE_program_decl) - self._la = 0 # Token type + def seconds_decl(self): + localctx = ASLParser.Seconds_declContext(self, self._ctx, self.state) + self.enterRule(localctx, 50, self.RULE_seconds_decl) try: - self.enterOuterAlt(localctx, 1) - self.state = 199 - self.match(ASLParser.LBRACE) - self.state = 200 - self.top_layer_stmt() - self.state = 205 + self.state = 463 self._errHandler.sync(self) - _la = self._input.LA(1) - while _la == 1: - self.state = 201 - self.match(ASLParser.COMMA) - self.state = 202 - self.top_layer_stmt() - self.state = 207 - self._errHandler.sync(self) - _la = self._input.LA(1) + la_ = self._interp.adaptivePredict(self._input, 14, self._ctx) + if la_ == 1: + localctx = ASLParser.Seconds_jsonataContext(self, localctx) + self.enterOuterAlt(localctx, 1) + self.state = 457 + self.match(ASLParser.SECONDS) + self.state = 458 + self.match(ASLParser.COLON) + self.state = 459 + self.match(ASLParser.STRINGJSONATA) + pass + + elif la_ == 2: + localctx = ASLParser.Seconds_intContext(self, localctx) + self.enterOuterAlt(localctx, 2) + self.state = 460 + self.match(ASLParser.SECONDS) + self.state = 461 + self.match(ASLParser.COLON) + self.state = 462 + self.match(ASLParser.INT) + pass - self.state = 208 - self.match(ASLParser.RBRACE) except RecognitionException as re: localctx.exception = re self._errHandler.reportError(self, re) @@ -8285,7 +14813,7 @@ def program_decl(self): self.exitRule() return localctx - class Top_layer_stmtContext(ParserRuleContext): + class Seconds_path_declContext(ParserRuleContext): __slots__ = "parser" def __init__( @@ -8294,72 +14822,100 @@ def __init__( super().__init__(parent, invokingState) self.parser = parser - def comment_decl(self): - return self.getTypedRuleContext(ASLParser.Comment_declContext, 0) + def getRuleIndex(self): + return ASLParser.RULE_seconds_path_decl - def version_decl(self): - return self.getTypedRuleContext(ASLParser.Version_declContext, 0) + def copyFrom(self, ctx: ParserRuleContext): + super().copyFrom(ctx) - def startat_decl(self): - return self.getTypedRuleContext(ASLParser.Startat_declContext, 0) + class Seconds_path_decl_valueContext(Seconds_path_declContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Seconds_path_declContext + super().__init__(parser) + self.copyFrom(ctx) - def states_decl(self): - return self.getTypedRuleContext(ASLParser.States_declContext, 0) + def SECONDSPATH(self): + return self.getToken(ASLParser.SECONDSPATH, 0) - def timeout_seconds_decl(self): - return self.getTypedRuleContext(ASLParser.Timeout_seconds_declContext, 0) + def COLON(self): + return self.getToken(ASLParser.COLON, 0) - def getRuleIndex(self): - return ASLParser.RULE_top_layer_stmt + def keyword_or_string(self): + return self.getTypedRuleContext(ASLParser.Keyword_or_stringContext, 0) def enterRule(self, listener: ParseTreeListener): - if hasattr(listener, "enterTop_layer_stmt"): - listener.enterTop_layer_stmt(self) + if hasattr(listener, "enterSeconds_path_decl_value"): + listener.enterSeconds_path_decl_value(self) def exitRule(self, listener: ParseTreeListener): - if hasattr(listener, "exitTop_layer_stmt"): - listener.exitTop_layer_stmt(self) + if hasattr(listener, "exitSeconds_path_decl_value"): + listener.exitSeconds_path_decl_value(self) def accept(self, visitor: ParseTreeVisitor): - if hasattr(visitor, "visitTop_layer_stmt"): - return visitor.visitTop_layer_stmt(self) + if hasattr(visitor, "visitSeconds_path_decl_value"): + return visitor.visitSeconds_path_decl_value(self) else: return visitor.visitChildren(self) - def top_layer_stmt(self): - localctx = ASLParser.Top_layer_stmtContext(self, self._ctx, self.state) - self.enterRule(localctx, 4, self.RULE_top_layer_stmt) + class Seconds_path_decl_varContext(Seconds_path_declContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Seconds_path_declContext + super().__init__(parser) + self.copyFrom(ctx) + + def SECONDSPATH(self): + return self.getToken(ASLParser.SECONDSPATH, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def variable_sample(self): + return self.getTypedRuleContext(ASLParser.Variable_sampleContext, 0) + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterSeconds_path_decl_var"): + listener.enterSeconds_path_decl_var(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitSeconds_path_decl_var"): + listener.exitSeconds_path_decl_var(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitSeconds_path_decl_var"): + return visitor.visitSeconds_path_decl_var(self) + else: + return visitor.visitChildren(self) + + def seconds_path_decl(self): + localctx = ASLParser.Seconds_path_declContext(self, self._ctx, self.state) + self.enterRule(localctx, 52, self.RULE_seconds_path_decl) try: - self.state = 215 + self.state = 471 self._errHandler.sync(self) - token = self._input.LA(1) - if token in [10]: + la_ = self._interp.adaptivePredict(self._input, 15, self._ctx) + if la_ == 1: + localctx = ASLParser.Seconds_path_decl_varContext(self, localctx) self.enterOuterAlt(localctx, 1) - self.state = 210 - self.comment_decl() + self.state = 465 + self.match(ASLParser.SECONDSPATH) + self.state = 466 + self.match(ASLParser.COLON) + self.state = 467 + self.variable_sample() pass - elif token in [14]: + + elif la_ == 2: + localctx = ASLParser.Seconds_path_decl_valueContext(self, localctx) self.enterOuterAlt(localctx, 2) - self.state = 211 - self.version_decl() - pass - elif token in [12]: - self.enterOuterAlt(localctx, 3) - self.state = 212 - self.startat_decl() - pass - elif token in [11]: - self.enterOuterAlt(localctx, 4) - self.state = 213 - self.states_decl() - pass - elif token in [74]: - self.enterOuterAlt(localctx, 5) - self.state = 214 - self.timeout_seconds_decl() + self.state = 468 + self.match(ASLParser.SECONDSPATH) + self.state = 469 + self.match(ASLParser.COLON) + self.state = 470 + self.keyword_or_string() pass - else: - raise NoViableAltException(self) except RecognitionException as re: localctx.exception = re @@ -8369,7 +14925,7 @@ def top_layer_stmt(self): self.exitRule() return localctx - class Startat_declContext(ParserRuleContext): + class Timestamp_declContext(ParserRuleContext): __slots__ = "parser" def __init__( @@ -8378,62 +14934,51 @@ def __init__( super().__init__(parent, invokingState) self.parser = parser - def STARTAT(self): - return self.getToken(ASLParser.STARTAT, 0) + def getRuleIndex(self): + return ASLParser.RULE_timestamp_decl + + def copyFrom(self, ctx: ParserRuleContext): + super().copyFrom(ctx) + + class Timestamp_jsonataContext(Timestamp_declContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Timestamp_declContext + super().__init__(parser) + self.copyFrom(ctx) + + def TIMESTAMP(self): + return self.getToken(ASLParser.TIMESTAMP, 0) def COLON(self): return self.getToken(ASLParser.COLON, 0) - def keyword_or_string(self): - return self.getTypedRuleContext(ASLParser.Keyword_or_stringContext, 0) - - def getRuleIndex(self): - return ASLParser.RULE_startat_decl + def STRINGJSONATA(self): + return self.getToken(ASLParser.STRINGJSONATA, 0) def enterRule(self, listener: ParseTreeListener): - if hasattr(listener, "enterStartat_decl"): - listener.enterStartat_decl(self) + if hasattr(listener, "enterTimestamp_jsonata"): + listener.enterTimestamp_jsonata(self) def exitRule(self, listener: ParseTreeListener): - if hasattr(listener, "exitStartat_decl"): - listener.exitStartat_decl(self) + if hasattr(listener, "exitTimestamp_jsonata"): + listener.exitTimestamp_jsonata(self) def accept(self, visitor: ParseTreeVisitor): - if hasattr(visitor, "visitStartat_decl"): - return visitor.visitStartat_decl(self) + if hasattr(visitor, "visitTimestamp_jsonata"): + return visitor.visitTimestamp_jsonata(self) else: return visitor.visitChildren(self) - def startat_decl(self): - localctx = ASLParser.Startat_declContext(self, self._ctx, self.state) - self.enterRule(localctx, 6, self.RULE_startat_decl) - try: - self.enterOuterAlt(localctx, 1) - self.state = 217 - self.match(ASLParser.STARTAT) - self.state = 218 - self.match(ASLParser.COLON) - self.state = 219 - self.keyword_or_string() - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - class Comment_declContext(ParserRuleContext): - __slots__ = "parser" - + class Timestamp_stringContext(Timestamp_declContext): def __init__( - self, parser, parent: ParserRuleContext = None, invokingState: int = -1 - ): - super().__init__(parent, invokingState) - self.parser = parser + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Timestamp_declContext + super().__init__(parser) + self.copyFrom(ctx) - def COMMENT(self): - return self.getToken(ASLParser.COMMENT, 0) + def TIMESTAMP(self): + return self.getToken(ASLParser.TIMESTAMP, 0) def COLON(self): return self.getToken(ASLParser.COLON, 0) @@ -8441,34 +14986,49 @@ def COLON(self): def keyword_or_string(self): return self.getTypedRuleContext(ASLParser.Keyword_or_stringContext, 0) - def getRuleIndex(self): - return ASLParser.RULE_comment_decl - def enterRule(self, listener: ParseTreeListener): - if hasattr(listener, "enterComment_decl"): - listener.enterComment_decl(self) + if hasattr(listener, "enterTimestamp_string"): + listener.enterTimestamp_string(self) def exitRule(self, listener: ParseTreeListener): - if hasattr(listener, "exitComment_decl"): - listener.exitComment_decl(self) + if hasattr(listener, "exitTimestamp_string"): + listener.exitTimestamp_string(self) def accept(self, visitor: ParseTreeVisitor): - if hasattr(visitor, "visitComment_decl"): - return visitor.visitComment_decl(self) + if hasattr(visitor, "visitTimestamp_string"): + return visitor.visitTimestamp_string(self) else: return visitor.visitChildren(self) - def comment_decl(self): - localctx = ASLParser.Comment_declContext(self, self._ctx, self.state) - self.enterRule(localctx, 8, self.RULE_comment_decl) - try: - self.enterOuterAlt(localctx, 1) - self.state = 221 - self.match(ASLParser.COMMENT) - self.state = 222 - self.match(ASLParser.COLON) - self.state = 223 - self.keyword_or_string() + def timestamp_decl(self): + localctx = ASLParser.Timestamp_declContext(self, self._ctx, self.state) + self.enterRule(localctx, 54, self.RULE_timestamp_decl) + try: + self.state = 479 + self._errHandler.sync(self) + la_ = self._interp.adaptivePredict(self._input, 16, self._ctx) + if la_ == 1: + localctx = ASLParser.Timestamp_jsonataContext(self, localctx) + self.enterOuterAlt(localctx, 1) + self.state = 473 + self.match(ASLParser.TIMESTAMP) + self.state = 474 + self.match(ASLParser.COLON) + self.state = 475 + self.match(ASLParser.STRINGJSONATA) + pass + + elif la_ == 2: + localctx = ASLParser.Timestamp_stringContext(self, localctx) + self.enterOuterAlt(localctx, 2) + self.state = 476 + self.match(ASLParser.TIMESTAMP) + self.state = 477 + self.match(ASLParser.COLON) + self.state = 478 + self.keyword_or_string() + pass + except RecognitionException as re: localctx.exception = re self._errHandler.reportError(self, re) @@ -8477,7 +15037,7 @@ def comment_decl(self): self.exitRule() return localctx - class Version_declContext(ParserRuleContext): + class Timestamp_path_declContext(ParserRuleContext): __slots__ = "parser" def __init__( @@ -8486,8 +15046,51 @@ def __init__( super().__init__(parent, invokingState) self.parser = parser - def VERSION(self): - return self.getToken(ASLParser.VERSION, 0) + def getRuleIndex(self): + return ASLParser.RULE_timestamp_path_decl + + def copyFrom(self, ctx: ParserRuleContext): + super().copyFrom(ctx) + + class Timestamp_path_decl_varContext(Timestamp_path_declContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Timestamp_path_declContext + super().__init__(parser) + self.copyFrom(ctx) + + def TIMESTAMPPATH(self): + return self.getToken(ASLParser.TIMESTAMPPATH, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def variable_sample(self): + return self.getTypedRuleContext(ASLParser.Variable_sampleContext, 0) + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterTimestamp_path_decl_var"): + listener.enterTimestamp_path_decl_var(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitTimestamp_path_decl_var"): + listener.exitTimestamp_path_decl_var(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitTimestamp_path_decl_var"): + return visitor.visitTimestamp_path_decl_var(self) + else: + return visitor.visitChildren(self) + + class Timestamp_path_decl_valueContext(Timestamp_path_declContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Timestamp_path_declContext + super().__init__(parser) + self.copyFrom(ctx) + + def TIMESTAMPPATH(self): + return self.getToken(ASLParser.TIMESTAMPPATH, 0) def COLON(self): return self.getToken(ASLParser.COLON, 0) @@ -8495,34 +15098,49 @@ def COLON(self): def keyword_or_string(self): return self.getTypedRuleContext(ASLParser.Keyword_or_stringContext, 0) - def getRuleIndex(self): - return ASLParser.RULE_version_decl - def enterRule(self, listener: ParseTreeListener): - if hasattr(listener, "enterVersion_decl"): - listener.enterVersion_decl(self) + if hasattr(listener, "enterTimestamp_path_decl_value"): + listener.enterTimestamp_path_decl_value(self) def exitRule(self, listener: ParseTreeListener): - if hasattr(listener, "exitVersion_decl"): - listener.exitVersion_decl(self) + if hasattr(listener, "exitTimestamp_path_decl_value"): + listener.exitTimestamp_path_decl_value(self) def accept(self, visitor: ParseTreeVisitor): - if hasattr(visitor, "visitVersion_decl"): - return visitor.visitVersion_decl(self) + if hasattr(visitor, "visitTimestamp_path_decl_value"): + return visitor.visitTimestamp_path_decl_value(self) else: return visitor.visitChildren(self) - def version_decl(self): - localctx = ASLParser.Version_declContext(self, self._ctx, self.state) - self.enterRule(localctx, 10, self.RULE_version_decl) + def timestamp_path_decl(self): + localctx = ASLParser.Timestamp_path_declContext(self, self._ctx, self.state) + self.enterRule(localctx, 56, self.RULE_timestamp_path_decl) try: - self.enterOuterAlt(localctx, 1) - self.state = 225 - self.match(ASLParser.VERSION) - self.state = 226 - self.match(ASLParser.COLON) - self.state = 227 - self.keyword_or_string() + self.state = 487 + self._errHandler.sync(self) + la_ = self._interp.adaptivePredict(self._input, 17, self._ctx) + if la_ == 1: + localctx = ASLParser.Timestamp_path_decl_varContext(self, localctx) + self.enterOuterAlt(localctx, 1) + self.state = 481 + self.match(ASLParser.TIMESTAMPPATH) + self.state = 482 + self.match(ASLParser.COLON) + self.state = 483 + self.variable_sample() + pass + + elif la_ == 2: + localctx = ASLParser.Timestamp_path_decl_valueContext(self, localctx) + self.enterOuterAlt(localctx, 2) + self.state = 484 + self.match(ASLParser.TIMESTAMPPATH) + self.state = 485 + self.match(ASLParser.COLON) + self.state = 486 + self.keyword_or_string() + pass + except RecognitionException as re: localctx.exception = re self._errHandler.reportError(self, re) @@ -8531,7 +15149,7 @@ def version_decl(self): self.exitRule() return localctx - class State_stmtContext(ParserRuleContext): + class Items_declContext(ParserRuleContext): __slots__ = "parser" def __init__( @@ -8540,366 +15158,257 @@ def __init__( super().__init__(parent, invokingState) self.parser = parser - def comment_decl(self): - return self.getTypedRuleContext(ASLParser.Comment_declContext, 0) + def getRuleIndex(self): + return ASLParser.RULE_items_decl - def type_decl(self): - return self.getTypedRuleContext(ASLParser.Type_declContext, 0) + def copyFrom(self, ctx: ParserRuleContext): + super().copyFrom(ctx) - def input_path_decl(self): - return self.getTypedRuleContext(ASLParser.Input_path_declContext, 0) + class Items_arrayContext(Items_declContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Items_declContext + super().__init__(parser) + self.copyFrom(ctx) - def resource_decl(self): - return self.getTypedRuleContext(ASLParser.Resource_declContext, 0) + def ITEMS(self): + return self.getToken(ASLParser.ITEMS, 0) - def next_decl(self): - return self.getTypedRuleContext(ASLParser.Next_declContext, 0) + def COLON(self): + return self.getToken(ASLParser.COLON, 0) - def result_decl(self): - return self.getTypedRuleContext(ASLParser.Result_declContext, 0) + def jsonata_template_value_array(self): + return self.getTypedRuleContext( + ASLParser.Jsonata_template_value_arrayContext, 0 + ) - def result_path_decl(self): - return self.getTypedRuleContext(ASLParser.Result_path_declContext, 0) + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterItems_array"): + listener.enterItems_array(self) - def output_path_decl(self): - return self.getTypedRuleContext(ASLParser.Output_path_declContext, 0) + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitItems_array"): + listener.exitItems_array(self) - def end_decl(self): - return self.getTypedRuleContext(ASLParser.End_declContext, 0) + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitItems_array"): + return visitor.visitItems_array(self) + else: + return visitor.visitChildren(self) - def default_decl(self): - return self.getTypedRuleContext(ASLParser.Default_declContext, 0) + class Items_jsonataContext(Items_declContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Items_declContext + super().__init__(parser) + self.copyFrom(ctx) - def choices_decl(self): - return self.getTypedRuleContext(ASLParser.Choices_declContext, 0) + def ITEMS(self): + return self.getToken(ASLParser.ITEMS, 0) - def error_decl(self): - return self.getTypedRuleContext(ASLParser.Error_declContext, 0) + def COLON(self): + return self.getToken(ASLParser.COLON, 0) - def error_path_decl(self): - return self.getTypedRuleContext(ASLParser.Error_path_declContext, 0) + def STRINGJSONATA(self): + return self.getToken(ASLParser.STRINGJSONATA, 0) - def cause_decl(self): - return self.getTypedRuleContext(ASLParser.Cause_declContext, 0) + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterItems_jsonata"): + listener.enterItems_jsonata(self) - def cause_path_decl(self): - return self.getTypedRuleContext(ASLParser.Cause_path_declContext, 0) + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitItems_jsonata"): + listener.exitItems_jsonata(self) - def seconds_decl(self): - return self.getTypedRuleContext(ASLParser.Seconds_declContext, 0) + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitItems_jsonata"): + return visitor.visitItems_jsonata(self) + else: + return visitor.visitChildren(self) - def seconds_path_decl(self): - return self.getTypedRuleContext(ASLParser.Seconds_path_declContext, 0) + def items_decl(self): + localctx = ASLParser.Items_declContext(self, self._ctx, self.state) + self.enterRule(localctx, 58, self.RULE_items_decl) + try: + self.state = 495 + self._errHandler.sync(self) + la_ = self._interp.adaptivePredict(self._input, 18, self._ctx) + if la_ == 1: + localctx = ASLParser.Items_arrayContext(self, localctx) + self.enterOuterAlt(localctx, 1) + self.state = 489 + self.match(ASLParser.ITEMS) + self.state = 490 + self.match(ASLParser.COLON) + self.state = 491 + self.jsonata_template_value_array() + pass - def timestamp_decl(self): - return self.getTypedRuleContext(ASLParser.Timestamp_declContext, 0) + elif la_ == 2: + localctx = ASLParser.Items_jsonataContext(self, localctx) + self.enterOuterAlt(localctx, 2) + self.state = 492 + self.match(ASLParser.ITEMS) + self.state = 493 + self.match(ASLParser.COLON) + self.state = 494 + self.match(ASLParser.STRINGJSONATA) + pass - def timestamp_path_decl(self): - return self.getTypedRuleContext(ASLParser.Timestamp_path_declContext, 0) + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx - def items_path_decl(self): - return self.getTypedRuleContext(ASLParser.Items_path_declContext, 0) + class Items_path_declContext(ParserRuleContext): + __slots__ = "parser" - def item_processor_decl(self): - return self.getTypedRuleContext(ASLParser.Item_processor_declContext, 0) + def __init__( + self, parser, parent: ParserRuleContext = None, invokingState: int = -1 + ): + super().__init__(parent, invokingState) + self.parser = parser - def iterator_decl(self): - return self.getTypedRuleContext(ASLParser.Iterator_declContext, 0) + def getRuleIndex(self): + return ASLParser.RULE_items_path_decl - def item_selector_decl(self): - return self.getTypedRuleContext(ASLParser.Item_selector_declContext, 0) + def copyFrom(self, ctx: ParserRuleContext): + super().copyFrom(ctx) - def item_reader_decl(self): - return self.getTypedRuleContext(ASLParser.Item_reader_declContext, 0) + class Items_path_decl_path_varContext(Items_path_declContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Items_path_declContext + super().__init__(parser) + self.copyFrom(ctx) - def max_concurrency_decl(self): - return self.getTypedRuleContext(ASLParser.Max_concurrency_declContext, 0) + def ITEMSPATH(self): + return self.getToken(ASLParser.ITEMSPATH, 0) - def max_concurrency_path_decl(self): - return self.getTypedRuleContext( - ASLParser.Max_concurrency_path_declContext, 0 - ) + def COLON(self): + return self.getToken(ASLParser.COLON, 0) - def timeout_seconds_decl(self): - return self.getTypedRuleContext(ASLParser.Timeout_seconds_declContext, 0) + def variable_sample(self): + return self.getTypedRuleContext(ASLParser.Variable_sampleContext, 0) - def timeout_seconds_path_decl(self): - return self.getTypedRuleContext( - ASLParser.Timeout_seconds_path_declContext, 0 - ) + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterItems_path_decl_path_var"): + listener.enterItems_path_decl_path_var(self) - def heartbeat_seconds_decl(self): - return self.getTypedRuleContext(ASLParser.Heartbeat_seconds_declContext, 0) + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitItems_path_decl_path_var"): + listener.exitItems_path_decl_path_var(self) - def heartbeat_seconds_path_decl(self): - return self.getTypedRuleContext( - ASLParser.Heartbeat_seconds_path_declContext, 0 - ) + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitItems_path_decl_path_var"): + return visitor.visitItems_path_decl_path_var(self) + else: + return visitor.visitChildren(self) - def branches_decl(self): - return self.getTypedRuleContext(ASLParser.Branches_declContext, 0) + class Items_path_decl_path_context_objectContext(Items_path_declContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Items_path_declContext + super().__init__(parser) + self.copyFrom(ctx) - def parameters_decl(self): - return self.getTypedRuleContext(ASLParser.Parameters_declContext, 0) + def ITEMSPATH(self): + return self.getToken(ASLParser.ITEMSPATH, 0) - def retry_decl(self): - return self.getTypedRuleContext(ASLParser.Retry_declContext, 0) + def COLON(self): + return self.getToken(ASLParser.COLON, 0) - def catch_decl(self): - return self.getTypedRuleContext(ASLParser.Catch_declContext, 0) + def STRINGPATHCONTEXTOBJ(self): + return self.getToken(ASLParser.STRINGPATHCONTEXTOBJ, 0) - def result_selector_decl(self): - return self.getTypedRuleContext(ASLParser.Result_selector_declContext, 0) + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterItems_path_decl_path_context_object"): + listener.enterItems_path_decl_path_context_object(self) - def tolerated_failure_count_decl(self): - return self.getTypedRuleContext( - ASLParser.Tolerated_failure_count_declContext, 0 - ) + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitItems_path_decl_path_context_object"): + listener.exitItems_path_decl_path_context_object(self) - def tolerated_failure_count_path_decl(self): - return self.getTypedRuleContext( - ASLParser.Tolerated_failure_count_path_declContext, 0 - ) + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitItems_path_decl_path_context_object"): + return visitor.visitItems_path_decl_path_context_object(self) + else: + return visitor.visitChildren(self) - def tolerated_failure_percentage_decl(self): - return self.getTypedRuleContext( - ASLParser.Tolerated_failure_percentage_declContext, 0 - ) + class Items_path_decl_pathContext(Items_path_declContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Items_path_declContext + super().__init__(parser) + self.copyFrom(ctx) - def tolerated_failure_percentage_path_decl(self): - return self.getTypedRuleContext( - ASLParser.Tolerated_failure_percentage_path_declContext, 0 - ) + def ITEMSPATH(self): + return self.getToken(ASLParser.ITEMSPATH, 0) - def label_decl(self): - return self.getTypedRuleContext(ASLParser.Label_declContext, 0) + def COLON(self): + return self.getToken(ASLParser.COLON, 0) - def getRuleIndex(self): - return ASLParser.RULE_state_stmt + def keyword_or_string(self): + return self.getTypedRuleContext(ASLParser.Keyword_or_stringContext, 0) def enterRule(self, listener: ParseTreeListener): - if hasattr(listener, "enterState_stmt"): - listener.enterState_stmt(self) + if hasattr(listener, "enterItems_path_decl_path"): + listener.enterItems_path_decl_path(self) def exitRule(self, listener: ParseTreeListener): - if hasattr(listener, "exitState_stmt"): - listener.exitState_stmt(self) + if hasattr(listener, "exitItems_path_decl_path"): + listener.exitItems_path_decl_path(self) def accept(self, visitor: ParseTreeVisitor): - if hasattr(visitor, "visitState_stmt"): - return visitor.visitState_stmt(self) + if hasattr(visitor, "visitItems_path_decl_path"): + return visitor.visitItems_path_decl_path(self) else: return visitor.visitChildren(self) - def state_stmt(self): - localctx = ASLParser.State_stmtContext(self, self._ctx, self.state) - self.enterRule(localctx, 12, self.RULE_state_stmt) + def items_path_decl(self): + localctx = ASLParser.Items_path_declContext(self, self._ctx, self.state) + self.enterRule(localctx, 60, self.RULE_items_path_decl) try: - self.state = 269 + self.state = 506 self._errHandler.sync(self) - token = self._input.LA(1) - if token in [10]: + la_ = self._interp.adaptivePredict(self._input, 19, self._ctx) + if la_ == 1: + localctx = ASLParser.Items_path_decl_path_context_objectContext( + self, localctx + ) self.enterOuterAlt(localctx, 1) - self.state = 229 - self.comment_decl() + self.state = 497 + self.match(ASLParser.ITEMSPATH) + self.state = 498 + self.match(ASLParser.COLON) + self.state = 499 + self.match(ASLParser.STRINGPATHCONTEXTOBJ) pass - elif token in [15]: + + elif la_ == 2: + localctx = ASLParser.Items_path_decl_path_varContext(self, localctx) self.enterOuterAlt(localctx, 2) - self.state = 230 - self.type_decl() + self.state = 500 + self.match(ASLParser.ITEMSPATH) + self.state = 501 + self.match(ASLParser.COLON) + self.state = 502 + self.variable_sample() pass - elif token in [90]: + + elif la_ == 3: + localctx = ASLParser.Items_path_decl_pathContext(self, localctx) self.enterOuterAlt(localctx, 3) - self.state = 231 - self.input_path_decl() - pass - elif token in [89]: - self.enterOuterAlt(localctx, 4) - self.state = 232 - self.resource_decl() - pass - elif token in [109]: - self.enterOuterAlt(localctx, 5) - self.state = 233 - self.next_decl() - pass - elif token in [94]: - self.enterOuterAlt(localctx, 6) - self.state = 234 - self.result_decl() - pass - elif token in [93]: - self.enterOuterAlt(localctx, 7) - self.state = 235 - self.result_path_decl() - pass - elif token in [91]: - self.enterOuterAlt(localctx, 8) - self.state = 236 - self.output_path_decl() - pass - elif token in [110]: - self.enterOuterAlt(localctx, 9) - self.state = 237 - self.end_decl() - pass - elif token in [26]: - self.enterOuterAlt(localctx, 10) - self.state = 238 - self.default_decl() - pass - elif token in [24]: - self.enterOuterAlt(localctx, 11) - self.state = 239 - self.choices_decl() - pass - elif token in [113]: - self.enterOuterAlt(localctx, 12) - self.state = 240 - self.error_decl() - pass - elif token in [114]: - self.enterOuterAlt(localctx, 13) - self.state = 241 - self.error_path_decl() - pass - elif token in [111]: - self.enterOuterAlt(localctx, 14) - self.state = 242 - self.cause_decl() - pass - elif token in [112]: - self.enterOuterAlt(localctx, 15) - self.state = 243 - self.cause_path_decl() - pass - elif token in [71]: - self.enterOuterAlt(localctx, 16) - self.state = 244 - self.seconds_decl() - pass - elif token in [70]: - self.enterOuterAlt(localctx, 17) - self.state = 245 - self.seconds_path_decl() - pass - elif token in [73]: - self.enterOuterAlt(localctx, 18) - self.state = 246 - self.timestamp_decl() - pass - elif token in [72]: - self.enterOuterAlt(localctx, 19) - self.state = 247 - self.timestamp_path_decl() - pass - elif token in [92]: - self.enterOuterAlt(localctx, 20) - self.state = 248 - self.items_path_decl() - pass - elif token in [84]: - self.enterOuterAlt(localctx, 21) - self.state = 249 - self.item_processor_decl() - pass - elif token in [85]: - self.enterOuterAlt(localctx, 22) - self.state = 250 - self.iterator_decl() - pass - elif token in [86]: - self.enterOuterAlt(localctx, 23) - self.state = 251 - self.item_selector_decl() - pass - elif token in [97]: - self.enterOuterAlt(localctx, 24) - self.state = 252 - self.item_reader_decl() - pass - elif token in [88]: - self.enterOuterAlt(localctx, 25) - self.state = 253 - self.max_concurrency_decl() - pass - elif token in [87]: - self.enterOuterAlt(localctx, 26) - self.state = 254 - self.max_concurrency_path_decl() - pass - elif token in [74]: - self.enterOuterAlt(localctx, 27) - self.state = 255 - self.timeout_seconds_decl() - pass - elif token in [75]: - self.enterOuterAlt(localctx, 28) - self.state = 256 - self.timeout_seconds_path_decl() - pass - elif token in [76]: - self.enterOuterAlt(localctx, 29) - self.state = 257 - self.heartbeat_seconds_decl() - pass - elif token in [77]: - self.enterOuterAlt(localctx, 30) - self.state = 258 - self.heartbeat_seconds_path_decl() - pass - elif token in [27]: - self.enterOuterAlt(localctx, 31) - self.state = 259 - self.branches_decl() - pass - elif token in [95]: - self.enterOuterAlt(localctx, 32) - self.state = 260 - self.parameters_decl() - pass - elif token in [115]: - self.enterOuterAlt(localctx, 33) - self.state = 261 - self.retry_decl() - pass - elif token in [124]: - self.enterOuterAlt(localctx, 34) - self.state = 262 - self.catch_decl() - pass - elif token in [96]: - self.enterOuterAlt(localctx, 35) - self.state = 263 - self.result_selector_decl() - pass - elif token in [104]: - self.enterOuterAlt(localctx, 36) - self.state = 264 - self.tolerated_failure_count_decl() - pass - elif token in [105]: - self.enterOuterAlt(localctx, 37) - self.state = 265 - self.tolerated_failure_count_path_decl() - pass - elif token in [106]: - self.enterOuterAlt(localctx, 38) - self.state = 266 - self.tolerated_failure_percentage_decl() - pass - elif token in [107]: - self.enterOuterAlt(localctx, 39) - self.state = 267 - self.tolerated_failure_percentage_path_decl() - pass - elif token in [108]: - self.enterOuterAlt(localctx, 40) - self.state = 268 - self.label_decl() + self.state = 503 + self.match(ASLParser.ITEMSPATH) + self.state = 504 + self.match(ASLParser.COLON) + self.state = 505 + self.keyword_or_string() pass - else: - raise NoViableAltException(self) except RecognitionException as re: localctx.exception = re @@ -8909,7 +15418,7 @@ def state_stmt(self): self.exitRule() return localctx - class States_declContext(ParserRuleContext): + class Max_concurrency_declContext(ParserRuleContext): __slots__ = "parser" def __init__( @@ -8918,75 +15427,101 @@ def __init__( super().__init__(parent, invokingState) self.parser = parser - def STATES(self): - return self.getToken(ASLParser.STATES, 0) + def getRuleIndex(self): + return ASLParser.RULE_max_concurrency_decl + + def copyFrom(self, ctx: ParserRuleContext): + super().copyFrom(ctx) + + class Max_concurrency_jsonataContext(Max_concurrency_declContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Max_concurrency_declContext + super().__init__(parser) + self.copyFrom(ctx) + + def MAXCONCURRENCY(self): + return self.getToken(ASLParser.MAXCONCURRENCY, 0) def COLON(self): return self.getToken(ASLParser.COLON, 0) - def LBRACE(self): - return self.getToken(ASLParser.LBRACE, 0) + def STRINGJSONATA(self): + return self.getToken(ASLParser.STRINGJSONATA, 0) - def state_decl(self, i: int = None): - if i is None: - return self.getTypedRuleContexts(ASLParser.State_declContext) - else: - return self.getTypedRuleContext(ASLParser.State_declContext, i) + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterMax_concurrency_jsonata"): + listener.enterMax_concurrency_jsonata(self) - def RBRACE(self): - return self.getToken(ASLParser.RBRACE, 0) + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitMax_concurrency_jsonata"): + listener.exitMax_concurrency_jsonata(self) - def COMMA(self, i: int = None): - if i is None: - return self.getTokens(ASLParser.COMMA) + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitMax_concurrency_jsonata"): + return visitor.visitMax_concurrency_jsonata(self) else: - return self.getToken(ASLParser.COMMA, i) + return visitor.visitChildren(self) - def getRuleIndex(self): - return ASLParser.RULE_states_decl + class Max_concurrency_intContext(Max_concurrency_declContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Max_concurrency_declContext + super().__init__(parser) + self.copyFrom(ctx) + + def MAXCONCURRENCY(self): + return self.getToken(ASLParser.MAXCONCURRENCY, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def INT(self): + return self.getToken(ASLParser.INT, 0) def enterRule(self, listener: ParseTreeListener): - if hasattr(listener, "enterStates_decl"): - listener.enterStates_decl(self) + if hasattr(listener, "enterMax_concurrency_int"): + listener.enterMax_concurrency_int(self) def exitRule(self, listener: ParseTreeListener): - if hasattr(listener, "exitStates_decl"): - listener.exitStates_decl(self) + if hasattr(listener, "exitMax_concurrency_int"): + listener.exitMax_concurrency_int(self) def accept(self, visitor: ParseTreeVisitor): - if hasattr(visitor, "visitStates_decl"): - return visitor.visitStates_decl(self) + if hasattr(visitor, "visitMax_concurrency_int"): + return visitor.visitMax_concurrency_int(self) else: return visitor.visitChildren(self) - def states_decl(self): - localctx = ASLParser.States_declContext(self, self._ctx, self.state) - self.enterRule(localctx, 14, self.RULE_states_decl) - self._la = 0 # Token type + def max_concurrency_decl(self): + localctx = ASLParser.Max_concurrency_declContext(self, self._ctx, self.state) + self.enterRule(localctx, 62, self.RULE_max_concurrency_decl) try: - self.enterOuterAlt(localctx, 1) - self.state = 271 - self.match(ASLParser.STATES) - self.state = 272 - self.match(ASLParser.COLON) - self.state = 273 - self.match(ASLParser.LBRACE) - self.state = 274 - self.state_decl() - self.state = 279 + self.state = 514 self._errHandler.sync(self) - _la = self._input.LA(1) - while _la == 1: - self.state = 275 - self.match(ASLParser.COMMA) - self.state = 276 - self.state_decl() - self.state = 281 - self._errHandler.sync(self) - _la = self._input.LA(1) + la_ = self._interp.adaptivePredict(self._input, 20, self._ctx) + if la_ == 1: + localctx = ASLParser.Max_concurrency_jsonataContext(self, localctx) + self.enterOuterAlt(localctx, 1) + self.state = 508 + self.match(ASLParser.MAXCONCURRENCY) + self.state = 509 + self.match(ASLParser.COLON) + self.state = 510 + self.match(ASLParser.STRINGJSONATA) + pass + + elif la_ == 2: + localctx = ASLParser.Max_concurrency_intContext(self, localctx) + self.enterOuterAlt(localctx, 2) + self.state = 511 + self.match(ASLParser.MAXCONCURRENCY) + self.state = 512 + self.match(ASLParser.COLON) + self.state = 513 + self.match(ASLParser.INT) + pass - self.state = 282 - self.match(ASLParser.RBRACE) except RecognitionException as re: localctx.exception = re self._errHandler.reportError(self, re) @@ -8995,7 +15530,7 @@ def states_decl(self): self.exitRule() return localctx - class State_nameContext(ParserRuleContext): + class Max_concurrency_path_declContext(ParserRuleContext): __slots__ = "parser" def __init__( @@ -9004,33 +15539,103 @@ def __init__( super().__init__(parent, invokingState) self.parser = parser - def keyword_or_string(self): - return self.getTypedRuleContext(ASLParser.Keyword_or_stringContext, 0) - def getRuleIndex(self): - return ASLParser.RULE_state_name + return ASLParser.RULE_max_concurrency_path_decl + + def copyFrom(self, ctx: ParserRuleContext): + super().copyFrom(ctx) + + class Max_concurrency_path_varContext(Max_concurrency_path_declContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Max_concurrency_path_declContext + super().__init__(parser) + self.copyFrom(ctx) + + def MAXCONCURRENCYPATH(self): + return self.getToken(ASLParser.MAXCONCURRENCYPATH, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def variable_sample(self): + return self.getTypedRuleContext(ASLParser.Variable_sampleContext, 0) def enterRule(self, listener: ParseTreeListener): - if hasattr(listener, "enterState_name"): - listener.enterState_name(self) + if hasattr(listener, "enterMax_concurrency_path_var"): + listener.enterMax_concurrency_path_var(self) def exitRule(self, listener: ParseTreeListener): - if hasattr(listener, "exitState_name"): - listener.exitState_name(self) + if hasattr(listener, "exitMax_concurrency_path_var"): + listener.exitMax_concurrency_path_var(self) def accept(self, visitor: ParseTreeVisitor): - if hasattr(visitor, "visitState_name"): - return visitor.visitState_name(self) + if hasattr(visitor, "visitMax_concurrency_path_var"): + return visitor.visitMax_concurrency_path_var(self) else: return visitor.visitChildren(self) - def state_name(self): - localctx = ASLParser.State_nameContext(self, self._ctx, self.state) - self.enterRule(localctx, 16, self.RULE_state_name) + class Max_concurrency_pathContext(Max_concurrency_path_declContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Max_concurrency_path_declContext + super().__init__(parser) + self.copyFrom(ctx) + + def MAXCONCURRENCYPATH(self): + return self.getToken(ASLParser.MAXCONCURRENCYPATH, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def STRINGPATH(self): + return self.getToken(ASLParser.STRINGPATH, 0) + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterMax_concurrency_path"): + listener.enterMax_concurrency_path(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitMax_concurrency_path"): + listener.exitMax_concurrency_path(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitMax_concurrency_path"): + return visitor.visitMax_concurrency_path(self) + else: + return visitor.visitChildren(self) + + def max_concurrency_path_decl(self): + localctx = ASLParser.Max_concurrency_path_declContext( + self, self._ctx, self.state + ) + self.enterRule(localctx, 64, self.RULE_max_concurrency_path_decl) try: - self.enterOuterAlt(localctx, 1) - self.state = 284 - self.keyword_or_string() + self.state = 522 + self._errHandler.sync(self) + la_ = self._interp.adaptivePredict(self._input, 21, self._ctx) + if la_ == 1: + localctx = ASLParser.Max_concurrency_path_varContext(self, localctx) + self.enterOuterAlt(localctx, 1) + self.state = 516 + self.match(ASLParser.MAXCONCURRENCYPATH) + self.state = 517 + self.match(ASLParser.COLON) + self.state = 518 + self.variable_sample() + pass + + elif la_ == 2: + localctx = ASLParser.Max_concurrency_pathContext(self, localctx) + self.enterOuterAlt(localctx, 2) + self.state = 519 + self.match(ASLParser.MAXCONCURRENCYPATH) + self.state = 520 + self.match(ASLParser.COLON) + self.state = 521 + self.match(ASLParser.STRINGPATH) + pass + except RecognitionException as re: localctx.exception = re self._errHandler.reportError(self, re) @@ -9039,7 +15644,7 @@ def state_name(self): self.exitRule() return localctx - class State_declContext(ParserRuleContext): + class Parameters_declContext(ParserRuleContext): __slots__ = "parser" def __init__( @@ -9048,43 +15653,43 @@ def __init__( super().__init__(parent, invokingState) self.parser = parser - def state_name(self): - return self.getTypedRuleContext(ASLParser.State_nameContext, 0) + def PARAMETERS(self): + return self.getToken(ASLParser.PARAMETERS, 0) def COLON(self): return self.getToken(ASLParser.COLON, 0) - def state_decl_body(self): - return self.getTypedRuleContext(ASLParser.State_decl_bodyContext, 0) + def payload_tmpl_decl(self): + return self.getTypedRuleContext(ASLParser.Payload_tmpl_declContext, 0) def getRuleIndex(self): - return ASLParser.RULE_state_decl + return ASLParser.RULE_parameters_decl def enterRule(self, listener: ParseTreeListener): - if hasattr(listener, "enterState_decl"): - listener.enterState_decl(self) + if hasattr(listener, "enterParameters_decl"): + listener.enterParameters_decl(self) def exitRule(self, listener: ParseTreeListener): - if hasattr(listener, "exitState_decl"): - listener.exitState_decl(self) + if hasattr(listener, "exitParameters_decl"): + listener.exitParameters_decl(self) def accept(self, visitor: ParseTreeVisitor): - if hasattr(visitor, "visitState_decl"): - return visitor.visitState_decl(self) + if hasattr(visitor, "visitParameters_decl"): + return visitor.visitParameters_decl(self) else: return visitor.visitChildren(self) - def state_decl(self): - localctx = ASLParser.State_declContext(self, self._ctx, self.state) - self.enterRule(localctx, 18, self.RULE_state_decl) + def parameters_decl(self): + localctx = ASLParser.Parameters_declContext(self, self._ctx, self.state) + self.enterRule(localctx, 66, self.RULE_parameters_decl) try: self.enterOuterAlt(localctx, 1) - self.state = 286 - self.state_name() - self.state = 287 + self.state = 524 + self.match(ASLParser.PARAMETERS) + self.state = 525 self.match(ASLParser.COLON) - self.state = 288 - self.state_decl_body() + self.state = 526 + self.payload_tmpl_decl() except RecognitionException as re: localctx.exception = re self._errHandler.reportError(self, re) @@ -9093,7 +15698,7 @@ def state_decl(self): self.exitRule() return localctx - class State_decl_bodyContext(ParserRuleContext): + class Credentials_declContext(ParserRuleContext): __slots__ = "parser" def __init__( @@ -9102,64 +15707,52 @@ def __init__( super().__init__(parent, invokingState) self.parser = parser + def CREDENTIALS(self): + return self.getToken(ASLParser.CREDENTIALS, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + def LBRACE(self): return self.getToken(ASLParser.LBRACE, 0) - def state_stmt(self, i: int = None): - if i is None: - return self.getTypedRuleContexts(ASLParser.State_stmtContext) - else: - return self.getTypedRuleContext(ASLParser.State_stmtContext, i) + def role_arn_decl(self): + return self.getTypedRuleContext(ASLParser.Role_arn_declContext, 0) def RBRACE(self): return self.getToken(ASLParser.RBRACE, 0) - def COMMA(self, i: int = None): - if i is None: - return self.getTokens(ASLParser.COMMA) - else: - return self.getToken(ASLParser.COMMA, i) - def getRuleIndex(self): - return ASLParser.RULE_state_decl_body + return ASLParser.RULE_credentials_decl def enterRule(self, listener: ParseTreeListener): - if hasattr(listener, "enterState_decl_body"): - listener.enterState_decl_body(self) + if hasattr(listener, "enterCredentials_decl"): + listener.enterCredentials_decl(self) def exitRule(self, listener: ParseTreeListener): - if hasattr(listener, "exitState_decl_body"): - listener.exitState_decl_body(self) + if hasattr(listener, "exitCredentials_decl"): + listener.exitCredentials_decl(self) def accept(self, visitor: ParseTreeVisitor): - if hasattr(visitor, "visitState_decl_body"): - return visitor.visitState_decl_body(self) + if hasattr(visitor, "visitCredentials_decl"): + return visitor.visitCredentials_decl(self) else: return visitor.visitChildren(self) - def state_decl_body(self): - localctx = ASLParser.State_decl_bodyContext(self, self._ctx, self.state) - self.enterRule(localctx, 20, self.RULE_state_decl_body) - self._la = 0 # Token type + def credentials_decl(self): + localctx = ASLParser.Credentials_declContext(self, self._ctx, self.state) + self.enterRule(localctx, 68, self.RULE_credentials_decl) try: self.enterOuterAlt(localctx, 1) - self.state = 290 + self.state = 528 + self.match(ASLParser.CREDENTIALS) + self.state = 529 + self.match(ASLParser.COLON) + self.state = 530 self.match(ASLParser.LBRACE) - self.state = 291 - self.state_stmt() - self.state = 296 - self._errHandler.sync(self) - _la = self._input.LA(1) - while _la == 1: - self.state = 292 - self.match(ASLParser.COMMA) - self.state = 293 - self.state_stmt() - self.state = 298 - self._errHandler.sync(self) - _la = self._input.LA(1) - - self.state = 299 + self.state = 531 + self.role_arn_decl() + self.state = 532 self.match(ASLParser.RBRACE) except RecognitionException as re: localctx.exception = re @@ -9169,7 +15762,7 @@ def state_decl_body(self): self.exitRule() return localctx - class Type_declContext(ParserRuleContext): + class Role_arn_declContext(ParserRuleContext): __slots__ = "parser" def __init__( @@ -9178,62 +15771,111 @@ def __init__( super().__init__(parent, invokingState) self.parser = parser - def TYPE(self): - return self.getToken(ASLParser.TYPE, 0) + def getRuleIndex(self): + return ASLParser.RULE_role_arn_decl + + def copyFrom(self, ctx: ParserRuleContext): + super().copyFrom(ctx) + + class Role_arn_jsonataContext(Role_arn_declContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Role_arn_declContext + super().__init__(parser) + self.copyFrom(ctx) + + def ROLEARN(self): + return self.getToken(ASLParser.ROLEARN, 0) def COLON(self): return self.getToken(ASLParser.COLON, 0) - def state_type(self): - return self.getTypedRuleContext(ASLParser.State_typeContext, 0) + def STRINGJSONATA(self): + return self.getToken(ASLParser.STRINGJSONATA, 0) - def getRuleIndex(self): - return ASLParser.RULE_type_decl + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterRole_arn_jsonata"): + listener.enterRole_arn_jsonata(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitRole_arn_jsonata"): + listener.exitRole_arn_jsonata(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitRole_arn_jsonata"): + return visitor.visitRole_arn_jsonata(self) + else: + return visitor.visitChildren(self) + + class Role_arn_path_context_objContext(Role_arn_declContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Role_arn_declContext + super().__init__(parser) + self.copyFrom(ctx) + + def ROLEARNPATH(self): + return self.getToken(ASLParser.ROLEARNPATH, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def STRINGPATHCONTEXTOBJ(self): + return self.getToken(ASLParser.STRINGPATHCONTEXTOBJ, 0) def enterRule(self, listener: ParseTreeListener): - if hasattr(listener, "enterType_decl"): - listener.enterType_decl(self) + if hasattr(listener, "enterRole_arn_path_context_obj"): + listener.enterRole_arn_path_context_obj(self) def exitRule(self, listener: ParseTreeListener): - if hasattr(listener, "exitType_decl"): - listener.exitType_decl(self) + if hasattr(listener, "exitRole_arn_path_context_obj"): + listener.exitRole_arn_path_context_obj(self) def accept(self, visitor: ParseTreeVisitor): - if hasattr(visitor, "visitType_decl"): - return visitor.visitType_decl(self) + if hasattr(visitor, "visitRole_arn_path_context_obj"): + return visitor.visitRole_arn_path_context_obj(self) else: return visitor.visitChildren(self) - def type_decl(self): - localctx = ASLParser.Type_declContext(self, self._ctx, self.state) - self.enterRule(localctx, 22, self.RULE_type_decl) - try: - self.enterOuterAlt(localctx, 1) - self.state = 301 - self.match(ASLParser.TYPE) - self.state = 302 - self.match(ASLParser.COLON) - self.state = 303 - self.state_type() - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx + class Role_arn_pathContext(Role_arn_declContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Role_arn_declContext + super().__init__(parser) + self.copyFrom(ctx) - class Next_declContext(ParserRuleContext): - __slots__ = "parser" + def ROLEARNPATH(self): + return self.getToken(ASLParser.ROLEARNPATH, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def STRINGPATH(self): + return self.getToken(ASLParser.STRINGPATH, 0) + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterRole_arn_path"): + listener.enterRole_arn_path(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitRole_arn_path"): + listener.exitRole_arn_path(self) + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitRole_arn_path"): + return visitor.visitRole_arn_path(self) + else: + return visitor.visitChildren(self) + + class Role_arn_strContext(Role_arn_declContext): def __init__( - self, parser, parent: ParserRuleContext = None, invokingState: int = -1 - ): - super().__init__(parent, invokingState) - self.parser = parser + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Role_arn_declContext + super().__init__(parser) + self.copyFrom(ctx) - def NEXT(self): - return self.getToken(ASLParser.NEXT, 0) + def ROLEARN(self): + return self.getToken(ASLParser.ROLEARN, 0) def COLON(self): return self.getToken(ASLParser.COLON, 0) @@ -9241,287 +15883,152 @@ def COLON(self): def keyword_or_string(self): return self.getTypedRuleContext(ASLParser.Keyword_or_stringContext, 0) - def getRuleIndex(self): - return ASLParser.RULE_next_decl - def enterRule(self, listener: ParseTreeListener): - if hasattr(listener, "enterNext_decl"): - listener.enterNext_decl(self) + if hasattr(listener, "enterRole_arn_str"): + listener.enterRole_arn_str(self) def exitRule(self, listener: ParseTreeListener): - if hasattr(listener, "exitNext_decl"): - listener.exitNext_decl(self) + if hasattr(listener, "exitRole_arn_str"): + listener.exitRole_arn_str(self) def accept(self, visitor: ParseTreeVisitor): - if hasattr(visitor, "visitNext_decl"): - return visitor.visitNext_decl(self) + if hasattr(visitor, "visitRole_arn_str"): + return visitor.visitRole_arn_str(self) else: return visitor.visitChildren(self) - def next_decl(self): - localctx = ASLParser.Next_declContext(self, self._ctx, self.state) - self.enterRule(localctx, 24, self.RULE_next_decl) - try: - self.enterOuterAlt(localctx, 1) - self.state = 305 - self.match(ASLParser.NEXT) - self.state = 306 - self.match(ASLParser.COLON) - self.state = 307 - self.keyword_or_string() - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - class Resource_declContext(ParserRuleContext): - __slots__ = "parser" - + class Role_arn_intrinsic_funcContext(Role_arn_declContext): def __init__( - self, parser, parent: ParserRuleContext = None, invokingState: int = -1 - ): - super().__init__(parent, invokingState) - self.parser = parser + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Role_arn_declContext + super().__init__(parser) + self.copyFrom(ctx) - def RESOURCE(self): - return self.getToken(ASLParser.RESOURCE, 0) + def ROLEARNPATH(self): + return self.getToken(ASLParser.ROLEARNPATH, 0) def COLON(self): return self.getToken(ASLParser.COLON, 0) - def keyword_or_string(self): - return self.getTypedRuleContext(ASLParser.Keyword_or_stringContext, 0) - - def getRuleIndex(self): - return ASLParser.RULE_resource_decl + def STRINGINTRINSICFUNC(self): + return self.getToken(ASLParser.STRINGINTRINSICFUNC, 0) def enterRule(self, listener: ParseTreeListener): - if hasattr(listener, "enterResource_decl"): - listener.enterResource_decl(self) + if hasattr(listener, "enterRole_arn_intrinsic_func"): + listener.enterRole_arn_intrinsic_func(self) def exitRule(self, listener: ParseTreeListener): - if hasattr(listener, "exitResource_decl"): - listener.exitResource_decl(self) + if hasattr(listener, "exitRole_arn_intrinsic_func"): + listener.exitRole_arn_intrinsic_func(self) def accept(self, visitor: ParseTreeVisitor): - if hasattr(visitor, "visitResource_decl"): - return visitor.visitResource_decl(self) + if hasattr(visitor, "visitRole_arn_intrinsic_func"): + return visitor.visitRole_arn_intrinsic_func(self) else: return visitor.visitChildren(self) - def resource_decl(self): - localctx = ASLParser.Resource_declContext(self, self._ctx, self.state) - self.enterRule(localctx, 26, self.RULE_resource_decl) - try: - self.enterOuterAlt(localctx, 1) - self.state = 309 - self.match(ASLParser.RESOURCE) - self.state = 310 - self.match(ASLParser.COLON) - self.state = 311 - self.keyword_or_string() - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - class Input_path_declContext(ParserRuleContext): - __slots__ = "parser" - + class Role_arn_varContext(Role_arn_declContext): def __init__( - self, parser, parent: ParserRuleContext = None, invokingState: int = -1 - ): - super().__init__(parent, invokingState) - self.parser = parser + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Role_arn_declContext + super().__init__(parser) + self.copyFrom(ctx) - def INPUTPATH(self): - return self.getToken(ASLParser.INPUTPATH, 0) + def ROLEARNPATH(self): + return self.getToken(ASLParser.ROLEARNPATH, 0) def COLON(self): return self.getToken(ASLParser.COLON, 0) - def NULL(self): - return self.getToken(ASLParser.NULL, 0) - - def keyword_or_string(self): - return self.getTypedRuleContext(ASLParser.Keyword_or_stringContext, 0) - - def getRuleIndex(self): - return ASLParser.RULE_input_path_decl + def variable_sample(self): + return self.getTypedRuleContext(ASLParser.Variable_sampleContext, 0) def enterRule(self, listener: ParseTreeListener): - if hasattr(listener, "enterInput_path_decl"): - listener.enterInput_path_decl(self) + if hasattr(listener, "enterRole_arn_var"): + listener.enterRole_arn_var(self) def exitRule(self, listener: ParseTreeListener): - if hasattr(listener, "exitInput_path_decl"): - listener.exitInput_path_decl(self) + if hasattr(listener, "exitRole_arn_var"): + listener.exitRole_arn_var(self) def accept(self, visitor: ParseTreeVisitor): - if hasattr(visitor, "visitInput_path_decl"): - return visitor.visitInput_path_decl(self) + if hasattr(visitor, "visitRole_arn_var"): + return visitor.visitRole_arn_var(self) else: return visitor.visitChildren(self) - def input_path_decl(self): - localctx = ASLParser.Input_path_declContext(self, self._ctx, self.state) - self.enterRule(localctx, 28, self.RULE_input_path_decl) + def role_arn_decl(self): + localctx = ASLParser.Role_arn_declContext(self, self._ctx, self.state) + self.enterRule(localctx, 70, self.RULE_role_arn_decl) try: - self.enterOuterAlt(localctx, 1) - self.state = 313 - self.match(ASLParser.INPUTPATH) - self.state = 314 - self.match(ASLParser.COLON) - self.state = 317 + self.state = 552 self._errHandler.sync(self) - token = self._input.LA(1) - if token in [9]: - self.state = 315 - self.match(ASLParser.NULL) + la_ = self._interp.adaptivePredict(self._input, 22, self._ctx) + if la_ == 1: + localctx = ASLParser.Role_arn_jsonataContext(self, localctx) + self.enterOuterAlt(localctx, 1) + self.state = 534 + self.match(ASLParser.ROLEARN) + self.state = 535 + self.match(ASLParser.COLON) + self.state = 536 + self.match(ASLParser.STRINGJSONATA) pass - elif token in [ - 10, - 11, - 12, - 13, - 15, - 16, - 17, - 18, - 19, - 20, - 21, - 22, - 23, - 24, - 25, - 26, - 27, - 28, - 29, - 30, - 31, - 32, - 33, - 34, - 35, - 36, - 37, - 38, - 39, - 40, - 41, - 42, - 43, - 44, - 45, - 46, - 47, - 48, - 49, - 50, - 51, - 52, - 53, - 54, - 55, - 56, - 57, - 58, - 59, - 60, - 61, - 62, - 63, - 64, - 65, - 66, - 67, - 68, - 69, - 70, - 71, - 72, - 73, - 74, - 75, - 76, - 77, - 78, - 79, - 80, - 81, - 82, - 83, - 84, - 85, - 86, - 87, - 88, - 89, - 90, - 91, - 92, - 93, - 94, - 95, - 96, - 97, - 98, - 99, - 100, - 101, - 102, - 103, - 104, - 105, - 106, - 107, - 108, - 109, - 110, - 111, - 113, - 115, - 116, - 117, - 118, - 119, - 120, - 121, - 122, - 123, - 124, - 125, - 127, - 128, - 129, - 130, - 131, - 132, - 133, - 134, - 135, - 136, - 137, - 138, - 139, - 140, - 141, - 142, - 143, - ]: - self.state = 316 + + elif la_ == 2: + localctx = ASLParser.Role_arn_pathContext(self, localctx) + self.enterOuterAlt(localctx, 2) + self.state = 537 + self.match(ASLParser.ROLEARNPATH) + self.state = 538 + self.match(ASLParser.COLON) + self.state = 539 + self.match(ASLParser.STRINGPATH) + pass + + elif la_ == 3: + localctx = ASLParser.Role_arn_path_context_objContext(self, localctx) + self.enterOuterAlt(localctx, 3) + self.state = 540 + self.match(ASLParser.ROLEARNPATH) + self.state = 541 + self.match(ASLParser.COLON) + self.state = 542 + self.match(ASLParser.STRINGPATHCONTEXTOBJ) + pass + + elif la_ == 4: + localctx = ASLParser.Role_arn_intrinsic_funcContext(self, localctx) + self.enterOuterAlt(localctx, 4) + self.state = 543 + self.match(ASLParser.ROLEARNPATH) + self.state = 544 + self.match(ASLParser.COLON) + self.state = 545 + self.match(ASLParser.STRINGINTRINSICFUNC) + pass + + elif la_ == 5: + localctx = ASLParser.Role_arn_varContext(self, localctx) + self.enterOuterAlt(localctx, 5) + self.state = 546 + self.match(ASLParser.ROLEARNPATH) + self.state = 547 + self.match(ASLParser.COLON) + self.state = 548 + self.variable_sample() + pass + + elif la_ == 6: + localctx = ASLParser.Role_arn_strContext(self, localctx) + self.enterOuterAlt(localctx, 6) + self.state = 549 + self.match(ASLParser.ROLEARN) + self.state = 550 + self.match(ASLParser.COLON) + self.state = 551 self.keyword_or_string() pass - else: - raise NoViableAltException(self) except RecognitionException as re: localctx.exception = re @@ -9531,7 +16038,7 @@ def input_path_decl(self): self.exitRule() return localctx - class Result_declContext(ParserRuleContext): + class Timeout_seconds_declContext(ParserRuleContext): __slots__ = "parser" def __init__( @@ -9540,43 +16047,101 @@ def __init__( super().__init__(parent, invokingState) self.parser = parser - def RESULT(self): - return self.getToken(ASLParser.RESULT, 0) + def getRuleIndex(self): + return ASLParser.RULE_timeout_seconds_decl + + def copyFrom(self, ctx: ParserRuleContext): + super().copyFrom(ctx) + + class Timeout_seconds_jsonataContext(Timeout_seconds_declContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Timeout_seconds_declContext + super().__init__(parser) + self.copyFrom(ctx) + + def TIMEOUTSECONDS(self): + return self.getToken(ASLParser.TIMEOUTSECONDS, 0) def COLON(self): return self.getToken(ASLParser.COLON, 0) - def json_value_decl(self): - return self.getTypedRuleContext(ASLParser.Json_value_declContext, 0) + def STRINGJSONATA(self): + return self.getToken(ASLParser.STRINGJSONATA, 0) - def getRuleIndex(self): - return ASLParser.RULE_result_decl + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterTimeout_seconds_jsonata"): + listener.enterTimeout_seconds_jsonata(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitTimeout_seconds_jsonata"): + listener.exitTimeout_seconds_jsonata(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitTimeout_seconds_jsonata"): + return visitor.visitTimeout_seconds_jsonata(self) + else: + return visitor.visitChildren(self) + + class Timeout_seconds_intContext(Timeout_seconds_declContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Timeout_seconds_declContext + super().__init__(parser) + self.copyFrom(ctx) + + def TIMEOUTSECONDS(self): + return self.getToken(ASLParser.TIMEOUTSECONDS, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def INT(self): + return self.getToken(ASLParser.INT, 0) def enterRule(self, listener: ParseTreeListener): - if hasattr(listener, "enterResult_decl"): - listener.enterResult_decl(self) + if hasattr(listener, "enterTimeout_seconds_int"): + listener.enterTimeout_seconds_int(self) def exitRule(self, listener: ParseTreeListener): - if hasattr(listener, "exitResult_decl"): - listener.exitResult_decl(self) + if hasattr(listener, "exitTimeout_seconds_int"): + listener.exitTimeout_seconds_int(self) def accept(self, visitor: ParseTreeVisitor): - if hasattr(visitor, "visitResult_decl"): - return visitor.visitResult_decl(self) + if hasattr(visitor, "visitTimeout_seconds_int"): + return visitor.visitTimeout_seconds_int(self) else: return visitor.visitChildren(self) - def result_decl(self): - localctx = ASLParser.Result_declContext(self, self._ctx, self.state) - self.enterRule(localctx, 30, self.RULE_result_decl) + def timeout_seconds_decl(self): + localctx = ASLParser.Timeout_seconds_declContext(self, self._ctx, self.state) + self.enterRule(localctx, 72, self.RULE_timeout_seconds_decl) try: - self.enterOuterAlt(localctx, 1) - self.state = 319 - self.match(ASLParser.RESULT) - self.state = 320 - self.match(ASLParser.COLON) - self.state = 321 - self.json_value_decl() + self.state = 560 + self._errHandler.sync(self) + la_ = self._interp.adaptivePredict(self._input, 23, self._ctx) + if la_ == 1: + localctx = ASLParser.Timeout_seconds_jsonataContext(self, localctx) + self.enterOuterAlt(localctx, 1) + self.state = 554 + self.match(ASLParser.TIMEOUTSECONDS) + self.state = 555 + self.match(ASLParser.COLON) + self.state = 556 + self.match(ASLParser.STRINGJSONATA) + pass + + elif la_ == 2: + localctx = ASLParser.Timeout_seconds_intContext(self, localctx) + self.enterOuterAlt(localctx, 2) + self.state = 557 + self.match(ASLParser.TIMEOUTSECONDS) + self.state = 558 + self.match(ASLParser.COLON) + self.state = 559 + self.match(ASLParser.INT) + pass + except RecognitionException as re: localctx.exception = re self._errHandler.reportError(self, re) @@ -9585,7 +16150,7 @@ def result_decl(self): self.exitRule() return localctx - class Result_path_declContext(ParserRuleContext): + class Timeout_seconds_path_declContext(ParserRuleContext): __slots__ = "parser" def __init__( @@ -9594,188 +16159,106 @@ def __init__( super().__init__(parent, invokingState) self.parser = parser - def RESULTPATH(self): - return self.getToken(ASLParser.RESULTPATH, 0) - - def COLON(self): - return self.getToken(ASLParser.COLON, 0) - - def NULL(self): - return self.getToken(ASLParser.NULL, 0) - - def keyword_or_string(self): - return self.getTypedRuleContext(ASLParser.Keyword_or_stringContext, 0) - def getRuleIndex(self): - return ASLParser.RULE_result_path_decl - - def enterRule(self, listener: ParseTreeListener): - if hasattr(listener, "enterResult_path_decl"): - listener.enterResult_path_decl(self) + return ASLParser.RULE_timeout_seconds_path_decl - def exitRule(self, listener: ParseTreeListener): - if hasattr(listener, "exitResult_path_decl"): - listener.exitResult_path_decl(self) + def copyFrom(self, ctx: ParserRuleContext): + super().copyFrom(ctx) - def accept(self, visitor: ParseTreeVisitor): - if hasattr(visitor, "visitResult_path_decl"): - return visitor.visitResult_path_decl(self) - else: - return visitor.visitChildren(self) + class Timeout_seconds_path_decl_varContext(Timeout_seconds_path_declContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Timeout_seconds_path_declContext + super().__init__(parser) + self.copyFrom(ctx) - def result_path_decl(self): - localctx = ASLParser.Result_path_declContext(self, self._ctx, self.state) - self.enterRule(localctx, 32, self.RULE_result_path_decl) - try: - self.enterOuterAlt(localctx, 1) - self.state = 323 - self.match(ASLParser.RESULTPATH) - self.state = 324 - self.match(ASLParser.COLON) - self.state = 327 - self._errHandler.sync(self) - token = self._input.LA(1) - if token in [9]: - self.state = 325 - self.match(ASLParser.NULL) - pass - elif token in [ - 10, - 11, - 12, - 13, - 15, - 16, - 17, - 18, - 19, - 20, - 21, - 22, - 23, - 24, - 25, - 26, - 27, - 28, - 29, - 30, - 31, - 32, - 33, - 34, - 35, - 36, - 37, - 38, - 39, - 40, - 41, - 42, - 43, - 44, - 45, - 46, - 47, - 48, - 49, - 50, - 51, - 52, - 53, - 54, - 55, - 56, - 57, - 58, - 59, - 60, - 61, - 62, - 63, - 64, - 65, - 66, - 67, - 68, - 69, - 70, - 71, - 72, - 73, - 74, - 75, - 76, - 77, - 78, - 79, - 80, - 81, - 82, - 83, - 84, - 85, - 86, - 87, - 88, - 89, - 90, - 91, - 92, - 93, - 94, - 95, - 96, - 97, - 98, - 99, - 100, - 101, - 102, - 103, - 104, - 105, - 106, - 107, - 108, - 109, - 110, - 111, - 113, - 115, - 116, - 117, - 118, - 119, - 120, - 121, - 122, - 123, - 124, - 125, - 127, - 128, - 129, - 130, - 131, - 132, - 133, - 134, - 135, - 136, - 137, - 138, - 139, - 140, - 141, - 142, - 143, - ]: - self.state = 326 - self.keyword_or_string() - pass + def TIMEOUTSECONDSPATH(self): + return self.getToken(ASLParser.TIMEOUTSECONDSPATH, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def variable_sample(self): + return self.getTypedRuleContext(ASLParser.Variable_sampleContext, 0) + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterTimeout_seconds_path_decl_var"): + listener.enterTimeout_seconds_path_decl_var(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitTimeout_seconds_path_decl_var"): + listener.exitTimeout_seconds_path_decl_var(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitTimeout_seconds_path_decl_var"): + return visitor.visitTimeout_seconds_path_decl_var(self) else: - raise NoViableAltException(self) + return visitor.visitChildren(self) + + class Timeout_seconds_path_decl_pathContext(Timeout_seconds_path_declContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Timeout_seconds_path_declContext + super().__init__(parser) + self.copyFrom(ctx) + + def TIMEOUTSECONDSPATH(self): + return self.getToken(ASLParser.TIMEOUTSECONDSPATH, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def STRINGPATH(self): + return self.getToken(ASLParser.STRINGPATH, 0) + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterTimeout_seconds_path_decl_path"): + listener.enterTimeout_seconds_path_decl_path(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitTimeout_seconds_path_decl_path"): + listener.exitTimeout_seconds_path_decl_path(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitTimeout_seconds_path_decl_path"): + return visitor.visitTimeout_seconds_path_decl_path(self) + else: + return visitor.visitChildren(self) + + def timeout_seconds_path_decl(self): + localctx = ASLParser.Timeout_seconds_path_declContext( + self, self._ctx, self.state + ) + self.enterRule(localctx, 74, self.RULE_timeout_seconds_path_decl) + try: + self.state = 568 + self._errHandler.sync(self) + la_ = self._interp.adaptivePredict(self._input, 24, self._ctx) + if la_ == 1: + localctx = ASLParser.Timeout_seconds_path_decl_varContext( + self, localctx + ) + self.enterOuterAlt(localctx, 1) + self.state = 562 + self.match(ASLParser.TIMEOUTSECONDSPATH) + self.state = 563 + self.match(ASLParser.COLON) + self.state = 564 + self.variable_sample() + pass + + elif la_ == 2: + localctx = ASLParser.Timeout_seconds_path_decl_pathContext( + self, localctx + ) + self.enterOuterAlt(localctx, 2) + self.state = 565 + self.match(ASLParser.TIMEOUTSECONDSPATH) + self.state = 566 + self.match(ASLParser.COLON) + self.state = 567 + self.match(ASLParser.STRINGPATH) + pass except RecognitionException as re: localctx.exception = re @@ -9785,7 +16268,7 @@ def result_path_decl(self): self.exitRule() return localctx - class Output_path_declContext(ParserRuleContext): + class Heartbeat_seconds_declContext(ParserRuleContext): __slots__ = "parser" def __init__( @@ -9794,189 +16277,263 @@ def __init__( super().__init__(parent, invokingState) self.parser = parser - def OUTPUTPATH(self): - return self.getToken(ASLParser.OUTPUTPATH, 0) + def getRuleIndex(self): + return ASLParser.RULE_heartbeat_seconds_decl + + def copyFrom(self, ctx: ParserRuleContext): + super().copyFrom(ctx) + + class Heartbeat_seconds_intContext(Heartbeat_seconds_declContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Heartbeat_seconds_declContext + super().__init__(parser) + self.copyFrom(ctx) + + def HEARTBEATSECONDS(self): + return self.getToken(ASLParser.HEARTBEATSECONDS, 0) def COLON(self): return self.getToken(ASLParser.COLON, 0) - def NULL(self): - return self.getToken(ASLParser.NULL, 0) + def INT(self): + return self.getToken(ASLParser.INT, 0) - def keyword_or_string(self): - return self.getTypedRuleContext(ASLParser.Keyword_or_stringContext, 0) + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterHeartbeat_seconds_int"): + listener.enterHeartbeat_seconds_int(self) - def getRuleIndex(self): - return ASLParser.RULE_output_path_decl + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitHeartbeat_seconds_int"): + listener.exitHeartbeat_seconds_int(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitHeartbeat_seconds_int"): + return visitor.visitHeartbeat_seconds_int(self) + else: + return visitor.visitChildren(self) + + class Heartbeat_seconds_jsonataContext(Heartbeat_seconds_declContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Heartbeat_seconds_declContext + super().__init__(parser) + self.copyFrom(ctx) + + def HEARTBEATSECONDS(self): + return self.getToken(ASLParser.HEARTBEATSECONDS, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def STRINGJSONATA(self): + return self.getToken(ASLParser.STRINGJSONATA, 0) def enterRule(self, listener: ParseTreeListener): - if hasattr(listener, "enterOutput_path_decl"): - listener.enterOutput_path_decl(self) + if hasattr(listener, "enterHeartbeat_seconds_jsonata"): + listener.enterHeartbeat_seconds_jsonata(self) def exitRule(self, listener: ParseTreeListener): - if hasattr(listener, "exitOutput_path_decl"): - listener.exitOutput_path_decl(self) + if hasattr(listener, "exitHeartbeat_seconds_jsonata"): + listener.exitHeartbeat_seconds_jsonata(self) def accept(self, visitor: ParseTreeVisitor): - if hasattr(visitor, "visitOutput_path_decl"): - return visitor.visitOutput_path_decl(self) + if hasattr(visitor, "visitHeartbeat_seconds_jsonata"): + return visitor.visitHeartbeat_seconds_jsonata(self) else: return visitor.visitChildren(self) - def output_path_decl(self): - localctx = ASLParser.Output_path_declContext(self, self._ctx, self.state) - self.enterRule(localctx, 34, self.RULE_output_path_decl) + def heartbeat_seconds_decl(self): + localctx = ASLParser.Heartbeat_seconds_declContext(self, self._ctx, self.state) + self.enterRule(localctx, 76, self.RULE_heartbeat_seconds_decl) try: - self.enterOuterAlt(localctx, 1) - self.state = 329 - self.match(ASLParser.OUTPUTPATH) - self.state = 330 - self.match(ASLParser.COLON) - self.state = 333 + self.state = 576 self._errHandler.sync(self) - token = self._input.LA(1) - if token in [9]: - self.state = 331 - self.match(ASLParser.NULL) + la_ = self._interp.adaptivePredict(self._input, 25, self._ctx) + if la_ == 1: + localctx = ASLParser.Heartbeat_seconds_jsonataContext(self, localctx) + self.enterOuterAlt(localctx, 1) + self.state = 570 + self.match(ASLParser.HEARTBEATSECONDS) + self.state = 571 + self.match(ASLParser.COLON) + self.state = 572 + self.match(ASLParser.STRINGJSONATA) pass - elif token in [ - 10, - 11, - 12, - 13, - 15, - 16, - 17, - 18, - 19, - 20, - 21, - 22, - 23, - 24, - 25, - 26, - 27, - 28, - 29, - 30, - 31, - 32, - 33, - 34, - 35, - 36, - 37, - 38, - 39, - 40, - 41, - 42, - 43, - 44, - 45, - 46, - 47, - 48, - 49, - 50, - 51, - 52, - 53, - 54, - 55, - 56, - 57, - 58, - 59, - 60, - 61, - 62, - 63, - 64, - 65, - 66, - 67, - 68, - 69, - 70, - 71, - 72, - 73, - 74, - 75, - 76, - 77, - 78, - 79, - 80, - 81, - 82, - 83, - 84, - 85, - 86, - 87, - 88, - 89, - 90, - 91, - 92, - 93, - 94, - 95, - 96, - 97, - 98, - 99, - 100, - 101, - 102, - 103, - 104, - 105, - 106, - 107, - 108, - 109, - 110, - 111, - 113, - 115, - 116, - 117, - 118, - 119, - 120, - 121, - 122, - 123, - 124, - 125, - 127, - 128, - 129, - 130, - 131, - 132, - 133, - 134, - 135, - 136, - 137, - 138, - 139, - 140, - 141, - 142, - 143, - ]: - self.state = 332 - self.keyword_or_string() + + elif la_ == 2: + localctx = ASLParser.Heartbeat_seconds_intContext(self, localctx) + self.enterOuterAlt(localctx, 2) + self.state = 573 + self.match(ASLParser.HEARTBEATSECONDS) + self.state = 574 + self.match(ASLParser.COLON) + self.state = 575 + self.match(ASLParser.INT) + pass + + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class Heartbeat_seconds_path_declContext(ParserRuleContext): + __slots__ = "parser" + + def __init__( + self, parser, parent: ParserRuleContext = None, invokingState: int = -1 + ): + super().__init__(parent, invokingState) + self.parser = parser + + def getRuleIndex(self): + return ASLParser.RULE_heartbeat_seconds_path_decl + + def copyFrom(self, ctx: ParserRuleContext): + super().copyFrom(ctx) + + class Heartbeat_seconds_path_decl_pathContext(Heartbeat_seconds_path_declContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Heartbeat_seconds_path_declContext + super().__init__(parser) + self.copyFrom(ctx) + + def HEARTBEATSECONDSPATH(self): + return self.getToken(ASLParser.HEARTBEATSECONDSPATH, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def STRINGPATH(self): + return self.getToken(ASLParser.STRINGPATH, 0) + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterHeartbeat_seconds_path_decl_path"): + listener.enterHeartbeat_seconds_path_decl_path(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitHeartbeat_seconds_path_decl_path"): + listener.exitHeartbeat_seconds_path_decl_path(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitHeartbeat_seconds_path_decl_path"): + return visitor.visitHeartbeat_seconds_path_decl_path(self) + else: + return visitor.visitChildren(self) + + class Heartbeat_seconds_path_decl_varContext(Heartbeat_seconds_path_declContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Heartbeat_seconds_path_declContext + super().__init__(parser) + self.copyFrom(ctx) + + def HEARTBEATSECONDSPATH(self): + return self.getToken(ASLParser.HEARTBEATSECONDSPATH, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def variable_sample(self): + return self.getTypedRuleContext(ASLParser.Variable_sampleContext, 0) + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterHeartbeat_seconds_path_decl_var"): + listener.enterHeartbeat_seconds_path_decl_var(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitHeartbeat_seconds_path_decl_var"): + listener.exitHeartbeat_seconds_path_decl_var(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitHeartbeat_seconds_path_decl_var"): + return visitor.visitHeartbeat_seconds_path_decl_var(self) + else: + return visitor.visitChildren(self) + + def heartbeat_seconds_path_decl(self): + localctx = ASLParser.Heartbeat_seconds_path_declContext( + self, self._ctx, self.state + ) + self.enterRule(localctx, 78, self.RULE_heartbeat_seconds_path_decl) + try: + self.state = 584 + self._errHandler.sync(self) + la_ = self._interp.adaptivePredict(self._input, 26, self._ctx) + if la_ == 1: + localctx = ASLParser.Heartbeat_seconds_path_decl_varContext( + self, localctx + ) + self.enterOuterAlt(localctx, 1) + self.state = 578 + self.match(ASLParser.HEARTBEATSECONDSPATH) + self.state = 579 + self.match(ASLParser.COLON) + self.state = 580 + self.variable_sample() + pass + + elif la_ == 2: + localctx = ASLParser.Heartbeat_seconds_path_decl_pathContext( + self, localctx + ) + self.enterOuterAlt(localctx, 2) + self.state = 581 + self.match(ASLParser.HEARTBEATSECONDSPATH) + self.state = 582 + self.match(ASLParser.COLON) + self.state = 583 + self.match(ASLParser.STRINGPATH) pass + + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class Variable_sampleContext(ParserRuleContext): + __slots__ = "parser" + + def __init__( + self, parser, parent: ParserRuleContext = None, invokingState: int = -1 + ): + super().__init__(parent, invokingState) + self.parser = parser + + def STRINGVAR(self): + return self.getToken(ASLParser.STRINGVAR, 0) + + def getRuleIndex(self): + return ASLParser.RULE_variable_sample + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterVariable_sample"): + listener.enterVariable_sample(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitVariable_sample"): + listener.exitVariable_sample(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitVariable_sample"): + return visitor.visitVariable_sample(self) else: - raise NoViableAltException(self) + return visitor.visitChildren(self) + def variable_sample(self): + localctx = ASLParser.Variable_sampleContext(self, self._ctx, self.state) + self.enterRule(localctx, 80, self.RULE_variable_sample) + try: + self.enterOuterAlt(localctx, 1) + self.state = 586 + self.match(ASLParser.STRINGVAR) except RecognitionException as re: localctx.exception = re self._errHandler.reportError(self, re) @@ -9985,7 +16542,7 @@ def output_path_decl(self): self.exitRule() return localctx - class End_declContext(ParserRuleContext): + class Payload_tmpl_declContext(ParserRuleContext): __slots__ = "parser" def __init__( @@ -9994,52 +16551,79 @@ def __init__( super().__init__(parent, invokingState) self.parser = parser - def END(self): - return self.getToken(ASLParser.END, 0) + def LBRACE(self): + return self.getToken(ASLParser.LBRACE, 0) - def COLON(self): - return self.getToken(ASLParser.COLON, 0) + def payload_binding(self, i: int = None): + if i is None: + return self.getTypedRuleContexts(ASLParser.Payload_bindingContext) + else: + return self.getTypedRuleContext(ASLParser.Payload_bindingContext, i) - def TRUE(self): - return self.getToken(ASLParser.TRUE, 0) + def RBRACE(self): + return self.getToken(ASLParser.RBRACE, 0) - def FALSE(self): - return self.getToken(ASLParser.FALSE, 0) + def COMMA(self, i: int = None): + if i is None: + return self.getTokens(ASLParser.COMMA) + else: + return self.getToken(ASLParser.COMMA, i) def getRuleIndex(self): - return ASLParser.RULE_end_decl + return ASLParser.RULE_payload_tmpl_decl def enterRule(self, listener: ParseTreeListener): - if hasattr(listener, "enterEnd_decl"): - listener.enterEnd_decl(self) + if hasattr(listener, "enterPayload_tmpl_decl"): + listener.enterPayload_tmpl_decl(self) def exitRule(self, listener: ParseTreeListener): - if hasattr(listener, "exitEnd_decl"): - listener.exitEnd_decl(self) + if hasattr(listener, "exitPayload_tmpl_decl"): + listener.exitPayload_tmpl_decl(self) def accept(self, visitor: ParseTreeVisitor): - if hasattr(visitor, "visitEnd_decl"): - return visitor.visitEnd_decl(self) + if hasattr(visitor, "visitPayload_tmpl_decl"): + return visitor.visitPayload_tmpl_decl(self) else: return visitor.visitChildren(self) - def end_decl(self): - localctx = ASLParser.End_declContext(self, self._ctx, self.state) - self.enterRule(localctx, 36, self.RULE_end_decl) + def payload_tmpl_decl(self): + localctx = ASLParser.Payload_tmpl_declContext(self, self._ctx, self.state) + self.enterRule(localctx, 82, self.RULE_payload_tmpl_decl) self._la = 0 # Token type try: - self.enterOuterAlt(localctx, 1) - self.state = 335 - self.match(ASLParser.END) - self.state = 336 - self.match(ASLParser.COLON) - self.state = 337 - _la = self._input.LA(1) - if not (_la == 7 or _la == 8): - self._errHandler.recoverInline(self) - else: - self._errHandler.reportMatch(self) - self.consume() + self.state = 601 + self._errHandler.sync(self) + la_ = self._interp.adaptivePredict(self._input, 28, self._ctx) + if la_ == 1: + self.enterOuterAlt(localctx, 1) + self.state = 588 + self.match(ASLParser.LBRACE) + self.state = 589 + self.payload_binding() + self.state = 594 + self._errHandler.sync(self) + _la = self._input.LA(1) + while _la == 1: + self.state = 590 + self.match(ASLParser.COMMA) + self.state = 591 + self.payload_binding() + self.state = 596 + self._errHandler.sync(self) + _la = self._input.LA(1) + + self.state = 597 + self.match(ASLParser.RBRACE) + pass + + elif la_ == 2: + self.enterOuterAlt(localctx, 2) + self.state = 599 + self.match(ASLParser.LBRACE) + self.state = 600 + self.match(ASLParser.RBRACE) + pass + except RecognitionException as re: localctx.exception = re self._errHandler.reportError(self, re) @@ -10048,7 +16632,7 @@ def end_decl(self): self.exitRule() return localctx - class Default_declContext(ParserRuleContext): + class Payload_bindingContext(ParserRuleContext): __slots__ = "parser" def __init__( @@ -10057,97 +16641,228 @@ def __init__( super().__init__(parent, invokingState) self.parser = parser - def DEFAULT(self): - return self.getToken(ASLParser.DEFAULT, 0) + def getRuleIndex(self): + return ASLParser.RULE_payload_binding + + def copyFrom(self, ctx: ParserRuleContext): + super().copyFrom(ctx) + + class Payload_binding_pathContext(Payload_bindingContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Payload_bindingContext + super().__init__(parser) + self.copyFrom(ctx) + + def STRINGDOLLAR(self): + return self.getToken(ASLParser.STRINGDOLLAR, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def STRINGPATH(self): + return self.getToken(ASLParser.STRINGPATH, 0) + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterPayload_binding_path"): + listener.enterPayload_binding_path(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitPayload_binding_path"): + listener.exitPayload_binding_path(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitPayload_binding_path"): + return visitor.visitPayload_binding_path(self) + else: + return visitor.visitChildren(self) + + class Payload_binding_path_context_objContext(Payload_bindingContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Payload_bindingContext + super().__init__(parser) + self.copyFrom(ctx) + + def STRINGDOLLAR(self): + return self.getToken(ASLParser.STRINGDOLLAR, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def STRINGPATHCONTEXTOBJ(self): + return self.getToken(ASLParser.STRINGPATHCONTEXTOBJ, 0) + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterPayload_binding_path_context_obj"): + listener.enterPayload_binding_path_context_obj(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitPayload_binding_path_context_obj"): + listener.exitPayload_binding_path_context_obj(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitPayload_binding_path_context_obj"): + return visitor.visitPayload_binding_path_context_obj(self) + else: + return visitor.visitChildren(self) + + class Payload_binding_intrinsic_funcContext(Payload_bindingContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Payload_bindingContext + super().__init__(parser) + self.copyFrom(ctx) + + def STRINGDOLLAR(self): + return self.getToken(ASLParser.STRINGDOLLAR, 0) def COLON(self): return self.getToken(ASLParser.COLON, 0) - def keyword_or_string(self): - return self.getTypedRuleContext(ASLParser.Keyword_or_stringContext, 0) - - def getRuleIndex(self): - return ASLParser.RULE_default_decl + def STRINGINTRINSICFUNC(self): + return self.getToken(ASLParser.STRINGINTRINSICFUNC, 0) def enterRule(self, listener: ParseTreeListener): - if hasattr(listener, "enterDefault_decl"): - listener.enterDefault_decl(self) + if hasattr(listener, "enterPayload_binding_intrinsic_func"): + listener.enterPayload_binding_intrinsic_func(self) def exitRule(self, listener: ParseTreeListener): - if hasattr(listener, "exitDefault_decl"): - listener.exitDefault_decl(self) + if hasattr(listener, "exitPayload_binding_intrinsic_func"): + listener.exitPayload_binding_intrinsic_func(self) def accept(self, visitor: ParseTreeVisitor): - if hasattr(visitor, "visitDefault_decl"): - return visitor.visitDefault_decl(self) + if hasattr(visitor, "visitPayload_binding_intrinsic_func"): + return visitor.visitPayload_binding_intrinsic_func(self) else: return visitor.visitChildren(self) - def default_decl(self): - localctx = ASLParser.Default_declContext(self, self._ctx, self.state) - self.enterRule(localctx, 38, self.RULE_default_decl) - try: - self.enterOuterAlt(localctx, 1) - self.state = 339 - self.match(ASLParser.DEFAULT) - self.state = 340 - self.match(ASLParser.COLON) - self.state = 341 - self.keyword_or_string() - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - class Error_declContext(ParserRuleContext): - __slots__ = "parser" - + class Payload_binding_varContext(Payload_bindingContext): def __init__( - self, parser, parent: ParserRuleContext = None, invokingState: int = -1 - ): - super().__init__(parent, invokingState) - self.parser = parser + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Payload_bindingContext + super().__init__(parser) + self.copyFrom(ctx) - def ERROR(self): - return self.getToken(ASLParser.ERROR, 0) + def STRINGDOLLAR(self): + return self.getToken(ASLParser.STRINGDOLLAR, 0) def COLON(self): return self.getToken(ASLParser.COLON, 0) + def variable_sample(self): + return self.getTypedRuleContext(ASLParser.Variable_sampleContext, 0) + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterPayload_binding_var"): + listener.enterPayload_binding_var(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitPayload_binding_var"): + listener.exitPayload_binding_var(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitPayload_binding_var"): + return visitor.visitPayload_binding_var(self) + else: + return visitor.visitChildren(self) + + class Payload_binding_valueContext(Payload_bindingContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Payload_bindingContext + super().__init__(parser) + self.copyFrom(ctx) + def keyword_or_string(self): return self.getTypedRuleContext(ASLParser.Keyword_or_stringContext, 0) - def getRuleIndex(self): - return ASLParser.RULE_error_decl + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def payload_value_decl(self): + return self.getTypedRuleContext(ASLParser.Payload_value_declContext, 0) def enterRule(self, listener: ParseTreeListener): - if hasattr(listener, "enterError_decl"): - listener.enterError_decl(self) + if hasattr(listener, "enterPayload_binding_value"): + listener.enterPayload_binding_value(self) def exitRule(self, listener: ParseTreeListener): - if hasattr(listener, "exitError_decl"): - listener.exitError_decl(self) + if hasattr(listener, "exitPayload_binding_value"): + listener.exitPayload_binding_value(self) def accept(self, visitor: ParseTreeVisitor): - if hasattr(visitor, "visitError_decl"): - return visitor.visitError_decl(self) + if hasattr(visitor, "visitPayload_binding_value"): + return visitor.visitPayload_binding_value(self) else: return visitor.visitChildren(self) - def error_decl(self): - localctx = ASLParser.Error_declContext(self, self._ctx, self.state) - self.enterRule(localctx, 40, self.RULE_error_decl) + def payload_binding(self): + localctx = ASLParser.Payload_bindingContext(self, self._ctx, self.state) + self.enterRule(localctx, 84, self.RULE_payload_binding) try: - self.enterOuterAlt(localctx, 1) - self.state = 343 - self.match(ASLParser.ERROR) - self.state = 344 - self.match(ASLParser.COLON) - self.state = 345 - self.keyword_or_string() + self.state = 619 + self._errHandler.sync(self) + la_ = self._interp.adaptivePredict(self._input, 29, self._ctx) + if la_ == 1: + localctx = ASLParser.Payload_binding_pathContext(self, localctx) + self.enterOuterAlt(localctx, 1) + self.state = 603 + self.match(ASLParser.STRINGDOLLAR) + self.state = 604 + self.match(ASLParser.COLON) + self.state = 605 + self.match(ASLParser.STRINGPATH) + pass + + elif la_ == 2: + localctx = ASLParser.Payload_binding_path_context_objContext( + self, localctx + ) + self.enterOuterAlt(localctx, 2) + self.state = 606 + self.match(ASLParser.STRINGDOLLAR) + self.state = 607 + self.match(ASLParser.COLON) + self.state = 608 + self.match(ASLParser.STRINGPATHCONTEXTOBJ) + pass + + elif la_ == 3: + localctx = ASLParser.Payload_binding_intrinsic_funcContext( + self, localctx + ) + self.enterOuterAlt(localctx, 3) + self.state = 609 + self.match(ASLParser.STRINGDOLLAR) + self.state = 610 + self.match(ASLParser.COLON) + self.state = 611 + self.match(ASLParser.STRINGINTRINSICFUNC) + pass + + elif la_ == 4: + localctx = ASLParser.Payload_binding_varContext(self, localctx) + self.enterOuterAlt(localctx, 4) + self.state = 612 + self.match(ASLParser.STRINGDOLLAR) + self.state = 613 + self.match(ASLParser.COLON) + self.state = 614 + self.variable_sample() + pass + + elif la_ == 5: + localctx = ASLParser.Payload_binding_valueContext(self, localctx) + self.enterOuterAlt(localctx, 5) + self.state = 615 + self.keyword_or_string() + self.state = 616 + self.match(ASLParser.COLON) + self.state = 617 + self.payload_value_decl() + pass + except RecognitionException as re: localctx.exception = re self._errHandler.reportError(self, re) @@ -10156,7 +16871,7 @@ def error_decl(self): self.exitRule() return localctx - class Error_path_declContext(ParserRuleContext): + class Payload_arr_declContext(ParserRuleContext): __slots__ = "parser" def __init__( @@ -10165,99 +16880,77 @@ def __init__( super().__init__(parent, invokingState) self.parser = parser - def getRuleIndex(self): - return ASLParser.RULE_error_path_decl - - def copyFrom(self, ctx: ParserRuleContext): - super().copyFrom(ctx) - - class Error_path_decl_intrinsicContext(Error_path_declContext): - def __init__( - self, parser, ctx: ParserRuleContext - ): # actually a ASLParser.Error_path_declContext - super().__init__(parser) - self.copyFrom(ctx) - - def ERRORPATH(self): - return self.getToken(ASLParser.ERRORPATH, 0) - - def COLON(self): - return self.getToken(ASLParser.COLON, 0) - - def intrinsic_func(self): - return self.getTypedRuleContext(ASLParser.Intrinsic_funcContext, 0) - - def enterRule(self, listener: ParseTreeListener): - if hasattr(listener, "enterError_path_decl_intrinsic"): - listener.enterError_path_decl_intrinsic(self) - - def exitRule(self, listener: ParseTreeListener): - if hasattr(listener, "exitError_path_decl_intrinsic"): - listener.exitError_path_decl_intrinsic(self) + def LBRACK(self): + return self.getToken(ASLParser.LBRACK, 0) - def accept(self, visitor: ParseTreeVisitor): - if hasattr(visitor, "visitError_path_decl_intrinsic"): - return visitor.visitError_path_decl_intrinsic(self) + def payload_value_decl(self, i: int = None): + if i is None: + return self.getTypedRuleContexts(ASLParser.Payload_value_declContext) else: - return visitor.visitChildren(self) - - class Error_path_decl_pathContext(Error_path_declContext): - def __init__( - self, parser, ctx: ParserRuleContext - ): # actually a ASLParser.Error_path_declContext - super().__init__(parser) - self.copyFrom(ctx) + return self.getTypedRuleContext(ASLParser.Payload_value_declContext, i) - def ERRORPATH(self): - return self.getToken(ASLParser.ERRORPATH, 0) + def RBRACK(self): + return self.getToken(ASLParser.RBRACK, 0) - def COLON(self): - return self.getToken(ASLParser.COLON, 0) + def COMMA(self, i: int = None): + if i is None: + return self.getTokens(ASLParser.COMMA) + else: + return self.getToken(ASLParser.COMMA, i) - def STRINGPATH(self): - return self.getToken(ASLParser.STRINGPATH, 0) + def getRuleIndex(self): + return ASLParser.RULE_payload_arr_decl def enterRule(self, listener: ParseTreeListener): - if hasattr(listener, "enterError_path_decl_path"): - listener.enterError_path_decl_path(self) + if hasattr(listener, "enterPayload_arr_decl"): + listener.enterPayload_arr_decl(self) def exitRule(self, listener: ParseTreeListener): - if hasattr(listener, "exitError_path_decl_path"): - listener.exitError_path_decl_path(self) + if hasattr(listener, "exitPayload_arr_decl"): + listener.exitPayload_arr_decl(self) def accept(self, visitor: ParseTreeVisitor): - if hasattr(visitor, "visitError_path_decl_path"): - return visitor.visitError_path_decl_path(self) + if hasattr(visitor, "visitPayload_arr_decl"): + return visitor.visitPayload_arr_decl(self) else: return visitor.visitChildren(self) - def error_path_decl(self): - localctx = ASLParser.Error_path_declContext(self, self._ctx, self.state) - self.enterRule(localctx, 42, self.RULE_error_path_decl) + def payload_arr_decl(self): + localctx = ASLParser.Payload_arr_declContext(self, self._ctx, self.state) + self.enterRule(localctx, 86, self.RULE_payload_arr_decl) + self._la = 0 # Token type try: - self.state = 353 + self.state = 634 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input, 8, self._ctx) + la_ = self._interp.adaptivePredict(self._input, 31, self._ctx) if la_ == 1: - localctx = ASLParser.Error_path_decl_pathContext(self, localctx) self.enterOuterAlt(localctx, 1) - self.state = 347 - self.match(ASLParser.ERRORPATH) - self.state = 348 - self.match(ASLParser.COLON) - self.state = 349 - self.match(ASLParser.STRINGPATH) + self.state = 621 + self.match(ASLParser.LBRACK) + self.state = 622 + self.payload_value_decl() + self.state = 627 + self._errHandler.sync(self) + _la = self._input.LA(1) + while _la == 1: + self.state = 623 + self.match(ASLParser.COMMA) + self.state = 624 + self.payload_value_decl() + self.state = 629 + self._errHandler.sync(self) + _la = self._input.LA(1) + + self.state = 630 + self.match(ASLParser.RBRACK) pass elif la_ == 2: - localctx = ASLParser.Error_path_decl_intrinsicContext(self, localctx) self.enterOuterAlt(localctx, 2) - self.state = 350 - self.match(ASLParser.ERRORPATH) - self.state = 351 - self.match(ASLParser.COLON) - self.state = 352 - self.intrinsic_func() + self.state = 632 + self.match(ASLParser.LBRACK) + self.state = 633 + self.match(ASLParser.RBRACK) pass except RecognitionException as re: @@ -10268,7 +16961,7 @@ def error_path_decl(self): self.exitRule() return localctx - class Cause_declContext(ParserRuleContext): + class Payload_value_declContext(ParserRuleContext): __slots__ = "parser" def __init__( @@ -10277,43 +16970,207 @@ def __init__( super().__init__(parent, invokingState) self.parser = parser - def CAUSE(self): - return self.getToken(ASLParser.CAUSE, 0) + def payload_arr_decl(self): + return self.getTypedRuleContext(ASLParser.Payload_arr_declContext, 0) - def COLON(self): - return self.getToken(ASLParser.COLON, 0) + def payload_tmpl_decl(self): + return self.getTypedRuleContext(ASLParser.Payload_tmpl_declContext, 0) - def keyword_or_string(self): - return self.getTypedRuleContext(ASLParser.Keyword_or_stringContext, 0) + def payload_value_lit(self): + return self.getTypedRuleContext(ASLParser.Payload_value_litContext, 0) def getRuleIndex(self): - return ASLParser.RULE_cause_decl + return ASLParser.RULE_payload_value_decl def enterRule(self, listener: ParseTreeListener): - if hasattr(listener, "enterCause_decl"): - listener.enterCause_decl(self) + if hasattr(listener, "enterPayload_value_decl"): + listener.enterPayload_value_decl(self) def exitRule(self, listener: ParseTreeListener): - if hasattr(listener, "exitCause_decl"): - listener.exitCause_decl(self) + if hasattr(listener, "exitPayload_value_decl"): + listener.exitPayload_value_decl(self) def accept(self, visitor: ParseTreeVisitor): - if hasattr(visitor, "visitCause_decl"): - return visitor.visitCause_decl(self) + if hasattr(visitor, "visitPayload_value_decl"): + return visitor.visitPayload_value_decl(self) else: return visitor.visitChildren(self) - def cause_decl(self): - localctx = ASLParser.Cause_declContext(self, self._ctx, self.state) - self.enterRule(localctx, 44, self.RULE_cause_decl) + def payload_value_decl(self): + localctx = ASLParser.Payload_value_declContext(self, self._ctx, self.state) + self.enterRule(localctx, 88, self.RULE_payload_value_decl) try: - self.enterOuterAlt(localctx, 1) - self.state = 355 - self.match(ASLParser.CAUSE) - self.state = 356 - self.match(ASLParser.COLON) - self.state = 357 - self.keyword_or_string() + self.state = 639 + self._errHandler.sync(self) + token = self._input.LA(1) + if token in [3]: + self.enterOuterAlt(localctx, 1) + self.state = 636 + self.payload_arr_decl() + pass + elif token in [5]: + self.enterOuterAlt(localctx, 2) + self.state = 637 + self.payload_tmpl_decl() + pass + elif token in [ + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 119, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 134, + 135, + 136, + 137, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + ]: + self.enterOuterAlt(localctx, 3) + self.state = 638 + self.payload_value_lit() + pass + else: + raise NoViableAltException(self) + except RecognitionException as re: localctx.exception = re self._errHandler.reportError(self, re) @@ -10322,7 +17179,7 @@ def cause_decl(self): self.exitRule() return localctx - class Cause_path_declContext(ParserRuleContext): + class Payload_value_litContext(ParserRuleContext): __slots__ = "parser" def __init__( @@ -10332,208 +17189,325 @@ def __init__( self.parser = parser def getRuleIndex(self): - return ASLParser.RULE_cause_path_decl + return ASLParser.RULE_payload_value_lit def copyFrom(self, ctx: ParserRuleContext): super().copyFrom(ctx) - class Cause_path_decl_pathContext(Cause_path_declContext): + class Payload_value_boolContext(Payload_value_litContext): def __init__( self, parser, ctx: ParserRuleContext - ): # actually a ASLParser.Cause_path_declContext + ): # actually a ASLParser.Payload_value_litContext super().__init__(parser) self.copyFrom(ctx) - def CAUSEPATH(self): - return self.getToken(ASLParser.CAUSEPATH, 0) - - def COLON(self): - return self.getToken(ASLParser.COLON, 0) + def TRUE(self): + return self.getToken(ASLParser.TRUE, 0) - def STRINGPATH(self): - return self.getToken(ASLParser.STRINGPATH, 0) + def FALSE(self): + return self.getToken(ASLParser.FALSE, 0) def enterRule(self, listener: ParseTreeListener): - if hasattr(listener, "enterCause_path_decl_path"): - listener.enterCause_path_decl_path(self) + if hasattr(listener, "enterPayload_value_bool"): + listener.enterPayload_value_bool(self) def exitRule(self, listener: ParseTreeListener): - if hasattr(listener, "exitCause_path_decl_path"): - listener.exitCause_path_decl_path(self) + if hasattr(listener, "exitPayload_value_bool"): + listener.exitPayload_value_bool(self) def accept(self, visitor: ParseTreeVisitor): - if hasattr(visitor, "visitCause_path_decl_path"): - return visitor.visitCause_path_decl_path(self) + if hasattr(visitor, "visitPayload_value_bool"): + return visitor.visitPayload_value_bool(self) else: return visitor.visitChildren(self) - class Cause_path_decl_intrinsicContext(Cause_path_declContext): + class Payload_value_intContext(Payload_value_litContext): def __init__( self, parser, ctx: ParserRuleContext - ): # actually a ASLParser.Cause_path_declContext + ): # actually a ASLParser.Payload_value_litContext super().__init__(parser) self.copyFrom(ctx) - def CAUSEPATH(self): - return self.getToken(ASLParser.CAUSEPATH, 0) - - def COLON(self): - return self.getToken(ASLParser.COLON, 0) - - def intrinsic_func(self): - return self.getTypedRuleContext(ASLParser.Intrinsic_funcContext, 0) + def INT(self): + return self.getToken(ASLParser.INT, 0) def enterRule(self, listener: ParseTreeListener): - if hasattr(listener, "enterCause_path_decl_intrinsic"): - listener.enterCause_path_decl_intrinsic(self) - - def exitRule(self, listener: ParseTreeListener): - if hasattr(listener, "exitCause_path_decl_intrinsic"): - listener.exitCause_path_decl_intrinsic(self) - - def accept(self, visitor: ParseTreeVisitor): - if hasattr(visitor, "visitCause_path_decl_intrinsic"): - return visitor.visitCause_path_decl_intrinsic(self) - else: - return visitor.visitChildren(self) - - def cause_path_decl(self): - localctx = ASLParser.Cause_path_declContext(self, self._ctx, self.state) - self.enterRule(localctx, 46, self.RULE_cause_path_decl) - try: - self.state = 365 - self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input, 9, self._ctx) - if la_ == 1: - localctx = ASLParser.Cause_path_decl_pathContext(self, localctx) - self.enterOuterAlt(localctx, 1) - self.state = 359 - self.match(ASLParser.CAUSEPATH) - self.state = 360 - self.match(ASLParser.COLON) - self.state = 361 - self.match(ASLParser.STRINGPATH) - pass - - elif la_ == 2: - localctx = ASLParser.Cause_path_decl_intrinsicContext(self, localctx) - self.enterOuterAlt(localctx, 2) - self.state = 362 - self.match(ASLParser.CAUSEPATH) - self.state = 363 - self.match(ASLParser.COLON) - self.state = 364 - self.intrinsic_func() - pass - - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - class Seconds_declContext(ParserRuleContext): - __slots__ = "parser" - - def __init__( - self, parser, parent: ParserRuleContext = None, invokingState: int = -1 - ): - super().__init__(parent, invokingState) - self.parser = parser + if hasattr(listener, "enterPayload_value_int"): + listener.enterPayload_value_int(self) - def SECONDS(self): - return self.getToken(ASLParser.SECONDS, 0) + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitPayload_value_int"): + listener.exitPayload_value_int(self) - def COLON(self): - return self.getToken(ASLParser.COLON, 0) + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitPayload_value_int"): + return visitor.visitPayload_value_int(self) + else: + return visitor.visitChildren(self) - def INT(self): - return self.getToken(ASLParser.INT, 0) + class Payload_value_strContext(Payload_value_litContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Payload_value_litContext + super().__init__(parser) + self.copyFrom(ctx) - def getRuleIndex(self): - return ASLParser.RULE_seconds_decl + def keyword_or_string(self): + return self.getTypedRuleContext(ASLParser.Keyword_or_stringContext, 0) def enterRule(self, listener: ParseTreeListener): - if hasattr(listener, "enterSeconds_decl"): - listener.enterSeconds_decl(self) + if hasattr(listener, "enterPayload_value_str"): + listener.enterPayload_value_str(self) def exitRule(self, listener: ParseTreeListener): - if hasattr(listener, "exitSeconds_decl"): - listener.exitSeconds_decl(self) + if hasattr(listener, "exitPayload_value_str"): + listener.exitPayload_value_str(self) def accept(self, visitor: ParseTreeVisitor): - if hasattr(visitor, "visitSeconds_decl"): - return visitor.visitSeconds_decl(self) + if hasattr(visitor, "visitPayload_value_str"): + return visitor.visitPayload_value_str(self) else: return visitor.visitChildren(self) - def seconds_decl(self): - localctx = ASLParser.Seconds_declContext(self, self._ctx, self.state) - self.enterRule(localctx, 48, self.RULE_seconds_decl) - try: - self.enterOuterAlt(localctx, 1) - self.state = 367 - self.match(ASLParser.SECONDS) - self.state = 368 - self.match(ASLParser.COLON) - self.state = 369 - self.match(ASLParser.INT) - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx + class Payload_value_floatContext(Payload_value_litContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Payload_value_litContext + super().__init__(parser) + self.copyFrom(ctx) - class Seconds_path_declContext(ParserRuleContext): - __slots__ = "parser" + def NUMBER(self): + return self.getToken(ASLParser.NUMBER, 0) - def __init__( - self, parser, parent: ParserRuleContext = None, invokingState: int = -1 - ): - super().__init__(parent, invokingState) - self.parser = parser + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterPayload_value_float"): + listener.enterPayload_value_float(self) - def SECONDSPATH(self): - return self.getToken(ASLParser.SECONDSPATH, 0) + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitPayload_value_float"): + listener.exitPayload_value_float(self) - def COLON(self): - return self.getToken(ASLParser.COLON, 0) + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitPayload_value_float"): + return visitor.visitPayload_value_float(self) + else: + return visitor.visitChildren(self) - def keyword_or_string(self): - return self.getTypedRuleContext(ASLParser.Keyword_or_stringContext, 0) + class Payload_value_nullContext(Payload_value_litContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Payload_value_litContext + super().__init__(parser) + self.copyFrom(ctx) - def getRuleIndex(self): - return ASLParser.RULE_seconds_path_decl + def NULL(self): + return self.getToken(ASLParser.NULL, 0) def enterRule(self, listener: ParseTreeListener): - if hasattr(listener, "enterSeconds_path_decl"): - listener.enterSeconds_path_decl(self) + if hasattr(listener, "enterPayload_value_null"): + listener.enterPayload_value_null(self) def exitRule(self, listener: ParseTreeListener): - if hasattr(listener, "exitSeconds_path_decl"): - listener.exitSeconds_path_decl(self) + if hasattr(listener, "exitPayload_value_null"): + listener.exitPayload_value_null(self) def accept(self, visitor: ParseTreeVisitor): - if hasattr(visitor, "visitSeconds_path_decl"): - return visitor.visitSeconds_path_decl(self) + if hasattr(visitor, "visitPayload_value_null"): + return visitor.visitPayload_value_null(self) + else: + return visitor.visitChildren(self) + + def payload_value_lit(self): + localctx = ASLParser.Payload_value_litContext(self, self._ctx, self.state) + self.enterRule(localctx, 90, self.RULE_payload_value_lit) + self._la = 0 # Token type + try: + self.state = 646 + self._errHandler.sync(self) + token = self._input.LA(1) + if token in [161]: + localctx = ASLParser.Payload_value_floatContext(self, localctx) + self.enterOuterAlt(localctx, 1) + self.state = 641 + self.match(ASLParser.NUMBER) + pass + elif token in [160]: + localctx = ASLParser.Payload_value_intContext(self, localctx) + self.enterOuterAlt(localctx, 2) + self.state = 642 + self.match(ASLParser.INT) + pass + elif token in [7, 8]: + localctx = ASLParser.Payload_value_boolContext(self, localctx) + self.enterOuterAlt(localctx, 3) + self.state = 643 + _la = self._input.LA(1) + if not (_la == 7 or _la == 8): + self._errHandler.recoverInline(self) + else: + self._errHandler.reportMatch(self) + self.consume() + pass + elif token in [9]: + localctx = ASLParser.Payload_value_nullContext(self, localctx) + self.enterOuterAlt(localctx, 4) + self.state = 644 + self.match(ASLParser.NULL) + pass + elif token in [ + 10, + 11, + 12, + 13, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 119, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 134, + 135, + 136, + 137, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + ]: + localctx = ASLParser.Payload_value_strContext(self, localctx) + self.enterOuterAlt(localctx, 5) + self.state = 645 + self.keyword_or_string() + pass else: - return visitor.visitChildren(self) + raise NoViableAltException(self) - def seconds_path_decl(self): - localctx = ASLParser.Seconds_path_declContext(self, self._ctx, self.state) - self.enterRule(localctx, 50, self.RULE_seconds_path_decl) - try: - self.enterOuterAlt(localctx, 1) - self.state = 371 - self.match(ASLParser.SECONDSPATH) - self.state = 372 - self.match(ASLParser.COLON) - self.state = 373 - self.keyword_or_string() except RecognitionException as re: localctx.exception = re self._errHandler.reportError(self, re) @@ -10542,7 +17516,7 @@ def seconds_path_decl(self): self.exitRule() return localctx - class Timestamp_declContext(ParserRuleContext): + class Assign_declContext(ParserRuleContext): __slots__ = "parser" def __init__( @@ -10551,43 +17525,43 @@ def __init__( super().__init__(parent, invokingState) self.parser = parser - def TIMESTAMP(self): - return self.getToken(ASLParser.TIMESTAMP, 0) + def ASSIGN(self): + return self.getToken(ASLParser.ASSIGN, 0) def COLON(self): return self.getToken(ASLParser.COLON, 0) - def keyword_or_string(self): - return self.getTypedRuleContext(ASLParser.Keyword_or_stringContext, 0) + def assign_decl_body(self): + return self.getTypedRuleContext(ASLParser.Assign_decl_bodyContext, 0) def getRuleIndex(self): - return ASLParser.RULE_timestamp_decl + return ASLParser.RULE_assign_decl def enterRule(self, listener: ParseTreeListener): - if hasattr(listener, "enterTimestamp_decl"): - listener.enterTimestamp_decl(self) + if hasattr(listener, "enterAssign_decl"): + listener.enterAssign_decl(self) def exitRule(self, listener: ParseTreeListener): - if hasattr(listener, "exitTimestamp_decl"): - listener.exitTimestamp_decl(self) + if hasattr(listener, "exitAssign_decl"): + listener.exitAssign_decl(self) def accept(self, visitor: ParseTreeVisitor): - if hasattr(visitor, "visitTimestamp_decl"): - return visitor.visitTimestamp_decl(self) + if hasattr(visitor, "visitAssign_decl"): + return visitor.visitAssign_decl(self) else: return visitor.visitChildren(self) - def timestamp_decl(self): - localctx = ASLParser.Timestamp_declContext(self, self._ctx, self.state) - self.enterRule(localctx, 52, self.RULE_timestamp_decl) + def assign_decl(self): + localctx = ASLParser.Assign_declContext(self, self._ctx, self.state) + self.enterRule(localctx, 92, self.RULE_assign_decl) try: self.enterOuterAlt(localctx, 1) - self.state = 375 - self.match(ASLParser.TIMESTAMP) - self.state = 376 + self.state = 648 + self.match(ASLParser.ASSIGN) + self.state = 649 self.match(ASLParser.COLON) - self.state = 377 - self.keyword_or_string() + self.state = 650 + self.assign_decl_body() except RecognitionException as re: localctx.exception = re self._errHandler.reportError(self, re) @@ -10596,7 +17570,7 @@ def timestamp_decl(self): self.exitRule() return localctx - class Timestamp_path_declContext(ParserRuleContext): + class Assign_decl_bodyContext(ParserRuleContext): __slots__ = "parser" def __init__( @@ -10605,43 +17579,79 @@ def __init__( super().__init__(parent, invokingState) self.parser = parser - def TIMESTAMPPATH(self): - return self.getToken(ASLParser.TIMESTAMPPATH, 0) + def LBRACE(self): + return self.getToken(ASLParser.LBRACE, 0) - def COLON(self): - return self.getToken(ASLParser.COLON, 0) + def RBRACE(self): + return self.getToken(ASLParser.RBRACE, 0) - def keyword_or_string(self): - return self.getTypedRuleContext(ASLParser.Keyword_or_stringContext, 0) + def assign_decl_binding(self, i: int = None): + if i is None: + return self.getTypedRuleContexts(ASLParser.Assign_decl_bindingContext) + else: + return self.getTypedRuleContext(ASLParser.Assign_decl_bindingContext, i) + + def COMMA(self, i: int = None): + if i is None: + return self.getTokens(ASLParser.COMMA) + else: + return self.getToken(ASLParser.COMMA, i) def getRuleIndex(self): - return ASLParser.RULE_timestamp_path_decl + return ASLParser.RULE_assign_decl_body def enterRule(self, listener: ParseTreeListener): - if hasattr(listener, "enterTimestamp_path_decl"): - listener.enterTimestamp_path_decl(self) + if hasattr(listener, "enterAssign_decl_body"): + listener.enterAssign_decl_body(self) def exitRule(self, listener: ParseTreeListener): - if hasattr(listener, "exitTimestamp_path_decl"): - listener.exitTimestamp_path_decl(self) + if hasattr(listener, "exitAssign_decl_body"): + listener.exitAssign_decl_body(self) def accept(self, visitor: ParseTreeVisitor): - if hasattr(visitor, "visitTimestamp_path_decl"): - return visitor.visitTimestamp_path_decl(self) + if hasattr(visitor, "visitAssign_decl_body"): + return visitor.visitAssign_decl_body(self) else: return visitor.visitChildren(self) - def timestamp_path_decl(self): - localctx = ASLParser.Timestamp_path_declContext(self, self._ctx, self.state) - self.enterRule(localctx, 54, self.RULE_timestamp_path_decl) + def assign_decl_body(self): + localctx = ASLParser.Assign_decl_bodyContext(self, self._ctx, self.state) + self.enterRule(localctx, 94, self.RULE_assign_decl_body) + self._la = 0 # Token type try: - self.enterOuterAlt(localctx, 1) - self.state = 379 - self.match(ASLParser.TIMESTAMPPATH) - self.state = 380 - self.match(ASLParser.COLON) - self.state = 381 - self.keyword_or_string() + self.state = 665 + self._errHandler.sync(self) + la_ = self._interp.adaptivePredict(self._input, 35, self._ctx) + if la_ == 1: + self.enterOuterAlt(localctx, 1) + self.state = 652 + self.match(ASLParser.LBRACE) + self.state = 653 + self.match(ASLParser.RBRACE) + pass + + elif la_ == 2: + self.enterOuterAlt(localctx, 2) + self.state = 654 + self.match(ASLParser.LBRACE) + self.state = 655 + self.assign_decl_binding() + self.state = 660 + self._errHandler.sync(self) + _la = self._input.LA(1) + while _la == 1: + self.state = 656 + self.match(ASLParser.COMMA) + self.state = 657 + self.assign_decl_binding() + self.state = 662 + self._errHandler.sync(self) + _la = self._input.LA(1) + + self.state = 663 + self.match(ASLParser.RBRACE) + pass + except RecognitionException as re: localctx.exception = re self._errHandler.reportError(self, re) @@ -10650,7 +17660,7 @@ def timestamp_path_decl(self): self.exitRule() return localctx - class Items_path_declContext(ParserRuleContext): + class Assign_decl_bindingContext(ParserRuleContext): __slots__ = "parser" def __init__( @@ -10659,43 +17669,33 @@ def __init__( super().__init__(parent, invokingState) self.parser = parser - def ITEMSPATH(self): - return self.getToken(ASLParser.ITEMSPATH, 0) - - def COLON(self): - return self.getToken(ASLParser.COLON, 0) - - def keyword_or_string(self): - return self.getTypedRuleContext(ASLParser.Keyword_or_stringContext, 0) + def assign_template_binding(self): + return self.getTypedRuleContext(ASLParser.Assign_template_bindingContext, 0) def getRuleIndex(self): - return ASLParser.RULE_items_path_decl + return ASLParser.RULE_assign_decl_binding def enterRule(self, listener: ParseTreeListener): - if hasattr(listener, "enterItems_path_decl"): - listener.enterItems_path_decl(self) + if hasattr(listener, "enterAssign_decl_binding"): + listener.enterAssign_decl_binding(self) def exitRule(self, listener: ParseTreeListener): - if hasattr(listener, "exitItems_path_decl"): - listener.exitItems_path_decl(self) + if hasattr(listener, "exitAssign_decl_binding"): + listener.exitAssign_decl_binding(self) def accept(self, visitor: ParseTreeVisitor): - if hasattr(visitor, "visitItems_path_decl"): - return visitor.visitItems_path_decl(self) + if hasattr(visitor, "visitAssign_decl_binding"): + return visitor.visitAssign_decl_binding(self) else: return visitor.visitChildren(self) - def items_path_decl(self): - localctx = ASLParser.Items_path_declContext(self, self._ctx, self.state) - self.enterRule(localctx, 56, self.RULE_items_path_decl) + def assign_decl_binding(self): + localctx = ASLParser.Assign_decl_bindingContext(self, self._ctx, self.state) + self.enterRule(localctx, 96, self.RULE_assign_decl_binding) try: self.enterOuterAlt(localctx, 1) - self.state = 383 - self.match(ASLParser.ITEMSPATH) - self.state = 384 - self.match(ASLParser.COLON) - self.state = 385 - self.keyword_or_string() + self.state = 667 + self.assign_template_binding() except RecognitionException as re: localctx.exception = re self._errHandler.reportError(self, re) @@ -10704,7 +17704,7 @@ def items_path_decl(self): self.exitRule() return localctx - class Max_concurrency_declContext(ParserRuleContext): + class Assign_template_value_objectContext(ParserRuleContext): __slots__ = "parser" def __init__( @@ -10713,43 +17713,85 @@ def __init__( super().__init__(parent, invokingState) self.parser = parser - def MAXCONCURRENCY(self): - return self.getToken(ASLParser.MAXCONCURRENCY, 0) + def LBRACE(self): + return self.getToken(ASLParser.LBRACE, 0) - def COLON(self): - return self.getToken(ASLParser.COLON, 0) + def RBRACE(self): + return self.getToken(ASLParser.RBRACE, 0) - def INT(self): - return self.getToken(ASLParser.INT, 0) + def assign_template_binding(self, i: int = None): + if i is None: + return self.getTypedRuleContexts( + ASLParser.Assign_template_bindingContext + ) + else: + return self.getTypedRuleContext( + ASLParser.Assign_template_bindingContext, i + ) + + def COMMA(self, i: int = None): + if i is None: + return self.getTokens(ASLParser.COMMA) + else: + return self.getToken(ASLParser.COMMA, i) def getRuleIndex(self): - return ASLParser.RULE_max_concurrency_decl + return ASLParser.RULE_assign_template_value_object def enterRule(self, listener: ParseTreeListener): - if hasattr(listener, "enterMax_concurrency_decl"): - listener.enterMax_concurrency_decl(self) + if hasattr(listener, "enterAssign_template_value_object"): + listener.enterAssign_template_value_object(self) def exitRule(self, listener: ParseTreeListener): - if hasattr(listener, "exitMax_concurrency_decl"): - listener.exitMax_concurrency_decl(self) + if hasattr(listener, "exitAssign_template_value_object"): + listener.exitAssign_template_value_object(self) def accept(self, visitor: ParseTreeVisitor): - if hasattr(visitor, "visitMax_concurrency_decl"): - return visitor.visitMax_concurrency_decl(self) + if hasattr(visitor, "visitAssign_template_value_object"): + return visitor.visitAssign_template_value_object(self) else: return visitor.visitChildren(self) - def max_concurrency_decl(self): - localctx = ASLParser.Max_concurrency_declContext(self, self._ctx, self.state) - self.enterRule(localctx, 58, self.RULE_max_concurrency_decl) + def assign_template_value_object(self): + localctx = ASLParser.Assign_template_value_objectContext( + self, self._ctx, self.state + ) + self.enterRule(localctx, 98, self.RULE_assign_template_value_object) + self._la = 0 # Token type try: - self.enterOuterAlt(localctx, 1) - self.state = 387 - self.match(ASLParser.MAXCONCURRENCY) - self.state = 388 - self.match(ASLParser.COLON) - self.state = 389 - self.match(ASLParser.INT) + self.state = 682 + self._errHandler.sync(self) + la_ = self._interp.adaptivePredict(self._input, 37, self._ctx) + if la_ == 1: + self.enterOuterAlt(localctx, 1) + self.state = 669 + self.match(ASLParser.LBRACE) + self.state = 670 + self.match(ASLParser.RBRACE) + pass + + elif la_ == 2: + self.enterOuterAlt(localctx, 2) + self.state = 671 + self.match(ASLParser.LBRACE) + self.state = 672 + self.assign_template_binding() + self.state = 677 + self._errHandler.sync(self) + _la = self._input.LA(1) + while _la == 1: + self.state = 673 + self.match(ASLParser.COMMA) + self.state = 674 + self.assign_template_binding() + self.state = 679 + self._errHandler.sync(self) + _la = self._input.LA(1) + + self.state = 680 + self.match(ASLParser.RBRACE) + pass + except RecognitionException as re: localctx.exception = re self._errHandler.reportError(self, re) @@ -10758,7 +17800,7 @@ def max_concurrency_decl(self): self.exitRule() return localctx - class Max_concurrency_path_declContext(ParserRuleContext): + class Assign_template_bindingContext(ParserRuleContext): __slots__ = "parser" def __init__( @@ -10767,8 +17809,21 @@ def __init__( super().__init__(parent, invokingState) self.parser = parser - def MAXCONCURRENCYPATH(self): - return self.getToken(ASLParser.MAXCONCURRENCYPATH, 0) + def getRuleIndex(self): + return ASLParser.RULE_assign_template_binding + + def copyFrom(self, ctx: ParserRuleContext): + super().copyFrom(ctx) + + class Assign_template_binding_pathContext(Assign_template_bindingContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Assign_template_bindingContext + super().__init__(parser) + self.copyFrom(ctx) + + def STRINGDOLLAR(self): + return self.getToken(ASLParser.STRINGDOLLAR, 0) def COLON(self): return self.getToken(ASLParser.COLON, 0) @@ -10776,254 +17831,208 @@ def COLON(self): def STRINGPATH(self): return self.getToken(ASLParser.STRINGPATH, 0) - def getRuleIndex(self): - return ASLParser.RULE_max_concurrency_path_decl - def enterRule(self, listener: ParseTreeListener): - if hasattr(listener, "enterMax_concurrency_path_decl"): - listener.enterMax_concurrency_path_decl(self) + if hasattr(listener, "enterAssign_template_binding_path"): + listener.enterAssign_template_binding_path(self) def exitRule(self, listener: ParseTreeListener): - if hasattr(listener, "exitMax_concurrency_path_decl"): - listener.exitMax_concurrency_path_decl(self) + if hasattr(listener, "exitAssign_template_binding_path"): + listener.exitAssign_template_binding_path(self) def accept(self, visitor: ParseTreeVisitor): - if hasattr(visitor, "visitMax_concurrency_path_decl"): - return visitor.visitMax_concurrency_path_decl(self) + if hasattr(visitor, "visitAssign_template_binding_path"): + return visitor.visitAssign_template_binding_path(self) else: return visitor.visitChildren(self) - def max_concurrency_path_decl(self): - localctx = ASLParser.Max_concurrency_path_declContext( - self, self._ctx, self.state - ) - self.enterRule(localctx, 60, self.RULE_max_concurrency_path_decl) - try: - self.enterOuterAlt(localctx, 1) - self.state = 391 - self.match(ASLParser.MAXCONCURRENCYPATH) - self.state = 392 - self.match(ASLParser.COLON) - self.state = 393 - self.match(ASLParser.STRINGPATH) - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - class Parameters_declContext(ParserRuleContext): - __slots__ = "parser" - + class Assign_template_binding_path_contextContext(Assign_template_bindingContext): def __init__( - self, parser, parent: ParserRuleContext = None, invokingState: int = -1 - ): - super().__init__(parent, invokingState) - self.parser = parser + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Assign_template_bindingContext + super().__init__(parser) + self.copyFrom(ctx) - def PARAMETERS(self): - return self.getToken(ASLParser.PARAMETERS, 0) + def STRINGDOLLAR(self): + return self.getToken(ASLParser.STRINGDOLLAR, 0) def COLON(self): return self.getToken(ASLParser.COLON, 0) - def payload_tmpl_decl(self): - return self.getTypedRuleContext(ASLParser.Payload_tmpl_declContext, 0) - - def getRuleIndex(self): - return ASLParser.RULE_parameters_decl + def STRINGPATHCONTEXTOBJ(self): + return self.getToken(ASLParser.STRINGPATHCONTEXTOBJ, 0) def enterRule(self, listener: ParseTreeListener): - if hasattr(listener, "enterParameters_decl"): - listener.enterParameters_decl(self) + if hasattr(listener, "enterAssign_template_binding_path_context"): + listener.enterAssign_template_binding_path_context(self) def exitRule(self, listener: ParseTreeListener): - if hasattr(listener, "exitParameters_decl"): - listener.exitParameters_decl(self) + if hasattr(listener, "exitAssign_template_binding_path_context"): + listener.exitAssign_template_binding_path_context(self) def accept(self, visitor: ParseTreeVisitor): - if hasattr(visitor, "visitParameters_decl"): - return visitor.visitParameters_decl(self) + if hasattr(visitor, "visitAssign_template_binding_path_context"): + return visitor.visitAssign_template_binding_path_context(self) else: return visitor.visitChildren(self) - def parameters_decl(self): - localctx = ASLParser.Parameters_declContext(self, self._ctx, self.state) - self.enterRule(localctx, 62, self.RULE_parameters_decl) - try: - self.enterOuterAlt(localctx, 1) - self.state = 395 - self.match(ASLParser.PARAMETERS) - self.state = 396 - self.match(ASLParser.COLON) - self.state = 397 - self.payload_tmpl_decl() - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - class Timeout_seconds_declContext(ParserRuleContext): - __slots__ = "parser" - + class Assign_template_binding_intrinsic_funcContext(Assign_template_bindingContext): def __init__( - self, parser, parent: ParserRuleContext = None, invokingState: int = -1 - ): - super().__init__(parent, invokingState) - self.parser = parser + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Assign_template_bindingContext + super().__init__(parser) + self.copyFrom(ctx) - def TIMEOUTSECONDS(self): - return self.getToken(ASLParser.TIMEOUTSECONDS, 0) + def STRINGDOLLAR(self): + return self.getToken(ASLParser.STRINGDOLLAR, 0) def COLON(self): return self.getToken(ASLParser.COLON, 0) - def INT(self): - return self.getToken(ASLParser.INT, 0) - - def getRuleIndex(self): - return ASLParser.RULE_timeout_seconds_decl + def STRINGINTRINSICFUNC(self): + return self.getToken(ASLParser.STRINGINTRINSICFUNC, 0) def enterRule(self, listener: ParseTreeListener): - if hasattr(listener, "enterTimeout_seconds_decl"): - listener.enterTimeout_seconds_decl(self) + if hasattr(listener, "enterAssign_template_binding_intrinsic_func"): + listener.enterAssign_template_binding_intrinsic_func(self) def exitRule(self, listener: ParseTreeListener): - if hasattr(listener, "exitTimeout_seconds_decl"): - listener.exitTimeout_seconds_decl(self) + if hasattr(listener, "exitAssign_template_binding_intrinsic_func"): + listener.exitAssign_template_binding_intrinsic_func(self) def accept(self, visitor: ParseTreeVisitor): - if hasattr(visitor, "visitTimeout_seconds_decl"): - return visitor.visitTimeout_seconds_decl(self) + if hasattr(visitor, "visitAssign_template_binding_intrinsic_func"): + return visitor.visitAssign_template_binding_intrinsic_func(self) else: - return visitor.visitChildren(self) - - def timeout_seconds_decl(self): - localctx = ASLParser.Timeout_seconds_declContext(self, self._ctx, self.state) - self.enterRule(localctx, 64, self.RULE_timeout_seconds_decl) - try: - self.enterOuterAlt(localctx, 1) - self.state = 399 - self.match(ASLParser.TIMEOUTSECONDS) - self.state = 400 - self.match(ASLParser.COLON) - self.state = 401 - self.match(ASLParser.INT) - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - class Timeout_seconds_path_declContext(ParserRuleContext): - __slots__ = "parser" - - def __init__( - self, parser, parent: ParserRuleContext = None, invokingState: int = -1 - ): - super().__init__(parent, invokingState) - self.parser = parser + return visitor.visitChildren(self) - def TIMEOUTSECONDSPATH(self): - return self.getToken(ASLParser.TIMEOUTSECONDSPATH, 0) + class Assign_template_binding_assign_valueContext(Assign_template_bindingContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Assign_template_bindingContext + super().__init__(parser) + self.copyFrom(ctx) + + def STRING(self): + return self.getToken(ASLParser.STRING, 0) def COLON(self): return self.getToken(ASLParser.COLON, 0) - def STRINGPATH(self): - return self.getToken(ASLParser.STRINGPATH, 0) - - def getRuleIndex(self): - return ASLParser.RULE_timeout_seconds_path_decl + def assign_template_value(self): + return self.getTypedRuleContext(ASLParser.Assign_template_valueContext, 0) def enterRule(self, listener: ParseTreeListener): - if hasattr(listener, "enterTimeout_seconds_path_decl"): - listener.enterTimeout_seconds_path_decl(self) + if hasattr(listener, "enterAssign_template_binding_assign_value"): + listener.enterAssign_template_binding_assign_value(self) def exitRule(self, listener: ParseTreeListener): - if hasattr(listener, "exitTimeout_seconds_path_decl"): - listener.exitTimeout_seconds_path_decl(self) + if hasattr(listener, "exitAssign_template_binding_assign_value"): + listener.exitAssign_template_binding_assign_value(self) def accept(self, visitor: ParseTreeVisitor): - if hasattr(visitor, "visitTimeout_seconds_path_decl"): - return visitor.visitTimeout_seconds_path_decl(self) + if hasattr(visitor, "visitAssign_template_binding_assign_value"): + return visitor.visitAssign_template_binding_assign_value(self) else: return visitor.visitChildren(self) - def timeout_seconds_path_decl(self): - localctx = ASLParser.Timeout_seconds_path_declContext( - self, self._ctx, self.state - ) - self.enterRule(localctx, 66, self.RULE_timeout_seconds_path_decl) - try: - self.enterOuterAlt(localctx, 1) - self.state = 403 - self.match(ASLParser.TIMEOUTSECONDSPATH) - self.state = 404 - self.match(ASLParser.COLON) - self.state = 405 - self.match(ASLParser.STRINGPATH) - except RecognitionException as re: - localctx.exception = re - self._errHandler.reportError(self, re) - self._errHandler.recover(self, re) - finally: - self.exitRule() - return localctx - - class Heartbeat_seconds_declContext(ParserRuleContext): - __slots__ = "parser" - + class Assign_template_binding_varContext(Assign_template_bindingContext): def __init__( - self, parser, parent: ParserRuleContext = None, invokingState: int = -1 - ): - super().__init__(parent, invokingState) - self.parser = parser + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Assign_template_bindingContext + super().__init__(parser) + self.copyFrom(ctx) - def HEARTBEATSECONDS(self): - return self.getToken(ASLParser.HEARTBEATSECONDS, 0) + def STRINGDOLLAR(self): + return self.getToken(ASLParser.STRINGDOLLAR, 0) def COLON(self): return self.getToken(ASLParser.COLON, 0) - def INT(self): - return self.getToken(ASLParser.INT, 0) - - def getRuleIndex(self): - return ASLParser.RULE_heartbeat_seconds_decl + def variable_sample(self): + return self.getTypedRuleContext(ASLParser.Variable_sampleContext, 0) def enterRule(self, listener: ParseTreeListener): - if hasattr(listener, "enterHeartbeat_seconds_decl"): - listener.enterHeartbeat_seconds_decl(self) + if hasattr(listener, "enterAssign_template_binding_var"): + listener.enterAssign_template_binding_var(self) def exitRule(self, listener: ParseTreeListener): - if hasattr(listener, "exitHeartbeat_seconds_decl"): - listener.exitHeartbeat_seconds_decl(self) + if hasattr(listener, "exitAssign_template_binding_var"): + listener.exitAssign_template_binding_var(self) def accept(self, visitor: ParseTreeVisitor): - if hasattr(visitor, "visitHeartbeat_seconds_decl"): - return visitor.visitHeartbeat_seconds_decl(self) + if hasattr(visitor, "visitAssign_template_binding_var"): + return visitor.visitAssign_template_binding_var(self) else: return visitor.visitChildren(self) - def heartbeat_seconds_decl(self): - localctx = ASLParser.Heartbeat_seconds_declContext(self, self._ctx, self.state) - self.enterRule(localctx, 68, self.RULE_heartbeat_seconds_decl) + def assign_template_binding(self): + localctx = ASLParser.Assign_template_bindingContext(self, self._ctx, self.state) + self.enterRule(localctx, 100, self.RULE_assign_template_binding) try: - self.enterOuterAlt(localctx, 1) - self.state = 407 - self.match(ASLParser.HEARTBEATSECONDS) - self.state = 408 - self.match(ASLParser.COLON) - self.state = 409 - self.match(ASLParser.INT) + self.state = 699 + self._errHandler.sync(self) + la_ = self._interp.adaptivePredict(self._input, 38, self._ctx) + if la_ == 1: + localctx = ASLParser.Assign_template_binding_pathContext(self, localctx) + self.enterOuterAlt(localctx, 1) + self.state = 684 + self.match(ASLParser.STRINGDOLLAR) + self.state = 685 + self.match(ASLParser.COLON) + self.state = 686 + self.match(ASLParser.STRINGPATH) + pass + + elif la_ == 2: + localctx = ASLParser.Assign_template_binding_path_contextContext( + self, localctx + ) + self.enterOuterAlt(localctx, 2) + self.state = 687 + self.match(ASLParser.STRINGDOLLAR) + self.state = 688 + self.match(ASLParser.COLON) + self.state = 689 + self.match(ASLParser.STRINGPATHCONTEXTOBJ) + pass + + elif la_ == 3: + localctx = ASLParser.Assign_template_binding_varContext(self, localctx) + self.enterOuterAlt(localctx, 3) + self.state = 690 + self.match(ASLParser.STRINGDOLLAR) + self.state = 691 + self.match(ASLParser.COLON) + self.state = 692 + self.variable_sample() + pass + + elif la_ == 4: + localctx = ASLParser.Assign_template_binding_intrinsic_funcContext( + self, localctx + ) + self.enterOuterAlt(localctx, 4) + self.state = 693 + self.match(ASLParser.STRINGDOLLAR) + self.state = 694 + self.match(ASLParser.COLON) + self.state = 695 + self.match(ASLParser.STRINGINTRINSICFUNC) + pass + + elif la_ == 5: + localctx = ASLParser.Assign_template_binding_assign_valueContext( + self, localctx + ) + self.enterOuterAlt(localctx, 5) + self.state = 696 + self.match(ASLParser.STRING) + self.state = 697 + self.match(ASLParser.COLON) + self.state = 698 + self.assign_template_value() + pass + except RecognitionException as re: localctx.exception = re self._errHandler.reportError(self, re) @@ -11032,7 +18041,7 @@ def heartbeat_seconds_decl(self): self.exitRule() return localctx - class Heartbeat_seconds_path_declContext(ParserRuleContext): + class Assign_template_valueContext(ParserRuleContext): __slots__ = "parser" def __init__( @@ -11041,45 +18050,213 @@ def __init__( super().__init__(parent, invokingState) self.parser = parser - def HEARTBEATSECONDSPATH(self): - return self.getToken(ASLParser.HEARTBEATSECONDSPATH, 0) + def assign_template_value_object(self): + return self.getTypedRuleContext( + ASLParser.Assign_template_value_objectContext, 0 + ) - def COLON(self): - return self.getToken(ASLParser.COLON, 0) + def assign_template_value_array(self): + return self.getTypedRuleContext( + ASLParser.Assign_template_value_arrayContext, 0 + ) - def STRINGPATH(self): - return self.getToken(ASLParser.STRINGPATH, 0) + def assign_template_value_terminal(self): + return self.getTypedRuleContext( + ASLParser.Assign_template_value_terminalContext, 0 + ) def getRuleIndex(self): - return ASLParser.RULE_heartbeat_seconds_path_decl + return ASLParser.RULE_assign_template_value def enterRule(self, listener: ParseTreeListener): - if hasattr(listener, "enterHeartbeat_seconds_path_decl"): - listener.enterHeartbeat_seconds_path_decl(self) + if hasattr(listener, "enterAssign_template_value"): + listener.enterAssign_template_value(self) def exitRule(self, listener: ParseTreeListener): - if hasattr(listener, "exitHeartbeat_seconds_path_decl"): - listener.exitHeartbeat_seconds_path_decl(self) + if hasattr(listener, "exitAssign_template_value"): + listener.exitAssign_template_value(self) def accept(self, visitor: ParseTreeVisitor): - if hasattr(visitor, "visitHeartbeat_seconds_path_decl"): - return visitor.visitHeartbeat_seconds_path_decl(self) + if hasattr(visitor, "visitAssign_template_value"): + return visitor.visitAssign_template_value(self) + else: + return visitor.visitChildren(self) + + def assign_template_value(self): + localctx = ASLParser.Assign_template_valueContext(self, self._ctx, self.state) + self.enterRule(localctx, 102, self.RULE_assign_template_value) + try: + self.state = 704 + self._errHandler.sync(self) + token = self._input.LA(1) + if token in [5]: + self.enterOuterAlt(localctx, 1) + self.state = 701 + self.assign_template_value_object() + pass + elif token in [3]: + self.enterOuterAlt(localctx, 2) + self.state = 702 + self.assign_template_value_array() + pass + elif token in [ + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24, + 25, + 26, + 27, + 28, + 29, + 30, + 31, + 32, + 33, + 34, + 35, + 36, + 37, + 38, + 39, + 40, + 41, + 42, + 43, + 44, + 45, + 46, + 47, + 48, + 49, + 50, + 51, + 52, + 53, + 54, + 55, + 56, + 57, + 58, + 59, + 60, + 61, + 62, + 63, + 64, + 65, + 66, + 67, + 68, + 69, + 70, + 71, + 72, + 73, + 74, + 75, + 76, + 77, + 78, + 79, + 80, + 81, + 82, + 83, + 84, + 85, + 86, + 87, + 88, + 89, + 90, + 91, + 92, + 93, + 94, + 95, + 96, + 97, + 98, + 99, + 100, + 101, + 102, + 103, + 104, + 105, + 106, + 107, + 108, + 109, + 110, + 111, + 112, + 113, + 114, + 115, + 116, + 117, + 119, + 121, + 122, + 123, + 124, + 125, + 126, + 127, + 128, + 129, + 130, + 131, + 134, + 135, + 136, + 137, + 139, + 140, + 141, + 142, + 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, + ]: + self.enterOuterAlt(localctx, 3) + self.state = 703 + self.assign_template_value_terminal() + pass else: - return visitor.visitChildren(self) + raise NoViableAltException(self) - def heartbeat_seconds_path_decl(self): - localctx = ASLParser.Heartbeat_seconds_path_declContext( - self, self._ctx, self.state - ) - self.enterRule(localctx, 70, self.RULE_heartbeat_seconds_path_decl) - try: - self.enterOuterAlt(localctx, 1) - self.state = 411 - self.match(ASLParser.HEARTBEATSECONDSPATH) - self.state = 412 - self.match(ASLParser.COLON) - self.state = 413 - self.match(ASLParser.STRINGPATH) except RecognitionException as re: localctx.exception = re self._errHandler.reportError(self, re) @@ -11088,7 +18265,7 @@ def heartbeat_seconds_path_decl(self): self.exitRule() return localctx - class Payload_tmpl_declContext(ParserRuleContext): + class Assign_template_value_arrayContext(ParserRuleContext): __slots__ = "parser" def __init__( @@ -11097,17 +18274,19 @@ def __init__( super().__init__(parent, invokingState) self.parser = parser - def LBRACE(self): - return self.getToken(ASLParser.LBRACE, 0) + def LBRACK(self): + return self.getToken(ASLParser.LBRACK, 0) - def payload_binding(self, i: int = None): + def RBRACK(self): + return self.getToken(ASLParser.RBRACK, 0) + + def assign_template_value(self, i: int = None): if i is None: - return self.getTypedRuleContexts(ASLParser.Payload_bindingContext) + return self.getTypedRuleContexts(ASLParser.Assign_template_valueContext) else: - return self.getTypedRuleContext(ASLParser.Payload_bindingContext, i) - - def RBRACE(self): - return self.getToken(ASLParser.RBRACE, 0) + return self.getTypedRuleContext( + ASLParser.Assign_template_valueContext, i + ) def COMMA(self, i: int = None): if i is None: @@ -11116,58 +18295,60 @@ def COMMA(self, i: int = None): return self.getToken(ASLParser.COMMA, i) def getRuleIndex(self): - return ASLParser.RULE_payload_tmpl_decl + return ASLParser.RULE_assign_template_value_array def enterRule(self, listener: ParseTreeListener): - if hasattr(listener, "enterPayload_tmpl_decl"): - listener.enterPayload_tmpl_decl(self) + if hasattr(listener, "enterAssign_template_value_array"): + listener.enterAssign_template_value_array(self) def exitRule(self, listener: ParseTreeListener): - if hasattr(listener, "exitPayload_tmpl_decl"): - listener.exitPayload_tmpl_decl(self) + if hasattr(listener, "exitAssign_template_value_array"): + listener.exitAssign_template_value_array(self) def accept(self, visitor: ParseTreeVisitor): - if hasattr(visitor, "visitPayload_tmpl_decl"): - return visitor.visitPayload_tmpl_decl(self) + if hasattr(visitor, "visitAssign_template_value_array"): + return visitor.visitAssign_template_value_array(self) else: return visitor.visitChildren(self) - def payload_tmpl_decl(self): - localctx = ASLParser.Payload_tmpl_declContext(self, self._ctx, self.state) - self.enterRule(localctx, 72, self.RULE_payload_tmpl_decl) + def assign_template_value_array(self): + localctx = ASLParser.Assign_template_value_arrayContext( + self, self._ctx, self.state + ) + self.enterRule(localctx, 104, self.RULE_assign_template_value_array) self._la = 0 # Token type try: - self.state = 428 + self.state = 719 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input, 11, self._ctx) + la_ = self._interp.adaptivePredict(self._input, 41, self._ctx) if la_ == 1: self.enterOuterAlt(localctx, 1) - self.state = 415 - self.match(ASLParser.LBRACE) - self.state = 416 - self.payload_binding() - self.state = 421 + self.state = 706 + self.match(ASLParser.LBRACK) + self.state = 707 + self.match(ASLParser.RBRACK) + pass + + elif la_ == 2: + self.enterOuterAlt(localctx, 2) + self.state = 708 + self.match(ASLParser.LBRACK) + self.state = 709 + self.assign_template_value() + self.state = 714 self._errHandler.sync(self) _la = self._input.LA(1) while _la == 1: - self.state = 417 + self.state = 710 self.match(ASLParser.COMMA) - self.state = 418 - self.payload_binding() - self.state = 423 + self.state = 711 + self.assign_template_value() + self.state = 716 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 424 - self.match(ASLParser.RBRACE) - pass - - elif la_ == 2: - self.enterOuterAlt(localctx, 2) - self.state = 426 - self.match(ASLParser.LBRACE) - self.state = 427 - self.match(ASLParser.RBRACE) + self.state = 717 + self.match(ASLParser.RBRACK) pass except RecognitionException as re: @@ -11178,7 +18359,7 @@ def payload_tmpl_decl(self): self.exitRule() return localctx - class Payload_bindingContext(ParserRuleContext): + class Assign_template_value_terminalContext(ParserRuleContext): __slots__ = "parser" def __init__( @@ -11188,184 +18369,351 @@ def __init__( self.parser = parser def getRuleIndex(self): - return ASLParser.RULE_payload_binding + return ASLParser.RULE_assign_template_value_terminal def copyFrom(self, ctx: ParserRuleContext): super().copyFrom(ctx) - class Payload_binding_pathContext(Payload_bindingContext): + class Assign_template_value_terminal_nullContext( + Assign_template_value_terminalContext + ): def __init__( self, parser, ctx: ParserRuleContext - ): # actually a ASLParser.Payload_bindingContext + ): # actually a ASLParser.Assign_template_value_terminalContext super().__init__(parser) self.copyFrom(ctx) - def STRINGDOLLAR(self): - return self.getToken(ASLParser.STRINGDOLLAR, 0) + def NULL(self): + return self.getToken(ASLParser.NULL, 0) - def COLON(self): - return self.getToken(ASLParser.COLON, 0) + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterAssign_template_value_terminal_null"): + listener.enterAssign_template_value_terminal_null(self) - def STRINGPATH(self): - return self.getToken(ASLParser.STRINGPATH, 0) + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitAssign_template_value_terminal_null"): + listener.exitAssign_template_value_terminal_null(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitAssign_template_value_terminal_null"): + return visitor.visitAssign_template_value_terminal_null(self) + else: + return visitor.visitChildren(self) + + class Assign_template_value_terminal_expressionContext( + Assign_template_value_terminalContext + ): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Assign_template_value_terminalContext + super().__init__(parser) + self.copyFrom(ctx) + + def STRINGJSONATA(self): + return self.getToken(ASLParser.STRINGJSONATA, 0) def enterRule(self, listener: ParseTreeListener): - if hasattr(listener, "enterPayload_binding_path"): - listener.enterPayload_binding_path(self) + if hasattr(listener, "enterAssign_template_value_terminal_expression"): + listener.enterAssign_template_value_terminal_expression(self) def exitRule(self, listener: ParseTreeListener): - if hasattr(listener, "exitPayload_binding_path"): - listener.exitPayload_binding_path(self) + if hasattr(listener, "exitAssign_template_value_terminal_expression"): + listener.exitAssign_template_value_terminal_expression(self) def accept(self, visitor: ParseTreeVisitor): - if hasattr(visitor, "visitPayload_binding_path"): - return visitor.visitPayload_binding_path(self) + if hasattr(visitor, "visitAssign_template_value_terminal_expression"): + return visitor.visitAssign_template_value_terminal_expression(self) else: return visitor.visitChildren(self) - class Payload_binding_path_context_objContext(Payload_bindingContext): + class Assign_template_value_terminal_intContext( + Assign_template_value_terminalContext + ): def __init__( self, parser, ctx: ParserRuleContext - ): # actually a ASLParser.Payload_bindingContext + ): # actually a ASLParser.Assign_template_value_terminalContext super().__init__(parser) self.copyFrom(ctx) - def STRINGDOLLAR(self): - return self.getToken(ASLParser.STRINGDOLLAR, 0) + def INT(self): + return self.getToken(ASLParser.INT, 0) - def COLON(self): - return self.getToken(ASLParser.COLON, 0) + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterAssign_template_value_terminal_int"): + listener.enterAssign_template_value_terminal_int(self) - def STRINGPATHCONTEXTOBJ(self): - return self.getToken(ASLParser.STRINGPATHCONTEXTOBJ, 0) + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitAssign_template_value_terminal_int"): + listener.exitAssign_template_value_terminal_int(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitAssign_template_value_terminal_int"): + return visitor.visitAssign_template_value_terminal_int(self) + else: + return visitor.visitChildren(self) + + class Assign_template_value_terminal_strContext( + Assign_template_value_terminalContext + ): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Assign_template_value_terminalContext + super().__init__(parser) + self.copyFrom(ctx) + + def keyword_or_string(self): + return self.getTypedRuleContext(ASLParser.Keyword_or_stringContext, 0) def enterRule(self, listener: ParseTreeListener): - if hasattr(listener, "enterPayload_binding_path_context_obj"): - listener.enterPayload_binding_path_context_obj(self) + if hasattr(listener, "enterAssign_template_value_terminal_str"): + listener.enterAssign_template_value_terminal_str(self) def exitRule(self, listener: ParseTreeListener): - if hasattr(listener, "exitPayload_binding_path_context_obj"): - listener.exitPayload_binding_path_context_obj(self) + if hasattr(listener, "exitAssign_template_value_terminal_str"): + listener.exitAssign_template_value_terminal_str(self) def accept(self, visitor: ParseTreeVisitor): - if hasattr(visitor, "visitPayload_binding_path_context_obj"): - return visitor.visitPayload_binding_path_context_obj(self) + if hasattr(visitor, "visitAssign_template_value_terminal_str"): + return visitor.visitAssign_template_value_terminal_str(self) else: return visitor.visitChildren(self) - class Payload_binding_intrinsic_funcContext(Payload_bindingContext): + class Assign_template_value_terminal_boolContext( + Assign_template_value_terminalContext + ): def __init__( self, parser, ctx: ParserRuleContext - ): # actually a ASLParser.Payload_bindingContext + ): # actually a ASLParser.Assign_template_value_terminalContext super().__init__(parser) self.copyFrom(ctx) - def STRINGDOLLAR(self): - return self.getToken(ASLParser.STRINGDOLLAR, 0) + def TRUE(self): + return self.getToken(ASLParser.TRUE, 0) + + def FALSE(self): + return self.getToken(ASLParser.FALSE, 0) + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterAssign_template_value_terminal_bool"): + listener.enterAssign_template_value_terminal_bool(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitAssign_template_value_terminal_bool"): + listener.exitAssign_template_value_terminal_bool(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitAssign_template_value_terminal_bool"): + return visitor.visitAssign_template_value_terminal_bool(self) + else: + return visitor.visitChildren(self) + + class Assign_template_value_terminal_floatContext( + Assign_template_value_terminalContext + ): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Assign_template_value_terminalContext + super().__init__(parser) + self.copyFrom(ctx) + + def NUMBER(self): + return self.getToken(ASLParser.NUMBER, 0) + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterAssign_template_value_terminal_float"): + listener.enterAssign_template_value_terminal_float(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitAssign_template_value_terminal_float"): + listener.exitAssign_template_value_terminal_float(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitAssign_template_value_terminal_float"): + return visitor.visitAssign_template_value_terminal_float(self) + else: + return visitor.visitChildren(self) + + def assign_template_value_terminal(self): + localctx = ASLParser.Assign_template_value_terminalContext( + self, self._ctx, self.state + ) + self.enterRule(localctx, 106, self.RULE_assign_template_value_terminal) + self._la = 0 # Token type + try: + self.state = 727 + self._errHandler.sync(self) + la_ = self._interp.adaptivePredict(self._input, 42, self._ctx) + if la_ == 1: + localctx = ASLParser.Assign_template_value_terminal_floatContext( + self, localctx + ) + self.enterOuterAlt(localctx, 1) + self.state = 721 + self.match(ASLParser.NUMBER) + pass + + elif la_ == 2: + localctx = ASLParser.Assign_template_value_terminal_intContext( + self, localctx + ) + self.enterOuterAlt(localctx, 2) + self.state = 722 + self.match(ASLParser.INT) + pass + + elif la_ == 3: + localctx = ASLParser.Assign_template_value_terminal_boolContext( + self, localctx + ) + self.enterOuterAlt(localctx, 3) + self.state = 723 + _la = self._input.LA(1) + if not (_la == 7 or _la == 8): + self._errHandler.recoverInline(self) + else: + self._errHandler.reportMatch(self) + self.consume() + pass + + elif la_ == 4: + localctx = ASLParser.Assign_template_value_terminal_nullContext( + self, localctx + ) + self.enterOuterAlt(localctx, 4) + self.state = 724 + self.match(ASLParser.NULL) + pass + + elif la_ == 5: + localctx = ASLParser.Assign_template_value_terminal_expressionContext( + self, localctx + ) + self.enterOuterAlt(localctx, 5) + self.state = 725 + self.match(ASLParser.STRINGJSONATA) + pass + + elif la_ == 6: + localctx = ASLParser.Assign_template_value_terminal_strContext( + self, localctx + ) + self.enterOuterAlt(localctx, 6) + self.state = 726 + self.keyword_or_string() + pass + + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class Arguments_declContext(ParserRuleContext): + __slots__ = "parser" + + def __init__( + self, parser, parent: ParserRuleContext = None, invokingState: int = -1 + ): + super().__init__(parent, invokingState) + self.parser = parser + + def getRuleIndex(self): + return ASLParser.RULE_arguments_decl + + def copyFrom(self, ctx: ParserRuleContext): + super().copyFrom(ctx) + + class Arguments_objectContext(Arguments_declContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Arguments_declContext + super().__init__(parser) + self.copyFrom(ctx) + + def ARGUMENTS(self): + return self.getToken(ASLParser.ARGUMENTS, 0) def COLON(self): return self.getToken(ASLParser.COLON, 0) - def intrinsic_func(self): - return self.getTypedRuleContext(ASLParser.Intrinsic_funcContext, 0) + def jsonata_template_value_object(self): + return self.getTypedRuleContext( + ASLParser.Jsonata_template_value_objectContext, 0 + ) def enterRule(self, listener: ParseTreeListener): - if hasattr(listener, "enterPayload_binding_intrinsic_func"): - listener.enterPayload_binding_intrinsic_func(self) + if hasattr(listener, "enterArguments_object"): + listener.enterArguments_object(self) def exitRule(self, listener: ParseTreeListener): - if hasattr(listener, "exitPayload_binding_intrinsic_func"): - listener.exitPayload_binding_intrinsic_func(self) + if hasattr(listener, "exitArguments_object"): + listener.exitArguments_object(self) def accept(self, visitor: ParseTreeVisitor): - if hasattr(visitor, "visitPayload_binding_intrinsic_func"): - return visitor.visitPayload_binding_intrinsic_func(self) + if hasattr(visitor, "visitArguments_object"): + return visitor.visitArguments_object(self) else: return visitor.visitChildren(self) - class Payload_binding_valueContext(Payload_bindingContext): + class Arguments_exprContext(Arguments_declContext): def __init__( self, parser, ctx: ParserRuleContext - ): # actually a ASLParser.Payload_bindingContext + ): # actually a ASLParser.Arguments_declContext super().__init__(parser) self.copyFrom(ctx) - def keyword_or_string(self): - return self.getTypedRuleContext(ASLParser.Keyword_or_stringContext, 0) + def ARGUMENTS(self): + return self.getToken(ASLParser.ARGUMENTS, 0) def COLON(self): return self.getToken(ASLParser.COLON, 0) - def payload_value_decl(self): - return self.getTypedRuleContext(ASLParser.Payload_value_declContext, 0) + def STRINGJSONATA(self): + return self.getToken(ASLParser.STRINGJSONATA, 0) def enterRule(self, listener: ParseTreeListener): - if hasattr(listener, "enterPayload_binding_value"): - listener.enterPayload_binding_value(self) + if hasattr(listener, "enterArguments_expr"): + listener.enterArguments_expr(self) def exitRule(self, listener: ParseTreeListener): - if hasattr(listener, "exitPayload_binding_value"): - listener.exitPayload_binding_value(self) + if hasattr(listener, "exitArguments_expr"): + listener.exitArguments_expr(self) - def accept(self, visitor: ParseTreeVisitor): - if hasattr(visitor, "visitPayload_binding_value"): - return visitor.visitPayload_binding_value(self) + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitArguments_expr"): + return visitor.visitArguments_expr(self) else: return visitor.visitChildren(self) - def payload_binding(self): - localctx = ASLParser.Payload_bindingContext(self, self._ctx, self.state) - self.enterRule(localctx, 74, self.RULE_payload_binding) + def arguments_decl(self): + localctx = ASLParser.Arguments_declContext(self, self._ctx, self.state) + self.enterRule(localctx, 108, self.RULE_arguments_decl) try: - self.state = 443 + self.state = 735 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input, 12, self._ctx) + la_ = self._interp.adaptivePredict(self._input, 43, self._ctx) if la_ == 1: - localctx = ASLParser.Payload_binding_pathContext(self, localctx) + localctx = ASLParser.Arguments_objectContext(self, localctx) self.enterOuterAlt(localctx, 1) - self.state = 430 - self.match(ASLParser.STRINGDOLLAR) - self.state = 431 + self.state = 729 + self.match(ASLParser.ARGUMENTS) + self.state = 730 self.match(ASLParser.COLON) - self.state = 432 - self.match(ASLParser.STRINGPATH) + self.state = 731 + self.jsonata_template_value_object() pass elif la_ == 2: - localctx = ASLParser.Payload_binding_path_context_objContext( - self, localctx - ) + localctx = ASLParser.Arguments_exprContext(self, localctx) self.enterOuterAlt(localctx, 2) - self.state = 433 - self.match(ASLParser.STRINGDOLLAR) - self.state = 434 - self.match(ASLParser.COLON) - self.state = 435 - self.match(ASLParser.STRINGPATHCONTEXTOBJ) - pass - - elif la_ == 3: - localctx = ASLParser.Payload_binding_intrinsic_funcContext( - self, localctx - ) - self.enterOuterAlt(localctx, 3) - self.state = 436 - self.match(ASLParser.STRINGDOLLAR) - self.state = 437 - self.match(ASLParser.COLON) - self.state = 438 - self.intrinsic_func() - pass - - elif la_ == 4: - localctx = ASLParser.Payload_binding_valueContext(self, localctx) - self.enterOuterAlt(localctx, 4) - self.state = 439 - self.keyword_or_string() - self.state = 440 + self.state = 732 + self.match(ASLParser.ARGUMENTS) + self.state = 733 self.match(ASLParser.COLON) - self.state = 441 - self.payload_value_decl() + self.state = 734 + self.match(ASLParser.STRINGJSONATA) pass except RecognitionException as re: @@ -11376,7 +18724,7 @@ def payload_binding(self): self.exitRule() return localctx - class Intrinsic_funcContext(ParserRuleContext): + class Output_declContext(ParserRuleContext): __slots__ = "parser" def __init__( @@ -11385,33 +18733,43 @@ def __init__( super().__init__(parent, invokingState) self.parser = parser - def STRING(self): - return self.getToken(ASLParser.STRING, 0) + def OUTPUT(self): + return self.getToken(ASLParser.OUTPUT, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def jsonata_template_value(self): + return self.getTypedRuleContext(ASLParser.Jsonata_template_valueContext, 0) def getRuleIndex(self): - return ASLParser.RULE_intrinsic_func + return ASLParser.RULE_output_decl def enterRule(self, listener: ParseTreeListener): - if hasattr(listener, "enterIntrinsic_func"): - listener.enterIntrinsic_func(self) + if hasattr(listener, "enterOutput_decl"): + listener.enterOutput_decl(self) def exitRule(self, listener: ParseTreeListener): - if hasattr(listener, "exitIntrinsic_func"): - listener.exitIntrinsic_func(self) + if hasattr(listener, "exitOutput_decl"): + listener.exitOutput_decl(self) def accept(self, visitor: ParseTreeVisitor): - if hasattr(visitor, "visitIntrinsic_func"): - return visitor.visitIntrinsic_func(self) + if hasattr(visitor, "visitOutput_decl"): + return visitor.visitOutput_decl(self) else: return visitor.visitChildren(self) - def intrinsic_func(self): - localctx = ASLParser.Intrinsic_funcContext(self, self._ctx, self.state) - self.enterRule(localctx, 76, self.RULE_intrinsic_func) + def output_decl(self): + localctx = ASLParser.Output_declContext(self, self._ctx, self.state) + self.enterRule(localctx, 110, self.RULE_output_decl) try: self.enterOuterAlt(localctx, 1) - self.state = 445 - self.match(ASLParser.STRING) + self.state = 737 + self.match(ASLParser.OUTPUT) + self.state = 738 + self.match(ASLParser.COLON) + self.state = 739 + self.jsonata_template_value() except RecognitionException as re: localctx.exception = re self._errHandler.reportError(self, re) @@ -11420,7 +18778,7 @@ def intrinsic_func(self): self.exitRule() return localctx - class Payload_arr_declContext(ParserRuleContext): + class Jsonata_template_value_objectContext(ParserRuleContext): __slots__ = "parser" def __init__( @@ -11429,17 +18787,21 @@ def __init__( super().__init__(parent, invokingState) self.parser = parser - def LBRACK(self): - return self.getToken(ASLParser.LBRACK, 0) + def LBRACE(self): + return self.getToken(ASLParser.LBRACE, 0) - def payload_value_decl(self, i: int = None): + def RBRACE(self): + return self.getToken(ASLParser.RBRACE, 0) + + def jsonata_template_binding(self, i: int = None): if i is None: - return self.getTypedRuleContexts(ASLParser.Payload_value_declContext) + return self.getTypedRuleContexts( + ASLParser.Jsonata_template_bindingContext + ) else: - return self.getTypedRuleContext(ASLParser.Payload_value_declContext, i) - - def RBRACK(self): - return self.getToken(ASLParser.RBRACK, 0) + return self.getTypedRuleContext( + ASLParser.Jsonata_template_bindingContext, i + ) def COMMA(self, i: int = None): if i is None: @@ -11448,58 +18810,60 @@ def COMMA(self, i: int = None): return self.getToken(ASLParser.COMMA, i) def getRuleIndex(self): - return ASLParser.RULE_payload_arr_decl + return ASLParser.RULE_jsonata_template_value_object def enterRule(self, listener: ParseTreeListener): - if hasattr(listener, "enterPayload_arr_decl"): - listener.enterPayload_arr_decl(self) + if hasattr(listener, "enterJsonata_template_value_object"): + listener.enterJsonata_template_value_object(self) def exitRule(self, listener: ParseTreeListener): - if hasattr(listener, "exitPayload_arr_decl"): - listener.exitPayload_arr_decl(self) + if hasattr(listener, "exitJsonata_template_value_object"): + listener.exitJsonata_template_value_object(self) def accept(self, visitor: ParseTreeVisitor): - if hasattr(visitor, "visitPayload_arr_decl"): - return visitor.visitPayload_arr_decl(self) + if hasattr(visitor, "visitJsonata_template_value_object"): + return visitor.visitJsonata_template_value_object(self) else: return visitor.visitChildren(self) - def payload_arr_decl(self): - localctx = ASLParser.Payload_arr_declContext(self, self._ctx, self.state) - self.enterRule(localctx, 78, self.RULE_payload_arr_decl) + def jsonata_template_value_object(self): + localctx = ASLParser.Jsonata_template_value_objectContext( + self, self._ctx, self.state + ) + self.enterRule(localctx, 112, self.RULE_jsonata_template_value_object) self._la = 0 # Token type try: - self.state = 460 + self.state = 754 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input, 14, self._ctx) + la_ = self._interp.adaptivePredict(self._input, 45, self._ctx) if la_ == 1: self.enterOuterAlt(localctx, 1) - self.state = 447 - self.match(ASLParser.LBRACK) - self.state = 448 - self.payload_value_decl() - self.state = 453 + self.state = 741 + self.match(ASLParser.LBRACE) + self.state = 742 + self.match(ASLParser.RBRACE) + pass + + elif la_ == 2: + self.enterOuterAlt(localctx, 2) + self.state = 743 + self.match(ASLParser.LBRACE) + self.state = 744 + self.jsonata_template_binding() + self.state = 749 self._errHandler.sync(self) _la = self._input.LA(1) while _la == 1: - self.state = 449 + self.state = 745 self.match(ASLParser.COMMA) - self.state = 450 - self.payload_value_decl() - self.state = 455 + self.state = 746 + self.jsonata_template_binding() + self.state = 751 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 456 - self.match(ASLParser.RBRACK) - pass - - elif la_ == 2: - self.enterOuterAlt(localctx, 2) - self.state = 458 - self.match(ASLParser.LBRACK) - self.state = 459 - self.match(ASLParser.RBRACK) + self.state = 752 + self.match(ASLParser.RBRACE) pass except RecognitionException as re: @@ -11510,7 +18874,7 @@ def payload_arr_decl(self): self.exitRule() return localctx - class Payload_value_declContext(ParserRuleContext): + class Jsonata_template_bindingContext(ParserRuleContext): __slots__ = "parser" def __init__( @@ -11519,66 +18883,45 @@ def __init__( super().__init__(parent, invokingState) self.parser = parser - def payload_binding(self): - return self.getTypedRuleContext(ASLParser.Payload_bindingContext, 0) - - def payload_arr_decl(self): - return self.getTypedRuleContext(ASLParser.Payload_arr_declContext, 0) + def keyword_or_string(self): + return self.getTypedRuleContext(ASLParser.Keyword_or_stringContext, 0) - def payload_tmpl_decl(self): - return self.getTypedRuleContext(ASLParser.Payload_tmpl_declContext, 0) + def COLON(self): + return self.getToken(ASLParser.COLON, 0) - def payload_value_lit(self): - return self.getTypedRuleContext(ASLParser.Payload_value_litContext, 0) + def jsonata_template_value(self): + return self.getTypedRuleContext(ASLParser.Jsonata_template_valueContext, 0) def getRuleIndex(self): - return ASLParser.RULE_payload_value_decl + return ASLParser.RULE_jsonata_template_binding def enterRule(self, listener: ParseTreeListener): - if hasattr(listener, "enterPayload_value_decl"): - listener.enterPayload_value_decl(self) + if hasattr(listener, "enterJsonata_template_binding"): + listener.enterJsonata_template_binding(self) def exitRule(self, listener: ParseTreeListener): - if hasattr(listener, "exitPayload_value_decl"): - listener.exitPayload_value_decl(self) + if hasattr(listener, "exitJsonata_template_binding"): + listener.exitJsonata_template_binding(self) def accept(self, visitor: ParseTreeVisitor): - if hasattr(visitor, "visitPayload_value_decl"): - return visitor.visitPayload_value_decl(self) + if hasattr(visitor, "visitJsonata_template_binding"): + return visitor.visitJsonata_template_binding(self) else: return visitor.visitChildren(self) - def payload_value_decl(self): - localctx = ASLParser.Payload_value_declContext(self, self._ctx, self.state) - self.enterRule(localctx, 80, self.RULE_payload_value_decl) + def jsonata_template_binding(self): + localctx = ASLParser.Jsonata_template_bindingContext( + self, self._ctx, self.state + ) + self.enterRule(localctx, 114, self.RULE_jsonata_template_binding) try: - self.state = 466 - self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input, 15, self._ctx) - if la_ == 1: - self.enterOuterAlt(localctx, 1) - self.state = 462 - self.payload_binding() - pass - - elif la_ == 2: - self.enterOuterAlt(localctx, 2) - self.state = 463 - self.payload_arr_decl() - pass - - elif la_ == 3: - self.enterOuterAlt(localctx, 3) - self.state = 464 - self.payload_tmpl_decl() - pass - - elif la_ == 4: - self.enterOuterAlt(localctx, 4) - self.state = 465 - self.payload_value_lit() - pass - + self.enterOuterAlt(localctx, 1) + self.state = 756 + self.keyword_or_string() + self.state = 757 + self.match(ASLParser.COLON) + self.state = 758 + self.jsonata_template_value() except RecognitionException as re: localctx.exception = re self._errHandler.reportError(self, re) @@ -11587,7 +18930,7 @@ def payload_value_decl(self): self.exitRule() return localctx - class Payload_value_litContext(ParserRuleContext): + class Jsonata_template_valueContext(ParserRuleContext): __slots__ = "parser" def __init__( @@ -11596,173 +18939,59 @@ def __init__( super().__init__(parent, invokingState) self.parser = parser - def getRuleIndex(self): - return ASLParser.RULE_payload_value_lit - - def copyFrom(self, ctx: ParserRuleContext): - super().copyFrom(ctx) - - class Payload_value_boolContext(Payload_value_litContext): - def __init__( - self, parser, ctx: ParserRuleContext - ): # actually a ASLParser.Payload_value_litContext - super().__init__(parser) - self.copyFrom(ctx) - - def TRUE(self): - return self.getToken(ASLParser.TRUE, 0) - - def FALSE(self): - return self.getToken(ASLParser.FALSE, 0) - - def enterRule(self, listener: ParseTreeListener): - if hasattr(listener, "enterPayload_value_bool"): - listener.enterPayload_value_bool(self) - - def exitRule(self, listener: ParseTreeListener): - if hasattr(listener, "exitPayload_value_bool"): - listener.exitPayload_value_bool(self) - - def accept(self, visitor: ParseTreeVisitor): - if hasattr(visitor, "visitPayload_value_bool"): - return visitor.visitPayload_value_bool(self) - else: - return visitor.visitChildren(self) - - class Payload_value_intContext(Payload_value_litContext): - def __init__( - self, parser, ctx: ParserRuleContext - ): # actually a ASLParser.Payload_value_litContext - super().__init__(parser) - self.copyFrom(ctx) - - def INT(self): - return self.getToken(ASLParser.INT, 0) - - def enterRule(self, listener: ParseTreeListener): - if hasattr(listener, "enterPayload_value_int"): - listener.enterPayload_value_int(self) - - def exitRule(self, listener: ParseTreeListener): - if hasattr(listener, "exitPayload_value_int"): - listener.exitPayload_value_int(self) - - def accept(self, visitor: ParseTreeVisitor): - if hasattr(visitor, "visitPayload_value_int"): - return visitor.visitPayload_value_int(self) - else: - return visitor.visitChildren(self) - - class Payload_value_strContext(Payload_value_litContext): - def __init__( - self, parser, ctx: ParserRuleContext - ): # actually a ASLParser.Payload_value_litContext - super().__init__(parser) - self.copyFrom(ctx) - - def keyword_or_string(self): - return self.getTypedRuleContext(ASLParser.Keyword_or_stringContext, 0) - - def enterRule(self, listener: ParseTreeListener): - if hasattr(listener, "enterPayload_value_str"): - listener.enterPayload_value_str(self) - - def exitRule(self, listener: ParseTreeListener): - if hasattr(listener, "exitPayload_value_str"): - listener.exitPayload_value_str(self) - - def accept(self, visitor: ParseTreeVisitor): - if hasattr(visitor, "visitPayload_value_str"): - return visitor.visitPayload_value_str(self) - else: - return visitor.visitChildren(self) - - class Payload_value_floatContext(Payload_value_litContext): - def __init__( - self, parser, ctx: ParserRuleContext - ): # actually a ASLParser.Payload_value_litContext - super().__init__(parser) - self.copyFrom(ctx) - - def NUMBER(self): - return self.getToken(ASLParser.NUMBER, 0) - - def enterRule(self, listener: ParseTreeListener): - if hasattr(listener, "enterPayload_value_float"): - listener.enterPayload_value_float(self) - - def exitRule(self, listener: ParseTreeListener): - if hasattr(listener, "exitPayload_value_float"): - listener.exitPayload_value_float(self) + def jsonata_template_value_object(self): + return self.getTypedRuleContext( + ASLParser.Jsonata_template_value_objectContext, 0 + ) - def accept(self, visitor: ParseTreeVisitor): - if hasattr(visitor, "visitPayload_value_float"): - return visitor.visitPayload_value_float(self) - else: - return visitor.visitChildren(self) + def jsonata_template_value_array(self): + return self.getTypedRuleContext( + ASLParser.Jsonata_template_value_arrayContext, 0 + ) - class Payload_value_nullContext(Payload_value_litContext): - def __init__( - self, parser, ctx: ParserRuleContext - ): # actually a ASLParser.Payload_value_litContext - super().__init__(parser) - self.copyFrom(ctx) + def jsonata_template_value_terminal(self): + return self.getTypedRuleContext( + ASLParser.Jsonata_template_value_terminalContext, 0 + ) - def NULL(self): - return self.getToken(ASLParser.NULL, 0) + def getRuleIndex(self): + return ASLParser.RULE_jsonata_template_value def enterRule(self, listener: ParseTreeListener): - if hasattr(listener, "enterPayload_value_null"): - listener.enterPayload_value_null(self) + if hasattr(listener, "enterJsonata_template_value"): + listener.enterJsonata_template_value(self) def exitRule(self, listener: ParseTreeListener): - if hasattr(listener, "exitPayload_value_null"): - listener.exitPayload_value_null(self) + if hasattr(listener, "exitJsonata_template_value"): + listener.exitJsonata_template_value(self) def accept(self, visitor: ParseTreeVisitor): - if hasattr(visitor, "visitPayload_value_null"): - return visitor.visitPayload_value_null(self) + if hasattr(visitor, "visitJsonata_template_value"): + return visitor.visitJsonata_template_value(self) else: return visitor.visitChildren(self) - def payload_value_lit(self): - localctx = ASLParser.Payload_value_litContext(self, self._ctx, self.state) - self.enterRule(localctx, 82, self.RULE_payload_value_lit) - self._la = 0 # Token type + def jsonata_template_value(self): + localctx = ASLParser.Jsonata_template_valueContext(self, self._ctx, self.state) + self.enterRule(localctx, 116, self.RULE_jsonata_template_value) try: - self.state = 473 + self.state = 763 self._errHandler.sync(self) token = self._input.LA(1) - if token in [145]: - localctx = ASLParser.Payload_value_floatContext(self, localctx) + if token in [5]: self.enterOuterAlt(localctx, 1) - self.state = 468 - self.match(ASLParser.NUMBER) + self.state = 760 + self.jsonata_template_value_object() pass - elif token in [144]: - localctx = ASLParser.Payload_value_intContext(self, localctx) + elif token in [3]: self.enterOuterAlt(localctx, 2) - self.state = 469 - self.match(ASLParser.INT) - pass - elif token in [7, 8]: - localctx = ASLParser.Payload_value_boolContext(self, localctx) - self.enterOuterAlt(localctx, 3) - self.state = 470 - _la = self._input.LA(1) - if not (_la == 7 or _la == 8): - self._errHandler.recoverInline(self) - else: - self._errHandler.reportMatch(self) - self.consume() - pass - elif token in [9]: - localctx = ASLParser.Payload_value_nullContext(self, localctx) - self.enterOuterAlt(localctx, 4) - self.state = 471 - self.match(ASLParser.NULL) + self.state = 761 + self.jsonata_template_value_array() pass elif token in [ + 7, + 8, + 9, 10, 11, 12, @@ -11864,43 +19093,405 @@ def payload_value_lit(self): 109, 110, 111, + 112, 113, + 114, 115, 116, 117, - 118, 119, - 120, 121, 122, 123, 124, 125, + 126, 127, 128, 129, 130, 131, - 132, - 133, 134, 135, 136, 137, - 138, 139, 140, 141, 142, 143, + 144, + 145, + 146, + 147, + 148, + 149, + 150, + 151, + 152, + 153, + 154, + 155, + 156, + 157, + 158, + 159, + 160, + 161, ]: - localctx = ASLParser.Payload_value_strContext(self, localctx) + self.enterOuterAlt(localctx, 3) + self.state = 762 + self.jsonata_template_value_terminal() + pass + else: + raise NoViableAltException(self) + + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class Jsonata_template_value_arrayContext(ParserRuleContext): + __slots__ = "parser" + + def __init__( + self, parser, parent: ParserRuleContext = None, invokingState: int = -1 + ): + super().__init__(parent, invokingState) + self.parser = parser + + def LBRACK(self): + return self.getToken(ASLParser.LBRACK, 0) + + def RBRACK(self): + return self.getToken(ASLParser.RBRACK, 0) + + def jsonata_template_value(self, i: int = None): + if i is None: + return self.getTypedRuleContexts( + ASLParser.Jsonata_template_valueContext + ) + else: + return self.getTypedRuleContext( + ASLParser.Jsonata_template_valueContext, i + ) + + def COMMA(self, i: int = None): + if i is None: + return self.getTokens(ASLParser.COMMA) + else: + return self.getToken(ASLParser.COMMA, i) + + def getRuleIndex(self): + return ASLParser.RULE_jsonata_template_value_array + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterJsonata_template_value_array"): + listener.enterJsonata_template_value_array(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitJsonata_template_value_array"): + listener.exitJsonata_template_value_array(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitJsonata_template_value_array"): + return visitor.visitJsonata_template_value_array(self) + else: + return visitor.visitChildren(self) + + def jsonata_template_value_array(self): + localctx = ASLParser.Jsonata_template_value_arrayContext( + self, self._ctx, self.state + ) + self.enterRule(localctx, 118, self.RULE_jsonata_template_value_array) + self._la = 0 # Token type + try: + self.state = 778 + self._errHandler.sync(self) + la_ = self._interp.adaptivePredict(self._input, 48, self._ctx) + if la_ == 1: + self.enterOuterAlt(localctx, 1) + self.state = 765 + self.match(ASLParser.LBRACK) + self.state = 766 + self.match(ASLParser.RBRACK) + pass + + elif la_ == 2: + self.enterOuterAlt(localctx, 2) + self.state = 767 + self.match(ASLParser.LBRACK) + self.state = 768 + self.jsonata_template_value() + self.state = 773 + self._errHandler.sync(self) + _la = self._input.LA(1) + while _la == 1: + self.state = 769 + self.match(ASLParser.COMMA) + self.state = 770 + self.jsonata_template_value() + self.state = 775 + self._errHandler.sync(self) + _la = self._input.LA(1) + + self.state = 776 + self.match(ASLParser.RBRACK) + pass + + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class Jsonata_template_value_terminalContext(ParserRuleContext): + __slots__ = "parser" + + def __init__( + self, parser, parent: ParserRuleContext = None, invokingState: int = -1 + ): + super().__init__(parent, invokingState) + self.parser = parser + + def getRuleIndex(self): + return ASLParser.RULE_jsonata_template_value_terminal + + def copyFrom(self, ctx: ParserRuleContext): + super().copyFrom(ctx) + + class Jsonata_template_value_terminal_boolContext( + Jsonata_template_value_terminalContext + ): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Jsonata_template_value_terminalContext + super().__init__(parser) + self.copyFrom(ctx) + + def TRUE(self): + return self.getToken(ASLParser.TRUE, 0) + + def FALSE(self): + return self.getToken(ASLParser.FALSE, 0) + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterJsonata_template_value_terminal_bool"): + listener.enterJsonata_template_value_terminal_bool(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitJsonata_template_value_terminal_bool"): + listener.exitJsonata_template_value_terminal_bool(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitJsonata_template_value_terminal_bool"): + return visitor.visitJsonata_template_value_terminal_bool(self) + else: + return visitor.visitChildren(self) + + class Jsonata_template_value_terminal_intContext( + Jsonata_template_value_terminalContext + ): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Jsonata_template_value_terminalContext + super().__init__(parser) + self.copyFrom(ctx) + + def INT(self): + return self.getToken(ASLParser.INT, 0) + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterJsonata_template_value_terminal_int"): + listener.enterJsonata_template_value_terminal_int(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitJsonata_template_value_terminal_int"): + listener.exitJsonata_template_value_terminal_int(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitJsonata_template_value_terminal_int"): + return visitor.visitJsonata_template_value_terminal_int(self) + else: + return visitor.visitChildren(self) + + class Jsonata_template_value_terminal_expressionContext( + Jsonata_template_value_terminalContext + ): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Jsonata_template_value_terminalContext + super().__init__(parser) + self.copyFrom(ctx) + + def STRINGJSONATA(self): + return self.getToken(ASLParser.STRINGJSONATA, 0) + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterJsonata_template_value_terminal_expression"): + listener.enterJsonata_template_value_terminal_expression(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitJsonata_template_value_terminal_expression"): + listener.exitJsonata_template_value_terminal_expression(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitJsonata_template_value_terminal_expression"): + return visitor.visitJsonata_template_value_terminal_expression(self) + else: + return visitor.visitChildren(self) + + class Jsonata_template_value_terminal_floatContext( + Jsonata_template_value_terminalContext + ): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Jsonata_template_value_terminalContext + super().__init__(parser) + self.copyFrom(ctx) + + def NUMBER(self): + return self.getToken(ASLParser.NUMBER, 0) + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterJsonata_template_value_terminal_float"): + listener.enterJsonata_template_value_terminal_float(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitJsonata_template_value_terminal_float"): + listener.exitJsonata_template_value_terminal_float(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitJsonata_template_value_terminal_float"): + return visitor.visitJsonata_template_value_terminal_float(self) + else: + return visitor.visitChildren(self) + + class Jsonata_template_value_terminal_nullContext( + Jsonata_template_value_terminalContext + ): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Jsonata_template_value_terminalContext + super().__init__(parser) + self.copyFrom(ctx) + + def NULL(self): + return self.getToken(ASLParser.NULL, 0) + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterJsonata_template_value_terminal_null"): + listener.enterJsonata_template_value_terminal_null(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitJsonata_template_value_terminal_null"): + listener.exitJsonata_template_value_terminal_null(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitJsonata_template_value_terminal_null"): + return visitor.visitJsonata_template_value_terminal_null(self) + else: + return visitor.visitChildren(self) + + class Jsonata_template_value_terminal_strContext( + Jsonata_template_value_terminalContext + ): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Jsonata_template_value_terminalContext + super().__init__(parser) + self.copyFrom(ctx) + + def keyword_or_string(self): + return self.getTypedRuleContext(ASLParser.Keyword_or_stringContext, 0) + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterJsonata_template_value_terminal_str"): + listener.enterJsonata_template_value_terminal_str(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitJsonata_template_value_terminal_str"): + listener.exitJsonata_template_value_terminal_str(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitJsonata_template_value_terminal_str"): + return visitor.visitJsonata_template_value_terminal_str(self) + else: + return visitor.visitChildren(self) + + def jsonata_template_value_terminal(self): + localctx = ASLParser.Jsonata_template_value_terminalContext( + self, self._ctx, self.state + ) + self.enterRule(localctx, 120, self.RULE_jsonata_template_value_terminal) + self._la = 0 # Token type + try: + self.state = 786 + self._errHandler.sync(self) + la_ = self._interp.adaptivePredict(self._input, 49, self._ctx) + if la_ == 1: + localctx = ASLParser.Jsonata_template_value_terminal_floatContext( + self, localctx + ) + self.enterOuterAlt(localctx, 1) + self.state = 780 + self.match(ASLParser.NUMBER) + pass + + elif la_ == 2: + localctx = ASLParser.Jsonata_template_value_terminal_intContext( + self, localctx + ) + self.enterOuterAlt(localctx, 2) + self.state = 781 + self.match(ASLParser.INT) + pass + + elif la_ == 3: + localctx = ASLParser.Jsonata_template_value_terminal_boolContext( + self, localctx + ) + self.enterOuterAlt(localctx, 3) + self.state = 782 + _la = self._input.LA(1) + if not (_la == 7 or _la == 8): + self._errHandler.recoverInline(self) + else: + self._errHandler.reportMatch(self) + self.consume() + pass + + elif la_ == 4: + localctx = ASLParser.Jsonata_template_value_terminal_nullContext( + self, localctx + ) + self.enterOuterAlt(localctx, 4) + self.state = 783 + self.match(ASLParser.NULL) + pass + + elif la_ == 5: + localctx = ASLParser.Jsonata_template_value_terminal_expressionContext( + self, localctx + ) self.enterOuterAlt(localctx, 5) - self.state = 472 + self.state = 784 + self.match(ASLParser.STRINGJSONATA) + pass + + elif la_ == 6: + localctx = ASLParser.Jsonata_template_value_terminal_strContext( + self, localctx + ) + self.enterOuterAlt(localctx, 6) + self.state = 785 self.keyword_or_string() pass - else: - raise NoViableAltException(self) except RecognitionException as re: localctx.exception = re @@ -11947,14 +19538,14 @@ def accept(self, visitor: ParseTreeVisitor): def result_selector_decl(self): localctx = ASLParser.Result_selector_declContext(self, self._ctx, self.state) - self.enterRule(localctx, 84, self.RULE_result_selector_decl) + self.enterRule(localctx, 122, self.RULE_result_selector_decl) try: self.enterOuterAlt(localctx, 1) - self.state = 475 + self.state = 788 self.match(ASLParser.RESULTSELECTOR) - self.state = 476 + self.state = 789 self.match(ASLParser.COLON) - self.state = 477 + self.state = 790 self.payload_tmpl_decl() except RecognitionException as re: localctx.exception = re @@ -12016,11 +19607,11 @@ def accept(self, visitor: ParseTreeVisitor): def state_type(self): localctx = ASLParser.State_typeContext(self, self._ctx, self.state) - self.enterRule(localctx, 86, self.RULE_state_type) + self.enterRule(localctx, 124, self.RULE_state_type) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 479 + self.state = 792 _la = self._input.LA(1) if not (((_la) & ~0x3F) == 0 and ((1 << _la) & 16711680) != 0): self._errHandler.recoverInline(self) @@ -12087,31 +19678,31 @@ def accept(self, visitor: ParseTreeVisitor): def choices_decl(self): localctx = ASLParser.Choices_declContext(self, self._ctx, self.state) - self.enterRule(localctx, 88, self.RULE_choices_decl) + self.enterRule(localctx, 126, self.RULE_choices_decl) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 481 + self.state = 794 self.match(ASLParser.CHOICES) - self.state = 482 + self.state = 795 self.match(ASLParser.COLON) - self.state = 483 + self.state = 796 self.match(ASLParser.LBRACK) - self.state = 484 + self.state = 797 self.choice_rule() - self.state = 489 + self.state = 802 self._errHandler.sync(self) _la = self._input.LA(1) while _la == 1: - self.state = 485 + self.state = 798 self.match(ASLParser.COMMA) - self.state = 486 + self.state = 799 self.choice_rule() - self.state = 491 + self.state = 804 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 492 + self.state = 805 self.match(ASLParser.RBRACK) except RecognitionException as re: localctx.exception = re @@ -12224,36 +19815,36 @@ def accept(self, visitor: ParseTreeVisitor): def choice_rule(self): localctx = ASLParser.Choice_ruleContext(self, self._ctx, self.state) - self.enterRule(localctx, 90, self.RULE_choice_rule) + self.enterRule(localctx, 128, self.RULE_choice_rule) self._la = 0 # Token type try: - self.state = 515 + self.state = 828 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input, 20, self._ctx) + la_ = self._interp.adaptivePredict(self._input, 53, self._ctx) if la_ == 1: localctx = ASLParser.Choice_rule_comparison_variableContext( self, localctx ) self.enterOuterAlt(localctx, 1) - self.state = 494 + self.state = 807 self.match(ASLParser.LBRACE) - self.state = 495 + self.state = 808 self.comparison_variable_stmt() - self.state = 498 + self.state = 811 self._errHandler.sync(self) _la = self._input.LA(1) while True: - self.state = 496 + self.state = 809 self.match(ASLParser.COMMA) - self.state = 497 + self.state = 810 self.comparison_variable_stmt() - self.state = 500 + self.state = 813 self._errHandler.sync(self) _la = self._input.LA(1) if not (_la == 1): break - self.state = 502 + self.state = 815 self.match(ASLParser.RBRACE) pass @@ -12262,23 +19853,23 @@ def choice_rule(self): self, localctx ) self.enterOuterAlt(localctx, 2) - self.state = 504 + self.state = 817 self.match(ASLParser.LBRACE) - self.state = 505 + self.state = 818 self.comparison_composite_stmt() - self.state = 510 + self.state = 823 self._errHandler.sync(self) _la = self._input.LA(1) while _la == 1: - self.state = 506 + self.state = 819 self.match(ASLParser.COMMA) - self.state = 507 + self.state = 820 self.comparison_composite_stmt() - self.state = 512 + self.state = 825 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 513 + self.state = 826 self.match(ASLParser.RBRACE) pass @@ -12308,6 +19899,9 @@ def comparison_func(self): def next_decl(self): return self.getTypedRuleContext(ASLParser.Next_declContext, 0) + def assign_decl(self): + return self.getTypedRuleContext(ASLParser.Assign_declContext, 0) + def comment_decl(self): return self.getTypedRuleContext(ASLParser.Comment_declContext, 0) @@ -12332,18 +19926,18 @@ def comparison_variable_stmt(self): localctx = ASLParser.Comparison_variable_stmtContext( self, self._ctx, self.state ) - self.enterRule(localctx, 92, self.RULE_comparison_variable_stmt) + self.enterRule(localctx, 130, self.RULE_comparison_variable_stmt) try: - self.state = 521 + self.state = 835 self._errHandler.sync(self) token = self._input.LA(1) - if token in [25]: + if token in [26]: self.enterOuterAlt(localctx, 1) - self.state = 517 + self.state = 830 self.variable_decl() pass elif token in [ - 29, + 25, 30, 31, 32, @@ -12351,7 +19945,7 @@ def comparison_variable_stmt(self): 34, 35, 36, - 38, + 37, 39, 40, 41, @@ -12361,7 +19955,7 @@ def comparison_variable_stmt(self): 45, 46, 47, - 49, + 48, 50, 51, 52, @@ -12382,19 +19976,25 @@ def comparison_variable_stmt(self): 67, 68, 69, + 70, ]: self.enterOuterAlt(localctx, 2) - self.state = 518 + self.state = 831 self.comparison_func() pass - elif token in [109]: + elif token in [115]: self.enterOuterAlt(localctx, 3) - self.state = 519 + self.state = 832 self.next_decl() pass - elif token in [10]: + elif token in [134]: self.enterOuterAlt(localctx, 4) - self.state = 520 + self.state = 833 + self.assign_decl() + pass + elif token in [10]: + self.enterOuterAlt(localctx, 5) + self.state = 834 self.comment_decl() pass else: @@ -12423,6 +20023,12 @@ def comparison_composite(self): def next_decl(self): return self.getTypedRuleContext(ASLParser.Next_declContext, 0) + def assign_decl(self): + return self.getTypedRuleContext(ASLParser.Assign_declContext, 0) + + def comment_decl(self): + return self.getTypedRuleContext(ASLParser.Comment_declContext, 0) + def getRuleIndex(self): return ASLParser.RULE_comparison_composite_stmt @@ -12444,21 +20050,31 @@ def comparison_composite_stmt(self): localctx = ASLParser.Comparison_composite_stmtContext( self, self._ctx, self.state ) - self.enterRule(localctx, 94, self.RULE_comparison_composite_stmt) + self.enterRule(localctx, 132, self.RULE_comparison_composite_stmt) try: - self.state = 525 + self.state = 841 self._errHandler.sync(self) token = self._input.LA(1) - if token in [28, 37, 48]: + if token in [29, 38, 49]: self.enterOuterAlt(localctx, 1) - self.state = 523 + self.state = 837 self.comparison_composite() pass - elif token in [109]: + elif token in [115]: self.enterOuterAlt(localctx, 2) - self.state = 524 + self.state = 838 self.next_decl() pass + elif token in [134]: + self.enterOuterAlt(localctx, 3) + self.state = 839 + self.assign_decl() + pass + elif token in [10]: + self.enterOuterAlt(localctx, 4) + self.state = 840 + self.comment_decl() + pass else: raise NoViableAltException(self) @@ -12522,39 +20138,39 @@ def accept(self, visitor: ParseTreeVisitor): def comparison_composite(self): localctx = ASLParser.Comparison_compositeContext(self, self._ctx, self.state) - self.enterRule(localctx, 96, self.RULE_comparison_composite) + self.enterRule(localctx, 134, self.RULE_comparison_composite) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 527 + self.state = 843 self.choice_operator() - self.state = 528 + self.state = 844 self.match(ASLParser.COLON) - self.state = 541 + self.state = 857 self._errHandler.sync(self) token = self._input.LA(1) if token in [5]: - self.state = 529 + self.state = 845 self.choice_rule() pass elif token in [3]: - self.state = 530 + self.state = 846 self.match(ASLParser.LBRACK) - self.state = 531 + self.state = 847 self.choice_rule() - self.state = 536 + self.state = 852 self._errHandler.sync(self) _la = self._input.LA(1) while _la == 1: - self.state = 532 + self.state = 848 self.match(ASLParser.COMMA) - self.state = 533 + self.state = 849 self.choice_rule() - self.state = 538 + self.state = 854 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 539 + self.state = 855 self.match(ASLParser.RBRACK) pass else: @@ -12577,43 +20193,144 @@ def __init__( super().__init__(parent, invokingState) self.parser = parser + def getRuleIndex(self): + return ASLParser.RULE_variable_decl + + def copyFrom(self, ctx: ParserRuleContext): + super().copyFrom(ctx) + + class Variable_decl_pathContext(Variable_declContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Variable_declContext + super().__init__(parser) + self.copyFrom(ctx) + def VARIABLE(self): return self.getToken(ASLParser.VARIABLE, 0) def COLON(self): return self.getToken(ASLParser.COLON, 0) - def keyword_or_string(self): - return self.getTypedRuleContext(ASLParser.Keyword_or_stringContext, 0) + def STRINGPATH(self): + return self.getToken(ASLParser.STRINGPATH, 0) - def getRuleIndex(self): - return ASLParser.RULE_variable_decl + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterVariable_decl_path"): + listener.enterVariable_decl_path(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitVariable_decl_path"): + listener.exitVariable_decl_path(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitVariable_decl_path"): + return visitor.visitVariable_decl_path(self) + else: + return visitor.visitChildren(self) + + class Variable_decl_path_context_objectContext(Variable_declContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Variable_declContext + super().__init__(parser) + self.copyFrom(ctx) + + def VARIABLE(self): + return self.getToken(ASLParser.VARIABLE, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def STRINGPATHCONTEXTOBJ(self): + return self.getToken(ASLParser.STRINGPATHCONTEXTOBJ, 0) + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterVariable_decl_path_context_object"): + listener.enterVariable_decl_path_context_object(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitVariable_decl_path_context_object"): + listener.exitVariable_decl_path_context_object(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitVariable_decl_path_context_object"): + return visitor.visitVariable_decl_path_context_object(self) + else: + return visitor.visitChildren(self) + + class Variable_decl_varContext(Variable_declContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Variable_declContext + super().__init__(parser) + self.copyFrom(ctx) + + def VARIABLE(self): + return self.getToken(ASLParser.VARIABLE, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def variable_sample(self): + return self.getTypedRuleContext(ASLParser.Variable_sampleContext, 0) def enterRule(self, listener: ParseTreeListener): - if hasattr(listener, "enterVariable_decl"): - listener.enterVariable_decl(self) + if hasattr(listener, "enterVariable_decl_var"): + listener.enterVariable_decl_var(self) def exitRule(self, listener: ParseTreeListener): - if hasattr(listener, "exitVariable_decl"): - listener.exitVariable_decl(self) + if hasattr(listener, "exitVariable_decl_var"): + listener.exitVariable_decl_var(self) def accept(self, visitor: ParseTreeVisitor): - if hasattr(visitor, "visitVariable_decl"): - return visitor.visitVariable_decl(self) + if hasattr(visitor, "visitVariable_decl_var"): + return visitor.visitVariable_decl_var(self) else: return visitor.visitChildren(self) def variable_decl(self): localctx = ASLParser.Variable_declContext(self, self._ctx, self.state) - self.enterRule(localctx, 98, self.RULE_variable_decl) + self.enterRule(localctx, 136, self.RULE_variable_decl) try: - self.enterOuterAlt(localctx, 1) - self.state = 543 - self.match(ASLParser.VARIABLE) - self.state = 544 - self.match(ASLParser.COLON) - self.state = 545 - self.keyword_or_string() + self.state = 868 + self._errHandler.sync(self) + la_ = self._interp.adaptivePredict(self._input, 58, self._ctx) + if la_ == 1: + localctx = ASLParser.Variable_decl_pathContext(self, localctx) + self.enterOuterAlt(localctx, 1) + self.state = 859 + self.match(ASLParser.VARIABLE) + self.state = 860 + self.match(ASLParser.COLON) + self.state = 861 + self.match(ASLParser.STRINGPATH) + pass + + elif la_ == 2: + localctx = ASLParser.Variable_decl_varContext(self, localctx) + self.enterOuterAlt(localctx, 2) + self.state = 862 + self.match(ASLParser.VARIABLE) + self.state = 863 + self.match(ASLParser.COLON) + self.state = 864 + self.variable_sample() + pass + + elif la_ == 3: + localctx = ASLParser.Variable_decl_path_context_objectContext( + self, localctx + ) + self.enterOuterAlt(localctx, 3) + self.state = 865 + self.match(ASLParser.VARIABLE) + self.state = 866 + self.match(ASLParser.COLON) + self.state = 867 + self.match(ASLParser.STRINGPATHCONTEXTOBJ) + pass + except RecognitionException as re: localctx.exception = re self._errHandler.reportError(self, re) @@ -12622,14 +20339,120 @@ def variable_decl(self): self.exitRule() return localctx - class Comparison_funcContext(ParserRuleContext): - __slots__ = "parser" + class Comparison_funcContext(ParserRuleContext): + __slots__ = "parser" + + def __init__( + self, parser, parent: ParserRuleContext = None, invokingState: int = -1 + ): + super().__init__(parent, invokingState) + self.parser = parser + + def getRuleIndex(self): + return ASLParser.RULE_comparison_func + + def copyFrom(self, ctx: ParserRuleContext): + super().copyFrom(ctx) + + class Condition_exprContext(Comparison_funcContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Comparison_funcContext + super().__init__(parser) + self.copyFrom(ctx) + + def CONDITION(self): + return self.getToken(ASLParser.CONDITION, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def STRINGJSONATA(self): + return self.getToken(ASLParser.STRINGJSONATA, 0) + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterCondition_expr"): + listener.enterCondition_expr(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitCondition_expr"): + listener.exitCondition_expr(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitCondition_expr"): + return visitor.visitCondition_expr(self) + else: + return visitor.visitChildren(self) + + class Condition_litContext(Comparison_funcContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Comparison_funcContext + super().__init__(parser) + self.copyFrom(ctx) + + def CONDITION(self): + return self.getToken(ASLParser.CONDITION, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def TRUE(self): + return self.getToken(ASLParser.TRUE, 0) + + def FALSE(self): + return self.getToken(ASLParser.FALSE, 0) + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterCondition_lit"): + listener.enterCondition_lit(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitCondition_lit"): + listener.exitCondition_lit(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitCondition_lit"): + return visitor.visitCondition_lit(self) + else: + return visitor.visitChildren(self) + + class Comparison_func_varContext(Comparison_funcContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Comparison_funcContext + super().__init__(parser) + self.copyFrom(ctx) + + def comparison_op(self): + return self.getTypedRuleContext(ASLParser.Comparison_opContext, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def variable_sample(self): + return self.getTypedRuleContext(ASLParser.Variable_sampleContext, 0) + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterComparison_func_var"): + listener.enterComparison_func_var(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitComparison_func_var"): + listener.exitComparison_func_var(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitComparison_func_var"): + return visitor.visitComparison_func_var(self) + else: + return visitor.visitChildren(self) + class Comparison_func_valueContext(Comparison_funcContext): def __init__( - self, parser, parent: ParserRuleContext = None, invokingState: int = -1 - ): - super().__init__(parent, invokingState) - self.parser = parser + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Comparison_funcContext + super().__init__(parser) + self.copyFrom(ctx) def comparison_op(self): return self.getTypedRuleContext(ASLParser.Comparison_opContext, 0) @@ -12640,34 +20463,77 @@ def COLON(self): def json_value_decl(self): return self.getTypedRuleContext(ASLParser.Json_value_declContext, 0) - def getRuleIndex(self): - return ASLParser.RULE_comparison_func - def enterRule(self, listener: ParseTreeListener): - if hasattr(listener, "enterComparison_func"): - listener.enterComparison_func(self) + if hasattr(listener, "enterComparison_func_value"): + listener.enterComparison_func_value(self) def exitRule(self, listener: ParseTreeListener): - if hasattr(listener, "exitComparison_func"): - listener.exitComparison_func(self) + if hasattr(listener, "exitComparison_func_value"): + listener.exitComparison_func_value(self) def accept(self, visitor: ParseTreeVisitor): - if hasattr(visitor, "visitComparison_func"): - return visitor.visitComparison_func(self) + if hasattr(visitor, "visitComparison_func_value"): + return visitor.visitComparison_func_value(self) else: return visitor.visitChildren(self) def comparison_func(self): localctx = ASLParser.Comparison_funcContext(self, self._ctx, self.state) - self.enterRule(localctx, 100, self.RULE_comparison_func) + self.enterRule(localctx, 138, self.RULE_comparison_func) + self._la = 0 # Token type try: - self.enterOuterAlt(localctx, 1) - self.state = 547 - self.comparison_op() - self.state = 548 - self.match(ASLParser.COLON) - self.state = 549 - self.json_value_decl() + self.state = 884 + self._errHandler.sync(self) + la_ = self._interp.adaptivePredict(self._input, 59, self._ctx) + if la_ == 1: + localctx = ASLParser.Condition_litContext(self, localctx) + self.enterOuterAlt(localctx, 1) + self.state = 870 + self.match(ASLParser.CONDITION) + self.state = 871 + self.match(ASLParser.COLON) + self.state = 872 + _la = self._input.LA(1) + if not (_la == 7 or _la == 8): + self._errHandler.recoverInline(self) + else: + self._errHandler.reportMatch(self) + self.consume() + pass + + elif la_ == 2: + localctx = ASLParser.Condition_exprContext(self, localctx) + self.enterOuterAlt(localctx, 2) + self.state = 873 + self.match(ASLParser.CONDITION) + self.state = 874 + self.match(ASLParser.COLON) + self.state = 875 + self.match(ASLParser.STRINGJSONATA) + pass + + elif la_ == 3: + localctx = ASLParser.Comparison_func_varContext(self, localctx) + self.enterOuterAlt(localctx, 3) + self.state = 876 + self.comparison_op() + self.state = 877 + self.match(ASLParser.COLON) + self.state = 878 + self.variable_sample() + pass + + elif la_ == 4: + localctx = ASLParser.Comparison_func_valueContext(self, localctx) + self.enterOuterAlt(localctx, 4) + self.state = 880 + self.comparison_op() + self.state = 881 + self.match(ASLParser.COLON) + self.state = 882 + self.json_value_decl() + pass + except RecognitionException as re: localctx.exception = re self._errHandler.reportError(self, re) @@ -12728,31 +20594,31 @@ def accept(self, visitor: ParseTreeVisitor): def branches_decl(self): localctx = ASLParser.Branches_declContext(self, self._ctx, self.state) - self.enterRule(localctx, 102, self.RULE_branches_decl) + self.enterRule(localctx, 140, self.RULE_branches_decl) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 551 + self.state = 886 self.match(ASLParser.BRANCHES) - self.state = 552 + self.state = 887 self.match(ASLParser.COLON) - self.state = 553 + self.state = 888 self.match(ASLParser.LBRACK) - self.state = 554 + self.state = 889 self.program_decl() - self.state = 559 + self.state = 894 self._errHandler.sync(self) _la = self._input.LA(1) while _la == 1: - self.state = 555 + self.state = 890 self.match(ASLParser.COMMA) - self.state = 556 + self.state = 891 self.program_decl() - self.state = 561 + self.state = 896 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 562 + self.state = 897 self.match(ASLParser.RBRACK) except RecognitionException as re: localctx.exception = re @@ -12814,31 +20680,31 @@ def accept(self, visitor: ParseTreeVisitor): def item_processor_decl(self): localctx = ASLParser.Item_processor_declContext(self, self._ctx, self.state) - self.enterRule(localctx, 104, self.RULE_item_processor_decl) + self.enterRule(localctx, 142, self.RULE_item_processor_decl) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 564 + self.state = 899 self.match(ASLParser.ITEMPROCESSOR) - self.state = 565 + self.state = 900 self.match(ASLParser.COLON) - self.state = 566 + self.state = 901 self.match(ASLParser.LBRACE) - self.state = 567 + self.state = 902 self.item_processor_item() - self.state = 572 + self.state = 907 self._errHandler.sync(self) _la = self._input.LA(1) while _la == 1: - self.state = 568 + self.state = 903 self.match(ASLParser.COMMA) - self.state = 569 + self.state = 904 self.item_processor_item() - self.state = 574 + self.state = 909 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 575 + self.state = 910 self.match(ASLParser.RBRACE) except RecognitionException as re: localctx.exception = re @@ -12888,29 +20754,29 @@ def accept(self, visitor: ParseTreeVisitor): def item_processor_item(self): localctx = ASLParser.Item_processor_itemContext(self, self._ctx, self.state) - self.enterRule(localctx, 106, self.RULE_item_processor_item) + self.enterRule(localctx, 144, self.RULE_item_processor_item) try: - self.state = 581 + self.state = 916 self._errHandler.sync(self) token = self._input.LA(1) - if token in [78]: + if token in [79]: self.enterOuterAlt(localctx, 1) - self.state = 577 + self.state = 912 self.processor_config_decl() pass elif token in [12]: self.enterOuterAlt(localctx, 2) - self.state = 578 + self.state = 913 self.startat_decl() pass elif token in [11]: self.enterOuterAlt(localctx, 3) - self.state = 579 + self.state = 914 self.states_decl() pass elif token in [10]: self.enterOuterAlt(localctx, 4) - self.state = 580 + self.state = 915 self.comment_decl() pass else: @@ -12980,31 +20846,31 @@ def accept(self, visitor: ParseTreeVisitor): def processor_config_decl(self): localctx = ASLParser.Processor_config_declContext(self, self._ctx, self.state) - self.enterRule(localctx, 108, self.RULE_processor_config_decl) + self.enterRule(localctx, 146, self.RULE_processor_config_decl) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 583 + self.state = 918 self.match(ASLParser.PROCESSORCONFIG) - self.state = 584 + self.state = 919 self.match(ASLParser.COLON) - self.state = 585 + self.state = 920 self.match(ASLParser.LBRACE) - self.state = 586 + self.state = 921 self.processor_config_field() - self.state = 591 + self.state = 926 self._errHandler.sync(self) _la = self._input.LA(1) while _la == 1: - self.state = 587 + self.state = 922 self.match(ASLParser.COMMA) - self.state = 588 + self.state = 923 self.processor_config_field() - self.state = 593 + self.state = 928 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 594 + self.state = 929 self.match(ASLParser.RBRACE) except RecognitionException as re: localctx.exception = re @@ -13048,19 +20914,19 @@ def accept(self, visitor: ParseTreeVisitor): def processor_config_field(self): localctx = ASLParser.Processor_config_fieldContext(self, self._ctx, self.state) - self.enterRule(localctx, 110, self.RULE_processor_config_field) + self.enterRule(localctx, 148, self.RULE_processor_config_field) try: - self.state = 598 + self.state = 933 self._errHandler.sync(self) token = self._input.LA(1) - if token in [79]: + if token in [80]: self.enterOuterAlt(localctx, 1) - self.state = 596 + self.state = 931 self.mode_decl() pass - elif token in [82]: + elif token in [83]: self.enterOuterAlt(localctx, 2) - self.state = 597 + self.state = 932 self.execution_decl() pass else: @@ -13111,14 +20977,14 @@ def accept(self, visitor: ParseTreeVisitor): def mode_decl(self): localctx = ASLParser.Mode_declContext(self, self._ctx, self.state) - self.enterRule(localctx, 112, self.RULE_mode_decl) + self.enterRule(localctx, 150, self.RULE_mode_decl) try: self.enterOuterAlt(localctx, 1) - self.state = 600 + self.state = 935 self.match(ASLParser.MODE) - self.state = 601 + self.state = 936 self.match(ASLParser.COLON) - self.state = 602 + self.state = 937 self.mode_type() except RecognitionException as re: localctx.exception = re @@ -13162,13 +21028,13 @@ def accept(self, visitor: ParseTreeVisitor): def mode_type(self): localctx = ASLParser.Mode_typeContext(self, self._ctx, self.state) - self.enterRule(localctx, 114, self.RULE_mode_type) + self.enterRule(localctx, 152, self.RULE_mode_type) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 604 + self.state = 939 _la = self._input.LA(1) - if not (_la == 80 or _la == 81): + if not (_la == 81 or _la == 82): self._errHandler.recoverInline(self) else: self._errHandler.reportMatch(self) @@ -13218,14 +21084,14 @@ def accept(self, visitor: ParseTreeVisitor): def execution_decl(self): localctx = ASLParser.Execution_declContext(self, self._ctx, self.state) - self.enterRule(localctx, 116, self.RULE_execution_decl) + self.enterRule(localctx, 154, self.RULE_execution_decl) try: self.enterOuterAlt(localctx, 1) - self.state = 606 + self.state = 941 self.match(ASLParser.EXECUTIONTYPE) - self.state = 607 + self.state = 942 self.match(ASLParser.COLON) - self.state = 608 + self.state = 943 self.execution_type() except RecognitionException as re: localctx.exception = re @@ -13266,10 +21132,10 @@ def accept(self, visitor: ParseTreeVisitor): def execution_type(self): localctx = ASLParser.Execution_typeContext(self, self._ctx, self.state) - self.enterRule(localctx, 118, self.RULE_execution_type) + self.enterRule(localctx, 156, self.RULE_execution_type) try: self.enterOuterAlt(localctx, 1) - self.state = 610 + self.state = 945 self.match(ASLParser.STANDARD) except RecognitionException as re: localctx.exception = re @@ -13331,31 +21197,31 @@ def accept(self, visitor: ParseTreeVisitor): def iterator_decl(self): localctx = ASLParser.Iterator_declContext(self, self._ctx, self.state) - self.enterRule(localctx, 120, self.RULE_iterator_decl) + self.enterRule(localctx, 158, self.RULE_iterator_decl) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 612 + self.state = 947 self.match(ASLParser.ITERATOR) - self.state = 613 + self.state = 948 self.match(ASLParser.COLON) - self.state = 614 + self.state = 949 self.match(ASLParser.LBRACE) - self.state = 615 + self.state = 950 self.iterator_decl_item() - self.state = 620 + self.state = 955 self._errHandler.sync(self) _la = self._input.LA(1) while _la == 1: - self.state = 616 + self.state = 951 self.match(ASLParser.COMMA) - self.state = 617 + self.state = 952 self.iterator_decl_item() - self.state = 622 + self.state = 957 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 623 + self.state = 958 self.match(ASLParser.RBRACE) except RecognitionException as re: localctx.exception = re @@ -13405,29 +21271,29 @@ def accept(self, visitor: ParseTreeVisitor): def iterator_decl_item(self): localctx = ASLParser.Iterator_decl_itemContext(self, self._ctx, self.state) - self.enterRule(localctx, 122, self.RULE_iterator_decl_item) + self.enterRule(localctx, 160, self.RULE_iterator_decl_item) try: - self.state = 629 + self.state = 964 self._errHandler.sync(self) token = self._input.LA(1) if token in [12]: self.enterOuterAlt(localctx, 1) - self.state = 625 + self.state = 960 self.startat_decl() pass elif token in [11]: self.enterOuterAlt(localctx, 2) - self.state = 626 + self.state = 961 self.states_decl() pass elif token in [10]: self.enterOuterAlt(localctx, 3) - self.state = 627 + self.state = 962 self.comment_decl() pass - elif token in [78]: + elif token in [79]: self.enterOuterAlt(localctx, 4) - self.state = 628 + self.state = 963 self.processor_config_decl() pass else: @@ -13478,14 +21344,14 @@ def accept(self, visitor: ParseTreeVisitor): def item_selector_decl(self): localctx = ASLParser.Item_selector_declContext(self, self._ctx, self.state) - self.enterRule(localctx, 124, self.RULE_item_selector_decl) + self.enterRule(localctx, 162, self.RULE_item_selector_decl) try: self.enterOuterAlt(localctx, 1) - self.state = 631 + self.state = 966 self.match(ASLParser.ITEMSELECTOR) - self.state = 632 + self.state = 967 self.match(ASLParser.COLON) - self.state = 633 + self.state = 968 self.payload_tmpl_decl() except RecognitionException as re: localctx.exception = re @@ -13547,31 +21413,31 @@ def accept(self, visitor: ParseTreeVisitor): def item_reader_decl(self): localctx = ASLParser.Item_reader_declContext(self, self._ctx, self.state) - self.enterRule(localctx, 126, self.RULE_item_reader_decl) + self.enterRule(localctx, 164, self.RULE_item_reader_decl) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 635 + self.state = 970 self.match(ASLParser.ITEMREADER) - self.state = 636 + self.state = 971 self.match(ASLParser.COLON) - self.state = 637 + self.state = 972 self.match(ASLParser.LBRACE) - self.state = 638 + self.state = 973 self.items_reader_field() - self.state = 643 + self.state = 978 self._errHandler.sync(self) _la = self._input.LA(1) while _la == 1: - self.state = 639 + self.state = 974 self.match(ASLParser.COMMA) - self.state = 640 + self.state = 975 self.items_reader_field() - self.state = 645 + self.state = 980 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 646 + self.state = 981 self.match(ASLParser.RBRACE) except RecognitionException as re: localctx.exception = re @@ -13593,11 +21459,14 @@ def __init__( def resource_decl(self): return self.getTypedRuleContext(ASLParser.Resource_declContext, 0) + def reader_config_decl(self): + return self.getTypedRuleContext(ASLParser.Reader_config_declContext, 0) + def parameters_decl(self): return self.getTypedRuleContext(ASLParser.Parameters_declContext, 0) - def reader_config_decl(self): - return self.getTypedRuleContext(ASLParser.Reader_config_declContext, 0) + def arguments_decl(self): + return self.getTypedRuleContext(ASLParser.Arguments_declContext, 0) def getRuleIndex(self): return ASLParser.RULE_items_reader_field @@ -13618,25 +21487,30 @@ def accept(self, visitor: ParseTreeVisitor): def items_reader_field(self): localctx = ASLParser.Items_reader_fieldContext(self, self._ctx, self.state) - self.enterRule(localctx, 128, self.RULE_items_reader_field) + self.enterRule(localctx, 166, self.RULE_items_reader_field) try: - self.state = 651 + self.state = 987 self._errHandler.sync(self) token = self._input.LA(1) - if token in [89]: + if token in [90]: self.enterOuterAlt(localctx, 1) - self.state = 648 + self.state = 983 self.resource_decl() pass - elif token in [95]: + elif token in [103]: self.enterOuterAlt(localctx, 2) - self.state = 649 - self.parameters_decl() + self.state = 984 + self.reader_config_decl() pass - elif token in [98]: + elif token in [97]: self.enterOuterAlt(localctx, 3) - self.state = 650 - self.reader_config_decl() + self.state = 985 + self.parameters_decl() + pass + elif token in [136]: + self.enterOuterAlt(localctx, 4) + self.state = 986 + self.arguments_decl() pass else: raise NoViableAltException(self) @@ -13701,31 +21575,31 @@ def accept(self, visitor: ParseTreeVisitor): def reader_config_decl(self): localctx = ASLParser.Reader_config_declContext(self, self._ctx, self.state) - self.enterRule(localctx, 130, self.RULE_reader_config_decl) + self.enterRule(localctx, 168, self.RULE_reader_config_decl) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 653 + self.state = 989 self.match(ASLParser.READERCONFIG) - self.state = 654 + self.state = 990 self.match(ASLParser.COLON) - self.state = 655 + self.state = 991 self.match(ASLParser.LBRACE) - self.state = 656 + self.state = 992 self.reader_config_field() - self.state = 661 + self.state = 997 self._errHandler.sync(self) _la = self._input.LA(1) while _la == 1: - self.state = 657 + self.state = 993 self.match(ASLParser.COMMA) - self.state = 658 + self.state = 994 self.reader_config_field() - self.state = 663 + self.state = 999 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 664 + self.state = 1000 self.match(ASLParser.RBRACE) except RecognitionException as re: localctx.exception = re @@ -13780,34 +21654,34 @@ def accept(self, visitor: ParseTreeVisitor): def reader_config_field(self): localctx = ASLParser.Reader_config_fieldContext(self, self._ctx, self.state) - self.enterRule(localctx, 132, self.RULE_reader_config_field) + self.enterRule(localctx, 170, self.RULE_reader_config_field) try: - self.state = 671 + self.state = 1007 self._errHandler.sync(self) token = self._input.LA(1) - if token in [99]: + if token in [104]: self.enterOuterAlt(localctx, 1) - self.state = 666 + self.state = 1002 self.input_type_decl() pass - elif token in [100]: + elif token in [105]: self.enterOuterAlt(localctx, 2) - self.state = 667 + self.state = 1003 self.csv_header_location_decl() pass - elif token in [101]: + elif token in [106]: self.enterOuterAlt(localctx, 3) - self.state = 668 + self.state = 1004 self.csv_headers_decl() pass - elif token in [102]: + elif token in [107]: self.enterOuterAlt(localctx, 4) - self.state = 669 + self.state = 1005 self.max_items_decl() pass - elif token in [103]: + elif token in [108]: self.enterOuterAlt(localctx, 5) - self.state = 670 + self.state = 1006 self.max_items_path_decl() pass else: @@ -13858,14 +21732,14 @@ def accept(self, visitor: ParseTreeVisitor): def input_type_decl(self): localctx = ASLParser.Input_type_declContext(self, self._ctx, self.state) - self.enterRule(localctx, 134, self.RULE_input_type_decl) + self.enterRule(localctx, 172, self.RULE_input_type_decl) try: self.enterOuterAlt(localctx, 1) - self.state = 673 + self.state = 1009 self.match(ASLParser.INPUTTYPE) - self.state = 674 + self.state = 1010 self.match(ASLParser.COLON) - self.state = 675 + self.state = 1011 self.keyword_or_string() except RecognitionException as re: localctx.exception = re @@ -13914,15 +21788,213 @@ def csv_header_location_decl(self): localctx = ASLParser.Csv_header_location_declContext( self, self._ctx, self.state ) - self.enterRule(localctx, 136, self.RULE_csv_header_location_decl) + self.enterRule(localctx, 174, self.RULE_csv_header_location_decl) try: self.enterOuterAlt(localctx, 1) - self.state = 677 + self.state = 1013 self.match(ASLParser.CSVHEADERLOCATION) - self.state = 678 + self.state = 1014 + self.match(ASLParser.COLON) + self.state = 1015 + self.keyword_or_string() + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class Csv_headers_declContext(ParserRuleContext): + __slots__ = "parser" + + def __init__( + self, parser, parent: ParserRuleContext = None, invokingState: int = -1 + ): + super().__init__(parent, invokingState) + self.parser = parser + + def CSVHEADERS(self): + return self.getToken(ASLParser.CSVHEADERS, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def LBRACK(self): + return self.getToken(ASLParser.LBRACK, 0) + + def keyword_or_string(self, i: int = None): + if i is None: + return self.getTypedRuleContexts(ASLParser.Keyword_or_stringContext) + else: + return self.getTypedRuleContext(ASLParser.Keyword_or_stringContext, i) + + def RBRACK(self): + return self.getToken(ASLParser.RBRACK, 0) + + def COMMA(self, i: int = None): + if i is None: + return self.getTokens(ASLParser.COMMA) + else: + return self.getToken(ASLParser.COMMA, i) + + def getRuleIndex(self): + return ASLParser.RULE_csv_headers_decl + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterCsv_headers_decl"): + listener.enterCsv_headers_decl(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitCsv_headers_decl"): + listener.exitCsv_headers_decl(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitCsv_headers_decl"): + return visitor.visitCsv_headers_decl(self) + else: + return visitor.visitChildren(self) + + def csv_headers_decl(self): + localctx = ASLParser.Csv_headers_declContext(self, self._ctx, self.state) + self.enterRule(localctx, 176, self.RULE_csv_headers_decl) + self._la = 0 # Token type + try: + self.enterOuterAlt(localctx, 1) + self.state = 1017 + self.match(ASLParser.CSVHEADERS) + self.state = 1018 self.match(ASLParser.COLON) - self.state = 679 + self.state = 1019 + self.match(ASLParser.LBRACK) + self.state = 1020 self.keyword_or_string() + self.state = 1025 + self._errHandler.sync(self) + _la = self._input.LA(1) + while _la == 1: + self.state = 1021 + self.match(ASLParser.COMMA) + self.state = 1022 + self.keyword_or_string() + self.state = 1027 + self._errHandler.sync(self) + _la = self._input.LA(1) + + self.state = 1028 + self.match(ASLParser.RBRACK) + except RecognitionException as re: + localctx.exception = re + self._errHandler.reportError(self, re) + self._errHandler.recover(self, re) + finally: + self.exitRule() + return localctx + + class Max_items_declContext(ParserRuleContext): + __slots__ = "parser" + + def __init__( + self, parser, parent: ParserRuleContext = None, invokingState: int = -1 + ): + super().__init__(parent, invokingState) + self.parser = parser + + def getRuleIndex(self): + return ASLParser.RULE_max_items_decl + + def copyFrom(self, ctx: ParserRuleContext): + super().copyFrom(ctx) + + class Max_items_jsonataContext(Max_items_declContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Max_items_declContext + super().__init__(parser) + self.copyFrom(ctx) + + def MAXITEMS(self): + return self.getToken(ASLParser.MAXITEMS, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def STRINGJSONATA(self): + return self.getToken(ASLParser.STRINGJSONATA, 0) + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterMax_items_jsonata"): + listener.enterMax_items_jsonata(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitMax_items_jsonata"): + listener.exitMax_items_jsonata(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitMax_items_jsonata"): + return visitor.visitMax_items_jsonata(self) + else: + return visitor.visitChildren(self) + + class Max_items_intContext(Max_items_declContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Max_items_declContext + super().__init__(parser) + self.copyFrom(ctx) + + def MAXITEMS(self): + return self.getToken(ASLParser.MAXITEMS, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def INT(self): + return self.getToken(ASLParser.INT, 0) + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterMax_items_int"): + listener.enterMax_items_int(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitMax_items_int"): + listener.exitMax_items_int(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitMax_items_int"): + return visitor.visitMax_items_int(self) + else: + return visitor.visitChildren(self) + + def max_items_decl(self): + localctx = ASLParser.Max_items_declContext(self, self._ctx, self.state) + self.enterRule(localctx, 178, self.RULE_max_items_decl) + try: + self.state = 1036 + self._errHandler.sync(self) + la_ = self._interp.adaptivePredict(self._input, 72, self._ctx) + if la_ == 1: + localctx = ASLParser.Max_items_jsonataContext(self, localctx) + self.enterOuterAlt(localctx, 1) + self.state = 1030 + self.match(ASLParser.MAXITEMS) + self.state = 1031 + self.match(ASLParser.COLON) + self.state = 1032 + self.match(ASLParser.STRINGJSONATA) + pass + + elif la_ == 2: + localctx = ASLParser.Max_items_intContext(self, localctx) + self.enterOuterAlt(localctx, 2) + self.state = 1033 + self.match(ASLParser.MAXITEMS) + self.state = 1034 + self.match(ASLParser.COLON) + self.state = 1035 + self.match(ASLParser.INT) + pass + except RecognitionException as re: localctx.exception = re self._errHandler.reportError(self, re) @@ -13931,7 +22003,7 @@ def csv_header_location_decl(self): self.exitRule() return localctx - class Csv_headers_declContext(ParserRuleContext): + class Max_items_path_declContext(ParserRuleContext): __slots__ = "parser" def __init__( @@ -13940,75 +22012,101 @@ def __init__( super().__init__(parent, invokingState) self.parser = parser - def CSVHEADERS(self): - return self.getToken(ASLParser.CSVHEADERS, 0) + def getRuleIndex(self): + return ASLParser.RULE_max_items_path_decl + + def copyFrom(self, ctx: ParserRuleContext): + super().copyFrom(ctx) + + class Max_items_path_varContext(Max_items_path_declContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Max_items_path_declContext + super().__init__(parser) + self.copyFrom(ctx) + + def MAXITEMSPATH(self): + return self.getToken(ASLParser.MAXITEMSPATH, 0) def COLON(self): return self.getToken(ASLParser.COLON, 0) - def LBRACK(self): - return self.getToken(ASLParser.LBRACK, 0) + def variable_sample(self): + return self.getTypedRuleContext(ASLParser.Variable_sampleContext, 0) - def keyword_or_string(self, i: int = None): - if i is None: - return self.getTypedRuleContexts(ASLParser.Keyword_or_stringContext) - else: - return self.getTypedRuleContext(ASLParser.Keyword_or_stringContext, i) + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterMax_items_path_var"): + listener.enterMax_items_path_var(self) - def RBRACK(self): - return self.getToken(ASLParser.RBRACK, 0) + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitMax_items_path_var"): + listener.exitMax_items_path_var(self) - def COMMA(self, i: int = None): - if i is None: - return self.getTokens(ASLParser.COMMA) + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitMax_items_path_var"): + return visitor.visitMax_items_path_var(self) else: - return self.getToken(ASLParser.COMMA, i) + return visitor.visitChildren(self) - def getRuleIndex(self): - return ASLParser.RULE_csv_headers_decl + class Max_items_pathContext(Max_items_path_declContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Max_items_path_declContext + super().__init__(parser) + self.copyFrom(ctx) + + def MAXITEMSPATH(self): + return self.getToken(ASLParser.MAXITEMSPATH, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def STRINGPATH(self): + return self.getToken(ASLParser.STRINGPATH, 0) def enterRule(self, listener: ParseTreeListener): - if hasattr(listener, "enterCsv_headers_decl"): - listener.enterCsv_headers_decl(self) + if hasattr(listener, "enterMax_items_path"): + listener.enterMax_items_path(self) def exitRule(self, listener: ParseTreeListener): - if hasattr(listener, "exitCsv_headers_decl"): - listener.exitCsv_headers_decl(self) + if hasattr(listener, "exitMax_items_path"): + listener.exitMax_items_path(self) def accept(self, visitor: ParseTreeVisitor): - if hasattr(visitor, "visitCsv_headers_decl"): - return visitor.visitCsv_headers_decl(self) + if hasattr(visitor, "visitMax_items_path"): + return visitor.visitMax_items_path(self) else: return visitor.visitChildren(self) - def csv_headers_decl(self): - localctx = ASLParser.Csv_headers_declContext(self, self._ctx, self.state) - self.enterRule(localctx, 138, self.RULE_csv_headers_decl) - self._la = 0 # Token type + def max_items_path_decl(self): + localctx = ASLParser.Max_items_path_declContext(self, self._ctx, self.state) + self.enterRule(localctx, 180, self.RULE_max_items_path_decl) try: - self.enterOuterAlt(localctx, 1) - self.state = 681 - self.match(ASLParser.CSVHEADERS) - self.state = 682 - self.match(ASLParser.COLON) - self.state = 683 - self.match(ASLParser.LBRACK) - self.state = 684 - self.keyword_or_string() - self.state = 689 + self.state = 1044 self._errHandler.sync(self) - _la = self._input.LA(1) - while _la == 1: - self.state = 685 - self.match(ASLParser.COMMA) - self.state = 686 - self.keyword_or_string() - self.state = 691 - self._errHandler.sync(self) - _la = self._input.LA(1) + la_ = self._interp.adaptivePredict(self._input, 73, self._ctx) + if la_ == 1: + localctx = ASLParser.Max_items_path_varContext(self, localctx) + self.enterOuterAlt(localctx, 1) + self.state = 1038 + self.match(ASLParser.MAXITEMSPATH) + self.state = 1039 + self.match(ASLParser.COLON) + self.state = 1040 + self.variable_sample() + pass + + elif la_ == 2: + localctx = ASLParser.Max_items_pathContext(self, localctx) + self.enterOuterAlt(localctx, 2) + self.state = 1041 + self.match(ASLParser.MAXITEMSPATH) + self.state = 1042 + self.match(ASLParser.COLON) + self.state = 1043 + self.match(ASLParser.STRINGPATH) + pass - self.state = 692 - self.match(ASLParser.RBRACK) except RecognitionException as re: localctx.exception = re self._errHandler.reportError(self, re) @@ -14017,7 +22115,7 @@ def csv_headers_decl(self): self.exitRule() return localctx - class Max_items_declContext(ParserRuleContext): + class Tolerated_failure_count_declContext(ParserRuleContext): __slots__ = "parser" def __init__( @@ -14026,8 +22124,21 @@ def __init__( super().__init__(parent, invokingState) self.parser = parser - def MAXITEMS(self): - return self.getToken(ASLParser.MAXITEMS, 0) + def getRuleIndex(self): + return ASLParser.RULE_tolerated_failure_count_decl + + def copyFrom(self, ctx: ParserRuleContext): + super().copyFrom(ctx) + + class Tolerated_failure_count_intContext(Tolerated_failure_count_declContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Tolerated_failure_count_declContext + super().__init__(parser) + self.copyFrom(ctx) + + def TOLERATEDFAILURECOUNT(self): + return self.getToken(ASLParser.TOLERATEDFAILURECOUNT, 0) def COLON(self): return self.getToken(ASLParser.COLON, 0) @@ -14035,34 +22146,83 @@ def COLON(self): def INT(self): return self.getToken(ASLParser.INT, 0) - def getRuleIndex(self): - return ASLParser.RULE_max_items_decl + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterTolerated_failure_count_int"): + listener.enterTolerated_failure_count_int(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitTolerated_failure_count_int"): + listener.exitTolerated_failure_count_int(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitTolerated_failure_count_int"): + return visitor.visitTolerated_failure_count_int(self) + else: + return visitor.visitChildren(self) + + class Tolerated_failure_count_jsonataContext(Tolerated_failure_count_declContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Tolerated_failure_count_declContext + super().__init__(parser) + self.copyFrom(ctx) + + def TOLERATEDFAILURECOUNT(self): + return self.getToken(ASLParser.TOLERATEDFAILURECOUNT, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def STRINGJSONATA(self): + return self.getToken(ASLParser.STRINGJSONATA, 0) def enterRule(self, listener: ParseTreeListener): - if hasattr(listener, "enterMax_items_decl"): - listener.enterMax_items_decl(self) + if hasattr(listener, "enterTolerated_failure_count_jsonata"): + listener.enterTolerated_failure_count_jsonata(self) def exitRule(self, listener: ParseTreeListener): - if hasattr(listener, "exitMax_items_decl"): - listener.exitMax_items_decl(self) + if hasattr(listener, "exitTolerated_failure_count_jsonata"): + listener.exitTolerated_failure_count_jsonata(self) def accept(self, visitor: ParseTreeVisitor): - if hasattr(visitor, "visitMax_items_decl"): - return visitor.visitMax_items_decl(self) + if hasattr(visitor, "visitTolerated_failure_count_jsonata"): + return visitor.visitTolerated_failure_count_jsonata(self) else: return visitor.visitChildren(self) - def max_items_decl(self): - localctx = ASLParser.Max_items_declContext(self, self._ctx, self.state) - self.enterRule(localctx, 140, self.RULE_max_items_decl) + def tolerated_failure_count_decl(self): + localctx = ASLParser.Tolerated_failure_count_declContext( + self, self._ctx, self.state + ) + self.enterRule(localctx, 182, self.RULE_tolerated_failure_count_decl) try: - self.enterOuterAlt(localctx, 1) - self.state = 694 - self.match(ASLParser.MAXITEMS) - self.state = 695 - self.match(ASLParser.COLON) - self.state = 696 - self.match(ASLParser.INT) + self.state = 1052 + self._errHandler.sync(self) + la_ = self._interp.adaptivePredict(self._input, 74, self._ctx) + if la_ == 1: + localctx = ASLParser.Tolerated_failure_count_jsonataContext( + self, localctx + ) + self.enterOuterAlt(localctx, 1) + self.state = 1046 + self.match(ASLParser.TOLERATEDFAILURECOUNT) + self.state = 1047 + self.match(ASLParser.COLON) + self.state = 1048 + self.match(ASLParser.STRINGJSONATA) + pass + + elif la_ == 2: + localctx = ASLParser.Tolerated_failure_count_intContext(self, localctx) + self.enterOuterAlt(localctx, 2) + self.state = 1049 + self.match(ASLParser.TOLERATEDFAILURECOUNT) + self.state = 1050 + self.match(ASLParser.COLON) + self.state = 1051 + self.match(ASLParser.INT) + pass + except RecognitionException as re: localctx.exception = re self._errHandler.reportError(self, re) @@ -14071,7 +22231,7 @@ def max_items_decl(self): self.exitRule() return localctx - class Max_items_path_declContext(ParserRuleContext): + class Tolerated_failure_count_path_declContext(ParserRuleContext): __slots__ = "parser" def __init__( @@ -14080,8 +22240,53 @@ def __init__( super().__init__(parent, invokingState) self.parser = parser - def MAXITEMSPATH(self): - return self.getToken(ASLParser.MAXITEMSPATH, 0) + def getRuleIndex(self): + return ASLParser.RULE_tolerated_failure_count_path_decl + + def copyFrom(self, ctx: ParserRuleContext): + super().copyFrom(ctx) + + class Tolerated_failure_count_path_varContext( + Tolerated_failure_count_path_declContext + ): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Tolerated_failure_count_path_declContext + super().__init__(parser) + self.copyFrom(ctx) + + def TOLERATEDFAILURECOUNTPATH(self): + return self.getToken(ASLParser.TOLERATEDFAILURECOUNTPATH, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def variable_sample(self): + return self.getTypedRuleContext(ASLParser.Variable_sampleContext, 0) + + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterTolerated_failure_count_path_var"): + listener.enterTolerated_failure_count_path_var(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitTolerated_failure_count_path_var"): + listener.exitTolerated_failure_count_path_var(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitTolerated_failure_count_path_var"): + return visitor.visitTolerated_failure_count_path_var(self) + else: + return visitor.visitChildren(self) + + class Tolerated_failure_count_pathContext(Tolerated_failure_count_path_declContext): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Tolerated_failure_count_path_declContext + super().__init__(parser) + self.copyFrom(ctx) + + def TOLERATEDFAILURECOUNTPATH(self): + return self.getToken(ASLParser.TOLERATEDFAILURECOUNTPATH, 0) def COLON(self): return self.getToken(ASLParser.COLON, 0) @@ -14089,34 +22294,53 @@ def COLON(self): def STRINGPATH(self): return self.getToken(ASLParser.STRINGPATH, 0) - def getRuleIndex(self): - return ASLParser.RULE_max_items_path_decl - def enterRule(self, listener: ParseTreeListener): - if hasattr(listener, "enterMax_items_path_decl"): - listener.enterMax_items_path_decl(self) + if hasattr(listener, "enterTolerated_failure_count_path"): + listener.enterTolerated_failure_count_path(self) def exitRule(self, listener: ParseTreeListener): - if hasattr(listener, "exitMax_items_path_decl"): - listener.exitMax_items_path_decl(self) + if hasattr(listener, "exitTolerated_failure_count_path"): + listener.exitTolerated_failure_count_path(self) def accept(self, visitor: ParseTreeVisitor): - if hasattr(visitor, "visitMax_items_path_decl"): - return visitor.visitMax_items_path_decl(self) + if hasattr(visitor, "visitTolerated_failure_count_path"): + return visitor.visitTolerated_failure_count_path(self) else: return visitor.visitChildren(self) - def max_items_path_decl(self): - localctx = ASLParser.Max_items_path_declContext(self, self._ctx, self.state) - self.enterRule(localctx, 142, self.RULE_max_items_path_decl) + def tolerated_failure_count_path_decl(self): + localctx = ASLParser.Tolerated_failure_count_path_declContext( + self, self._ctx, self.state + ) + self.enterRule(localctx, 184, self.RULE_tolerated_failure_count_path_decl) try: - self.enterOuterAlt(localctx, 1) - self.state = 698 - self.match(ASLParser.MAXITEMSPATH) - self.state = 699 - self.match(ASLParser.COLON) - self.state = 700 - self.match(ASLParser.STRINGPATH) + self.state = 1060 + self._errHandler.sync(self) + la_ = self._interp.adaptivePredict(self._input, 75, self._ctx) + if la_ == 1: + localctx = ASLParser.Tolerated_failure_count_path_varContext( + self, localctx + ) + self.enterOuterAlt(localctx, 1) + self.state = 1054 + self.match(ASLParser.TOLERATEDFAILURECOUNTPATH) + self.state = 1055 + self.match(ASLParser.COLON) + self.state = 1056 + self.variable_sample() + pass + + elif la_ == 2: + localctx = ASLParser.Tolerated_failure_count_pathContext(self, localctx) + self.enterOuterAlt(localctx, 2) + self.state = 1057 + self.match(ASLParser.TOLERATEDFAILURECOUNTPATH) + self.state = 1058 + self.match(ASLParser.COLON) + self.state = 1059 + self.match(ASLParser.STRINGPATH) + pass + except RecognitionException as re: localctx.exception = re self._errHandler.reportError(self, re) @@ -14125,7 +22349,7 @@ def max_items_path_decl(self): self.exitRule() return localctx - class Tolerated_failure_count_declContext(ParserRuleContext): + class Tolerated_failure_percentage_declContext(ParserRuleContext): __slots__ = "parser" def __init__( @@ -14134,45 +22358,111 @@ def __init__( super().__init__(parent, invokingState) self.parser = parser - def TOLERATEDFAILURECOUNT(self): - return self.getToken(ASLParser.TOLERATEDFAILURECOUNT, 0) + def getRuleIndex(self): + return ASLParser.RULE_tolerated_failure_percentage_decl + + def copyFrom(self, ctx: ParserRuleContext): + super().copyFrom(ctx) + + class Tolerated_failure_percentage_jsonataContext( + Tolerated_failure_percentage_declContext + ): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Tolerated_failure_percentage_declContext + super().__init__(parser) + self.copyFrom(ctx) + + def TOLERATEDFAILUREPERCENTAGE(self): + return self.getToken(ASLParser.TOLERATEDFAILUREPERCENTAGE, 0) def COLON(self): return self.getToken(ASLParser.COLON, 0) - def INT(self): - return self.getToken(ASLParser.INT, 0) + def STRINGJSONATA(self): + return self.getToken(ASLParser.STRINGJSONATA, 0) - def getRuleIndex(self): - return ASLParser.RULE_tolerated_failure_count_decl + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterTolerated_failure_percentage_jsonata"): + listener.enterTolerated_failure_percentage_jsonata(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitTolerated_failure_percentage_jsonata"): + listener.exitTolerated_failure_percentage_jsonata(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitTolerated_failure_percentage_jsonata"): + return visitor.visitTolerated_failure_percentage_jsonata(self) + else: + return visitor.visitChildren(self) + + class Tolerated_failure_percentage_numberContext( + Tolerated_failure_percentage_declContext + ): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Tolerated_failure_percentage_declContext + super().__init__(parser) + self.copyFrom(ctx) + + def TOLERATEDFAILUREPERCENTAGE(self): + return self.getToken(ASLParser.TOLERATEDFAILUREPERCENTAGE, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def NUMBER(self): + return self.getToken(ASLParser.NUMBER, 0) def enterRule(self, listener: ParseTreeListener): - if hasattr(listener, "enterTolerated_failure_count_decl"): - listener.enterTolerated_failure_count_decl(self) + if hasattr(listener, "enterTolerated_failure_percentage_number"): + listener.enterTolerated_failure_percentage_number(self) def exitRule(self, listener: ParseTreeListener): - if hasattr(listener, "exitTolerated_failure_count_decl"): - listener.exitTolerated_failure_count_decl(self) + if hasattr(listener, "exitTolerated_failure_percentage_number"): + listener.exitTolerated_failure_percentage_number(self) def accept(self, visitor: ParseTreeVisitor): - if hasattr(visitor, "visitTolerated_failure_count_decl"): - return visitor.visitTolerated_failure_count_decl(self) + if hasattr(visitor, "visitTolerated_failure_percentage_number"): + return visitor.visitTolerated_failure_percentage_number(self) else: return visitor.visitChildren(self) - def tolerated_failure_count_decl(self): - localctx = ASLParser.Tolerated_failure_count_declContext( + def tolerated_failure_percentage_decl(self): + localctx = ASLParser.Tolerated_failure_percentage_declContext( self, self._ctx, self.state ) - self.enterRule(localctx, 144, self.RULE_tolerated_failure_count_decl) + self.enterRule(localctx, 186, self.RULE_tolerated_failure_percentage_decl) try: - self.enterOuterAlt(localctx, 1) - self.state = 702 - self.match(ASLParser.TOLERATEDFAILURECOUNT) - self.state = 703 - self.match(ASLParser.COLON) - self.state = 704 - self.match(ASLParser.INT) + self.state = 1068 + self._errHandler.sync(self) + la_ = self._interp.adaptivePredict(self._input, 76, self._ctx) + if la_ == 1: + localctx = ASLParser.Tolerated_failure_percentage_jsonataContext( + self, localctx + ) + self.enterOuterAlt(localctx, 1) + self.state = 1062 + self.match(ASLParser.TOLERATEDFAILUREPERCENTAGE) + self.state = 1063 + self.match(ASLParser.COLON) + self.state = 1064 + self.match(ASLParser.STRINGJSONATA) + pass + + elif la_ == 2: + localctx = ASLParser.Tolerated_failure_percentage_numberContext( + self, localctx + ) + self.enterOuterAlt(localctx, 2) + self.state = 1065 + self.match(ASLParser.TOLERATEDFAILUREPERCENTAGE) + self.state = 1066 + self.match(ASLParser.COLON) + self.state = 1067 + self.match(ASLParser.NUMBER) + pass + except RecognitionException as re: localctx.exception = re self._errHandler.reportError(self, re) @@ -14181,7 +22471,7 @@ def tolerated_failure_count_decl(self): self.exitRule() return localctx - class Tolerated_failure_count_path_declContext(ParserRuleContext): + class Tolerated_failure_percentage_path_declContext(ParserRuleContext): __slots__ = "parser" def __init__( @@ -14190,8 +22480,23 @@ def __init__( super().__init__(parent, invokingState) self.parser = parser - def TOLERATEDFAILURECOUNTPATH(self): - return self.getToken(ASLParser.TOLERATEDFAILURECOUNTPATH, 0) + def getRuleIndex(self): + return ASLParser.RULE_tolerated_failure_percentage_path_decl + + def copyFrom(self, ctx: ParserRuleContext): + super().copyFrom(ctx) + + class Tolerated_failure_percentage_pathContext( + Tolerated_failure_percentage_path_declContext + ): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Tolerated_failure_percentage_path_declContext + super().__init__(parser) + self.copyFrom(ctx) + + def TOLERATEDFAILUREPERCENTAGEPATH(self): + return self.getToken(ASLParser.TOLERATEDFAILUREPERCENTAGEPATH, 0) def COLON(self): return self.getToken(ASLParser.COLON, 0) @@ -14199,36 +22504,87 @@ def COLON(self): def STRINGPATH(self): return self.getToken(ASLParser.STRINGPATH, 0) - def getRuleIndex(self): - return ASLParser.RULE_tolerated_failure_count_path_decl + def enterRule(self, listener: ParseTreeListener): + if hasattr(listener, "enterTolerated_failure_percentage_path"): + listener.enterTolerated_failure_percentage_path(self) + + def exitRule(self, listener: ParseTreeListener): + if hasattr(listener, "exitTolerated_failure_percentage_path"): + listener.exitTolerated_failure_percentage_path(self) + + def accept(self, visitor: ParseTreeVisitor): + if hasattr(visitor, "visitTolerated_failure_percentage_path"): + return visitor.visitTolerated_failure_percentage_path(self) + else: + return visitor.visitChildren(self) + + class Tolerated_failure_percentage_path_varContext( + Tolerated_failure_percentage_path_declContext + ): + def __init__( + self, parser, ctx: ParserRuleContext + ): # actually a ASLParser.Tolerated_failure_percentage_path_declContext + super().__init__(parser) + self.copyFrom(ctx) + + def TOLERATEDFAILUREPERCENTAGEPATH(self): + return self.getToken(ASLParser.TOLERATEDFAILUREPERCENTAGEPATH, 0) + + def COLON(self): + return self.getToken(ASLParser.COLON, 0) + + def variable_sample(self): + return self.getTypedRuleContext(ASLParser.Variable_sampleContext, 0) def enterRule(self, listener: ParseTreeListener): - if hasattr(listener, "enterTolerated_failure_count_path_decl"): - listener.enterTolerated_failure_count_path_decl(self) + if hasattr(listener, "enterTolerated_failure_percentage_path_var"): + listener.enterTolerated_failure_percentage_path_var(self) def exitRule(self, listener: ParseTreeListener): - if hasattr(listener, "exitTolerated_failure_count_path_decl"): - listener.exitTolerated_failure_count_path_decl(self) + if hasattr(listener, "exitTolerated_failure_percentage_path_var"): + listener.exitTolerated_failure_percentage_path_var(self) def accept(self, visitor: ParseTreeVisitor): - if hasattr(visitor, "visitTolerated_failure_count_path_decl"): - return visitor.visitTolerated_failure_count_path_decl(self) + if hasattr(visitor, "visitTolerated_failure_percentage_path_var"): + return visitor.visitTolerated_failure_percentage_path_var(self) else: return visitor.visitChildren(self) - def tolerated_failure_count_path_decl(self): - localctx = ASLParser.Tolerated_failure_count_path_declContext( + def tolerated_failure_percentage_path_decl(self): + localctx = ASLParser.Tolerated_failure_percentage_path_declContext( self, self._ctx, self.state ) - self.enterRule(localctx, 146, self.RULE_tolerated_failure_count_path_decl) + self.enterRule(localctx, 188, self.RULE_tolerated_failure_percentage_path_decl) try: - self.enterOuterAlt(localctx, 1) - self.state = 706 - self.match(ASLParser.TOLERATEDFAILURECOUNTPATH) - self.state = 707 - self.match(ASLParser.COLON) - self.state = 708 - self.match(ASLParser.STRINGPATH) + self.state = 1076 + self._errHandler.sync(self) + la_ = self._interp.adaptivePredict(self._input, 77, self._ctx) + if la_ == 1: + localctx = ASLParser.Tolerated_failure_percentage_path_varContext( + self, localctx + ) + self.enterOuterAlt(localctx, 1) + self.state = 1070 + self.match(ASLParser.TOLERATEDFAILUREPERCENTAGEPATH) + self.state = 1071 + self.match(ASLParser.COLON) + self.state = 1072 + self.variable_sample() + pass + + elif la_ == 2: + localctx = ASLParser.Tolerated_failure_percentage_pathContext( + self, localctx + ) + self.enterOuterAlt(localctx, 2) + self.state = 1073 + self.match(ASLParser.TOLERATEDFAILUREPERCENTAGEPATH) + self.state = 1074 + self.match(ASLParser.COLON) + self.state = 1075 + self.match(ASLParser.STRINGPATH) + pass + except RecognitionException as re: localctx.exception = re self._errHandler.reportError(self, re) @@ -14237,7 +22593,7 @@ def tolerated_failure_count_path_decl(self): self.exitRule() return localctx - class Tolerated_failure_percentage_declContext(ParserRuleContext): + class Label_declContext(ParserRuleContext): __slots__ = "parser" def __init__( @@ -14246,45 +22602,43 @@ def __init__( super().__init__(parent, invokingState) self.parser = parser - def TOLERATEDFAILUREPERCENTAGE(self): - return self.getToken(ASLParser.TOLERATEDFAILUREPERCENTAGE, 0) + def LABEL(self): + return self.getToken(ASLParser.LABEL, 0) def COLON(self): return self.getToken(ASLParser.COLON, 0) - def NUMBER(self): - return self.getToken(ASLParser.NUMBER, 0) + def keyword_or_string(self): + return self.getTypedRuleContext(ASLParser.Keyword_or_stringContext, 0) def getRuleIndex(self): - return ASLParser.RULE_tolerated_failure_percentage_decl + return ASLParser.RULE_label_decl def enterRule(self, listener: ParseTreeListener): - if hasattr(listener, "enterTolerated_failure_percentage_decl"): - listener.enterTolerated_failure_percentage_decl(self) + if hasattr(listener, "enterLabel_decl"): + listener.enterLabel_decl(self) def exitRule(self, listener: ParseTreeListener): - if hasattr(listener, "exitTolerated_failure_percentage_decl"): - listener.exitTolerated_failure_percentage_decl(self) + if hasattr(listener, "exitLabel_decl"): + listener.exitLabel_decl(self) def accept(self, visitor: ParseTreeVisitor): - if hasattr(visitor, "visitTolerated_failure_percentage_decl"): - return visitor.visitTolerated_failure_percentage_decl(self) + if hasattr(visitor, "visitLabel_decl"): + return visitor.visitLabel_decl(self) else: return visitor.visitChildren(self) - def tolerated_failure_percentage_decl(self): - localctx = ASLParser.Tolerated_failure_percentage_declContext( - self, self._ctx, self.state - ) - self.enterRule(localctx, 148, self.RULE_tolerated_failure_percentage_decl) + def label_decl(self): + localctx = ASLParser.Label_declContext(self, self._ctx, self.state) + self.enterRule(localctx, 190, self.RULE_label_decl) try: self.enterOuterAlt(localctx, 1) - self.state = 710 - self.match(ASLParser.TOLERATEDFAILUREPERCENTAGE) - self.state = 711 + self.state = 1078 + self.match(ASLParser.LABEL) + self.state = 1079 self.match(ASLParser.COLON) - self.state = 712 - self.match(ASLParser.NUMBER) + self.state = 1080 + self.keyword_or_string() except RecognitionException as re: localctx.exception = re self._errHandler.reportError(self, re) @@ -14293,7 +22647,7 @@ def tolerated_failure_percentage_decl(self): self.exitRule() return localctx - class Tolerated_failure_percentage_path_declContext(ParserRuleContext): + class Result_writer_declContext(ParserRuleContext): __slots__ = "parser" def __init__( @@ -14302,45 +22656,75 @@ def __init__( super().__init__(parent, invokingState) self.parser = parser - def TOLERATEDFAILUREPERCENTAGEPATH(self): - return self.getToken(ASLParser.TOLERATEDFAILUREPERCENTAGEPATH, 0) + def RESULTWRITER(self): + return self.getToken(ASLParser.RESULTWRITER, 0) def COLON(self): return self.getToken(ASLParser.COLON, 0) - def STRINGPATH(self): - return self.getToken(ASLParser.STRINGPATH, 0) + def LBRACE(self): + return self.getToken(ASLParser.LBRACE, 0) + + def result_writer_field(self, i: int = None): + if i is None: + return self.getTypedRuleContexts(ASLParser.Result_writer_fieldContext) + else: + return self.getTypedRuleContext(ASLParser.Result_writer_fieldContext, i) + + def RBRACE(self): + return self.getToken(ASLParser.RBRACE, 0) + + def COMMA(self, i: int = None): + if i is None: + return self.getTokens(ASLParser.COMMA) + else: + return self.getToken(ASLParser.COMMA, i) def getRuleIndex(self): - return ASLParser.RULE_tolerated_failure_percentage_path_decl + return ASLParser.RULE_result_writer_decl def enterRule(self, listener: ParseTreeListener): - if hasattr(listener, "enterTolerated_failure_percentage_path_decl"): - listener.enterTolerated_failure_percentage_path_decl(self) + if hasattr(listener, "enterResult_writer_decl"): + listener.enterResult_writer_decl(self) def exitRule(self, listener: ParseTreeListener): - if hasattr(listener, "exitTolerated_failure_percentage_path_decl"): - listener.exitTolerated_failure_percentage_path_decl(self) + if hasattr(listener, "exitResult_writer_decl"): + listener.exitResult_writer_decl(self) def accept(self, visitor: ParseTreeVisitor): - if hasattr(visitor, "visitTolerated_failure_percentage_path_decl"): - return visitor.visitTolerated_failure_percentage_path_decl(self) + if hasattr(visitor, "visitResult_writer_decl"): + return visitor.visitResult_writer_decl(self) else: return visitor.visitChildren(self) - def tolerated_failure_percentage_path_decl(self): - localctx = ASLParser.Tolerated_failure_percentage_path_declContext( - self, self._ctx, self.state - ) - self.enterRule(localctx, 150, self.RULE_tolerated_failure_percentage_path_decl) + def result_writer_decl(self): + localctx = ASLParser.Result_writer_declContext(self, self._ctx, self.state) + self.enterRule(localctx, 192, self.RULE_result_writer_decl) + self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 714 - self.match(ASLParser.TOLERATEDFAILUREPERCENTAGEPATH) - self.state = 715 + self.state = 1082 + self.match(ASLParser.RESULTWRITER) + self.state = 1083 self.match(ASLParser.COLON) - self.state = 716 - self.match(ASLParser.STRINGPATH) + self.state = 1084 + self.match(ASLParser.LBRACE) + self.state = 1085 + self.result_writer_field() + self.state = 1090 + self._errHandler.sync(self) + _la = self._input.LA(1) + while _la == 1: + self.state = 1086 + self.match(ASLParser.COMMA) + self.state = 1087 + self.result_writer_field() + self.state = 1092 + self._errHandler.sync(self) + _la = self._input.LA(1) + + self.state = 1093 + self.match(ASLParser.RBRACE) except RecognitionException as re: localctx.exception = re self._errHandler.reportError(self, re) @@ -14349,7 +22733,7 @@ def tolerated_failure_percentage_path_decl(self): self.exitRule() return localctx - class Label_declContext(ParserRuleContext): + class Result_writer_fieldContext(ParserRuleContext): __slots__ = "parser" def __init__( @@ -14358,43 +22742,49 @@ def __init__( super().__init__(parent, invokingState) self.parser = parser - def LABEL(self): - return self.getToken(ASLParser.LABEL, 0) - - def COLON(self): - return self.getToken(ASLParser.COLON, 0) + def resource_decl(self): + return self.getTypedRuleContext(ASLParser.Resource_declContext, 0) - def keyword_or_string(self): - return self.getTypedRuleContext(ASLParser.Keyword_or_stringContext, 0) + def parameters_decl(self): + return self.getTypedRuleContext(ASLParser.Parameters_declContext, 0) def getRuleIndex(self): - return ASLParser.RULE_label_decl + return ASLParser.RULE_result_writer_field def enterRule(self, listener: ParseTreeListener): - if hasattr(listener, "enterLabel_decl"): - listener.enterLabel_decl(self) + if hasattr(listener, "enterResult_writer_field"): + listener.enterResult_writer_field(self) def exitRule(self, listener: ParseTreeListener): - if hasattr(listener, "exitLabel_decl"): - listener.exitLabel_decl(self) + if hasattr(listener, "exitResult_writer_field"): + listener.exitResult_writer_field(self) def accept(self, visitor: ParseTreeVisitor): - if hasattr(visitor, "visitLabel_decl"): - return visitor.visitLabel_decl(self) + if hasattr(visitor, "visitResult_writer_field"): + return visitor.visitResult_writer_field(self) else: return visitor.visitChildren(self) - def label_decl(self): - localctx = ASLParser.Label_declContext(self, self._ctx, self.state) - self.enterRule(localctx, 152, self.RULE_label_decl) + def result_writer_field(self): + localctx = ASLParser.Result_writer_fieldContext(self, self._ctx, self.state) + self.enterRule(localctx, 194, self.RULE_result_writer_field) try: - self.enterOuterAlt(localctx, 1) - self.state = 718 - self.match(ASLParser.LABEL) - self.state = 719 - self.match(ASLParser.COLON) - self.state = 720 - self.keyword_or_string() + self.state = 1097 + self._errHandler.sync(self) + token = self._input.LA(1) + if token in [90]: + self.enterOuterAlt(localctx, 1) + self.state = 1095 + self.resource_decl() + pass + elif token in [97]: + self.enterOuterAlt(localctx, 2) + self.state = 1096 + self.parameters_decl() + pass + else: + raise NoViableAltException(self) + except RecognitionException as re: localctx.exception = re self._errHandler.reportError(self, re) @@ -14455,35 +22845,35 @@ def accept(self, visitor: ParseTreeVisitor): def retry_decl(self): localctx = ASLParser.Retry_declContext(self, self._ctx, self.state) - self.enterRule(localctx, 154, self.RULE_retry_decl) + self.enterRule(localctx, 196, self.RULE_retry_decl) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 722 + self.state = 1099 self.match(ASLParser.RETRY) - self.state = 723 + self.state = 1100 self.match(ASLParser.COLON) - self.state = 724 + self.state = 1101 self.match(ASLParser.LBRACK) - self.state = 733 + self.state = 1110 self._errHandler.sync(self) _la = self._input.LA(1) if _la == 5: - self.state = 725 + self.state = 1102 self.retrier_decl() - self.state = 730 + self.state = 1107 self._errHandler.sync(self) _la = self._input.LA(1) while _la == 1: - self.state = 726 + self.state = 1103 self.match(ASLParser.COMMA) - self.state = 727 + self.state = 1104 self.retrier_decl() - self.state = 732 + self.state = 1109 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 735 + self.state = 1112 self.match(ASLParser.RBRACK) except RecognitionException as re: localctx.exception = re @@ -14539,27 +22929,27 @@ def accept(self, visitor: ParseTreeVisitor): def retrier_decl(self): localctx = ASLParser.Retrier_declContext(self, self._ctx, self.state) - self.enterRule(localctx, 156, self.RULE_retrier_decl) + self.enterRule(localctx, 198, self.RULE_retrier_decl) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 737 + self.state = 1114 self.match(ASLParser.LBRACE) - self.state = 738 + self.state = 1115 self.retrier_stmt() - self.state = 743 + self.state = 1120 self._errHandler.sync(self) _la = self._input.LA(1) while _la == 1: - self.state = 739 + self.state = 1116 self.match(ASLParser.COMMA) - self.state = 740 + self.state = 1117 self.retrier_stmt() - self.state = 745 + self.state = 1122 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 746 + self.state = 1123 self.match(ASLParser.RBRACE) except RecognitionException as re: localctx.exception = re @@ -14618,44 +23008,44 @@ def accept(self, visitor: ParseTreeVisitor): def retrier_stmt(self): localctx = ASLParser.Retrier_stmtContext(self, self._ctx, self.state) - self.enterRule(localctx, 158, self.RULE_retrier_stmt) + self.enterRule(localctx, 200, self.RULE_retrier_stmt) try: - self.state = 755 + self.state = 1132 self._errHandler.sync(self) token = self._input.LA(1) - if token in [116]: + if token in [122]: self.enterOuterAlt(localctx, 1) - self.state = 748 + self.state = 1125 self.error_equals_decl() pass - elif token in [117]: + elif token in [123]: self.enterOuterAlt(localctx, 2) - self.state = 749 + self.state = 1126 self.interval_seconds_decl() pass - elif token in [118]: + elif token in [124]: self.enterOuterAlt(localctx, 3) - self.state = 750 + self.state = 1127 self.max_attempts_decl() pass - elif token in [119]: + elif token in [125]: self.enterOuterAlt(localctx, 4) - self.state = 751 + self.state = 1128 self.backoff_rate_decl() pass - elif token in [120]: + elif token in [126]: self.enterOuterAlt(localctx, 5) - self.state = 752 + self.state = 1129 self.max_delay_seconds_decl() pass - elif token in [121]: + elif token in [127]: self.enterOuterAlt(localctx, 6) - self.state = 753 + self.state = 1130 self.jitter_strategy_decl() pass elif token in [10]: self.enterOuterAlt(localctx, 7) - self.state = 754 + self.state = 1131 self.comment_decl() pass else: @@ -14721,31 +23111,31 @@ def accept(self, visitor: ParseTreeVisitor): def error_equals_decl(self): localctx = ASLParser.Error_equals_declContext(self, self._ctx, self.state) - self.enterRule(localctx, 160, self.RULE_error_equals_decl) + self.enterRule(localctx, 202, self.RULE_error_equals_decl) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 757 + self.state = 1134 self.match(ASLParser.ERROREQUALS) - self.state = 758 + self.state = 1135 self.match(ASLParser.COLON) - self.state = 759 + self.state = 1136 self.match(ASLParser.LBRACK) - self.state = 760 + self.state = 1137 self.error_name() - self.state = 765 + self.state = 1142 self._errHandler.sync(self) _la = self._input.LA(1) while _la == 1: - self.state = 761 + self.state = 1138 self.match(ASLParser.COMMA) - self.state = 762 + self.state = 1139 self.error_name() - self.state = 767 + self.state = 1144 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 768 + self.state = 1145 self.match(ASLParser.RBRACK) except RecognitionException as re: localctx.exception = re @@ -14792,14 +23182,14 @@ def accept(self, visitor: ParseTreeVisitor): def interval_seconds_decl(self): localctx = ASLParser.Interval_seconds_declContext(self, self._ctx, self.state) - self.enterRule(localctx, 162, self.RULE_interval_seconds_decl) + self.enterRule(localctx, 204, self.RULE_interval_seconds_decl) try: self.enterOuterAlt(localctx, 1) - self.state = 770 + self.state = 1147 self.match(ASLParser.INTERVALSECONDS) - self.state = 771 + self.state = 1148 self.match(ASLParser.COLON) - self.state = 772 + self.state = 1149 self.match(ASLParser.INT) except RecognitionException as re: localctx.exception = re @@ -14846,14 +23236,14 @@ def accept(self, visitor: ParseTreeVisitor): def max_attempts_decl(self): localctx = ASLParser.Max_attempts_declContext(self, self._ctx, self.state) - self.enterRule(localctx, 164, self.RULE_max_attempts_decl) + self.enterRule(localctx, 206, self.RULE_max_attempts_decl) try: self.enterOuterAlt(localctx, 1) - self.state = 774 + self.state = 1151 self.match(ASLParser.MAXATTEMPTS) - self.state = 775 + self.state = 1152 self.match(ASLParser.COLON) - self.state = 776 + self.state = 1153 self.match(ASLParser.INT) except RecognitionException as re: localctx.exception = re @@ -14903,17 +23293,17 @@ def accept(self, visitor: ParseTreeVisitor): def backoff_rate_decl(self): localctx = ASLParser.Backoff_rate_declContext(self, self._ctx, self.state) - self.enterRule(localctx, 166, self.RULE_backoff_rate_decl) + self.enterRule(localctx, 208, self.RULE_backoff_rate_decl) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 778 + self.state = 1155 self.match(ASLParser.BACKOFFRATE) - self.state = 779 + self.state = 1156 self.match(ASLParser.COLON) - self.state = 780 + self.state = 1157 _la = self._input.LA(1) - if not (_la == 144 or _la == 145): + if not (_la == 160 or _la == 161): self._errHandler.recoverInline(self) else: self._errHandler.reportMatch(self) @@ -14963,14 +23353,14 @@ def accept(self, visitor: ParseTreeVisitor): def max_delay_seconds_decl(self): localctx = ASLParser.Max_delay_seconds_declContext(self, self._ctx, self.state) - self.enterRule(localctx, 168, self.RULE_max_delay_seconds_decl) + self.enterRule(localctx, 210, self.RULE_max_delay_seconds_decl) try: self.enterOuterAlt(localctx, 1) - self.state = 782 + self.state = 1159 self.match(ASLParser.MAXDELAYSECONDS) - self.state = 783 + self.state = 1160 self.match(ASLParser.COLON) - self.state = 784 + self.state = 1161 self.match(ASLParser.INT) except RecognitionException as re: localctx.exception = re @@ -15020,17 +23410,17 @@ def accept(self, visitor: ParseTreeVisitor): def jitter_strategy_decl(self): localctx = ASLParser.Jitter_strategy_declContext(self, self._ctx, self.state) - self.enterRule(localctx, 170, self.RULE_jitter_strategy_decl) + self.enterRule(localctx, 212, self.RULE_jitter_strategy_decl) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 786 + self.state = 1163 self.match(ASLParser.JITTERSTRATEGY) - self.state = 787 + self.state = 1164 self.match(ASLParser.COLON) - self.state = 788 + self.state = 1165 _la = self._input.LA(1) - if not (_la == 122 or _la == 123): + if not (_la == 128 or _la == 129): self._errHandler.recoverInline(self) else: self._errHandler.reportMatch(self) @@ -15095,35 +23485,35 @@ def accept(self, visitor: ParseTreeVisitor): def catch_decl(self): localctx = ASLParser.Catch_declContext(self, self._ctx, self.state) - self.enterRule(localctx, 172, self.RULE_catch_decl) + self.enterRule(localctx, 214, self.RULE_catch_decl) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 790 + self.state = 1167 self.match(ASLParser.CATCH) - self.state = 791 + self.state = 1168 self.match(ASLParser.COLON) - self.state = 792 + self.state = 1169 self.match(ASLParser.LBRACK) - self.state = 801 + self.state = 1178 self._errHandler.sync(self) _la = self._input.LA(1) if _la == 5: - self.state = 793 + self.state = 1170 self.catcher_decl() - self.state = 798 + self.state = 1175 self._errHandler.sync(self) _la = self._input.LA(1) while _la == 1: - self.state = 794 + self.state = 1171 self.match(ASLParser.COMMA) - self.state = 795 + self.state = 1172 self.catcher_decl() - self.state = 800 + self.state = 1177 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 803 + self.state = 1180 self.match(ASLParser.RBRACK) except RecognitionException as re: localctx.exception = re @@ -15179,27 +23569,27 @@ def accept(self, visitor: ParseTreeVisitor): def catcher_decl(self): localctx = ASLParser.Catcher_declContext(self, self._ctx, self.state) - self.enterRule(localctx, 174, self.RULE_catcher_decl) + self.enterRule(localctx, 216, self.RULE_catcher_decl) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 805 + self.state = 1182 self.match(ASLParser.LBRACE) - self.state = 806 + self.state = 1183 self.catcher_stmt() - self.state = 811 + self.state = 1188 self._errHandler.sync(self) _la = self._input.LA(1) while _la == 1: - self.state = 807 + self.state = 1184 self.match(ASLParser.COMMA) - self.state = 808 + self.state = 1185 self.catcher_stmt() - self.state = 813 + self.state = 1190 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 814 + self.state = 1191 self.match(ASLParser.RBRACE) except RecognitionException as re: localctx.exception = re @@ -15227,6 +23617,12 @@ def result_path_decl(self): def next_decl(self): return self.getTypedRuleContext(ASLParser.Next_declContext, 0) + def assign_decl(self): + return self.getTypedRuleContext(ASLParser.Assign_declContext, 0) + + def output_decl(self): + return self.getTypedRuleContext(ASLParser.Output_declContext, 0) + def comment_decl(self): return self.getTypedRuleContext(ASLParser.Comment_declContext, 0) @@ -15249,29 +23645,39 @@ def accept(self, visitor: ParseTreeVisitor): def catcher_stmt(self): localctx = ASLParser.Catcher_stmtContext(self, self._ctx, self.state) - self.enterRule(localctx, 176, self.RULE_catcher_stmt) + self.enterRule(localctx, 218, self.RULE_catcher_stmt) try: - self.state = 820 + self.state = 1199 self._errHandler.sync(self) token = self._input.LA(1) - if token in [116]: + if token in [122]: self.enterOuterAlt(localctx, 1) - self.state = 816 + self.state = 1193 self.error_equals_decl() pass - elif token in [93]: + elif token in [95]: self.enterOuterAlt(localctx, 2) - self.state = 817 + self.state = 1194 self.result_path_decl() pass - elif token in [109]: + elif token in [115]: self.enterOuterAlt(localctx, 3) - self.state = 818 + self.state = 1195 self.next_decl() pass - elif token in [10]: + elif token in [134]: self.enterOuterAlt(localctx, 4) - self.state = 819 + self.state = 1196 + self.assign_decl() + pass + elif token in [135]: + self.enterOuterAlt(localctx, 5) + self.state = 1197 + self.output_decl() + pass + elif token in [10]: + self.enterOuterAlt(localctx, 6) + self.state = 1198 self.comment_decl() pass else: @@ -15430,14 +23836,14 @@ def accept(self, visitor: ParseTreeVisitor): def comparison_op(self): localctx = ASLParser.Comparison_opContext(self, self._ctx, self.state) - self.enterRule(localctx, 178, self.RULE_comparison_op) + self.enterRule(localctx, 220, self.RULE_comparison_op) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 822 + self.state = 1201 _la = self._input.LA(1) if not ( - ((_la - 29) & ~0x3F) == 0 and ((1 << (_la - 29)) & 2199022731007) != 0 + ((_la - 30) & ~0x3F) == 0 and ((1 << (_la - 30)) & 2199022731007) != 0 ): self._errHandler.recoverInline(self) else: @@ -15488,13 +23894,13 @@ def accept(self, visitor: ParseTreeVisitor): def choice_operator(self): localctx = ASLParser.Choice_operatorContext(self, self._ctx, self.state) - self.enterRule(localctx, 180, self.RULE_choice_operator) + self.enterRule(localctx, 222, self.RULE_choice_operator) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 824 + self.state = 1203 _la = self._input.LA(1) - if not (((_la) & ~0x3F) == 0 and ((1 << _la) & 281612684099584) != 0): + if not (((_la) & ~0x3F) == 0 and ((1 << _la) & 563225368199168) != 0): self._errHandler.recoverInline(self) else: self._errHandler.reportMatch(self) @@ -15563,6 +23969,9 @@ def ERRORNAMEStatesResultWriterFailed(self): def ERRORNAMEStatesRuntime(self): return self.getToken(ASLParser.ERRORNAMEStatesRuntime, 0) + def ERRORNAMEStatesQueryEvaluationError(self): + return self.getToken(ASLParser.ERRORNAMEStatesQueryEvaluationError, 0) + def getRuleIndex(self): return ASLParser.RULE_states_error_name @@ -15582,13 +23991,13 @@ def accept(self, visitor: ParseTreeVisitor): def states_error_name(self): localctx = ASLParser.States_error_nameContext(self, self._ctx, self.state) - self.enterRule(localctx, 182, self.RULE_states_error_name) + self.enterRule(localctx, 224, self.RULE_states_error_name) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 826 + self.state = 1205 _la = self._input.LA(1) - if not (((_la - 125) & ~0x3F) == 0 and ((1 << (_la - 125)) & 32767) != 0): + if not (((_la - 137) & ~0x3F) == 0 and ((1 << (_la - 137)) & 65535) != 0): self._errHandler.recoverInline(self) else: self._errHandler.reportMatch(self) @@ -15635,20 +24044,20 @@ def accept(self, visitor: ParseTreeVisitor): def error_name(self): localctx = ASLParser.Error_nameContext(self, self._ctx, self.state) - self.enterRule(localctx, 184, self.RULE_error_name) + self.enterRule(localctx, 226, self.RULE_error_name) try: - self.state = 830 + self.state = 1209 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input, 46, self._ctx) + la_ = self._interp.adaptivePredict(self._input, 89, self._ctx) if la_ == 1: self.enterOuterAlt(localctx, 1) - self.state = 828 + self.state = 1207 self.states_error_name() pass elif la_ == 2: self.enterOuterAlt(localctx, 2) - self.state = 829 + self.state = 1208 self.keyword_or_string() pass @@ -15706,39 +24115,39 @@ def accept(self, visitor: ParseTreeVisitor): def json_obj_decl(self): localctx = ASLParser.Json_obj_declContext(self, self._ctx, self.state) - self.enterRule(localctx, 186, self.RULE_json_obj_decl) + self.enterRule(localctx, 228, self.RULE_json_obj_decl) self._la = 0 # Token type try: - self.state = 845 + self.state = 1224 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input, 48, self._ctx) + la_ = self._interp.adaptivePredict(self._input, 91, self._ctx) if la_ == 1: self.enterOuterAlt(localctx, 1) - self.state = 832 + self.state = 1211 self.match(ASLParser.LBRACE) - self.state = 833 + self.state = 1212 self.json_binding() - self.state = 838 + self.state = 1217 self._errHandler.sync(self) _la = self._input.LA(1) while _la == 1: - self.state = 834 + self.state = 1213 self.match(ASLParser.COMMA) - self.state = 835 + self.state = 1214 self.json_binding() - self.state = 840 + self.state = 1219 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 841 + self.state = 1220 self.match(ASLParser.RBRACE) pass elif la_ == 2: self.enterOuterAlt(localctx, 2) - self.state = 843 + self.state = 1222 self.match(ASLParser.LBRACE) - self.state = 844 + self.state = 1223 self.match(ASLParser.RBRACE) pass @@ -15787,14 +24196,14 @@ def accept(self, visitor: ParseTreeVisitor): def json_binding(self): localctx = ASLParser.Json_bindingContext(self, self._ctx, self.state) - self.enterRule(localctx, 188, self.RULE_json_binding) + self.enterRule(localctx, 230, self.RULE_json_binding) try: self.enterOuterAlt(localctx, 1) - self.state = 847 + self.state = 1226 self.keyword_or_string() - self.state = 848 + self.state = 1227 self.match(ASLParser.COLON) - self.state = 849 + self.state = 1228 self.json_value_decl() except RecognitionException as re: localctx.exception = re @@ -15850,39 +24259,39 @@ def accept(self, visitor: ParseTreeVisitor): def json_arr_decl(self): localctx = ASLParser.Json_arr_declContext(self, self._ctx, self.state) - self.enterRule(localctx, 190, self.RULE_json_arr_decl) + self.enterRule(localctx, 232, self.RULE_json_arr_decl) self._la = 0 # Token type try: - self.state = 864 + self.state = 1243 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input, 50, self._ctx) + la_ = self._interp.adaptivePredict(self._input, 93, self._ctx) if la_ == 1: self.enterOuterAlt(localctx, 1) - self.state = 851 + self.state = 1230 self.match(ASLParser.LBRACK) - self.state = 852 + self.state = 1231 self.json_value_decl() - self.state = 857 + self.state = 1236 self._errHandler.sync(self) _la = self._input.LA(1) while _la == 1: - self.state = 853 + self.state = 1232 self.match(ASLParser.COMMA) - self.state = 854 + self.state = 1233 self.json_value_decl() - self.state = 859 + self.state = 1238 self._errHandler.sync(self) _la = self._input.LA(1) - self.state = 860 + self.state = 1239 self.match(ASLParser.RBRACK) pass elif la_ == 2: self.enterOuterAlt(localctx, 2) - self.state = 862 + self.state = 1241 self.match(ASLParser.LBRACK) - self.state = 863 + self.state = 1242 self.match(ASLParser.RBRACK) pass @@ -15949,62 +24358,62 @@ def accept(self, visitor: ParseTreeVisitor): def json_value_decl(self): localctx = ASLParser.Json_value_declContext(self, self._ctx, self.state) - self.enterRule(localctx, 192, self.RULE_json_value_decl) + self.enterRule(localctx, 234, self.RULE_json_value_decl) try: - self.state = 875 + self.state = 1254 self._errHandler.sync(self) - la_ = self._interp.adaptivePredict(self._input, 51, self._ctx) + la_ = self._interp.adaptivePredict(self._input, 94, self._ctx) if la_ == 1: self.enterOuterAlt(localctx, 1) - self.state = 866 + self.state = 1245 self.match(ASLParser.NUMBER) pass elif la_ == 2: self.enterOuterAlt(localctx, 2) - self.state = 867 + self.state = 1246 self.match(ASLParser.INT) pass elif la_ == 3: self.enterOuterAlt(localctx, 3) - self.state = 868 + self.state = 1247 self.match(ASLParser.TRUE) pass elif la_ == 4: self.enterOuterAlt(localctx, 4) - self.state = 869 + self.state = 1248 self.match(ASLParser.FALSE) pass elif la_ == 5: self.enterOuterAlt(localctx, 5) - self.state = 870 + self.state = 1249 self.match(ASLParser.NULL) pass elif la_ == 6: self.enterOuterAlt(localctx, 6) - self.state = 871 + self.state = 1250 self.json_binding() pass elif la_ == 7: self.enterOuterAlt(localctx, 7) - self.state = 872 + self.state = 1251 self.json_arr_decl() pass elif la_ == 8: self.enterOuterAlt(localctx, 8) - self.state = 873 + self.state = 1252 self.json_obj_decl() pass elif la_ == 9: self.enterOuterAlt(localctx, 9) - self.state = 874 + self.state = 1253 self.keyword_or_string() pass @@ -16028,15 +24437,36 @@ def __init__( def STRINGDOLLAR(self): return self.getToken(ASLParser.STRINGDOLLAR, 0) + def STRINGINTRINSICFUNC(self): + return self.getToken(ASLParser.STRINGINTRINSICFUNC, 0) + + def STRINGVAR(self): + return self.getToken(ASLParser.STRINGVAR, 0) + def STRINGPATHCONTEXTOBJ(self): return self.getToken(ASLParser.STRINGPATHCONTEXTOBJ, 0) def STRINGPATH(self): return self.getToken(ASLParser.STRINGPATH, 0) + def STRINGJSONATA(self): + return self.getToken(ASLParser.STRINGJSONATA, 0) + def STRING(self): return self.getToken(ASLParser.STRING, 0) + def QUERYLANGUAGE(self): + return self.getToken(ASLParser.QUERYLANGUAGE, 0) + + def ASSIGN(self): + return self.getToken(ASLParser.ASSIGN, 0) + + def ARGUMENTS(self): + return self.getToken(ASLParser.ARGUMENTS, 0) + + def OUTPUT(self): + return self.getToken(ASLParser.OUTPUT, 0) + def COMMENT(self): return self.getToken(ASLParser.COMMENT, 0) @@ -16079,6 +24509,9 @@ def MAP(self): def CHOICES(self): return self.getToken(ASLParser.CHOICES, 0) + def CONDITION(self): + return self.getToken(ASLParser.CONDITION, 0) + def VARIABLE(self): return self.getToken(ASLParser.VARIABLE, 0) @@ -16256,6 +24689,9 @@ def EXECUTIONTYPE(self): def STANDARD(self): return self.getToken(ASLParser.STANDARD, 0) + def ITEMS(self): + return self.getToken(ASLParser.ITEMS, 0) + def ITEMPROCESSOR(self): return self.getToken(ASLParser.ITEMPROCESSOR, 0) @@ -16292,6 +24728,15 @@ def RESULT(self): def PARAMETERS(self): return self.getToken(ASLParser.PARAMETERS, 0) + def CREDENTIALS(self): + return self.getToken(ASLParser.CREDENTIALS, 0) + + def ROLEARN(self): + return self.getToken(ASLParser.ROLEARN, 0) + + def ROLEARNPATH(self): + return self.getToken(ASLParser.ROLEARNPATH, 0) + def RESULTSELECTOR(self): return self.getToken(ASLParser.RESULTSELECTOR, 0) @@ -16331,6 +24776,9 @@ def TOLERATEDFAILUREPERCENTAGEPATH(self): def LABEL(self): return self.getToken(ASLParser.LABEL, 0) + def RESULTWRITER(self): + return self.getToken(ASLParser.RESULTWRITER, 0) + def NEXT(self): return self.getToken(ASLParser.NEXT, 0) @@ -16417,6 +24865,9 @@ def ERRORNAMEStatesResultWriterFailed(self): def ERRORNAMEStatesRuntime(self): return self.getToken(ASLParser.ERRORNAMEStatesRuntime, 0) + def ERRORNAMEStatesQueryEvaluationError(self): + return self.getToken(ASLParser.ERRORNAMEStatesQueryEvaluationError, 0) + def getRuleIndex(self): return ASLParser.RULE_keyword_or_string @@ -16436,19 +24887,22 @@ def accept(self, visitor: ParseTreeVisitor): def keyword_or_string(self): localctx = ASLParser.Keyword_or_stringContext(self, self._ctx, self.state) - self.enterRule(localctx, 194, self.RULE_keyword_or_string) + self.enterRule(localctx, 236, self.RULE_keyword_or_string) self._la = 0 # Token type try: self.enterOuterAlt(localctx, 1) - self.state = 877 + self.state = 1256 _la = self._input.LA(1) if not ( (((_la) & ~0x3F) == 0 and ((1 << _la) & -17408) != 0) or ( ((_la - 64) & ~0x3F) == 0 - and ((1 << (_la - 64)) & -4613093393310941185) != 0 + and ((1 << (_la - 64)) & -90071992547409921) != 0 + ) + or ( + ((_la - 128) & ~0x3F) == 0 + and ((1 << (_la - 128)) & 4294966223) != 0 ) - or (((_la - 128) & ~0x3F) == 0 and ((1 << (_la - 128)) & 65535) != 0) ): self._errHandler.recoverInline(self) else: diff --git a/moto/stepfunctions/parser/asl/antlr/runtime/ASLParser.tokens b/moto/stepfunctions/parser/asl/antlr/runtime/ASLParser.tokens deleted file mode 100644 index 7f35b74e8fff..000000000000 --- a/moto/stepfunctions/parser/asl/antlr/runtime/ASLParser.tokens +++ /dev/null @@ -1,259 +0,0 @@ -COMMA=1 -COLON=2 -LBRACK=3 -RBRACK=4 -LBRACE=5 -RBRACE=6 -TRUE=7 -FALSE=8 -NULL=9 -COMMENT=10 -STATES=11 -STARTAT=12 -NEXTSTATE=13 -VERSION=14 -TYPE=15 -TASK=16 -CHOICE=17 -FAIL=18 -SUCCEED=19 -PASS=20 -WAIT=21 -PARALLEL=22 -MAP=23 -CHOICES=24 -VARIABLE=25 -DEFAULT=26 -BRANCHES=27 -AND=28 -BOOLEANEQUALS=29 -BOOLEANQUALSPATH=30 -ISBOOLEAN=31 -ISNULL=32 -ISNUMERIC=33 -ISPRESENT=34 -ISSTRING=35 -ISTIMESTAMP=36 -NOT=37 -NUMERICEQUALS=38 -NUMERICEQUALSPATH=39 -NUMERICGREATERTHAN=40 -NUMERICGREATERTHANPATH=41 -NUMERICGREATERTHANEQUALS=42 -NUMERICGREATERTHANEQUALSPATH=43 -NUMERICLESSTHAN=44 -NUMERICLESSTHANPATH=45 -NUMERICLESSTHANEQUALS=46 -NUMERICLESSTHANEQUALSPATH=47 -OR=48 -STRINGEQUALS=49 -STRINGEQUALSPATH=50 -STRINGGREATERTHAN=51 -STRINGGREATERTHANPATH=52 -STRINGGREATERTHANEQUALS=53 -STRINGGREATERTHANEQUALSPATH=54 -STRINGLESSTHAN=55 -STRINGLESSTHANPATH=56 -STRINGLESSTHANEQUALS=57 -STRINGLESSTHANEQUALSPATH=58 -STRINGMATCHES=59 -TIMESTAMPEQUALS=60 -TIMESTAMPEQUALSPATH=61 -TIMESTAMPGREATERTHAN=62 -TIMESTAMPGREATERTHANPATH=63 -TIMESTAMPGREATERTHANEQUALS=64 -TIMESTAMPGREATERTHANEQUALSPATH=65 -TIMESTAMPLESSTHAN=66 -TIMESTAMPLESSTHANPATH=67 -TIMESTAMPLESSTHANEQUALS=68 -TIMESTAMPLESSTHANEQUALSPATH=69 -SECONDSPATH=70 -SECONDS=71 -TIMESTAMPPATH=72 -TIMESTAMP=73 -TIMEOUTSECONDS=74 -TIMEOUTSECONDSPATH=75 -HEARTBEATSECONDS=76 -HEARTBEATSECONDSPATH=77 -PROCESSORCONFIG=78 -MODE=79 -INLINE=80 -DISTRIBUTED=81 -EXECUTIONTYPE=82 -STANDARD=83 -ITEMPROCESSOR=84 -ITERATOR=85 -ITEMSELECTOR=86 -MAXCONCURRENCY=87 -RESOURCE=88 -INPUTPATH=89 -OUTPUTPATH=90 -ITEMSPATH=91 -RESULTPATH=92 -RESULT=93 -PARAMETERS=94 -RESULTSELECTOR=95 -ITEMREADER=96 -READERCONFIG=97 -INPUTTYPE=98 -CSVHEADERLOCATION=99 -CSVHEADERS=100 -MAXITEMS=101 -MAXITEMSPATH=102 -NEXT=103 -END=104 -CAUSE=105 -ERROR=106 -RETRY=107 -ERROREQUALS=108 -INTERVALSECONDS=109 -MAXATTEMPTS=110 -BACKOFFRATE=111 -CATCH=112 -ERRORNAMEStatesALL=113 -ERRORNAMEStatesHeartbeatTimeout=114 -ERRORNAMEStatesTimeout=115 -ERRORNAMEStatesTaskFailed=116 -ERRORNAMEStatesPermissions=117 -ERRORNAMEStatesResultPathMatchFailure=118 -ERRORNAMEStatesParameterPathFailure=119 -ERRORNAMEStatesBranchFailed=120 -ERRORNAMEStatesNoChoiceMatched=121 -ERRORNAMEStatesIntrinsicFailure=122 -ERRORNAMEStatesExceedToleratedFailureThreshold=123 -ERRORNAMEStatesItemReaderFailed=124 -ERRORNAMEStatesResultWriterFailed=125 -ERRORNAMEStatesRuntime=126 -STRINGDOLLAR=127 -STRINGPATHCONTEXTOBJ=128 -STRINGPATH=129 -STRING=130 -INT=131 -NUMBER=132 -WS=133 -','=1 -':'=2 -'['=3 -']'=4 -'{'=5 -'}'=6 -'true'=7 -'false'=8 -'null'=9 -'"Comment"'=10 -'"States"'=11 -'"StartAt"'=12 -'"NextState"'=13 -'"Version"'=14 -'"Type"'=15 -'"Task"'=16 -'"Choice"'=17 -'"Fail"'=18 -'"Succeed"'=19 -'"Pass"'=20 -'"Wait"'=21 -'"Parallel"'=22 -'"Map"'=23 -'"Choices"'=24 -'"Variable"'=25 -'"Default"'=26 -'"Branches"'=27 -'"And"'=28 -'"BooleanEquals"'=29 -'"BooleanEqualsPath"'=30 -'"IsBoolean"'=31 -'"IsNull"'=32 -'"IsNumeric"'=33 -'"IsPresent"'=34 -'"IsString"'=35 -'"IsTimestamp"'=36 -'"Not"'=37 -'"NumericEquals"'=38 -'"NumericEqualsPath"'=39 -'"NumericGreaterThan"'=40 -'"NumericGreaterThanPath"'=41 -'"NumericGreaterThanEquals"'=42 -'"NumericGreaterThanEqualsPath"'=43 -'"NumericLessThan"'=44 -'"NumericLessThanPath"'=45 -'"NumericLessThanEquals"'=46 -'"NumericLessThanEqualsPath"'=47 -'"Or"'=48 -'"StringEquals"'=49 -'"StringEqualsPath"'=50 -'"StringGreaterThan"'=51 -'"StringGreaterThanPath"'=52 -'"StringGreaterThanEquals"'=53 -'"StringGreaterThanEqualsPath"'=54 -'"StringLessThan"'=55 -'"StringLessThanPath"'=56 -'"StringLessThanEquals"'=57 -'"StringLessThanEqualsPath"'=58 -'"StringMatches"'=59 -'"TimestampEquals"'=60 -'"TimestampEqualsPath"'=61 -'"TimestampGreaterThan"'=62 -'"TimestampGreaterThanPath"'=63 -'"TimestampGreaterThanEquals"'=64 -'"TimestampGreaterThanEqualsPath"'=65 -'"TimestampLessThan"'=66 -'"TimestampLessThanPath"'=67 -'"TimestampLessThanEquals"'=68 -'"TimestampLessThanEqualsPath"'=69 -'"SecondsPath"'=70 -'"Seconds"'=71 -'"TimestampPath"'=72 -'"Timestamp"'=73 -'"TimeoutSeconds"'=74 -'"TimeoutSecondsPath"'=75 -'"HeartbeatSeconds"'=76 -'"HeartbeatSecondsPath"'=77 -'"ProcessorConfig"'=78 -'"Mode"'=79 -'"INLINE"'=80 -'"DISTRIBUTED"'=81 -'"ExecutionType"'=82 -'"STANDARD"'=83 -'"ItemProcessor"'=84 -'"Iterator"'=85 -'"ItemSelector"'=86 -'"MaxConcurrency"'=87 -'"Resource"'=88 -'"InputPath"'=89 -'"OutputPath"'=90 -'"ItemsPath"'=91 -'"ResultPath"'=92 -'"Result"'=93 -'"Parameters"'=94 -'"ResultSelector"'=95 -'"ItemReader"'=96 -'"ReaderConfig"'=97 -'"InputType"'=98 -'"CSVHeaderLocation"'=99 -'"CSVHeaders"'=100 -'"MaxItems"'=101 -'"MaxItemsPath"'=102 -'"Next"'=103 -'"End"'=104 -'"Cause"'=105 -'"Error"'=106 -'"Retry"'=107 -'"ErrorEquals"'=108 -'"IntervalSeconds"'=109 -'"MaxAttempts"'=110 -'"BackoffRate"'=111 -'"Catch"'=112 -'"States.ALL"'=113 -'"States.HeartbeatTimeout"'=114 -'"States.Timeout"'=115 -'"States.TaskFailed"'=116 -'"States.Permissions"'=117 -'"States.ResultPathMatchFailure"'=118 -'"States.ParameterPathFailure"'=119 -'"States.BranchFailed"'=120 -'"States.NoChoiceMatched"'=121 -'"States.IntrinsicFailure"'=122 -'"States.ExceedToleratedFailureThreshold"'=123 -'"States.ItemReaderFailed"'=124 -'"States.ResultWriterFailed"'=125 -'"States.Runtime"'=126 diff --git a/moto/stepfunctions/parser/asl/antlr/runtime/ASLParserListener.py b/moto/stepfunctions/parser/asl/antlr/runtime/ASLParserListener.py index 2fc2e67021d4..e7c3a8700500 100644 --- a/moto/stepfunctions/parser/asl/antlr/runtime/ASLParserListener.py +++ b/moto/stepfunctions/parser/asl/antlr/runtime/ASLParserListener.py @@ -1,4 +1,4 @@ -# Generated from ASLParser.g4 by ANTLR 4.13.1 +# Generated from ASLParser.g4 by ANTLR 4.13.2 from antlr4 import ParseTreeListener if "." in __name__: @@ -57,6 +57,14 @@ def enterVersion_decl(self, ctx: ASLParser.Version_declContext): def exitVersion_decl(self, ctx: ASLParser.Version_declContext): pass + # Enter a parse tree produced by ASLParser#query_language_decl. + def enterQuery_language_decl(self, ctx: ASLParser.Query_language_declContext): + pass + + # Exit a parse tree produced by ASLParser#query_language_decl. + def exitQuery_language_decl(self, ctx: ASLParser.Query_language_declContext): + pass + # Enter a parse tree produced by ASLParser#state_stmt. def enterState_stmt(self, ctx: ASLParser.State_stmtContext): pass @@ -121,12 +129,32 @@ def enterResource_decl(self, ctx: ASLParser.Resource_declContext): def exitResource_decl(self, ctx: ASLParser.Resource_declContext): pass - # Enter a parse tree produced by ASLParser#input_path_decl. - def enterInput_path_decl(self, ctx: ASLParser.Input_path_declContext): + # Enter a parse tree produced by ASLParser#input_path_decl_var. + def enterInput_path_decl_var(self, ctx: ASLParser.Input_path_decl_varContext): pass - # Exit a parse tree produced by ASLParser#input_path_decl. - def exitInput_path_decl(self, ctx: ASLParser.Input_path_declContext): + # Exit a parse tree produced by ASLParser#input_path_decl_var. + def exitInput_path_decl_var(self, ctx: ASLParser.Input_path_decl_varContext): + pass + + # Enter a parse tree produced by ASLParser#input_path_decl_path_context_object. + def enterInput_path_decl_path_context_object( + self, ctx: ASLParser.Input_path_decl_path_context_objectContext + ): + pass + + # Exit a parse tree produced by ASLParser#input_path_decl_path_context_object. + def exitInput_path_decl_path_context_object( + self, ctx: ASLParser.Input_path_decl_path_context_objectContext + ): + pass + + # Enter a parse tree produced by ASLParser#input_path_decl_path. + def enterInput_path_decl_path(self, ctx: ASLParser.Input_path_decl_pathContext): + pass + + # Exit a parse tree produced by ASLParser#input_path_decl_path. + def exitInput_path_decl_path(self, ctx: ASLParser.Input_path_decl_pathContext): pass # Enter a parse tree produced by ASLParser#result_decl. @@ -145,12 +173,32 @@ def enterResult_path_decl(self, ctx: ASLParser.Result_path_declContext): def exitResult_path_decl(self, ctx: ASLParser.Result_path_declContext): pass - # Enter a parse tree produced by ASLParser#output_path_decl. - def enterOutput_path_decl(self, ctx: ASLParser.Output_path_declContext): + # Enter a parse tree produced by ASLParser#output_path_decl_var. + def enterOutput_path_decl_var(self, ctx: ASLParser.Output_path_decl_varContext): + pass + + # Exit a parse tree produced by ASLParser#output_path_decl_var. + def exitOutput_path_decl_var(self, ctx: ASLParser.Output_path_decl_varContext): + pass + + # Enter a parse tree produced by ASLParser#output_path_decl_path_context_object. + def enterOutput_path_decl_path_context_object( + self, ctx: ASLParser.Output_path_decl_path_context_objectContext + ): + pass + + # Exit a parse tree produced by ASLParser#output_path_decl_path_context_object. + def exitOutput_path_decl_path_context_object( + self, ctx: ASLParser.Output_path_decl_path_context_objectContext + ): + pass + + # Enter a parse tree produced by ASLParser#output_path_decl_path. + def enterOutput_path_decl_path(self, ctx: ASLParser.Output_path_decl_pathContext): pass - # Exit a parse tree produced by ASLParser#output_path_decl. - def exitOutput_path_decl(self, ctx: ASLParser.Output_path_declContext): + # Exit a parse tree produced by ASLParser#output_path_decl_path. + def exitOutput_path_decl_path(self, ctx: ASLParser.Output_path_decl_pathContext): pass # Enter a parse tree produced by ASLParser#end_decl. @@ -169,12 +217,28 @@ def enterDefault_decl(self, ctx: ASLParser.Default_declContext): def exitDefault_decl(self, ctx: ASLParser.Default_declContext): pass - # Enter a parse tree produced by ASLParser#error_decl. - def enterError_decl(self, ctx: ASLParser.Error_declContext): + # Enter a parse tree produced by ASLParser#error_jsonata. + def enterError_jsonata(self, ctx: ASLParser.Error_jsonataContext): + pass + + # Exit a parse tree produced by ASLParser#error_jsonata. + def exitError_jsonata(self, ctx: ASLParser.Error_jsonataContext): + pass + + # Enter a parse tree produced by ASLParser#error_string. + def enterError_string(self, ctx: ASLParser.Error_stringContext): + pass + + # Exit a parse tree produced by ASLParser#error_string. + def exitError_string(self, ctx: ASLParser.Error_stringContext): + pass + + # Enter a parse tree produced by ASLParser#error_path_decl_var. + def enterError_path_decl_var(self, ctx: ASLParser.Error_path_decl_varContext): pass - # Exit a parse tree produced by ASLParser#error_decl. - def exitError_decl(self, ctx: ASLParser.Error_declContext): + # Exit a parse tree produced by ASLParser#error_path_decl_var. + def exitError_path_decl_var(self, ctx: ASLParser.Error_path_decl_varContext): pass # Enter a parse tree produced by ASLParser#error_path_decl_path. @@ -185,6 +249,18 @@ def enterError_path_decl_path(self, ctx: ASLParser.Error_path_decl_pathContext): def exitError_path_decl_path(self, ctx: ASLParser.Error_path_decl_pathContext): pass + # Enter a parse tree produced by ASLParser#error_path_decl_context. + def enterError_path_decl_context( + self, ctx: ASLParser.Error_path_decl_contextContext + ): + pass + + # Exit a parse tree produced by ASLParser#error_path_decl_context. + def exitError_path_decl_context( + self, ctx: ASLParser.Error_path_decl_contextContext + ): + pass + # Enter a parse tree produced by ASLParser#error_path_decl_intrinsic. def enterError_path_decl_intrinsic( self, ctx: ASLParser.Error_path_decl_intrinsicContext @@ -197,12 +273,28 @@ def exitError_path_decl_intrinsic( ): pass - # Enter a parse tree produced by ASLParser#cause_decl. - def enterCause_decl(self, ctx: ASLParser.Cause_declContext): + # Enter a parse tree produced by ASLParser#cause_jsonata. + def enterCause_jsonata(self, ctx: ASLParser.Cause_jsonataContext): pass - # Exit a parse tree produced by ASLParser#cause_decl. - def exitCause_decl(self, ctx: ASLParser.Cause_declContext): + # Exit a parse tree produced by ASLParser#cause_jsonata. + def exitCause_jsonata(self, ctx: ASLParser.Cause_jsonataContext): + pass + + # Enter a parse tree produced by ASLParser#cause_string. + def enterCause_string(self, ctx: ASLParser.Cause_stringContext): + pass + + # Exit a parse tree produced by ASLParser#cause_string. + def exitCause_string(self, ctx: ASLParser.Cause_stringContext): + pass + + # Enter a parse tree produced by ASLParser#cause_path_decl_var. + def enterCause_path_decl_var(self, ctx: ASLParser.Cause_path_decl_varContext): + pass + + # Exit a parse tree produced by ASLParser#cause_path_decl_var. + def exitCause_path_decl_var(self, ctx: ASLParser.Cause_path_decl_varContext): pass # Enter a parse tree produced by ASLParser#cause_path_decl_path. @@ -213,6 +305,18 @@ def enterCause_path_decl_path(self, ctx: ASLParser.Cause_path_decl_pathContext): def exitCause_path_decl_path(self, ctx: ASLParser.Cause_path_decl_pathContext): pass + # Enter a parse tree produced by ASLParser#cause_path_decl_context. + def enterCause_path_decl_context( + self, ctx: ASLParser.Cause_path_decl_contextContext + ): + pass + + # Exit a parse tree produced by ASLParser#cause_path_decl_context. + def exitCause_path_decl_context( + self, ctx: ASLParser.Cause_path_decl_contextContext + ): + pass + # Enter a parse tree produced by ASLParser#cause_path_decl_intrinsic. def enterCause_path_decl_intrinsic( self, ctx: ASLParser.Cause_path_decl_intrinsicContext @@ -225,66 +329,170 @@ def exitCause_path_decl_intrinsic( ): pass - # Enter a parse tree produced by ASLParser#seconds_decl. - def enterSeconds_decl(self, ctx: ASLParser.Seconds_declContext): + # Enter a parse tree produced by ASLParser#seconds_jsonata. + def enterSeconds_jsonata(self, ctx: ASLParser.Seconds_jsonataContext): + pass + + # Exit a parse tree produced by ASLParser#seconds_jsonata. + def exitSeconds_jsonata(self, ctx: ASLParser.Seconds_jsonataContext): + pass + + # Enter a parse tree produced by ASLParser#seconds_int. + def enterSeconds_int(self, ctx: ASLParser.Seconds_intContext): + pass + + # Exit a parse tree produced by ASLParser#seconds_int. + def exitSeconds_int(self, ctx: ASLParser.Seconds_intContext): + pass + + # Enter a parse tree produced by ASLParser#seconds_path_decl_var. + def enterSeconds_path_decl_var(self, ctx: ASLParser.Seconds_path_decl_varContext): + pass + + # Exit a parse tree produced by ASLParser#seconds_path_decl_var. + def exitSeconds_path_decl_var(self, ctx: ASLParser.Seconds_path_decl_varContext): + pass + + # Enter a parse tree produced by ASLParser#seconds_path_decl_value. + def enterSeconds_path_decl_value( + self, ctx: ASLParser.Seconds_path_decl_valueContext + ): + pass + + # Exit a parse tree produced by ASLParser#seconds_path_decl_value. + def exitSeconds_path_decl_value( + self, ctx: ASLParser.Seconds_path_decl_valueContext + ): + pass + + # Enter a parse tree produced by ASLParser#timestamp_jsonata. + def enterTimestamp_jsonata(self, ctx: ASLParser.Timestamp_jsonataContext): + pass + + # Exit a parse tree produced by ASLParser#timestamp_jsonata. + def exitTimestamp_jsonata(self, ctx: ASLParser.Timestamp_jsonataContext): + pass + + # Enter a parse tree produced by ASLParser#timestamp_string. + def enterTimestamp_string(self, ctx: ASLParser.Timestamp_stringContext): + pass + + # Exit a parse tree produced by ASLParser#timestamp_string. + def exitTimestamp_string(self, ctx: ASLParser.Timestamp_stringContext): + pass + + # Enter a parse tree produced by ASLParser#timestamp_path_decl_var. + def enterTimestamp_path_decl_var( + self, ctx: ASLParser.Timestamp_path_decl_varContext + ): + pass + + # Exit a parse tree produced by ASLParser#timestamp_path_decl_var. + def exitTimestamp_path_decl_var( + self, ctx: ASLParser.Timestamp_path_decl_varContext + ): pass - # Exit a parse tree produced by ASLParser#seconds_decl. - def exitSeconds_decl(self, ctx: ASLParser.Seconds_declContext): + # Enter a parse tree produced by ASLParser#timestamp_path_decl_value. + def enterTimestamp_path_decl_value( + self, ctx: ASLParser.Timestamp_path_decl_valueContext + ): pass - # Enter a parse tree produced by ASLParser#seconds_path_decl. - def enterSeconds_path_decl(self, ctx: ASLParser.Seconds_path_declContext): + # Exit a parse tree produced by ASLParser#timestamp_path_decl_value. + def exitTimestamp_path_decl_value( + self, ctx: ASLParser.Timestamp_path_decl_valueContext + ): pass - # Exit a parse tree produced by ASLParser#seconds_path_decl. - def exitSeconds_path_decl(self, ctx: ASLParser.Seconds_path_declContext): + # Enter a parse tree produced by ASLParser#items_array. + def enterItems_array(self, ctx: ASLParser.Items_arrayContext): pass - # Enter a parse tree produced by ASLParser#timestamp_decl. - def enterTimestamp_decl(self, ctx: ASLParser.Timestamp_declContext): + # Exit a parse tree produced by ASLParser#items_array. + def exitItems_array(self, ctx: ASLParser.Items_arrayContext): pass - # Exit a parse tree produced by ASLParser#timestamp_decl. - def exitTimestamp_decl(self, ctx: ASLParser.Timestamp_declContext): + # Enter a parse tree produced by ASLParser#items_jsonata. + def enterItems_jsonata(self, ctx: ASLParser.Items_jsonataContext): pass - # Enter a parse tree produced by ASLParser#timestamp_path_decl. - def enterTimestamp_path_decl(self, ctx: ASLParser.Timestamp_path_declContext): + # Exit a parse tree produced by ASLParser#items_jsonata. + def exitItems_jsonata(self, ctx: ASLParser.Items_jsonataContext): pass - # Exit a parse tree produced by ASLParser#timestamp_path_decl. - def exitTimestamp_path_decl(self, ctx: ASLParser.Timestamp_path_declContext): + # Enter a parse tree produced by ASLParser#items_path_decl_path_context_object. + def enterItems_path_decl_path_context_object( + self, ctx: ASLParser.Items_path_decl_path_context_objectContext + ): pass - # Enter a parse tree produced by ASLParser#items_path_decl. - def enterItems_path_decl(self, ctx: ASLParser.Items_path_declContext): + # Exit a parse tree produced by ASLParser#items_path_decl_path_context_object. + def exitItems_path_decl_path_context_object( + self, ctx: ASLParser.Items_path_decl_path_context_objectContext + ): pass - # Exit a parse tree produced by ASLParser#items_path_decl. - def exitItems_path_decl(self, ctx: ASLParser.Items_path_declContext): + # Enter a parse tree produced by ASLParser#items_path_decl_path_var. + def enterItems_path_decl_path_var( + self, ctx: ASLParser.Items_path_decl_path_varContext + ): + pass + + # Exit a parse tree produced by ASLParser#items_path_decl_path_var. + def exitItems_path_decl_path_var( + self, ctx: ASLParser.Items_path_decl_path_varContext + ): + pass + + # Enter a parse tree produced by ASLParser#items_path_decl_path. + def enterItems_path_decl_path(self, ctx: ASLParser.Items_path_decl_pathContext): + pass + + # Exit a parse tree produced by ASLParser#items_path_decl_path. + def exitItems_path_decl_path(self, ctx: ASLParser.Items_path_decl_pathContext): + pass + + # Enter a parse tree produced by ASLParser#max_concurrency_jsonata. + def enterMax_concurrency_jsonata( + self, ctx: ASLParser.Max_concurrency_jsonataContext + ): + pass + + # Exit a parse tree produced by ASLParser#max_concurrency_jsonata. + def exitMax_concurrency_jsonata( + self, ctx: ASLParser.Max_concurrency_jsonataContext + ): pass - # Enter a parse tree produced by ASLParser#max_concurrency_decl. - def enterMax_concurrency_decl(self, ctx: ASLParser.Max_concurrency_declContext): + # Enter a parse tree produced by ASLParser#max_concurrency_int. + def enterMax_concurrency_int(self, ctx: ASLParser.Max_concurrency_intContext): pass - # Exit a parse tree produced by ASLParser#max_concurrency_decl. - def exitMax_concurrency_decl(self, ctx: ASLParser.Max_concurrency_declContext): + # Exit a parse tree produced by ASLParser#max_concurrency_int. + def exitMax_concurrency_int(self, ctx: ASLParser.Max_concurrency_intContext): pass - # Enter a parse tree produced by ASLParser#max_concurrency_path_decl. - def enterMax_concurrency_path_decl( - self, ctx: ASLParser.Max_concurrency_path_declContext + # Enter a parse tree produced by ASLParser#max_concurrency_path_var. + def enterMax_concurrency_path_var( + self, ctx: ASLParser.Max_concurrency_path_varContext ): pass - # Exit a parse tree produced by ASLParser#max_concurrency_path_decl. - def exitMax_concurrency_path_decl( - self, ctx: ASLParser.Max_concurrency_path_declContext + # Exit a parse tree produced by ASLParser#max_concurrency_path_var. + def exitMax_concurrency_path_var( + self, ctx: ASLParser.Max_concurrency_path_varContext ): pass + # Enter a parse tree produced by ASLParser#max_concurrency_path. + def enterMax_concurrency_path(self, ctx: ASLParser.Max_concurrency_pathContext): + pass + + # Exit a parse tree produced by ASLParser#max_concurrency_path. + def exitMax_concurrency_path(self, ctx: ASLParser.Max_concurrency_pathContext): + pass + # Enter a parse tree produced by ASLParser#parameters_decl. def enterParameters_decl(self, ctx: ASLParser.Parameters_declContext): pass @@ -293,46 +501,166 @@ def enterParameters_decl(self, ctx: ASLParser.Parameters_declContext): def exitParameters_decl(self, ctx: ASLParser.Parameters_declContext): pass - # Enter a parse tree produced by ASLParser#timeout_seconds_decl. - def enterTimeout_seconds_decl(self, ctx: ASLParser.Timeout_seconds_declContext): + # Enter a parse tree produced by ASLParser#credentials_decl. + def enterCredentials_decl(self, ctx: ASLParser.Credentials_declContext): + pass + + # Exit a parse tree produced by ASLParser#credentials_decl. + def exitCredentials_decl(self, ctx: ASLParser.Credentials_declContext): + pass + + # Enter a parse tree produced by ASLParser#role_arn_jsonata. + def enterRole_arn_jsonata(self, ctx: ASLParser.Role_arn_jsonataContext): + pass + + # Exit a parse tree produced by ASLParser#role_arn_jsonata. + def exitRole_arn_jsonata(self, ctx: ASLParser.Role_arn_jsonataContext): + pass + + # Enter a parse tree produced by ASLParser#role_arn_path. + def enterRole_arn_path(self, ctx: ASLParser.Role_arn_pathContext): + pass + + # Exit a parse tree produced by ASLParser#role_arn_path. + def exitRole_arn_path(self, ctx: ASLParser.Role_arn_pathContext): + pass + + # Enter a parse tree produced by ASLParser#role_arn_path_context_obj. + def enterRole_arn_path_context_obj( + self, ctx: ASLParser.Role_arn_path_context_objContext + ): + pass + + # Exit a parse tree produced by ASLParser#role_arn_path_context_obj. + def exitRole_arn_path_context_obj( + self, ctx: ASLParser.Role_arn_path_context_objContext + ): + pass + + # Enter a parse tree produced by ASLParser#role_arn_intrinsic_func. + def enterRole_arn_intrinsic_func( + self, ctx: ASLParser.Role_arn_intrinsic_funcContext + ): + pass + + # Exit a parse tree produced by ASLParser#role_arn_intrinsic_func. + def exitRole_arn_intrinsic_func( + self, ctx: ASLParser.Role_arn_intrinsic_funcContext + ): + pass + + # Enter a parse tree produced by ASLParser#role_arn_var. + def enterRole_arn_var(self, ctx: ASLParser.Role_arn_varContext): + pass + + # Exit a parse tree produced by ASLParser#role_arn_var. + def exitRole_arn_var(self, ctx: ASLParser.Role_arn_varContext): + pass + + # Enter a parse tree produced by ASLParser#role_arn_str. + def enterRole_arn_str(self, ctx: ASLParser.Role_arn_strContext): pass - # Exit a parse tree produced by ASLParser#timeout_seconds_decl. - def exitTimeout_seconds_decl(self, ctx: ASLParser.Timeout_seconds_declContext): + # Exit a parse tree produced by ASLParser#role_arn_str. + def exitRole_arn_str(self, ctx: ASLParser.Role_arn_strContext): pass - # Enter a parse tree produced by ASLParser#timeout_seconds_path_decl. - def enterTimeout_seconds_path_decl( - self, ctx: ASLParser.Timeout_seconds_path_declContext + # Enter a parse tree produced by ASLParser#timeout_seconds_jsonata. + def enterTimeout_seconds_jsonata( + self, ctx: ASLParser.Timeout_seconds_jsonataContext ): pass - # Exit a parse tree produced by ASLParser#timeout_seconds_path_decl. - def exitTimeout_seconds_path_decl( - self, ctx: ASLParser.Timeout_seconds_path_declContext + # Exit a parse tree produced by ASLParser#timeout_seconds_jsonata. + def exitTimeout_seconds_jsonata( + self, ctx: ASLParser.Timeout_seconds_jsonataContext ): pass - # Enter a parse tree produced by ASLParser#heartbeat_seconds_decl. - def enterHeartbeat_seconds_decl(self, ctx: ASLParser.Heartbeat_seconds_declContext): + # Enter a parse tree produced by ASLParser#timeout_seconds_int. + def enterTimeout_seconds_int(self, ctx: ASLParser.Timeout_seconds_intContext): pass - # Exit a parse tree produced by ASLParser#heartbeat_seconds_decl. - def exitHeartbeat_seconds_decl(self, ctx: ASLParser.Heartbeat_seconds_declContext): + # Exit a parse tree produced by ASLParser#timeout_seconds_int. + def exitTimeout_seconds_int(self, ctx: ASLParser.Timeout_seconds_intContext): + pass + + # Enter a parse tree produced by ASLParser#timeout_seconds_path_decl_var. + def enterTimeout_seconds_path_decl_var( + self, ctx: ASLParser.Timeout_seconds_path_decl_varContext + ): + pass + + # Exit a parse tree produced by ASLParser#timeout_seconds_path_decl_var. + def exitTimeout_seconds_path_decl_var( + self, ctx: ASLParser.Timeout_seconds_path_decl_varContext + ): pass - # Enter a parse tree produced by ASLParser#heartbeat_seconds_path_decl. - def enterHeartbeat_seconds_path_decl( - self, ctx: ASLParser.Heartbeat_seconds_path_declContext + # Enter a parse tree produced by ASLParser#timeout_seconds_path_decl_path. + def enterTimeout_seconds_path_decl_path( + self, ctx: ASLParser.Timeout_seconds_path_decl_pathContext ): pass - # Exit a parse tree produced by ASLParser#heartbeat_seconds_path_decl. - def exitHeartbeat_seconds_path_decl( - self, ctx: ASLParser.Heartbeat_seconds_path_declContext + # Exit a parse tree produced by ASLParser#timeout_seconds_path_decl_path. + def exitTimeout_seconds_path_decl_path( + self, ctx: ASLParser.Timeout_seconds_path_decl_pathContext ): pass + # Enter a parse tree produced by ASLParser#heartbeat_seconds_jsonata. + def enterHeartbeat_seconds_jsonata( + self, ctx: ASLParser.Heartbeat_seconds_jsonataContext + ): + pass + + # Exit a parse tree produced by ASLParser#heartbeat_seconds_jsonata. + def exitHeartbeat_seconds_jsonata( + self, ctx: ASLParser.Heartbeat_seconds_jsonataContext + ): + pass + + # Enter a parse tree produced by ASLParser#heartbeat_seconds_int. + def enterHeartbeat_seconds_int(self, ctx: ASLParser.Heartbeat_seconds_intContext): + pass + + # Exit a parse tree produced by ASLParser#heartbeat_seconds_int. + def exitHeartbeat_seconds_int(self, ctx: ASLParser.Heartbeat_seconds_intContext): + pass + + # Enter a parse tree produced by ASLParser#heartbeat_seconds_path_decl_var. + def enterHeartbeat_seconds_path_decl_var( + self, ctx: ASLParser.Heartbeat_seconds_path_decl_varContext + ): + pass + + # Exit a parse tree produced by ASLParser#heartbeat_seconds_path_decl_var. + def exitHeartbeat_seconds_path_decl_var( + self, ctx: ASLParser.Heartbeat_seconds_path_decl_varContext + ): + pass + + # Enter a parse tree produced by ASLParser#heartbeat_seconds_path_decl_path. + def enterHeartbeat_seconds_path_decl_path( + self, ctx: ASLParser.Heartbeat_seconds_path_decl_pathContext + ): + pass + + # Exit a parse tree produced by ASLParser#heartbeat_seconds_path_decl_path. + def exitHeartbeat_seconds_path_decl_path( + self, ctx: ASLParser.Heartbeat_seconds_path_decl_pathContext + ): + pass + + # Enter a parse tree produced by ASLParser#variable_sample. + def enterVariable_sample(self, ctx: ASLParser.Variable_sampleContext): + pass + + # Exit a parse tree produced by ASLParser#variable_sample. + def exitVariable_sample(self, ctx: ASLParser.Variable_sampleContext): + pass + # Enter a parse tree produced by ASLParser#payload_tmpl_decl. def enterPayload_tmpl_decl(self, ctx: ASLParser.Payload_tmpl_declContext): pass @@ -373,20 +701,20 @@ def exitPayload_binding_intrinsic_func( ): pass - # Enter a parse tree produced by ASLParser#payload_binding_value. - def enterPayload_binding_value(self, ctx: ASLParser.Payload_binding_valueContext): + # Enter a parse tree produced by ASLParser#payload_binding_var. + def enterPayload_binding_var(self, ctx: ASLParser.Payload_binding_varContext): pass - # Exit a parse tree produced by ASLParser#payload_binding_value. - def exitPayload_binding_value(self, ctx: ASLParser.Payload_binding_valueContext): + # Exit a parse tree produced by ASLParser#payload_binding_var. + def exitPayload_binding_var(self, ctx: ASLParser.Payload_binding_varContext): pass - # Enter a parse tree produced by ASLParser#intrinsic_func. - def enterIntrinsic_func(self, ctx: ASLParser.Intrinsic_funcContext): + # Enter a parse tree produced by ASLParser#payload_binding_value. + def enterPayload_binding_value(self, ctx: ASLParser.Payload_binding_valueContext): pass - # Exit a parse tree produced by ASLParser#intrinsic_func. - def exitIntrinsic_func(self, ctx: ASLParser.Intrinsic_funcContext): + # Exit a parse tree produced by ASLParser#payload_binding_value. + def exitPayload_binding_value(self, ctx: ASLParser.Payload_binding_valueContext): pass # Enter a parse tree produced by ASLParser#payload_arr_decl. @@ -445,6 +773,334 @@ def enterPayload_value_str(self, ctx: ASLParser.Payload_value_strContext): def exitPayload_value_str(self, ctx: ASLParser.Payload_value_strContext): pass + # Enter a parse tree produced by ASLParser#assign_decl. + def enterAssign_decl(self, ctx: ASLParser.Assign_declContext): + pass + + # Exit a parse tree produced by ASLParser#assign_decl. + def exitAssign_decl(self, ctx: ASLParser.Assign_declContext): + pass + + # Enter a parse tree produced by ASLParser#assign_decl_body. + def enterAssign_decl_body(self, ctx: ASLParser.Assign_decl_bodyContext): + pass + + # Exit a parse tree produced by ASLParser#assign_decl_body. + def exitAssign_decl_body(self, ctx: ASLParser.Assign_decl_bodyContext): + pass + + # Enter a parse tree produced by ASLParser#assign_decl_binding. + def enterAssign_decl_binding(self, ctx: ASLParser.Assign_decl_bindingContext): + pass + + # Exit a parse tree produced by ASLParser#assign_decl_binding. + def exitAssign_decl_binding(self, ctx: ASLParser.Assign_decl_bindingContext): + pass + + # Enter a parse tree produced by ASLParser#assign_template_value_object. + def enterAssign_template_value_object( + self, ctx: ASLParser.Assign_template_value_objectContext + ): + pass + + # Exit a parse tree produced by ASLParser#assign_template_value_object. + def exitAssign_template_value_object( + self, ctx: ASLParser.Assign_template_value_objectContext + ): + pass + + # Enter a parse tree produced by ASLParser#assign_template_binding_path. + def enterAssign_template_binding_path( + self, ctx: ASLParser.Assign_template_binding_pathContext + ): + pass + + # Exit a parse tree produced by ASLParser#assign_template_binding_path. + def exitAssign_template_binding_path( + self, ctx: ASLParser.Assign_template_binding_pathContext + ): + pass + + # Enter a parse tree produced by ASLParser#assign_template_binding_path_context. + def enterAssign_template_binding_path_context( + self, ctx: ASLParser.Assign_template_binding_path_contextContext + ): + pass + + # Exit a parse tree produced by ASLParser#assign_template_binding_path_context. + def exitAssign_template_binding_path_context( + self, ctx: ASLParser.Assign_template_binding_path_contextContext + ): + pass + + # Enter a parse tree produced by ASLParser#assign_template_binding_var. + def enterAssign_template_binding_var( + self, ctx: ASLParser.Assign_template_binding_varContext + ): + pass + + # Exit a parse tree produced by ASLParser#assign_template_binding_var. + def exitAssign_template_binding_var( + self, ctx: ASLParser.Assign_template_binding_varContext + ): + pass + + # Enter a parse tree produced by ASLParser#assign_template_binding_intrinsic_func. + def enterAssign_template_binding_intrinsic_func( + self, ctx: ASLParser.Assign_template_binding_intrinsic_funcContext + ): + pass + + # Exit a parse tree produced by ASLParser#assign_template_binding_intrinsic_func. + def exitAssign_template_binding_intrinsic_func( + self, ctx: ASLParser.Assign_template_binding_intrinsic_funcContext + ): + pass + + # Enter a parse tree produced by ASLParser#assign_template_binding_assign_value. + def enterAssign_template_binding_assign_value( + self, ctx: ASLParser.Assign_template_binding_assign_valueContext + ): + pass + + # Exit a parse tree produced by ASLParser#assign_template_binding_assign_value. + def exitAssign_template_binding_assign_value( + self, ctx: ASLParser.Assign_template_binding_assign_valueContext + ): + pass + + # Enter a parse tree produced by ASLParser#assign_template_value. + def enterAssign_template_value(self, ctx: ASLParser.Assign_template_valueContext): + pass + + # Exit a parse tree produced by ASLParser#assign_template_value. + def exitAssign_template_value(self, ctx: ASLParser.Assign_template_valueContext): + pass + + # Enter a parse tree produced by ASLParser#assign_template_value_array. + def enterAssign_template_value_array( + self, ctx: ASLParser.Assign_template_value_arrayContext + ): + pass + + # Exit a parse tree produced by ASLParser#assign_template_value_array. + def exitAssign_template_value_array( + self, ctx: ASLParser.Assign_template_value_arrayContext + ): + pass + + # Enter a parse tree produced by ASLParser#assign_template_value_terminal_float. + def enterAssign_template_value_terminal_float( + self, ctx: ASLParser.Assign_template_value_terminal_floatContext + ): + pass + + # Exit a parse tree produced by ASLParser#assign_template_value_terminal_float. + def exitAssign_template_value_terminal_float( + self, ctx: ASLParser.Assign_template_value_terminal_floatContext + ): + pass + + # Enter a parse tree produced by ASLParser#assign_template_value_terminal_int. + def enterAssign_template_value_terminal_int( + self, ctx: ASLParser.Assign_template_value_terminal_intContext + ): + pass + + # Exit a parse tree produced by ASLParser#assign_template_value_terminal_int. + def exitAssign_template_value_terminal_int( + self, ctx: ASLParser.Assign_template_value_terminal_intContext + ): + pass + + # Enter a parse tree produced by ASLParser#assign_template_value_terminal_bool. + def enterAssign_template_value_terminal_bool( + self, ctx: ASLParser.Assign_template_value_terminal_boolContext + ): + pass + + # Exit a parse tree produced by ASLParser#assign_template_value_terminal_bool. + def exitAssign_template_value_terminal_bool( + self, ctx: ASLParser.Assign_template_value_terminal_boolContext + ): + pass + + # Enter a parse tree produced by ASLParser#assign_template_value_terminal_null. + def enterAssign_template_value_terminal_null( + self, ctx: ASLParser.Assign_template_value_terminal_nullContext + ): + pass + + # Exit a parse tree produced by ASLParser#assign_template_value_terminal_null. + def exitAssign_template_value_terminal_null( + self, ctx: ASLParser.Assign_template_value_terminal_nullContext + ): + pass + + # Enter a parse tree produced by ASLParser#assign_template_value_terminal_expression. + def enterAssign_template_value_terminal_expression( + self, ctx: ASLParser.Assign_template_value_terminal_expressionContext + ): + pass + + # Exit a parse tree produced by ASLParser#assign_template_value_terminal_expression. + def exitAssign_template_value_terminal_expression( + self, ctx: ASLParser.Assign_template_value_terminal_expressionContext + ): + pass + + # Enter a parse tree produced by ASLParser#assign_template_value_terminal_str. + def enterAssign_template_value_terminal_str( + self, ctx: ASLParser.Assign_template_value_terminal_strContext + ): + pass + + # Exit a parse tree produced by ASLParser#assign_template_value_terminal_str. + def exitAssign_template_value_terminal_str( + self, ctx: ASLParser.Assign_template_value_terminal_strContext + ): + pass + + # Enter a parse tree produced by ASLParser#arguments_object. + def enterArguments_object(self, ctx: ASLParser.Arguments_objectContext): + pass + + # Exit a parse tree produced by ASLParser#arguments_object. + def exitArguments_object(self, ctx: ASLParser.Arguments_objectContext): + pass + + # Enter a parse tree produced by ASLParser#arguments_expr. + def enterArguments_expr(self, ctx: ASLParser.Arguments_exprContext): + pass + + # Exit a parse tree produced by ASLParser#arguments_expr. + def exitArguments_expr(self, ctx: ASLParser.Arguments_exprContext): + pass + + # Enter a parse tree produced by ASLParser#output_decl. + def enterOutput_decl(self, ctx: ASLParser.Output_declContext): + pass + + # Exit a parse tree produced by ASLParser#output_decl. + def exitOutput_decl(self, ctx: ASLParser.Output_declContext): + pass + + # Enter a parse tree produced by ASLParser#jsonata_template_value_object. + def enterJsonata_template_value_object( + self, ctx: ASLParser.Jsonata_template_value_objectContext + ): + pass + + # Exit a parse tree produced by ASLParser#jsonata_template_value_object. + def exitJsonata_template_value_object( + self, ctx: ASLParser.Jsonata_template_value_objectContext + ): + pass + + # Enter a parse tree produced by ASLParser#jsonata_template_binding. + def enterJsonata_template_binding( + self, ctx: ASLParser.Jsonata_template_bindingContext + ): + pass + + # Exit a parse tree produced by ASLParser#jsonata_template_binding. + def exitJsonata_template_binding( + self, ctx: ASLParser.Jsonata_template_bindingContext + ): + pass + + # Enter a parse tree produced by ASLParser#jsonata_template_value. + def enterJsonata_template_value(self, ctx: ASLParser.Jsonata_template_valueContext): + pass + + # Exit a parse tree produced by ASLParser#jsonata_template_value. + def exitJsonata_template_value(self, ctx: ASLParser.Jsonata_template_valueContext): + pass + + # Enter a parse tree produced by ASLParser#jsonata_template_value_array. + def enterJsonata_template_value_array( + self, ctx: ASLParser.Jsonata_template_value_arrayContext + ): + pass + + # Exit a parse tree produced by ASLParser#jsonata_template_value_array. + def exitJsonata_template_value_array( + self, ctx: ASLParser.Jsonata_template_value_arrayContext + ): + pass + + # Enter a parse tree produced by ASLParser#jsonata_template_value_terminal_float. + def enterJsonata_template_value_terminal_float( + self, ctx: ASLParser.Jsonata_template_value_terminal_floatContext + ): + pass + + # Exit a parse tree produced by ASLParser#jsonata_template_value_terminal_float. + def exitJsonata_template_value_terminal_float( + self, ctx: ASLParser.Jsonata_template_value_terminal_floatContext + ): + pass + + # Enter a parse tree produced by ASLParser#jsonata_template_value_terminal_int. + def enterJsonata_template_value_terminal_int( + self, ctx: ASLParser.Jsonata_template_value_terminal_intContext + ): + pass + + # Exit a parse tree produced by ASLParser#jsonata_template_value_terminal_int. + def exitJsonata_template_value_terminal_int( + self, ctx: ASLParser.Jsonata_template_value_terminal_intContext + ): + pass + + # Enter a parse tree produced by ASLParser#jsonata_template_value_terminal_bool. + def enterJsonata_template_value_terminal_bool( + self, ctx: ASLParser.Jsonata_template_value_terminal_boolContext + ): + pass + + # Exit a parse tree produced by ASLParser#jsonata_template_value_terminal_bool. + def exitJsonata_template_value_terminal_bool( + self, ctx: ASLParser.Jsonata_template_value_terminal_boolContext + ): + pass + + # Enter a parse tree produced by ASLParser#jsonata_template_value_terminal_null. + def enterJsonata_template_value_terminal_null( + self, ctx: ASLParser.Jsonata_template_value_terminal_nullContext + ): + pass + + # Exit a parse tree produced by ASLParser#jsonata_template_value_terminal_null. + def exitJsonata_template_value_terminal_null( + self, ctx: ASLParser.Jsonata_template_value_terminal_nullContext + ): + pass + + # Enter a parse tree produced by ASLParser#jsonata_template_value_terminal_expression. + def enterJsonata_template_value_terminal_expression( + self, ctx: ASLParser.Jsonata_template_value_terminal_expressionContext + ): + pass + + # Exit a parse tree produced by ASLParser#jsonata_template_value_terminal_expression. + def exitJsonata_template_value_terminal_expression( + self, ctx: ASLParser.Jsonata_template_value_terminal_expressionContext + ): + pass + + # Enter a parse tree produced by ASLParser#jsonata_template_value_terminal_str. + def enterJsonata_template_value_terminal_str( + self, ctx: ASLParser.Jsonata_template_value_terminal_strContext + ): + pass + + # Exit a parse tree produced by ASLParser#jsonata_template_value_terminal_str. + def exitJsonata_template_value_terminal_str( + self, ctx: ASLParser.Jsonata_template_value_terminal_strContext + ): + pass + # Enter a parse tree produced by ASLParser#result_selector_decl. def enterResult_selector_decl(self, ctx: ASLParser.Result_selector_declContext): pass @@ -525,20 +1181,64 @@ def enterComparison_composite(self, ctx: ASLParser.Comparison_compositeContext): def exitComparison_composite(self, ctx: ASLParser.Comparison_compositeContext): pass - # Enter a parse tree produced by ASLParser#variable_decl. - def enterVariable_decl(self, ctx: ASLParser.Variable_declContext): + # Enter a parse tree produced by ASLParser#variable_decl_path. + def enterVariable_decl_path(self, ctx: ASLParser.Variable_decl_pathContext): pass - # Exit a parse tree produced by ASLParser#variable_decl. - def exitVariable_decl(self, ctx: ASLParser.Variable_declContext): + # Exit a parse tree produced by ASLParser#variable_decl_path. + def exitVariable_decl_path(self, ctx: ASLParser.Variable_decl_pathContext): pass - # Enter a parse tree produced by ASLParser#comparison_func. - def enterComparison_func(self, ctx: ASLParser.Comparison_funcContext): + # Enter a parse tree produced by ASLParser#variable_decl_var. + def enterVariable_decl_var(self, ctx: ASLParser.Variable_decl_varContext): pass - # Exit a parse tree produced by ASLParser#comparison_func. - def exitComparison_func(self, ctx: ASLParser.Comparison_funcContext): + # Exit a parse tree produced by ASLParser#variable_decl_var. + def exitVariable_decl_var(self, ctx: ASLParser.Variable_decl_varContext): + pass + + # Enter a parse tree produced by ASLParser#variable_decl_path_context_object. + def enterVariable_decl_path_context_object( + self, ctx: ASLParser.Variable_decl_path_context_objectContext + ): + pass + + # Exit a parse tree produced by ASLParser#variable_decl_path_context_object. + def exitVariable_decl_path_context_object( + self, ctx: ASLParser.Variable_decl_path_context_objectContext + ): + pass + + # Enter a parse tree produced by ASLParser#condition_lit. + def enterCondition_lit(self, ctx: ASLParser.Condition_litContext): + pass + + # Exit a parse tree produced by ASLParser#condition_lit. + def exitCondition_lit(self, ctx: ASLParser.Condition_litContext): + pass + + # Enter a parse tree produced by ASLParser#condition_expr. + def enterCondition_expr(self, ctx: ASLParser.Condition_exprContext): + pass + + # Exit a parse tree produced by ASLParser#condition_expr. + def exitCondition_expr(self, ctx: ASLParser.Condition_exprContext): + pass + + # Enter a parse tree produced by ASLParser#comparison_func_var. + def enterComparison_func_var(self, ctx: ASLParser.Comparison_func_varContext): + pass + + # Exit a parse tree produced by ASLParser#comparison_func_var. + def exitComparison_func_var(self, ctx: ASLParser.Comparison_func_varContext): + pass + + # Enter a parse tree produced by ASLParser#comparison_func_value. + def enterComparison_func_value(self, ctx: ASLParser.Comparison_func_valueContext): + pass + + # Exit a parse tree produced by ASLParser#comparison_func_value. + def exitComparison_func_value(self, ctx: ASLParser.Comparison_func_valueContext): pass # Enter a parse tree produced by ASLParser#branches_decl. @@ -697,67 +1397,131 @@ def enterCsv_headers_decl(self, ctx: ASLParser.Csv_headers_declContext): def exitCsv_headers_decl(self, ctx: ASLParser.Csv_headers_declContext): pass - # Enter a parse tree produced by ASLParser#max_items_decl. - def enterMax_items_decl(self, ctx: ASLParser.Max_items_declContext): + # Enter a parse tree produced by ASLParser#max_items_jsonata. + def enterMax_items_jsonata(self, ctx: ASLParser.Max_items_jsonataContext): + pass + + # Exit a parse tree produced by ASLParser#max_items_jsonata. + def exitMax_items_jsonata(self, ctx: ASLParser.Max_items_jsonataContext): + pass + + # Enter a parse tree produced by ASLParser#max_items_int. + def enterMax_items_int(self, ctx: ASLParser.Max_items_intContext): pass - # Exit a parse tree produced by ASLParser#max_items_decl. - def exitMax_items_decl(self, ctx: ASLParser.Max_items_declContext): + # Exit a parse tree produced by ASLParser#max_items_int. + def exitMax_items_int(self, ctx: ASLParser.Max_items_intContext): pass - # Enter a parse tree produced by ASLParser#max_items_path_decl. - def enterMax_items_path_decl(self, ctx: ASLParser.Max_items_path_declContext): + # Enter a parse tree produced by ASLParser#max_items_path_var. + def enterMax_items_path_var(self, ctx: ASLParser.Max_items_path_varContext): pass - # Exit a parse tree produced by ASLParser#max_items_path_decl. - def exitMax_items_path_decl(self, ctx: ASLParser.Max_items_path_declContext): + # Exit a parse tree produced by ASLParser#max_items_path_var. + def exitMax_items_path_var(self, ctx: ASLParser.Max_items_path_varContext): pass - # Enter a parse tree produced by ASLParser#tolerated_failure_count_decl. - def enterTolerated_failure_count_decl( - self, ctx: ASLParser.Tolerated_failure_count_declContext + # Enter a parse tree produced by ASLParser#max_items_path. + def enterMax_items_path(self, ctx: ASLParser.Max_items_pathContext): + pass + + # Exit a parse tree produced by ASLParser#max_items_path. + def exitMax_items_path(self, ctx: ASLParser.Max_items_pathContext): + pass + + # Enter a parse tree produced by ASLParser#tolerated_failure_count_jsonata. + def enterTolerated_failure_count_jsonata( + self, ctx: ASLParser.Tolerated_failure_count_jsonataContext + ): + pass + + # Exit a parse tree produced by ASLParser#tolerated_failure_count_jsonata. + def exitTolerated_failure_count_jsonata( + self, ctx: ASLParser.Tolerated_failure_count_jsonataContext + ): + pass + + # Enter a parse tree produced by ASLParser#tolerated_failure_count_int. + def enterTolerated_failure_count_int( + self, ctx: ASLParser.Tolerated_failure_count_intContext ): pass - # Exit a parse tree produced by ASLParser#tolerated_failure_count_decl. - def exitTolerated_failure_count_decl( - self, ctx: ASLParser.Tolerated_failure_count_declContext + # Exit a parse tree produced by ASLParser#tolerated_failure_count_int. + def exitTolerated_failure_count_int( + self, ctx: ASLParser.Tolerated_failure_count_intContext ): pass - # Enter a parse tree produced by ASLParser#tolerated_failure_count_path_decl. - def enterTolerated_failure_count_path_decl( - self, ctx: ASLParser.Tolerated_failure_count_path_declContext + # Enter a parse tree produced by ASLParser#tolerated_failure_count_path_var. + def enterTolerated_failure_count_path_var( + self, ctx: ASLParser.Tolerated_failure_count_path_varContext ): pass - # Exit a parse tree produced by ASLParser#tolerated_failure_count_path_decl. - def exitTolerated_failure_count_path_decl( - self, ctx: ASLParser.Tolerated_failure_count_path_declContext + # Exit a parse tree produced by ASLParser#tolerated_failure_count_path_var. + def exitTolerated_failure_count_path_var( + self, ctx: ASLParser.Tolerated_failure_count_path_varContext ): pass - # Enter a parse tree produced by ASLParser#tolerated_failure_percentage_decl. - def enterTolerated_failure_percentage_decl( - self, ctx: ASLParser.Tolerated_failure_percentage_declContext + # Enter a parse tree produced by ASLParser#tolerated_failure_count_path. + def enterTolerated_failure_count_path( + self, ctx: ASLParser.Tolerated_failure_count_pathContext ): pass - # Exit a parse tree produced by ASLParser#tolerated_failure_percentage_decl. - def exitTolerated_failure_percentage_decl( - self, ctx: ASLParser.Tolerated_failure_percentage_declContext + # Exit a parse tree produced by ASLParser#tolerated_failure_count_path. + def exitTolerated_failure_count_path( + self, ctx: ASLParser.Tolerated_failure_count_pathContext ): pass - # Enter a parse tree produced by ASLParser#tolerated_failure_percentage_path_decl. - def enterTolerated_failure_percentage_path_decl( - self, ctx: ASLParser.Tolerated_failure_percentage_path_declContext + # Enter a parse tree produced by ASLParser#tolerated_failure_percentage_jsonata. + def enterTolerated_failure_percentage_jsonata( + self, ctx: ASLParser.Tolerated_failure_percentage_jsonataContext ): pass - # Exit a parse tree produced by ASLParser#tolerated_failure_percentage_path_decl. - def exitTolerated_failure_percentage_path_decl( - self, ctx: ASLParser.Tolerated_failure_percentage_path_declContext + # Exit a parse tree produced by ASLParser#tolerated_failure_percentage_jsonata. + def exitTolerated_failure_percentage_jsonata( + self, ctx: ASLParser.Tolerated_failure_percentage_jsonataContext + ): + pass + + # Enter a parse tree produced by ASLParser#tolerated_failure_percentage_number. + def enterTolerated_failure_percentage_number( + self, ctx: ASLParser.Tolerated_failure_percentage_numberContext + ): + pass + + # Exit a parse tree produced by ASLParser#tolerated_failure_percentage_number. + def exitTolerated_failure_percentage_number( + self, ctx: ASLParser.Tolerated_failure_percentage_numberContext + ): + pass + + # Enter a parse tree produced by ASLParser#tolerated_failure_percentage_path_var. + def enterTolerated_failure_percentage_path_var( + self, ctx: ASLParser.Tolerated_failure_percentage_path_varContext + ): + pass + + # Exit a parse tree produced by ASLParser#tolerated_failure_percentage_path_var. + def exitTolerated_failure_percentage_path_var( + self, ctx: ASLParser.Tolerated_failure_percentage_path_varContext + ): + pass + + # Enter a parse tree produced by ASLParser#tolerated_failure_percentage_path. + def enterTolerated_failure_percentage_path( + self, ctx: ASLParser.Tolerated_failure_percentage_pathContext + ): + pass + + # Exit a parse tree produced by ASLParser#tolerated_failure_percentage_path. + def exitTolerated_failure_percentage_path( + self, ctx: ASLParser.Tolerated_failure_percentage_pathContext ): pass @@ -769,6 +1533,22 @@ def enterLabel_decl(self, ctx: ASLParser.Label_declContext): def exitLabel_decl(self, ctx: ASLParser.Label_declContext): pass + # Enter a parse tree produced by ASLParser#result_writer_decl. + def enterResult_writer_decl(self, ctx: ASLParser.Result_writer_declContext): + pass + + # Exit a parse tree produced by ASLParser#result_writer_decl. + def exitResult_writer_decl(self, ctx: ASLParser.Result_writer_declContext): + pass + + # Enter a parse tree produced by ASLParser#result_writer_field. + def enterResult_writer_field(self, ctx: ASLParser.Result_writer_fieldContext): + pass + + # Exit a parse tree produced by ASLParser#result_writer_field. + def exitResult_writer_field(self, ctx: ASLParser.Result_writer_fieldContext): + pass + # Enter a parse tree produced by ASLParser#retry_decl. def enterRetry_decl(self, ctx: ASLParser.Retry_declContext): pass diff --git a/moto/stepfunctions/parser/asl/antlr/runtime/ASLParserVisitor.py b/moto/stepfunctions/parser/asl/antlr/runtime/ASLParserVisitor.py index f5cfc8bc0218..88f384ce0f6e 100644 --- a/moto/stepfunctions/parser/asl/antlr/runtime/ASLParserVisitor.py +++ b/moto/stepfunctions/parser/asl/antlr/runtime/ASLParserVisitor.py @@ -1,4 +1,4 @@ -# Generated from ASLParser.g4 by ANTLR 4.13.1 +# Generated from ASLParser.g4 by ANTLR 4.13.2 from antlr4 import ParseTreeVisitor if "." in __name__: @@ -34,6 +34,10 @@ def visitComment_decl(self, ctx: ASLParser.Comment_declContext): def visitVersion_decl(self, ctx: ASLParser.Version_declContext): return self.visitChildren(ctx) + # Visit a parse tree produced by ASLParser#query_language_decl. + def visitQuery_language_decl(self, ctx: ASLParser.Query_language_declContext): + return self.visitChildren(ctx) + # Visit a parse tree produced by ASLParser#state_stmt. def visitState_stmt(self, ctx: ASLParser.State_stmtContext): return self.visitChildren(ctx) @@ -66,8 +70,18 @@ def visitNext_decl(self, ctx: ASLParser.Next_declContext): def visitResource_decl(self, ctx: ASLParser.Resource_declContext): return self.visitChildren(ctx) - # Visit a parse tree produced by ASLParser#input_path_decl. - def visitInput_path_decl(self, ctx: ASLParser.Input_path_declContext): + # Visit a parse tree produced by ASLParser#input_path_decl_var. + def visitInput_path_decl_var(self, ctx: ASLParser.Input_path_decl_varContext): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#input_path_decl_path_context_object. + def visitInput_path_decl_path_context_object( + self, ctx: ASLParser.Input_path_decl_path_context_objectContext + ): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#input_path_decl_path. + def visitInput_path_decl_path(self, ctx: ASLParser.Input_path_decl_pathContext): return self.visitChildren(ctx) # Visit a parse tree produced by ASLParser#result_decl. @@ -78,8 +92,18 @@ def visitResult_decl(self, ctx: ASLParser.Result_declContext): def visitResult_path_decl(self, ctx: ASLParser.Result_path_declContext): return self.visitChildren(ctx) - # Visit a parse tree produced by ASLParser#output_path_decl. - def visitOutput_path_decl(self, ctx: ASLParser.Output_path_declContext): + # Visit a parse tree produced by ASLParser#output_path_decl_var. + def visitOutput_path_decl_var(self, ctx: ASLParser.Output_path_decl_varContext): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#output_path_decl_path_context_object. + def visitOutput_path_decl_path_context_object( + self, ctx: ASLParser.Output_path_decl_path_context_objectContext + ): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#output_path_decl_path. + def visitOutput_path_decl_path(self, ctx: ASLParser.Output_path_decl_pathContext): return self.visitChildren(ctx) # Visit a parse tree produced by ASLParser#end_decl. @@ -90,88 +114,228 @@ def visitEnd_decl(self, ctx: ASLParser.End_declContext): def visitDefault_decl(self, ctx: ASLParser.Default_declContext): return self.visitChildren(ctx) - # Visit a parse tree produced by ASLParser#error_decl. - def visitError_decl(self, ctx: ASLParser.Error_declContext): + # Visit a parse tree produced by ASLParser#error_jsonata. + def visitError_jsonata(self, ctx: ASLParser.Error_jsonataContext): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#error_string. + def visitError_string(self, ctx: ASLParser.Error_stringContext): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#error_path_decl_var. + def visitError_path_decl_var(self, ctx: ASLParser.Error_path_decl_varContext): return self.visitChildren(ctx) # Visit a parse tree produced by ASLParser#error_path_decl_path. def visitError_path_decl_path(self, ctx: ASLParser.Error_path_decl_pathContext): return self.visitChildren(ctx) + # Visit a parse tree produced by ASLParser#error_path_decl_context. + def visitError_path_decl_context( + self, ctx: ASLParser.Error_path_decl_contextContext + ): + return self.visitChildren(ctx) + # Visit a parse tree produced by ASLParser#error_path_decl_intrinsic. def visitError_path_decl_intrinsic( self, ctx: ASLParser.Error_path_decl_intrinsicContext ): return self.visitChildren(ctx) - # Visit a parse tree produced by ASLParser#cause_decl. - def visitCause_decl(self, ctx: ASLParser.Cause_declContext): + # Visit a parse tree produced by ASLParser#cause_jsonata. + def visitCause_jsonata(self, ctx: ASLParser.Cause_jsonataContext): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#cause_string. + def visitCause_string(self, ctx: ASLParser.Cause_stringContext): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#cause_path_decl_var. + def visitCause_path_decl_var(self, ctx: ASLParser.Cause_path_decl_varContext): return self.visitChildren(ctx) # Visit a parse tree produced by ASLParser#cause_path_decl_path. def visitCause_path_decl_path(self, ctx: ASLParser.Cause_path_decl_pathContext): return self.visitChildren(ctx) + # Visit a parse tree produced by ASLParser#cause_path_decl_context. + def visitCause_path_decl_context( + self, ctx: ASLParser.Cause_path_decl_contextContext + ): + return self.visitChildren(ctx) + # Visit a parse tree produced by ASLParser#cause_path_decl_intrinsic. def visitCause_path_decl_intrinsic( self, ctx: ASLParser.Cause_path_decl_intrinsicContext ): return self.visitChildren(ctx) - # Visit a parse tree produced by ASLParser#seconds_decl. - def visitSeconds_decl(self, ctx: ASLParser.Seconds_declContext): + # Visit a parse tree produced by ASLParser#seconds_jsonata. + def visitSeconds_jsonata(self, ctx: ASLParser.Seconds_jsonataContext): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#seconds_int. + def visitSeconds_int(self, ctx: ASLParser.Seconds_intContext): return self.visitChildren(ctx) - # Visit a parse tree produced by ASLParser#seconds_path_decl. - def visitSeconds_path_decl(self, ctx: ASLParser.Seconds_path_declContext): + # Visit a parse tree produced by ASLParser#seconds_path_decl_var. + def visitSeconds_path_decl_var(self, ctx: ASLParser.Seconds_path_decl_varContext): return self.visitChildren(ctx) - # Visit a parse tree produced by ASLParser#timestamp_decl. - def visitTimestamp_decl(self, ctx: ASLParser.Timestamp_declContext): + # Visit a parse tree produced by ASLParser#seconds_path_decl_value. + def visitSeconds_path_decl_value( + self, ctx: ASLParser.Seconds_path_decl_valueContext + ): return self.visitChildren(ctx) - # Visit a parse tree produced by ASLParser#timestamp_path_decl. - def visitTimestamp_path_decl(self, ctx: ASLParser.Timestamp_path_declContext): + # Visit a parse tree produced by ASLParser#timestamp_jsonata. + def visitTimestamp_jsonata(self, ctx: ASLParser.Timestamp_jsonataContext): return self.visitChildren(ctx) - # Visit a parse tree produced by ASLParser#items_path_decl. - def visitItems_path_decl(self, ctx: ASLParser.Items_path_declContext): + # Visit a parse tree produced by ASLParser#timestamp_string. + def visitTimestamp_string(self, ctx: ASLParser.Timestamp_stringContext): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#timestamp_path_decl_var. + def visitTimestamp_path_decl_var( + self, ctx: ASLParser.Timestamp_path_decl_varContext + ): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#timestamp_path_decl_value. + def visitTimestamp_path_decl_value( + self, ctx: ASLParser.Timestamp_path_decl_valueContext + ): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#items_array. + def visitItems_array(self, ctx: ASLParser.Items_arrayContext): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#items_jsonata. + def visitItems_jsonata(self, ctx: ASLParser.Items_jsonataContext): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#items_path_decl_path_context_object. + def visitItems_path_decl_path_context_object( + self, ctx: ASLParser.Items_path_decl_path_context_objectContext + ): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#items_path_decl_path_var. + def visitItems_path_decl_path_var( + self, ctx: ASLParser.Items_path_decl_path_varContext + ): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#items_path_decl_path. + def visitItems_path_decl_path(self, ctx: ASLParser.Items_path_decl_pathContext): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#max_concurrency_jsonata. + def visitMax_concurrency_jsonata( + self, ctx: ASLParser.Max_concurrency_jsonataContext + ): return self.visitChildren(ctx) - # Visit a parse tree produced by ASLParser#max_concurrency_decl. - def visitMax_concurrency_decl(self, ctx: ASLParser.Max_concurrency_declContext): + # Visit a parse tree produced by ASLParser#max_concurrency_int. + def visitMax_concurrency_int(self, ctx: ASLParser.Max_concurrency_intContext): return self.visitChildren(ctx) - # Visit a parse tree produced by ASLParser#max_concurrency_path_decl. - def visitMax_concurrency_path_decl( - self, ctx: ASLParser.Max_concurrency_path_declContext + # Visit a parse tree produced by ASLParser#max_concurrency_path_var. + def visitMax_concurrency_path_var( + self, ctx: ASLParser.Max_concurrency_path_varContext ): return self.visitChildren(ctx) + # Visit a parse tree produced by ASLParser#max_concurrency_path. + def visitMax_concurrency_path(self, ctx: ASLParser.Max_concurrency_pathContext): + return self.visitChildren(ctx) + # Visit a parse tree produced by ASLParser#parameters_decl. def visitParameters_decl(self, ctx: ASLParser.Parameters_declContext): return self.visitChildren(ctx) - # Visit a parse tree produced by ASLParser#timeout_seconds_decl. - def visitTimeout_seconds_decl(self, ctx: ASLParser.Timeout_seconds_declContext): + # Visit a parse tree produced by ASLParser#credentials_decl. + def visitCredentials_decl(self, ctx: ASLParser.Credentials_declContext): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#role_arn_jsonata. + def visitRole_arn_jsonata(self, ctx: ASLParser.Role_arn_jsonataContext): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#role_arn_path. + def visitRole_arn_path(self, ctx: ASLParser.Role_arn_pathContext): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#role_arn_path_context_obj. + def visitRole_arn_path_context_obj( + self, ctx: ASLParser.Role_arn_path_context_objContext + ): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#role_arn_intrinsic_func. + def visitRole_arn_intrinsic_func( + self, ctx: ASLParser.Role_arn_intrinsic_funcContext + ): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#role_arn_var. + def visitRole_arn_var(self, ctx: ASLParser.Role_arn_varContext): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#role_arn_str. + def visitRole_arn_str(self, ctx: ASLParser.Role_arn_strContext): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#timeout_seconds_jsonata. + def visitTimeout_seconds_jsonata( + self, ctx: ASLParser.Timeout_seconds_jsonataContext + ): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#timeout_seconds_int. + def visitTimeout_seconds_int(self, ctx: ASLParser.Timeout_seconds_intContext): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#timeout_seconds_path_decl_var. + def visitTimeout_seconds_path_decl_var( + self, ctx: ASLParser.Timeout_seconds_path_decl_varContext + ): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#timeout_seconds_path_decl_path. + def visitTimeout_seconds_path_decl_path( + self, ctx: ASLParser.Timeout_seconds_path_decl_pathContext + ): return self.visitChildren(ctx) - # Visit a parse tree produced by ASLParser#timeout_seconds_path_decl. - def visitTimeout_seconds_path_decl( - self, ctx: ASLParser.Timeout_seconds_path_declContext + # Visit a parse tree produced by ASLParser#heartbeat_seconds_jsonata. + def visitHeartbeat_seconds_jsonata( + self, ctx: ASLParser.Heartbeat_seconds_jsonataContext ): return self.visitChildren(ctx) - # Visit a parse tree produced by ASLParser#heartbeat_seconds_decl. - def visitHeartbeat_seconds_decl(self, ctx: ASLParser.Heartbeat_seconds_declContext): + # Visit a parse tree produced by ASLParser#heartbeat_seconds_int. + def visitHeartbeat_seconds_int(self, ctx: ASLParser.Heartbeat_seconds_intContext): return self.visitChildren(ctx) - # Visit a parse tree produced by ASLParser#heartbeat_seconds_path_decl. - def visitHeartbeat_seconds_path_decl( - self, ctx: ASLParser.Heartbeat_seconds_path_declContext + # Visit a parse tree produced by ASLParser#heartbeat_seconds_path_decl_var. + def visitHeartbeat_seconds_path_decl_var( + self, ctx: ASLParser.Heartbeat_seconds_path_decl_varContext ): return self.visitChildren(ctx) + # Visit a parse tree produced by ASLParser#heartbeat_seconds_path_decl_path. + def visitHeartbeat_seconds_path_decl_path( + self, ctx: ASLParser.Heartbeat_seconds_path_decl_pathContext + ): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#variable_sample. + def visitVariable_sample(self, ctx: ASLParser.Variable_sampleContext): + return self.visitChildren(ctx) + # Visit a parse tree produced by ASLParser#payload_tmpl_decl. def visitPayload_tmpl_decl(self, ctx: ASLParser.Payload_tmpl_declContext): return self.visitChildren(ctx) @@ -192,12 +356,12 @@ def visitPayload_binding_intrinsic_func( ): return self.visitChildren(ctx) - # Visit a parse tree produced by ASLParser#payload_binding_value. - def visitPayload_binding_value(self, ctx: ASLParser.Payload_binding_valueContext): + # Visit a parse tree produced by ASLParser#payload_binding_var. + def visitPayload_binding_var(self, ctx: ASLParser.Payload_binding_varContext): return self.visitChildren(ctx) - # Visit a parse tree produced by ASLParser#intrinsic_func. - def visitIntrinsic_func(self, ctx: ASLParser.Intrinsic_funcContext): + # Visit a parse tree produced by ASLParser#payload_binding_value. + def visitPayload_binding_value(self, ctx: ASLParser.Payload_binding_valueContext): return self.visitChildren(ctx) # Visit a parse tree produced by ASLParser#payload_arr_decl. @@ -228,6 +392,170 @@ def visitPayload_value_null(self, ctx: ASLParser.Payload_value_nullContext): def visitPayload_value_str(self, ctx: ASLParser.Payload_value_strContext): return self.visitChildren(ctx) + # Visit a parse tree produced by ASLParser#assign_decl. + def visitAssign_decl(self, ctx: ASLParser.Assign_declContext): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#assign_decl_body. + def visitAssign_decl_body(self, ctx: ASLParser.Assign_decl_bodyContext): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#assign_decl_binding. + def visitAssign_decl_binding(self, ctx: ASLParser.Assign_decl_bindingContext): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#assign_template_value_object. + def visitAssign_template_value_object( + self, ctx: ASLParser.Assign_template_value_objectContext + ): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#assign_template_binding_path. + def visitAssign_template_binding_path( + self, ctx: ASLParser.Assign_template_binding_pathContext + ): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#assign_template_binding_path_context. + def visitAssign_template_binding_path_context( + self, ctx: ASLParser.Assign_template_binding_path_contextContext + ): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#assign_template_binding_var. + def visitAssign_template_binding_var( + self, ctx: ASLParser.Assign_template_binding_varContext + ): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#assign_template_binding_intrinsic_func. + def visitAssign_template_binding_intrinsic_func( + self, ctx: ASLParser.Assign_template_binding_intrinsic_funcContext + ): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#assign_template_binding_assign_value. + def visitAssign_template_binding_assign_value( + self, ctx: ASLParser.Assign_template_binding_assign_valueContext + ): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#assign_template_value. + def visitAssign_template_value(self, ctx: ASLParser.Assign_template_valueContext): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#assign_template_value_array. + def visitAssign_template_value_array( + self, ctx: ASLParser.Assign_template_value_arrayContext + ): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#assign_template_value_terminal_float. + def visitAssign_template_value_terminal_float( + self, ctx: ASLParser.Assign_template_value_terminal_floatContext + ): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#assign_template_value_terminal_int. + def visitAssign_template_value_terminal_int( + self, ctx: ASLParser.Assign_template_value_terminal_intContext + ): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#assign_template_value_terminal_bool. + def visitAssign_template_value_terminal_bool( + self, ctx: ASLParser.Assign_template_value_terminal_boolContext + ): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#assign_template_value_terminal_null. + def visitAssign_template_value_terminal_null( + self, ctx: ASLParser.Assign_template_value_terminal_nullContext + ): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#assign_template_value_terminal_expression. + def visitAssign_template_value_terminal_expression( + self, ctx: ASLParser.Assign_template_value_terminal_expressionContext + ): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#assign_template_value_terminal_str. + def visitAssign_template_value_terminal_str( + self, ctx: ASLParser.Assign_template_value_terminal_strContext + ): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#arguments_object. + def visitArguments_object(self, ctx: ASLParser.Arguments_objectContext): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#arguments_expr. + def visitArguments_expr(self, ctx: ASLParser.Arguments_exprContext): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#output_decl. + def visitOutput_decl(self, ctx: ASLParser.Output_declContext): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#jsonata_template_value_object. + def visitJsonata_template_value_object( + self, ctx: ASLParser.Jsonata_template_value_objectContext + ): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#jsonata_template_binding. + def visitJsonata_template_binding( + self, ctx: ASLParser.Jsonata_template_bindingContext + ): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#jsonata_template_value. + def visitJsonata_template_value(self, ctx: ASLParser.Jsonata_template_valueContext): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#jsonata_template_value_array. + def visitJsonata_template_value_array( + self, ctx: ASLParser.Jsonata_template_value_arrayContext + ): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#jsonata_template_value_terminal_float. + def visitJsonata_template_value_terminal_float( + self, ctx: ASLParser.Jsonata_template_value_terminal_floatContext + ): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#jsonata_template_value_terminal_int. + def visitJsonata_template_value_terminal_int( + self, ctx: ASLParser.Jsonata_template_value_terminal_intContext + ): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#jsonata_template_value_terminal_bool. + def visitJsonata_template_value_terminal_bool( + self, ctx: ASLParser.Jsonata_template_value_terminal_boolContext + ): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#jsonata_template_value_terminal_null. + def visitJsonata_template_value_terminal_null( + self, ctx: ASLParser.Jsonata_template_value_terminal_nullContext + ): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#jsonata_template_value_terminal_expression. + def visitJsonata_template_value_terminal_expression( + self, ctx: ASLParser.Jsonata_template_value_terminal_expressionContext + ): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#jsonata_template_value_terminal_str. + def visitJsonata_template_value_terminal_str( + self, ctx: ASLParser.Jsonata_template_value_terminal_strContext + ): + return self.visitChildren(ctx) + # Visit a parse tree produced by ASLParser#result_selector_decl. def visitResult_selector_decl(self, ctx: ASLParser.Result_selector_declContext): return self.visitChildren(ctx) @@ -268,12 +596,34 @@ def visitComparison_composite_stmt( def visitComparison_composite(self, ctx: ASLParser.Comparison_compositeContext): return self.visitChildren(ctx) - # Visit a parse tree produced by ASLParser#variable_decl. - def visitVariable_decl(self, ctx: ASLParser.Variable_declContext): + # Visit a parse tree produced by ASLParser#variable_decl_path. + def visitVariable_decl_path(self, ctx: ASLParser.Variable_decl_pathContext): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#variable_decl_var. + def visitVariable_decl_var(self, ctx: ASLParser.Variable_decl_varContext): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#variable_decl_path_context_object. + def visitVariable_decl_path_context_object( + self, ctx: ASLParser.Variable_decl_path_context_objectContext + ): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#condition_lit. + def visitCondition_lit(self, ctx: ASLParser.Condition_litContext): return self.visitChildren(ctx) - # Visit a parse tree produced by ASLParser#comparison_func. - def visitComparison_func(self, ctx: ASLParser.Comparison_funcContext): + # Visit a parse tree produced by ASLParser#condition_expr. + def visitCondition_expr(self, ctx: ASLParser.Condition_exprContext): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#comparison_func_var. + def visitComparison_func_var(self, ctx: ASLParser.Comparison_func_varContext): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#comparison_func_value. + def visitComparison_func_value(self, ctx: ASLParser.Comparison_func_valueContext): return self.visitChildren(ctx) # Visit a parse tree produced by ASLParser#branches_decl. @@ -354,35 +704,67 @@ def visitCsv_header_location_decl( def visitCsv_headers_decl(self, ctx: ASLParser.Csv_headers_declContext): return self.visitChildren(ctx) - # Visit a parse tree produced by ASLParser#max_items_decl. - def visitMax_items_decl(self, ctx: ASLParser.Max_items_declContext): + # Visit a parse tree produced by ASLParser#max_items_jsonata. + def visitMax_items_jsonata(self, ctx: ASLParser.Max_items_jsonataContext): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#max_items_int. + def visitMax_items_int(self, ctx: ASLParser.Max_items_intContext): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#max_items_path_var. + def visitMax_items_path_var(self, ctx: ASLParser.Max_items_path_varContext): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#max_items_path. + def visitMax_items_path(self, ctx: ASLParser.Max_items_pathContext): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#tolerated_failure_count_jsonata. + def visitTolerated_failure_count_jsonata( + self, ctx: ASLParser.Tolerated_failure_count_jsonataContext + ): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#tolerated_failure_count_int. + def visitTolerated_failure_count_int( + self, ctx: ASLParser.Tolerated_failure_count_intContext + ): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#tolerated_failure_count_path_var. + def visitTolerated_failure_count_path_var( + self, ctx: ASLParser.Tolerated_failure_count_path_varContext + ): return self.visitChildren(ctx) - # Visit a parse tree produced by ASLParser#max_items_path_decl. - def visitMax_items_path_decl(self, ctx: ASLParser.Max_items_path_declContext): + # Visit a parse tree produced by ASLParser#tolerated_failure_count_path. + def visitTolerated_failure_count_path( + self, ctx: ASLParser.Tolerated_failure_count_pathContext + ): return self.visitChildren(ctx) - # Visit a parse tree produced by ASLParser#tolerated_failure_count_decl. - def visitTolerated_failure_count_decl( - self, ctx: ASLParser.Tolerated_failure_count_declContext + # Visit a parse tree produced by ASLParser#tolerated_failure_percentage_jsonata. + def visitTolerated_failure_percentage_jsonata( + self, ctx: ASLParser.Tolerated_failure_percentage_jsonataContext ): return self.visitChildren(ctx) - # Visit a parse tree produced by ASLParser#tolerated_failure_count_path_decl. - def visitTolerated_failure_count_path_decl( - self, ctx: ASLParser.Tolerated_failure_count_path_declContext + # Visit a parse tree produced by ASLParser#tolerated_failure_percentage_number. + def visitTolerated_failure_percentage_number( + self, ctx: ASLParser.Tolerated_failure_percentage_numberContext ): return self.visitChildren(ctx) - # Visit a parse tree produced by ASLParser#tolerated_failure_percentage_decl. - def visitTolerated_failure_percentage_decl( - self, ctx: ASLParser.Tolerated_failure_percentage_declContext + # Visit a parse tree produced by ASLParser#tolerated_failure_percentage_path_var. + def visitTolerated_failure_percentage_path_var( + self, ctx: ASLParser.Tolerated_failure_percentage_path_varContext ): return self.visitChildren(ctx) - # Visit a parse tree produced by ASLParser#tolerated_failure_percentage_path_decl. - def visitTolerated_failure_percentage_path_decl( - self, ctx: ASLParser.Tolerated_failure_percentage_path_declContext + # Visit a parse tree produced by ASLParser#tolerated_failure_percentage_path. + def visitTolerated_failure_percentage_path( + self, ctx: ASLParser.Tolerated_failure_percentage_pathContext ): return self.visitChildren(ctx) @@ -390,6 +772,14 @@ def visitTolerated_failure_percentage_path_decl( def visitLabel_decl(self, ctx: ASLParser.Label_declContext): return self.visitChildren(ctx) + # Visit a parse tree produced by ASLParser#result_writer_decl. + def visitResult_writer_decl(self, ctx: ASLParser.Result_writer_declContext): + return self.visitChildren(ctx) + + # Visit a parse tree produced by ASLParser#result_writer_field. + def visitResult_writer_field(self, ctx: ASLParser.Result_writer_fieldContext): + return self.visitChildren(ctx) + # Visit a parse tree produced by ASLParser#retry_decl. def visitRetry_decl(self, ctx: ASLParser.Retry_declContext): return self.visitChildren(ctx) diff --git a/moto/stepfunctions/parser/asl/eval/contextobject/__init__.py b/moto/stepfunctions/parser/asl/component/common/assign/__init__.py similarity index 100% rename from moto/stepfunctions/parser/asl/eval/contextobject/__init__.py rename to moto/stepfunctions/parser/asl/component/common/assign/__init__.py diff --git a/moto/stepfunctions/parser/asl/component/common/assign/assign_decl.py b/moto/stepfunctions/parser/asl/component/common/assign/assign_decl.py new file mode 100644 index 000000000000..7a209911114e --- /dev/null +++ b/moto/stepfunctions/parser/asl/component/common/assign/assign_decl.py @@ -0,0 +1,24 @@ +from typing import Any, Dict, List + +from moto.stepfunctions.parser.asl.component.common.assign.assign_decl_binding import ( + AssignDeclBinding, +) +from moto.stepfunctions.parser.asl.component.eval_component import EvalComponent +from moto.stepfunctions.parser.asl.eval.environment import Environment + + +class AssignDecl(EvalComponent): + declaration_bindings: List[AssignDeclBinding] + + def __init__(self, declaration_bindings: List[AssignDeclBinding]): + super().__init__() + self.declaration_bindings = declaration_bindings + + def _eval_body(self, env: Environment) -> None: + declarations: Dict[str, Any] = dict() + for declaration_binding in self.declaration_bindings: + declaration_binding.eval(env=env) + binding: Dict[str, Any] = env.stack.pop() + declarations.update(binding) + for identifier, value in declarations.items(): + env.variable_store.set(variable_identifier=identifier, variable_value=value) diff --git a/moto/stepfunctions/parser/asl/component/common/assign/assign_decl_binding.py b/moto/stepfunctions/parser/asl/component/common/assign/assign_decl_binding.py new file mode 100644 index 000000000000..fbb9f150bd29 --- /dev/null +++ b/moto/stepfunctions/parser/asl/component/common/assign/assign_decl_binding.py @@ -0,0 +1,17 @@ +from moto.stepfunctions.parser.asl.component.common.assign.assign_template_binding import ( + AssignTemplateBinding, +) +from moto.stepfunctions.parser.asl.component.eval_component import EvalComponent +from moto.stepfunctions.parser.asl.eval.environment import Environment + + +class AssignDeclBinding(EvalComponent): + binding: AssignTemplateBinding + + def __init__(self, binding: AssignTemplateBinding): + super().__init__() + self.binding = binding + + def _eval_body(self, env: Environment) -> None: + env.stack.append(dict()) + self.binding.eval(env=env) diff --git a/moto/stepfunctions/parser/asl/component/common/assign/assign_template_binding.py b/moto/stepfunctions/parser/asl/component/common/assign/assign_template_binding.py new file mode 100644 index 000000000000..4651633a6749 --- /dev/null +++ b/moto/stepfunctions/parser/asl/component/common/assign/assign_template_binding.py @@ -0,0 +1,106 @@ +from __future__ import annotations + +import abc +from typing import Any + +from moto.stepfunctions.parser.asl.component.common.assign.assign_template_value import ( + AssignTemplateValue, +) +from moto.stepfunctions.parser.asl.component.common.variable_sample import ( + VariableSample, +) +from moto.stepfunctions.parser.asl.component.eval_component import EvalComponent +from moto.stepfunctions.parser.asl.component.intrinsic.function.function import Function +from moto.stepfunctions.parser.asl.eval.environment import Environment +from moto.stepfunctions.parser.asl.parse.intrinsic.intrinsic_parser import ( + IntrinsicParser, +) +from moto.stepfunctions.parser.asl.utils.json_path import extract_json + + +class AssignTemplateBinding(EvalComponent, abc.ABC): + identifier: str + + def __init__(self, identifier: str): + super().__init__() + self.identifier = identifier + + @abc.abstractmethod + def _eval_value(self, env: Environment) -> Any: ... + + def _eval_body(self, env: Environment) -> None: + assign_object: dict = env.stack.pop() + assign_value = self._eval_value(env=env) + assign_object[self.identifier] = assign_value + env.stack.append(assign_object) + + +class AssignTemplateBindingPath(AssignTemplateBinding): + path: str + + def __init__(self, identifier: str, path: str): + super().__init__(identifier=identifier) + self.path = path + + def _eval_value(self, env: Environment) -> Any: + memory_value = env.stack[-1] + path_output = extract_json(self.path, memory_value) + return path_output + + +class AssignTemplateBindingPathContext(AssignTemplateBindingPath): + @classmethod + def from_raw( + cls, identifier: str, string_path_context_obj: str + ) -> AssignTemplateBindingPathContext: + path_context_obj: str = string_path_context_obj[1:] + return cls(identifier=identifier, path=path_context_obj) + + def _eval_value(self, env: Environment) -> Any: + path_output = extract_json( + self.path, env.states.context_object.context_object_data + ) + return path_output + + +class AssignTemplateBindingIntrinsicFunction(AssignTemplateBinding): + function_literal: str + function: Function + + def __init__(self, identifier: str, function_literal: str): + super().__init__(identifier=identifier) + self.function_literal = function_literal + self.function, _ = IntrinsicParser.parse(self.function_literal) + + def _eval_value(self, env: Environment) -> Any: + # TODO: resolve jsonata variable references as arguments. + # should probably be done in the function object. + self.function.eval(env=env) + val = env.stack.pop() + return val + + +class AssignTemplateBindingVar(AssignTemplateBinding): + variable_sample: VariableSample + + def __init__(self, identifier: str, variable_sample: VariableSample): + super().__init__(identifier=identifier) + self.variable_sample = variable_sample + + def _eval_value(self, env: Environment) -> Any: + self.variable_sample.eval(env=env) + value = env.stack.pop() + return value + + +class AssignTemplateBindingValue(AssignTemplateBinding): + assign_value: AssignTemplateValue + + def __init__(self, identifier: str, assign_value: AssignTemplateValue): + super().__init__(identifier=identifier) + self.assign_value = assign_value + + def _eval_value(self, env: Environment) -> Any: + self.assign_value.eval(env=env) + value = env.stack.pop() + return value diff --git a/moto/stepfunctions/parser/asl/component/common/assign/assign_template_value.py b/moto/stepfunctions/parser/asl/component/common/assign/assign_template_value.py new file mode 100644 index 000000000000..03f609140614 --- /dev/null +++ b/moto/stepfunctions/parser/asl/component/common/assign/assign_template_value.py @@ -0,0 +1,6 @@ +import abc + +from moto.stepfunctions.parser.asl.component.eval_component import EvalComponent + + +class AssignTemplateValue(EvalComponent, abc.ABC): ... diff --git a/moto/stepfunctions/parser/asl/component/common/assign/assign_template_value_array.py b/moto/stepfunctions/parser/asl/component/common/assign/assign_template_value_array.py new file mode 100644 index 000000000000..1046ec04ea1e --- /dev/null +++ b/moto/stepfunctions/parser/asl/component/common/assign/assign_template_value_array.py @@ -0,0 +1,20 @@ +from typing import List + +from moto.stepfunctions.parser.asl.component.common.assign.assign_template_value import ( + AssignTemplateValue, +) +from moto.stepfunctions.parser.asl.eval.environment import Environment + + +class AssignTemplateValueArray(AssignTemplateValue): + values: List[AssignTemplateValue] + + def __init__(self, values: List[AssignTemplateValue]): + self.values = values + + def _eval_body(self, env: Environment) -> None: + arr = list() + for value in self.values: + value.eval(env) + arr.append(env.stack.pop()) + env.stack.append(arr) diff --git a/moto/stepfunctions/parser/asl/component/common/assign/assign_template_value_object.py b/moto/stepfunctions/parser/asl/component/common/assign/assign_template_value_object.py new file mode 100644 index 000000000000..e9dc29d165b9 --- /dev/null +++ b/moto/stepfunctions/parser/asl/component/common/assign/assign_template_value_object.py @@ -0,0 +1,21 @@ +from typing import List + +from moto.stepfunctions.parser.asl.component.common.assign.assign_template_binding import ( + AssignTemplateBinding, +) +from moto.stepfunctions.parser.asl.component.common.assign.assign_template_value import ( + AssignTemplateValue, +) +from moto.stepfunctions.parser.asl.eval.environment import Environment + + +class AssignTemplateValueObject(AssignTemplateValue): + bindings: List[AssignTemplateBinding] + + def __init__(self, bindings: List[AssignTemplateBinding]): + self.bindings = bindings + + def _eval_body(self, env: Environment) -> None: + env.stack.append(dict()) + for binding in self.bindings: + binding.eval(env) diff --git a/moto/stepfunctions/parser/asl/component/common/assign/assign_template_value_terminal.py b/moto/stepfunctions/parser/asl/component/common/assign/assign_template_value_terminal.py new file mode 100644 index 000000000000..58e9942b9480 --- /dev/null +++ b/moto/stepfunctions/parser/asl/component/common/assign/assign_template_value_terminal.py @@ -0,0 +1,94 @@ +import abc +from typing import Any, Set + +from moto.stepfunctions.parser.asl.component.common.assign.assign_template_value import ( + AssignTemplateValue, +) +from moto.stepfunctions.parser.asl.component.intrinsic.jsonata import ( + get_intrinsic_functions_declarations, +) +from moto.stepfunctions.parser.asl.eval.environment import Environment +from moto.stepfunctions.parser.asl.jsonata.jsonata import ( + JSONataExpression, + VariableDeclarations, + VariableReference, + compose_jsonata_expression, + eval_jsonata_expression, + extract_jsonata_variable_references, +) +from moto.stepfunctions.parser.asl.jsonata.validations import ( + validate_jsonata_expression_output, +) + + +class AssignTemplateValueTerminal(AssignTemplateValue, abc.ABC): ... + + +class AssignTemplateValueTerminalLit(AssignTemplateValueTerminal): + value: Any + + def __init__(self, value: Any): + super().__init__() + self.value = value + + def _eval_body(self, env: Environment) -> None: + env.stack.append(self.value) + + +class AssignTemplateValueTerminalExpression(AssignTemplateValueTerminal): + expression: str + + def __init__(self, expression: str): + super().__init__() + # TODO: check for illegal functions ($, $$, $eval) + self.expression = expression + + def _eval_body(self, env: Environment) -> None: + # Get the variables sampled in the jsonata expression. + expression_variable_references: Set[VariableReference] = ( + extract_jsonata_variable_references(self.expression) + ) + + # Sample declarations for used intrinsic functions. Place this at the start allowing users to + # override these identifiers with custom variable declarations. + functions_variable_declarations: VariableDeclarations = ( + get_intrinsic_functions_declarations( + variable_references=expression_variable_references + ) + ) + + # Sample $states values into expression. + states_variable_declarations: VariableDeclarations = ( + env.states.to_variable_declarations( + variable_references=expression_variable_references + ) + ) + + # Sample Variable store values in to expression. + # TODO: this could be optimised by sampling only those invoked. + variable_declarations: VariableDeclarations = ( + env.variable_store.get_variable_declarations() + ) + + rich_jsonata_expression: JSONataExpression = compose_jsonata_expression( + final_jsonata_expression=self.expression, + variable_declarations_list=[ + functions_variable_declarations, + states_variable_declarations, + variable_declarations, + ], + ) + result = eval_jsonata_expression(rich_jsonata_expression) + + validate_jsonata_expression_output( + env, self.expression, rich_jsonata_expression, result + ) + + env.stack.append(result) + + +class AssignTemplateValueTerminalExpressionSuppressed( + AssignTemplateValueTerminalExpression +): + def _eval_body(self, env: Environment) -> None: + env.stack.append(self.expression) diff --git a/moto/stepfunctions/parser/asl/component/common/catch/catcher_decl.py b/moto/stepfunctions/parser/asl/component/common/catch/catcher_decl.py index 04f9ea4e262a..ff25369bbd18 100644 --- a/moto/stepfunctions/parser/asl/component/common/catch/catcher_decl.py +++ b/moto/stepfunctions/parser/asl/component/common/catch/catcher_decl.py @@ -2,6 +2,7 @@ from typing import Final, Optional +from moto.stepfunctions.parser.asl.component.common.assign.assign_decl import AssignDecl from moto.stepfunctions.parser.asl.component.common.catch.catcher_outcome import ( CatcherOutcomeCaught, CatcherOutcomeNotCaught, @@ -17,30 +18,44 @@ FailureEvent, ) from moto.stepfunctions.parser.asl.component.common.flow.next import Next +from moto.stepfunctions.parser.asl.component.common.outputdecl import Output from moto.stepfunctions.parser.asl.component.common.path.result_path import ResultPath from moto.stepfunctions.parser.asl.component.eval_component import EvalComponent from moto.stepfunctions.parser.asl.eval.environment import Environment +class CatcherOutput(dict): + def __init__(self, error: str, cause: str): + super().__init__() + self["Error"] = error + self["Cause"] = cause + + class CatcherDecl(EvalComponent): - _DEFAULT_RESULT_PATH: Final[ResultPath] = ResultPath(result_path_src="$") + DEFAULT_RESULT_PATH: ResultPath = ResultPath(result_path_src="$") error_equals: Final[ErrorEqualsDecl] - result_path: Final[ResultPath] + next_decl: Next + result_path: Optional[ResultPath] + assign: Optional[AssignDecl] + output: Optional[Output] comment: Final[Optional[Comment]] - next_decl: Final[Next] def __init__( self, error_equals: ErrorEqualsDecl, next_decl: Next, + result_path: Optional[ResultPath], + assign: Optional[AssignDecl], + output: Optional[Output], comment: Optional[Comment], - result_path: ResultPath = _DEFAULT_RESULT_PATH, ): self.error_equals = error_equals - self.result_path = result_path or CatcherDecl._DEFAULT_RESULT_PATH - self.comment = comment self.next_decl = next_decl + self.result_path = result_path + self.assign = assign + self.output = output + self.comment = comment @classmethod def from_catcher_props(cls, props: CatcherProps) -> CatcherDecl: @@ -58,32 +73,11 @@ def from_catcher_props(cls, props: CatcherProps) -> CatcherDecl: ), ), result_path=props.get(typ=ResultPath), + assign=props.get(typ=AssignDecl), + output=props.get(typ=Output), comment=props.get(typ=Comment), ) - @staticmethod - def _extract_error_cause(failure_event: FailureEvent) -> dict: - # TODO: consider formalising all EventDetails to ensure FailureEvent can always reach the state below. - # As per AWS's Api specification, all failure event carry one - # details field, with at least fields 'cause and 'error' - specs_event_details = list(failure_event.event_details.values()) - if ( - len(specs_event_details) != 1 - and "error" in specs_event_details - and "cause" in specs_event_details - ): - raise RuntimeError( - f"Internal Error: invalid event details declaration in FailureEvent: '{failure_event}'." - ) - spec_event_details: dict = list(failure_event.event_details.values())[0] - error = spec_event_details["error"] - cause = spec_event_details.get("cause") or "" - # Stepfunctions renames these fields to capital in this scenario. - return { - "Error": error, - "Cause": cause, - } - def _eval_body(self, env: Environment) -> None: failure_event: FailureEvent = env.stack.pop() @@ -92,10 +86,23 @@ def _eval_body(self, env: Environment) -> None: equals: bool = env.stack.pop() if equals: - error_cause: dict = self._extract_error_cause(failure_event) - env.stack.append(error_cause) + # Input for the catch block is the error output. + env.stack.append(env.states.get_error_output()) + + if self.assign: + self.assign.eval(env=env) + + if self.result_path: + self.result_path.eval(env) + + # Prepare the state output: successful catch states override the states' output procedure. + if self.output: + self.output.eval(env=env) + else: + output_value = env.stack.pop() + env.states.reset(output_value) - self.result_path.eval(env) + # Append successful output to notify the outcome upstream. env.next_state_name = self.next_decl.name env.stack.append(CatcherOutcomeCaught()) else: diff --git a/moto/stepfunctions/parser/asl/component/common/error_name/custom_error_name.py b/moto/stepfunctions/parser/asl/component/common/error_name/custom_error_name.py index 252f6e5e5e5e..70a0d6cce47c 100644 --- a/moto/stepfunctions/parser/asl/component/common/error_name/custom_error_name.py +++ b/moto/stepfunctions/parser/asl/component/common/error_name/custom_error_name.py @@ -1,19 +1,21 @@ -from typing import Final +from typing import Optional from moto.stepfunctions.parser.asl.component.common.error_name.error_name import ( ErrorName, ) +ILLEGAL_CUSTOM_ERROR_PREFIX: str = "States." + class CustomErrorName(ErrorName): """ States MAY report errors with other names, which MUST NOT begin with the prefix "States.". """ - _ILLEGAL_PREFIX: Final[str] = "States." - - def __init__(self, error_name: str): - if error_name and error_name.startswith(CustomErrorName._ILLEGAL_PREFIX): + def __init__(self, error_name: Optional[str]): + if error_name is not None and error_name.startswith( + ILLEGAL_CUSTOM_ERROR_PREFIX + ): raise ValueError( f"Custom Error Names MUST NOT begin with the prefix 'States.', got '{error_name}'." ) diff --git a/moto/stepfunctions/parser/asl/component/common/error_name/error_name.py b/moto/stepfunctions/parser/asl/component/common/error_name/error_name.py index 852039ed869e..fe6164c8a09f 100644 --- a/moto/stepfunctions/parser/asl/component/common/error_name/error_name.py +++ b/moto/stepfunctions/parser/asl/component/common/error_name/error_name.py @@ -1,16 +1,18 @@ from __future__ import annotations import abc -from typing import Final +from typing import Optional from moto.stepfunctions.parser.asl.component.component import Component class ErrorName(Component, abc.ABC): - def __init__(self, error_name: str): - self.error_name: Final[str] = error_name + error_name: Optional[str] - def matches(self, error_name: str) -> bool: + def __init__(self, error_name: Optional[str]): + self.error_name = error_name + + def matches(self, error_name: Optional[str]) -> bool: return self.error_name == error_name def __eq__(self, other): diff --git a/moto/stepfunctions/parser/asl/component/common/error_name/failure_event.py b/moto/stepfunctions/parser/asl/component/common/error_name/failure_event.py index 20f81bcb9aa6..c0cfb4838115 100644 --- a/moto/stepfunctions/parser/asl/component/common/error_name/failure_event.py +++ b/moto/stepfunctions/parser/asl/component/common/error_name/failure_event.py @@ -1,23 +1,36 @@ from typing import Final, Optional, Tuple -from moto.stepfunctions.parser.api import ExecutionFailedEventDetails, HistoryEventType +from moto.stepfunctions.parser.api import ( + EvaluationFailedEventDetails, + ExecutionFailedEventDetails, + HistoryEventType, +) from moto.stepfunctions.parser.asl.component.common.error_name.error_name import ( ErrorName, ) +from moto.stepfunctions.parser.asl.component.common.error_name.states_error_name_type import ( + StatesErrorNameType, +) +from moto.stepfunctions.parser.asl.eval.environment import Environment from moto.stepfunctions.parser.asl.eval.event.event_detail import EventDetails class FailureEvent: + state_name: str + source_event_id: int error_name: Final[Optional[ErrorName]] event_type: Final[HistoryEventType] event_details: Final[Optional[EventDetails]] def __init__( self, + env: Environment, error_name: Optional[ErrorName], event_type: HistoryEventType, event_details: Optional[EventDetails] = None, ): + self.state_name = env.next_state_name + self.source_event_id = env.event_history_context.source_event_id self.error_name = error_name self.event_type = event_type self.event_details = event_details @@ -43,6 +56,34 @@ def extract_error_cause_pair(self) -> Optional[Tuple[Optional[str], Optional[str cause = failure_event_spec["cause"] return error, cause + def get_evaluation_failed_event_details( + self, + ) -> Optional[EvaluationFailedEventDetails]: + original_failed_event_details = self.failure_event.event_details[ + "evaluationFailedEventDetails" + ] + evaluation_failed_event_details = EvaluationFailedEventDetails() + + error = original_failed_event_details["error"] + cause = original_failed_event_details["cause"] + location = original_failed_event_details.get("location") + state_name = self.failure_event.state_name + + if error != StatesErrorNameType.StatesQueryEvaluationError.to_name(): + return None + if error: + evaluation_failed_event_details["error"] = error + if cause: + event_id = self.failure_event.source_event_id + decorated_cause = f"An error occurred while executing the state '{state_name}' (entered at the event id #{event_id}). {cause}" + evaluation_failed_event_details["cause"] = decorated_cause + if location: + evaluation_failed_event_details["location"] = location + if state_name: + evaluation_failed_event_details["state"] = state_name + + return evaluation_failed_event_details + def get_execution_failed_event_details( self, ) -> Optional[ExecutionFailedEventDetails]: @@ -54,5 +95,15 @@ def get_execution_failed_event_details( if error: execution_failed_event_details["error"] = error if cause: - execution_failed_event_details["cause"] = cause + if ( + error == StatesErrorNameType.StatesRuntime.to_name() + or error == StatesErrorNameType.StatesQueryEvaluationError.to_name() + ): + state_name = self.failure_event.state_name + event_id = self.failure_event.source_event_id + decorated_cause = f"An error occurred while executing the state '{state_name}' (entered at the event id #{event_id}). {cause}" + execution_failed_event_details["cause"] = decorated_cause + else: + execution_failed_event_details["cause"] = cause + return execution_failed_event_details diff --git a/moto/stepfunctions/parser/asl/component/common/error_name/states_error_name_type.py b/moto/stepfunctions/parser/asl/component/common/error_name/states_error_name_type.py index 4b2f02b3e6e7..c7c05ed530e7 100644 --- a/moto/stepfunctions/parser/asl/component/common/error_name/states_error_name_type.py +++ b/moto/stepfunctions/parser/asl/component/common/error_name/states_error_name_type.py @@ -8,6 +8,7 @@ class StatesErrorNameType(Enum): StatesALL = ASLLexer.ERRORNAMEStatesALL + StatesStatesDataLimitExceeded = ASLLexer.ERRORNAMEStatesDataLimitExceeded StatesHeartbeatTimeout = ASLLexer.ERRORNAMEStatesHeartbeatTimeout StatesTimeout = ASLLexer.ERRORNAMEStatesTimeout StatesTaskFailed = ASLLexer.ERRORNAMEStatesTaskFailed @@ -23,6 +24,7 @@ class StatesErrorNameType(Enum): StatesItemReaderFailed = ASLLexer.ERRORNAMEStatesItemReaderFailed StatesResultWriterFailed = ASLLexer.ERRORNAMEStatesResultWriterFailed StatesRuntime = ASLLexer.ERRORNAMEStatesRuntime + StatesQueryEvaluationError = ASLLexer.ERRORNAMEStatesQueryEvaluationError def to_name(self) -> str: return _error_name(self) diff --git a/moto/stepfunctions/parser/asl/component/common/jsonata/__init__.py b/moto/stepfunctions/parser/asl/component/common/jsonata/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/moto/stepfunctions/parser/asl/component/common/jsonata/jsonata_template_binding.py b/moto/stepfunctions/parser/asl/component/common/jsonata/jsonata_template_binding.py new file mode 100644 index 000000000000..5d521ae4f5a6 --- /dev/null +++ b/moto/stepfunctions/parser/asl/component/common/jsonata/jsonata_template_binding.py @@ -0,0 +1,23 @@ +from __future__ import annotations + +from moto.stepfunctions.parser.asl.component.common.jsonata.jsonata_template_value import ( + JSONataTemplateValue, +) +from moto.stepfunctions.parser.asl.component.eval_component import EvalComponent +from moto.stepfunctions.parser.asl.eval.environment import Environment + + +class JSONataTemplateBinding(EvalComponent): + identifier: str + value: JSONataTemplateValue + + def __init__(self, identifier: str, value: JSONataTemplateValue): + self.identifier = identifier + self.value = value + + def _eval_body(self, env: Environment) -> None: + binding_container: dict = env.stack.pop() + self.value.eval(env=env) + value = env.stack.pop() + binding_container[self.identifier] = value + env.stack.append(binding_container) diff --git a/moto/stepfunctions/parser/asl/component/common/jsonata/jsonata_template_value.py b/moto/stepfunctions/parser/asl/component/common/jsonata/jsonata_template_value.py new file mode 100644 index 000000000000..7c17c8773a94 --- /dev/null +++ b/moto/stepfunctions/parser/asl/component/common/jsonata/jsonata_template_value.py @@ -0,0 +1,6 @@ +import abc + +from moto.stepfunctions.parser.asl.component.eval_component import EvalComponent + + +class JSONataTemplateValue(EvalComponent, abc.ABC): ... diff --git a/moto/stepfunctions/parser/asl/component/common/jsonata/jsonata_template_value_array.py b/moto/stepfunctions/parser/asl/component/common/jsonata/jsonata_template_value_array.py new file mode 100644 index 000000000000..f91e039f8dee --- /dev/null +++ b/moto/stepfunctions/parser/asl/component/common/jsonata/jsonata_template_value_array.py @@ -0,0 +1,20 @@ +from typing import List + +from moto.stepfunctions.parser.asl.component.common.jsonata.jsonata_template_value import ( + JSONataTemplateValue, +) +from moto.stepfunctions.parser.asl.eval.environment import Environment + + +class JSONataTemplateValueArray(JSONataTemplateValue): + values: List[JSONataTemplateValue] + + def __init__(self, values: List[JSONataTemplateValue]): + self.values = values + + def _eval_body(self, env: Environment) -> None: + arr = list() + for value in self.values: + value.eval(env) + arr.append(env.stack.pop()) + env.stack.append(arr) diff --git a/moto/stepfunctions/parser/asl/component/common/jsonata/jsonata_template_value_object.py b/moto/stepfunctions/parser/asl/component/common/jsonata/jsonata_template_value_object.py new file mode 100644 index 000000000000..f1bb4f272dcf --- /dev/null +++ b/moto/stepfunctions/parser/asl/component/common/jsonata/jsonata_template_value_object.py @@ -0,0 +1,21 @@ +from typing import List + +from moto.stepfunctions.parser.asl.component.common.jsonata.jsonata_template_binding import ( + JSONataTemplateBinding, +) +from moto.stepfunctions.parser.asl.component.common.jsonata.jsonata_template_value import ( + JSONataTemplateValue, +) +from moto.stepfunctions.parser.asl.eval.environment import Environment + + +class JSONataTemplateValueObject(JSONataTemplateValue): + bindings: List[JSONataTemplateBinding] + + def __init__(self, bindings: List[JSONataTemplateBinding]): + self.bindings = bindings + + def _eval_body(self, env: Environment) -> None: + env.stack.append(dict()) + for binding in self.bindings: + binding.eval(env) diff --git a/moto/stepfunctions/parser/asl/component/common/jsonata/jsonata_template_value_terminal.py b/moto/stepfunctions/parser/asl/component/common/jsonata/jsonata_template_value_terminal.py new file mode 100644 index 000000000000..8e2a83d31907 --- /dev/null +++ b/moto/stepfunctions/parser/asl/component/common/jsonata/jsonata_template_value_terminal.py @@ -0,0 +1,87 @@ +import abc +from typing import Any, Set + +from moto.stepfunctions.parser.asl.component.common.jsonata.jsonata_template_value import ( + JSONataTemplateValue, +) +from moto.stepfunctions.parser.asl.component.intrinsic.jsonata import ( + get_intrinsic_functions_declarations, +) +from moto.stepfunctions.parser.asl.eval.environment import Environment +from moto.stepfunctions.parser.asl.jsonata.jsonata import ( + JSONataExpression, + VariableDeclarations, + VariableReference, + compose_jsonata_expression, + eval_jsonata_expression, + extract_jsonata_variable_references, +) +from moto.stepfunctions.parser.asl.jsonata.validations import ( + validate_jsonata_expression_output, +) + + +class JSONataTemplateValueTerminal(JSONataTemplateValue, abc.ABC): ... + + +class JSONataTemplateValueTerminalLit(JSONataTemplateValueTerminal): + value: Any + + def __init__(self, value: Any): + super().__init__() + self.value = value + + def _eval_body(self, env: Environment) -> None: + env.stack.append(self.value) + + +class JSONataTemplateValueTerminalExpression(JSONataTemplateValueTerminal): + expression: str + + def __init__(self, expression: str): + super().__init__() + # TODO: check for illegal functions ($, $$, $eval) + self.expression = expression + + def _eval_body(self, env: Environment) -> None: + # Get the variables sampled in the jsonata expression. + expression_variable_references: Set[VariableReference] = ( + extract_jsonata_variable_references(self.expression) + ) + + # Sample declarations for used intrinsic functions. Place this at the start allowing users to + # override these identifiers with custom variable declarations. + functions_variable_declarations: VariableDeclarations = ( + get_intrinsic_functions_declarations( + variable_references=expression_variable_references + ) + ) + + # Sample $states values into expression. + states_variable_declarations: VariableDeclarations = ( + env.states.to_variable_declarations( + variable_references=expression_variable_references + ) + ) + + # Sample Variable store values in to expression. + # TODO: this could be optimised by sampling only those invoked. + variable_declarations: VariableDeclarations = ( + env.variable_store.get_variable_declarations() + ) + + rich_jsonata_expression: JSONataExpression = compose_jsonata_expression( + final_jsonata_expression=self.expression, + variable_declarations_list=[ + functions_variable_declarations, + states_variable_declarations, + variable_declarations, + ], + ) + result = eval_jsonata_expression(rich_jsonata_expression) + + validate_jsonata_expression_output( + env, self.expression, rich_jsonata_expression, result + ) + + env.stack.append(result) diff --git a/moto/stepfunctions/parser/asl/component/common/outputdecl.py b/moto/stepfunctions/parser/asl/component/common/outputdecl.py new file mode 100644 index 000000000000..59f919bc4f6f --- /dev/null +++ b/moto/stepfunctions/parser/asl/component/common/outputdecl.py @@ -0,0 +1,17 @@ +from moto.stepfunctions.parser.asl.component.common.jsonata.jsonata_template_value import ( + JSONataTemplateValue, +) +from moto.stepfunctions.parser.asl.component.eval_component import EvalComponent +from moto.stepfunctions.parser.asl.eval.environment import Environment + + +class Output(EvalComponent): + jsonata_template_value: JSONataTemplateValue + + def __init__(self, jsonata_template_value: JSONataTemplateValue): + self.jsonata_template_value = jsonata_template_value + + def _eval_body(self, env: Environment) -> None: + self.jsonata_template_value.eval(env=env) + output_value = env.stack.pop() + env.states.reset(input_value=output_value) diff --git a/moto/stepfunctions/parser/asl/component/common/parameters.py b/moto/stepfunctions/parser/asl/component/common/parameters.py deleted file mode 100644 index a6c0a7e06b86..000000000000 --- a/moto/stepfunctions/parser/asl/component/common/parameters.py +++ /dev/null @@ -1,15 +0,0 @@ -from typing import Final - -from moto.stepfunctions.parser.asl.component.common.payload.payloadvalue.payloadtmpl.payload_tmpl import ( - PayloadTmpl, -) -from moto.stepfunctions.parser.asl.component.eval_component import EvalComponent -from moto.stepfunctions.parser.asl.eval.environment import Environment - - -class Parameters(EvalComponent): - def __init__(self, payload_tmpl: PayloadTmpl): - self.payload_tmpl: Final[PayloadTmpl] = payload_tmpl - - def _eval_body(self, env: Environment) -> None: - self.payload_tmpl.eval(env=env) diff --git a/moto/stepfunctions/parser/asl/component/common/parargs.py b/moto/stepfunctions/parser/asl/component/common/parargs.py new file mode 100644 index 000000000000..8d7f70cdd453 --- /dev/null +++ b/moto/stepfunctions/parser/asl/component/common/parargs.py @@ -0,0 +1,30 @@ +import abc + +from moto.stepfunctions.parser.asl.component.common.jsonata.jsonata_template_value import ( + JSONataTemplateValue, +) +from moto.stepfunctions.parser.asl.component.common.payload.payloadvalue.payloadtmpl.payload_tmpl import ( + PayloadTmpl, +) +from moto.stepfunctions.parser.asl.component.eval_component import EvalComponent +from moto.stepfunctions.parser.asl.eval.environment import Environment + + +class Parargs(EvalComponent, abc.ABC): + template_eval_component: EvalComponent + + def __init__(self, template_eval_component: EvalComponent): + self.template_eval_component = template_eval_component + + def _eval_body(self, env: Environment) -> None: + self.template_eval_component.eval(env=env) + + +class Parameters(Parargs): + def __init__(self, payload_tmpl: PayloadTmpl): + super().__init__(template_eval_component=payload_tmpl) + + +class Arguments(Parargs): + def __init__(self, jsonata_payload_value: JSONataTemplateValue): + super().__init__(template_eval_component=jsonata_payload_value) diff --git a/moto/stepfunctions/parser/asl/component/common/path/input_path.py b/moto/stepfunctions/parser/asl/component/common/path/input_path.py index 5b03cb1293d0..e4a3a94b6ad3 100644 --- a/moto/stepfunctions/parser/asl/component/common/path/input_path.py +++ b/moto/stepfunctions/parser/asl/component/common/path/input_path.py @@ -1,24 +1,51 @@ +import abc import copy -from typing import Final, Optional +from typing import Optional +from moto.stepfunctions.parser.asl.component.common.variable_sample import ( + VariableSample, +) from moto.stepfunctions.parser.asl.component.eval_component import EvalComponent from moto.stepfunctions.parser.asl.eval.environment import Environment -from moto.stepfunctions.parser.asl.utils.json_path import JSONPathUtils +from moto.stepfunctions.parser.asl.utils.json_path import extract_json -class InputPath(EvalComponent): - DEFAULT_PATH: Final[str] = "$" +class InputPath(EvalComponent, abc.ABC): ... - input_path_src: Final[Optional[str]] - def __init__(self, input_path_src: Optional[str]): - self.input_path_src = input_path_src +class InputPathBase(InputPath): + DEFAULT_PATH: str = "$" + + path: Optional[str] + + def __init__(self, path: Optional[str]): + self.path = path def _eval_body(self, env: Environment) -> None: - if self.input_path_src is None: + if self.path is None: value = dict() - elif self.input_path_src == InputPath.DEFAULT_PATH: - value = env.inp + elif self.path == self.DEFAULT_PATH: + value = env.states.get_input() else: - value = JSONPathUtils.extract_json(self.input_path_src, env.inp) + value = extract_json(self.path, env.states.get_input()) + env.stack.append(copy.deepcopy(value)) + + +class InputPathContextObject(InputPathBase): + def __init__(self, path: str): + path_tail = path[1:] + super().__init__(path=path_tail) + + def _eval_body(self, env: Environment) -> None: + value = extract_json(self.path, env.states.context_object.context_object_data) env.stack.append(copy.deepcopy(value)) + + +class InputPathVar(InputPath): + variable_sample: VariableSample + + def __init__(self, variable_sample: VariableSample): + self.variable_sample = variable_sample + + def _eval_body(self, env: Environment) -> None: + self.variable_sample.eval(env=env) diff --git a/moto/stepfunctions/parser/asl/component/common/path/items_path.py b/moto/stepfunctions/parser/asl/component/common/path/items_path.py index ff439218bc60..85a5bce36699 100644 --- a/moto/stepfunctions/parser/asl/component/common/path/items_path.py +++ b/moto/stepfunctions/parser/asl/component/common/path/items_path.py @@ -3,17 +3,45 @@ from moto.stepfunctions.parser.asl.component.eval_component import EvalComponent from moto.stepfunctions.parser.asl.eval.environment import Environment -from moto.stepfunctions.parser.asl.utils.json_path import JSONPathUtils +from moto.stepfunctions.parser.asl.jsonata.jsonata import ( + VariableDeclarations, + compose_jsonata_expression, + eval_jsonata_expression, +) +from moto.stepfunctions.parser.asl.utils.json_path import extract_json class ItemsPath(EvalComponent): DEFAULT_PATH: Final[str] = "$" - def __init__(self, items_path_src: str = DEFAULT_PATH): - self.items_path_src: Final[str] = items_path_src + def __init__(self, path: str = DEFAULT_PATH): + self.path = path def _eval_body(self, env: Environment) -> None: - if self.items_path_src != ItemsPath.DEFAULT_PATH: - value = copy.deepcopy(env.stack[-1]) - value = JSONPathUtils.extract_json(self.items_path_src, value) - env.stack.append(value) + value = copy.deepcopy(env.stack[-1]) + if self.path != ItemsPath.DEFAULT_PATH: + value = extract_json(self.path, value) + env.stack.append(value) + + +class ItemsPathContextObject(ItemsPath): + def __init__(self, path: str): + path_tail = path[1:] + super().__init__(path=path_tail) + + def _eval_body(self, env: Environment) -> None: + value = extract_json(self.path, env.states.context_object.context_object_data) + env.stack.append(copy.deepcopy(value)) + + +class ItemsPathVar(ItemsPath): + def _eval_body(self, env: Environment) -> None: + variable_declarations: VariableDeclarations = ( + env.variable_store.get_variable_declarations() + ) + jsonata_expression = compose_jsonata_expression( + final_jsonata_expression=self.path, # noqa + variable_declarations_list=[variable_declarations], + ) + value = eval_jsonata_expression(jsonata_expression=jsonata_expression) + env.stack.append(copy.deepcopy(value)) diff --git a/moto/stepfunctions/parser/asl/component/common/path/output_path.py b/moto/stepfunctions/parser/asl/component/common/path/output_path.py index 002c653ce0fd..f9cece38039e 100644 --- a/moto/stepfunctions/parser/asl/component/common/path/output_path.py +++ b/moto/stepfunctions/parser/asl/component/common/path/output_path.py @@ -1,22 +1,54 @@ -from typing import Final, Optional +import abc +from typing import Optional +from moto.stepfunctions.parser.asl.component.common.variable_sample import ( + VariableSample, +) from moto.stepfunctions.parser.asl.component.eval_component import EvalComponent from moto.stepfunctions.parser.asl.eval.environment import Environment -from moto.stepfunctions.parser.asl.utils.json_path import JSONPathUtils +from moto.stepfunctions.parser.asl.utils.json_path import extract_json -class OutputPath(EvalComponent): - DEFAULT_PATH: Final[str] = "$" +class OutputPath(EvalComponent, abc.ABC): ... - output_path: Final[Optional[str]] + +class OutputPathBase(OutputPath): + DEFAULT_PATH: str = "$" + + output_path: Optional[str] def __init__(self, output_path: Optional[str]): self.output_path = output_path def _eval_body(self, env: Environment) -> None: if self.output_path is None: - env.inp = dict() + env.states.reset(input_value=dict()) else: current_output = env.stack.pop() - state_output = JSONPathUtils.extract_json(self.output_path, current_output) - env.inp = state_output + state_output = extract_json(self.output_path, current_output) + env.states.reset(input_value=state_output) + + +class OutputPathContextObject(OutputPathBase): + def __init__(self, output_path: str): + output_path_tail = output_path[1:] + super().__init__(output_path=output_path_tail) + + def _eval_body(self, env: Environment) -> None: + env.stack.pop() # Discards the state output in favour of the context object path. + value = extract_json( + self.output_path, env.states.context_object.context_object_data + ) + env.states.reset(input_value=value) + + +class OutputPathVar(OutputPath): + variable_sample: VariableSample + + def __init__(self, variable_sample: VariableSample): + self.variable_sample = variable_sample + + def _eval_body(self, env: Environment) -> None: + self.variable_sample.eval(env=env) + value = env.stack.pop() + env.states.reset(input_value=value) diff --git a/moto/stepfunctions/parser/asl/component/common/path/result_path.py b/moto/stepfunctions/parser/asl/component/common/path/result_path.py index 87b97a5591f0..7efd2b35b5e7 100644 --- a/moto/stepfunctions/parser/asl/component/common/path/result_path.py +++ b/moto/stepfunctions/parser/asl/component/common/path/result_path.py @@ -16,7 +16,7 @@ def __init__(self, result_path_src: Optional[str]): self.result_path_src = result_path_src def _eval_body(self, env: Environment) -> None: - state_input = copy.deepcopy(env.inp) + state_input = env.states.get_input() # Discard task output if there is one, and set the output ot be the state's input. if self.result_path_src is None: diff --git a/moto/stepfunctions/parser/asl/component/common/payload/payloadvalue/payloadbinding/payload_binding_intrinsic_func.py b/moto/stepfunctions/parser/asl/component/common/payload/payloadvalue/payloadbinding/payload_binding_intrinsic_func.py index 3b2ddab2b27e..38a6d177e090 100644 --- a/moto/stepfunctions/parser/asl/component/common/payload/payloadvalue/payloadbinding/payload_binding_intrinsic_func.py +++ b/moto/stepfunctions/parser/asl/component/common/payload/payloadvalue/payloadbinding/payload_binding_intrinsic_func.py @@ -11,10 +11,12 @@ class PayloadBindingIntrinsicFunc(PayloadBinding): + function: Function + def __init__(self, field: str, intrinsic_func: str): super().__init__(field=field) self.src: Final[str] = intrinsic_func - self.function: Final[Function] = IntrinsicParser.parse(self.src) + self.function, _ = IntrinsicParser.parse(self.src) @classmethod def from_raw(cls, string_dollar: str, intrinsic_func: str): diff --git a/moto/stepfunctions/parser/asl/component/common/payload/payloadvalue/payloadbinding/payload_binding_path.py b/moto/stepfunctions/parser/asl/component/common/payload/payloadvalue/payloadbinding/payload_binding_path.py index 37fa477dfd91..c39c1e3da652 100644 --- a/moto/stepfunctions/parser/asl/component/common/payload/payloadvalue/payloadbinding/payload_binding_path.py +++ b/moto/stepfunctions/parser/asl/component/common/payload/payloadvalue/payloadbinding/payload_binding_path.py @@ -17,7 +17,7 @@ from moto.stepfunctions.parser.asl.eval.environment import Environment from moto.stepfunctions.parser.asl.eval.event.event_detail import EventDetails from moto.stepfunctions.parser.asl.utils.encoding import to_json_str -from moto.stepfunctions.parser.asl.utils.json_path import JSONPathUtils +from moto.stepfunctions.parser.asl.utils.json_path import extract_json class PayloadBindingPath(PayloadBinding): @@ -33,9 +33,10 @@ def from_raw(cls, string_dollar: str, string_path: str): def _eval_val(self, env: Environment) -> Any: inp = env.stack[-1] try: - value = JSONPathUtils.extract_json(self.path, inp) + value = extract_json(self.path, inp) except RuntimeError: failure_event = FailureEvent( + env=env, error_name=StatesErrorName(typ=StatesErrorNameType.StatesRuntime), event_type=HistoryEventType.TaskFailed, event_details=EventDetails( diff --git a/moto/stepfunctions/parser/asl/component/common/payload/payloadvalue/payloadbinding/payload_binding_path_context_obj.py b/moto/stepfunctions/parser/asl/component/common/payload/payloadvalue/payloadbinding/payload_binding_path_context_obj.py index c54a11351b57..d3760735c59a 100644 --- a/moto/stepfunctions/parser/asl/component/common/payload/payloadvalue/payloadbinding/payload_binding_path_context_obj.py +++ b/moto/stepfunctions/parser/asl/component/common/payload/payloadvalue/payloadbinding/payload_binding_path_context_obj.py @@ -4,7 +4,7 @@ PayloadBinding, ) from moto.stepfunctions.parser.asl.eval.environment import Environment -from moto.stepfunctions.parser.asl.utils.json_path import JSONPathUtils +from moto.stepfunctions.parser.asl.utils.json_path import extract_json class PayloadBindingPathContextObj(PayloadBinding): @@ -19,12 +19,7 @@ def from_raw(cls, string_dollar: str, string_path_context_obj: str): return cls(field=field, path_context_obj=path_context_obj) def _eval_val(self, env: Environment) -> Any: - if self.path_context_obj.endswith("Task.Token"): - task_token = env.context_object_manager.update_task_token() - env.callback_pool_manager.add(task_token) - value = task_token - else: - value = JSONPathUtils.extract_json( - self.path_context_obj, env.context_object_manager.context_object - ) + value = extract_json( + self.path_context_obj, env.states.context_object.context_object_data + ) return value diff --git a/moto/stepfunctions/parser/asl/component/common/payload/payloadvalue/payloadbinding/payload_binding_var.py b/moto/stepfunctions/parser/asl/component/common/payload/payloadvalue/payloadbinding/payload_binding_var.py new file mode 100644 index 000000000000..63566d0fd910 --- /dev/null +++ b/moto/stepfunctions/parser/asl/component/common/payload/payloadvalue/payloadbinding/payload_binding_var.py @@ -0,0 +1,27 @@ +from typing import Any + +from moto.stepfunctions.parser.asl.component.common.payload.payloadvalue.payloadbinding.payload_binding import ( + PayloadBinding, +) +from moto.stepfunctions.parser.asl.component.common.variable_sample import ( + VariableSample, +) +from moto.stepfunctions.parser.asl.eval.environment import Environment + + +class PayloadBindingVar(PayloadBinding): + variable_sample: VariableSample + + def __init__(self, field: str, variable_sample: VariableSample): + super().__init__(field=field) + self.variable_sample = variable_sample + + @classmethod + def from_raw(cls, string_dollar: str, variable_sample: VariableSample): + field: str = string_dollar[:-2] + return cls(field=field, variable_sample=variable_sample) + + def _eval_val(self, env: Environment) -> Any: + self.variable_sample.eval(env=env) + value = env.stack.pop() + return value diff --git a/moto/stepfunctions/parser/asl/component/common/payload/payloadvalue/payloadvaluelit/payload_value_variable_sample.py b/moto/stepfunctions/parser/asl/component/common/payload/payloadvalue/payloadvaluelit/payload_value_variable_sample.py new file mode 100644 index 000000000000..afbcd9defe74 --- /dev/null +++ b/moto/stepfunctions/parser/asl/component/common/payload/payloadvalue/payloadvaluelit/payload_value_variable_sample.py @@ -0,0 +1,18 @@ +from moto.stepfunctions.parser.asl.component.common.payload.payloadvalue.payload_value import ( + PayloadValue, +) +from moto.stepfunctions.parser.asl.component.common.variable_sample import ( + VariableSample, +) +from moto.stepfunctions.parser.asl.eval.environment import Environment + + +class PayloadValueVariableSample(PayloadValue): + variable_sample: VariableSample + + def __init__(self, variable_sample: VariableSample): + super().__init__() + self.variable_sample = variable_sample + + def _eval_body(self, env: Environment) -> None: + self.variable_sample.eval(env=env) diff --git a/moto/stepfunctions/parser/asl/component/common/query_language.py b/moto/stepfunctions/parser/asl/component/common/query_language.py new file mode 100644 index 000000000000..6b18ffab1ae3 --- /dev/null +++ b/moto/stepfunctions/parser/asl/component/common/query_language.py @@ -0,0 +1,29 @@ +from __future__ import annotations + +import enum + +from moto.stepfunctions.parser.asl.antlr.runtime.ASLLexer import ASLLexer +from moto.stepfunctions.parser.asl.component.component import Component + + +class QueryLanguageMode(enum.Enum): + JSONPath = ASLLexer.JSONPATH + JSONata = ASLLexer.JSONATA + + def __str__(self): + return self.name + + def __repr__(self): + return f"QueryLanguageMode.{self}({self.value})" + + +DEFAULT_QUERY_LANGUAGE_MODE: QueryLanguageMode = QueryLanguageMode.JSONPath + + +class QueryLanguage(Component): + query_language_mode: QueryLanguageMode + + def __init__( + self, query_language_mode: QueryLanguageMode = DEFAULT_QUERY_LANGUAGE_MODE + ): + self.query_language_mode = query_language_mode diff --git a/moto/stepfunctions/parser/asl/component/common/result_selector.py b/moto/stepfunctions/parser/asl/component/common/result_selector.py index f741eeb3745e..a07bad65b852 100644 --- a/moto/stepfunctions/parser/asl/component/common/result_selector.py +++ b/moto/stepfunctions/parser/asl/component/common/result_selector.py @@ -6,8 +6,10 @@ class ResultSelector(EvalComponent): + payload_tmpl: PayloadTmpl + def __init__(self, payload_tmpl: PayloadTmpl): - self.payload_tmpl: PayloadTmpl = payload_tmpl + self.payload_tmpl = payload_tmpl def _eval_body(self, env: Environment) -> None: self.payload_tmpl.eval(env=env) diff --git a/moto/stepfunctions/parser/asl/component/common/retry/interval_seconds_decl.py b/moto/stepfunctions/parser/asl/component/common/retry/interval_seconds_decl.py index 0a0eefd0663b..a152ba23982d 100644 --- a/moto/stepfunctions/parser/asl/component/common/retry/interval_seconds_decl.py +++ b/moto/stepfunctions/parser/asl/component/common/retry/interval_seconds_decl.py @@ -16,8 +16,10 @@ class IntervalSecondsDecl(EvalComponent): def __init__(self, seconds: int = DEFAULT_SECONDS): if not (1 <= seconds <= IntervalSecondsDecl.MAX_VALUE): raise ValueError( - f"IntervalSeconds value MUST be a positive integer between 1 and {IntervalSecondsDecl.MAX_VALUE}, got '{seconds}'." + f"IntervalSeconds value MUST be a positive integer between " + f"1 and {IntervalSecondsDecl.MAX_VALUE}, got '{seconds}'." ) + self.seconds: Final[int] = seconds def _eval_body(self, env: Environment) -> None: diff --git a/moto/stepfunctions/parser/asl/component/common/retry/retrier_decl.py b/moto/stepfunctions/parser/asl/component/common/retry/retrier_decl.py index 785c8cd68845..946b16da5561 100644 --- a/moto/stepfunctions/parser/asl/component/common/retry/retrier_decl.py +++ b/moto/stepfunctions/parser/asl/component/common/retry/retrier_decl.py @@ -60,9 +60,6 @@ def __init__( self.jitter_strategy = jitter_strategy or JitterStrategyDecl() self.comment = comment - self._attempts_counter: int = 0 - self._next_interval_seconds: float = self.interval_seconds.seconds - @classmethod def from_retrier_props(cls, props: RetrierProps) -> RetrierDecl: return cls( @@ -75,6 +72,8 @@ def from_retrier_props(cls, props: RetrierProps) -> RetrierDecl: interval_seconds=props.get(IntervalSecondsDecl), max_attempts=props.get(MaxAttemptsDecl), backoff_rate=props.get(BackoffRateDecl), + max_delay_seconds=props.get(MaxDelaySecondsDecl), + jitter_strategy=props.get(JitterStrategyDecl), comment=props.get(Comment), ) diff --git a/moto/stepfunctions/parser/asl/component/common/timeouts/heartbeat.py b/moto/stepfunctions/parser/asl/component/common/timeouts/heartbeat.py index 16c9e506abfa..a1c53e59d6b4 100644 --- a/moto/stepfunctions/parser/asl/component/common/timeouts/heartbeat.py +++ b/moto/stepfunctions/parser/asl/component/common/timeouts/heartbeat.py @@ -1,9 +1,15 @@ import abc from typing import Final +from moto.stepfunctions.parser.asl.component.common.jsonata.jsonata_template_value_terminal import ( + JSONataTemplateValueTerminalExpression, +) +from moto.stepfunctions.parser.asl.component.common.variable_sample import ( + VariableSample, +) from moto.stepfunctions.parser.asl.component.eval_component import EvalComponent from moto.stepfunctions.parser.asl.eval.environment import Environment -from moto.stepfunctions.parser.asl.utils.json_path import JSONPathUtils +from moto.stepfunctions.parser.asl.utils.json_path import extract_json class Heartbeat(EvalComponent, abc.ABC): @@ -27,6 +33,27 @@ def _eval_seconds(self, env: Environment) -> int: return self.heartbeat_seconds +class HeartbeatSecondsJSONata(Heartbeat): + jsonata_template_value_terminal_expression: Final[ + JSONataTemplateValueTerminalExpression + ] + + def __init__( + self, + jsonata_template_value_terminal_expression: JSONataTemplateValueTerminalExpression, + ): + super().__init__() + self.jsonata_template_value_terminal_expression = ( + jsonata_template_value_terminal_expression + ) + + def _eval_seconds(self, env: Environment) -> int: + self.jsonata_template_value_terminal_expression.eval(env=env) + # TODO: add snapshot tests to verify AWS's behaviour about non integer values. + seconds = int(env.stack.pop()) + return seconds + + class HeartbeatSecondsPath(Heartbeat): def __init__(self, path: str): self.path: Final[str] = path @@ -37,7 +64,24 @@ def from_raw(cls, path: str): def _eval_seconds(self, env: Environment) -> int: inp = env.stack[-1] - seconds = JSONPathUtils.extract_json(self.path, inp) + seconds = extract_json(self.path, inp) + if not isinstance(seconds, int) and seconds <= 0: + raise ValueError( + f"Expected non-negative integer for HeartbeatSecondsPath, got '{seconds}' instead." + ) + return seconds + + +class HeartbeatSecondsPathVar(HeartbeatSecondsPath): + variable_sample: VariableSample + + def __init__(self, variable_sample: VariableSample): + super().__init__(path=variable_sample.expression) + self.variable_sample = variable_sample + + def _eval_seconds(self, env: Environment) -> int: + self.variable_sample.eval(env=env) + seconds = env.stack.pop() if not isinstance(seconds, int) and seconds <= 0: raise ValueError( f"Expected non-negative integer for HeartbeatSecondsPath, got '{seconds}' instead." diff --git a/moto/stepfunctions/parser/asl/component/common/timeouts/timeout.py b/moto/stepfunctions/parser/asl/component/common/timeouts/timeout.py index 23056a71d6ee..0eee0f62975f 100644 --- a/moto/stepfunctions/parser/asl/component/common/timeouts/timeout.py +++ b/moto/stepfunctions/parser/asl/component/common/timeouts/timeout.py @@ -1,9 +1,15 @@ import abc from typing import Final, Optional +from moto.stepfunctions.parser.asl.component.common.jsonata.jsonata_template_value_terminal import ( + JSONataTemplateValueTerminalExpression, +) +from moto.stepfunctions.parser.asl.component.common.variable_sample import ( + VariableSample, +) from moto.stepfunctions.parser.asl.component.eval_component import EvalComponent from moto.stepfunctions.parser.asl.eval.environment import Environment -from moto.stepfunctions.parser.asl.utils.json_path import JSONPathUtils +from moto.stepfunctions.parser.asl.utils.json_path import extract_json class Timeout(EvalComponent, abc.ABC): @@ -38,6 +44,30 @@ def _eval_seconds(self, env: Environment) -> int: return self.timeout_seconds +class TimeoutSecondsJSONata(Timeout): + jsonata_template_value_terminal_expression: Final[ + JSONataTemplateValueTerminalExpression + ] + + def __init__( + self, + jsonata_template_value_terminal_expression: JSONataTemplateValueTerminalExpression, + ): + super().__init__() + self.jsonata_template_value_terminal_expression = ( + jsonata_template_value_terminal_expression + ) + + def is_default_value(self) -> bool: + return False + + def _eval_seconds(self, env: Environment) -> int: + self.jsonata_template_value_terminal_expression.eval(env=env) + # TODO: add snapshot tests to verify AWS's behaviour about non integer values. + seconds = int(env.stack.pop()) + return seconds + + class TimeoutSecondsPath(Timeout): def __init__(self, path: str): self.path: Final[str] = path @@ -51,7 +81,24 @@ def is_default_value(self) -> bool: def _eval_seconds(self, env: Environment) -> int: inp = env.stack[-1] - seconds = JSONPathUtils.extract_json(self.path, inp) + seconds = extract_json(self.path, inp) + if not isinstance(seconds, int) and seconds <= 0: + raise ValueError( + f"Expected non-negative integer for TimeoutSecondsPath, got '{seconds}' instead." + ) + return seconds + + +class TimeoutSecondsPathVar(TimeoutSecondsPath): + variable_sample: VariableSample + + def __init__(self, variable_sample: VariableSample): + super().__init__(path=variable_sample.expression) + self.variable_sample = variable_sample + + def _eval_seconds(self, env: Environment) -> int: + self.variable_sample.eval(env=env) + seconds = env.stack.pop() if not isinstance(seconds, int) and seconds <= 0: raise ValueError( f"Expected non-negative integer for TimeoutSecondsPath, got '{seconds}' instead." diff --git a/moto/stepfunctions/parser/asl/component/common/variable_sample.py b/moto/stepfunctions/parser/asl/component/common/variable_sample.py new file mode 100644 index 000000000000..c1038964d191 --- /dev/null +++ b/moto/stepfunctions/parser/asl/component/common/variable_sample.py @@ -0,0 +1,55 @@ +from typing import Set + +from moto.stepfunctions.parser.asl.component.common.query_language import ( + QueryLanguageMode, +) +from moto.stepfunctions.parser.asl.component.eval_component import EvalComponent +from moto.stepfunctions.parser.asl.eval.environment import Environment +from moto.stepfunctions.parser.asl.jsonata.jsonata import ( + JSONataExpression, + VariableDeclarations, + VariableReference, + compose_jsonata_expression, + eval_jsonata_expression, + extract_jsonata_variable_references, +) + + +class VariableSample(EvalComponent): + query_language_mode: QueryLanguageMode + expression: str + + def __init__(self, query_language_mode: QueryLanguageMode, expression: str): + super().__init__() + # TODO: check for illegal functions ($, $$, $eval) + self.query_language_mode = query_language_mode + self.expression = expression + + def _eval_body(self, env: Environment) -> None: + # Get the variables sampled in the jsonata expression. + expression_variable_references: Set[VariableReference] = ( + extract_jsonata_variable_references(self.expression) + ) + variable_declarations_list = list() + if self.query_language_mode == QueryLanguageMode.JSONata: + # Sample $states values into expression. + states_variable_declarations: VariableDeclarations = ( + env.states.to_variable_declarations( + variable_references=expression_variable_references + ) + ) + variable_declarations_list.append(states_variable_declarations) + + # Sample Variable store values in to expression. + # TODO: this could be optimised by sampling only those invoked. + variable_declarations: VariableDeclarations = ( + env.variable_store.get_variable_declarations() + ) + variable_declarations_list.append(variable_declarations) + + rich_jsonata_expression: JSONataExpression = compose_jsonata_expression( + final_jsonata_expression=self.expression, + variable_declarations_list=variable_declarations_list, + ) + result = eval_jsonata_expression(rich_jsonata_expression) + env.stack.append(result) diff --git a/moto/stepfunctions/parser/asl/component/eval_component.py b/moto/stepfunctions/parser/asl/component/eval_component.py index 86e3fd992a64..9024a1c7c438 100644 --- a/moto/stepfunctions/parser/asl/component/eval_component.py +++ b/moto/stepfunctions/parser/asl/component/eval_component.py @@ -2,13 +2,13 @@ import logging from typing import Optional -from moto.moto_api._internal import mock_random from moto.stepfunctions.parser.asl.component.common.error_name.failure_event import ( FailureEventException, ) from moto.stepfunctions.parser.asl.component.component import Component from moto.stepfunctions.parser.asl.eval.environment import Environment from moto.stepfunctions.parser.asl.utils.encoding import to_json_str +from moto.stepfunctions.parser.utils import long_uid LOG = logging.getLogger(__name__) @@ -19,13 +19,17 @@ class EvalComponent(Component, abc.ABC): @property def heap_key(self) -> str: if self.__heap_key is None: - self.__heap_key = str(mock_random.uuid4()) + self.__heap_key = long_uid() return self.__heap_key def _log_evaluation_step(self, subject: str = "Generic") -> None: - LOG.debug( - f"[ASL] [{subject.lower()[:4]}] [{self.__class__.__name__}]: '{repr(self)}'" - ) + if LOG.isEnabledFor(logging.DEBUG): + LOG.debug( + "[ASL] [%s] [%s]: '%s'", + subject.lower()[:4], + self.__class__.__name__, + repr(self), + ) def _log_failure_event_exception( self, failure_event_exception: FailureEventException @@ -42,7 +46,7 @@ def _log_failure_event_exception( error_log = ", ".join(error_log_parts) component_repr = repr(self) - LOG.error(f"{error_log} at '{component_repr}'") + LOG.error("%s at '%s'", error_log, component_repr) def _log_exception(self, exception: Exception) -> None: exception_name = exception.__class__.__name__ @@ -57,7 +61,7 @@ def _log_exception(self, exception: Exception) -> None: error_log = ", ".join(error_log_parts) component_repr = repr(self) - LOG.error(f"{error_log} at '{component_repr}'") + LOG.error("%s at '%s'", error_log, component_repr) def eval(self, env: Environment) -> None: if env.is_running(): diff --git a/moto/stepfunctions/parser/asl/component/intrinsic/argument/function_argument_context_path.py b/moto/stepfunctions/parser/asl/component/intrinsic/argument/function_argument_context_path.py index 052b6d974543..33fcb31f8317 100644 --- a/moto/stepfunctions/parser/asl/component/intrinsic/argument/function_argument_context_path.py +++ b/moto/stepfunctions/parser/asl/component/intrinsic/argument/function_argument_context_path.py @@ -2,7 +2,7 @@ FunctionArgument, ) from moto.stepfunctions.parser.asl.eval.environment import Environment -from moto.stepfunctions.parser.asl.utils.json_path import JSONPathUtils +from moto.stepfunctions.parser.asl.utils.json_path import extract_json class FunctionArgumentContextPath(FunctionArgument): @@ -13,7 +13,7 @@ def __init__(self, json_path: str): self._json_path: str = json_path def _eval_body(self, env: Environment) -> None: - self._value = JSONPathUtils.extract_json( - self._json_path, env.context_object_manager.context_object + self._value = extract_json( + self._json_path, env.states.context_object.context_object_data ) super()._eval_body(env=env) diff --git a/moto/stepfunctions/parser/asl/component/intrinsic/argument/function_argument_json_path.py b/moto/stepfunctions/parser/asl/component/intrinsic/argument/function_argument_json_path.py index f9ec948e7191..f59f5f84d8ac 100644 --- a/moto/stepfunctions/parser/asl/component/intrinsic/argument/function_argument_json_path.py +++ b/moto/stepfunctions/parser/asl/component/intrinsic/argument/function_argument_json_path.py @@ -2,7 +2,7 @@ FunctionArgument, ) from moto.stepfunctions.parser.asl.eval.environment import Environment -from moto.stepfunctions.parser.asl.utils.json_path import JSONPathUtils +from moto.stepfunctions.parser.asl.utils.json_path import extract_json class FunctionArgumentJsonPath(FunctionArgument): @@ -14,5 +14,5 @@ def __init__(self, json_path: str): def _eval_body(self, env: Environment) -> None: inp = env.stack[-1] - self._value = JSONPathUtils.extract_json(self._json_path, inp) + self._value = extract_json(self._json_path, inp) super()._eval_body(env=env) diff --git a/moto/stepfunctions/parser/asl/component/intrinsic/argument/function_argument_var.py b/moto/stepfunctions/parser/asl/component/intrinsic/argument/function_argument_var.py new file mode 100644 index 000000000000..a15bf33e4e40 --- /dev/null +++ b/moto/stepfunctions/parser/asl/component/intrinsic/argument/function_argument_var.py @@ -0,0 +1,20 @@ +from moto.stepfunctions.parser.asl.component.common.variable_sample import ( + VariableSample, +) +from moto.stepfunctions.parser.asl.component.intrinsic.argument.function_argument import ( + FunctionArgument, +) +from moto.stepfunctions.parser.asl.eval.environment import Environment + + +class FunctionArgumentVar(FunctionArgument): + variable_sample: VariableSample + + def __init__(self, variable_sample: VariableSample): + super().__init__() + self.variable_sample = variable_sample + + def _eval_body(self, env: Environment) -> None: + self.variable_sample.eval(env=env) + self._value = env.stack.pop() + super()._eval_body(env=env) diff --git a/moto/stepfunctions/parser/asl/component/intrinsic/function/statesfunction/factory.py b/moto/stepfunctions/parser/asl/component/intrinsic/function/statesfunction/factory.py index 3c948afaf5a2..51f4ee9a98a9 100644 --- a/moto/stepfunctions/parser/asl/component/intrinsic/function/statesfunction/factory.py +++ b/moto/stepfunctions/parser/asl/component/intrinsic/function/statesfunction/factory.py @@ -52,6 +52,7 @@ class StatesFunctionFactory: def from_name( func_name: StatesFunctionName, arg_list: FunctionArgumentList ) -> StatesFunction: + # Array. if func_name.function_type == StatesFunctionNameType.Array: return array.Array(arg_list=arg_list) if func_name.function_type == StatesFunctionNameType.ArrayPartition: diff --git a/moto/stepfunctions/parser/asl/component/intrinsic/function/statesfunction/generic/string_format.py b/moto/stepfunctions/parser/asl/component/intrinsic/function/statesfunction/generic/string_format.py index ab9381476891..4ec313677315 100644 --- a/moto/stepfunctions/parser/asl/component/intrinsic/function/statesfunction/generic/string_format.py +++ b/moto/stepfunctions/parser/asl/component/intrinsic/function/statesfunction/generic/string_format.py @@ -1,12 +1,18 @@ import json from typing import Any, Final, List +from moto.stepfunctions.parser.asl.component.intrinsic.argument.function_argument_json_path import ( + FunctionArgumentJsonPath, +) from moto.stepfunctions.parser.asl.component.intrinsic.argument.function_argument_list import ( FunctionArgumentList, ) from moto.stepfunctions.parser.asl.component.intrinsic.argument.function_argument_string import ( FunctionArgumentString, ) +from moto.stepfunctions.parser.asl.component.intrinsic.argument.function_argument_var import ( + FunctionArgumentVar, +) from moto.stepfunctions.parser.asl.component.intrinsic.function.statesfunction.states_function import ( StatesFunction, ) @@ -49,7 +55,10 @@ def __init__(self, arg_list: FunctionArgumentList): raise ValueError( f"Expected at least 1 argument for function type '{type(self)}', but got: '{arg_list}'." ) - if not isinstance(arg_list.arg_list[0], FunctionArgumentString): + if not isinstance( + arg_list.arg_list[0], + (FunctionArgumentString, FunctionArgumentVar, FunctionArgumentJsonPath), + ): raise ValueError( f"Expected the first argument for function type '{type(self)}' to be a string, but got: '{arg_list.arg_list[0]}'." ) diff --git a/moto/stepfunctions/parser/asl/component/intrinsic/function/statesfunction/string_operations/string_split.py b/moto/stepfunctions/parser/asl/component/intrinsic/function/statesfunction/string_operations/string_split.py index 1ef6b02c1df2..0c9dfb571d75 100644 --- a/moto/stepfunctions/parser/asl/component/intrinsic/function/statesfunction/string_operations/string_split.py +++ b/moto/stepfunctions/parser/asl/component/intrinsic/function/statesfunction/string_operations/string_split.py @@ -64,10 +64,7 @@ def _eval_body(self, env: Environment) -> None: if not isinstance(del_chars, str): raise ValueError(f"Expected string value, but got '{del_chars}'.") - patterns = [] - for c in del_chars: - patterns.append(f"\\{c}") - pattern = "|".join(patterns) + pattern = "|".join(re.escape(c) for c in del_chars) parts = re.split(pattern, string) parts_clean = list(filter(bool, parts)) diff --git a/moto/stepfunctions/parser/asl/component/intrinsic/jsonata.py b/moto/stepfunctions/parser/asl/component/intrinsic/jsonata.py new file mode 100644 index 000000000000..52b2858e33a1 --- /dev/null +++ b/moto/stepfunctions/parser/asl/component/intrinsic/jsonata.py @@ -0,0 +1,85 @@ +from typing import Dict, List, Optional, Set + +from moto.stepfunctions.parser.asl.jsonata.jsonata import ( + VariableDeclarations, + VariableReference, +) + +_VARIABLE_REFERENCE_PARTITION: VariableReference = "$partition" +_DECLARATION_PARTITION: str = """ +$partition:=function($array,$chunk_size){ + $chunk_size=0?null: + $chunk_size>=$count($array)?[[$array]]: + $map( + [0..$floor($count($array)/$chunk_size)-(1-$count($array)%$chunk_size)], + function($i){ + $filter($array,function($v,$index){ + $index>=$i*$chunk_size and $index<($i+1)*$chunk_size + }) + } + ) +}; +""".replace("\n", "") + +_VARIABLE_REFERENCE_RANGE: VariableReference = "$range" +_DECLARATION_RANGE: str = """ +$range:=function($first,$last,$step){ + $first>$last and $step>0?[]: + $first<$last and $step<0?[]: + $map([0..$floor(($last-$first)/$step)],function($i){ + $first+$i*$step + }) +}; +""".replace("\n", "") + +# TODO: add support for $hash. +_VARIABLE_REFERENCE_HASH: VariableReference = "$hash" +_DECLARATION_HASH: VariableReference = """ +$hash:=function($value,$algo){ + "Function $hash is currently not supported" +}; +""".replace("\n", "") + +_VARIABLE_REFERENCE_RANDOMSEEDED: VariableReference = "$randomSeeded" +_DECLARATION_RANDOMSEEDED: str = """ +$randomSeeded:=function($seed){ + ($seed*9301+49297)%233280/233280 +}; +""" + +# TODO: add support for $uuid +_VARIABLE_REFERENCE_UUID: VariableReference = "$uuid" +_DECLARATION_UUID: str = """ +$uuid:=function(){ + "Function $uuid is currently not supported" +}; +""" + +_VARIABLE_REFERENCE_PARSE: VariableReference = "$parse" +_DECLARATION_PARSE: str = """ +$parse:=function($v){ + $eval($v) +}; +""" + +_DECLARATION_BY_VARIABLE_REFERENCE: Dict[VariableReference, str] = { + _VARIABLE_REFERENCE_PARTITION: _DECLARATION_PARTITION, + _VARIABLE_REFERENCE_RANGE: _DECLARATION_RANGE, + _VARIABLE_REFERENCE_HASH: _DECLARATION_HASH, + _VARIABLE_REFERENCE_RANDOMSEEDED: _DECLARATION_RANDOMSEEDED, + _VARIABLE_REFERENCE_UUID: _DECLARATION_UUID, + _VARIABLE_REFERENCE_PARSE: _DECLARATION_PARSE, +} + + +def get_intrinsic_functions_declarations( + variable_references: Set[VariableReference], +) -> VariableDeclarations: + declarations: List[str] = list() + for variable_reference in variable_references: + declaration: Optional[VariableDeclarations] = ( + _DECLARATION_BY_VARIABLE_REFERENCE.get(variable_reference) + ) + if declaration: + declarations.append(declaration) + return "".join(declarations) diff --git a/moto/stepfunctions/parser/asl/component/program/program.py b/moto/stepfunctions/parser/asl/component/program/program.py index 36a8ad0f384a..7d39ce30837b 100644 --- a/moto/stepfunctions/parser/asl/component/program/program.py +++ b/moto/stepfunctions/parser/asl/component/program/program.py @@ -21,13 +21,14 @@ StatesErrorNameType, ) from moto.stepfunctions.parser.asl.component.common.flow.start_at import StartAt +from moto.stepfunctions.parser.asl.component.common.query_language import QueryLanguage from moto.stepfunctions.parser.asl.component.common.timeouts.timeout import ( TimeoutSeconds, ) -from moto.stepfunctions.parser.asl.component.common.version import Version from moto.stepfunctions.parser.asl.component.eval_component import EvalComponent +from moto.stepfunctions.parser.asl.component.program.states import States +from moto.stepfunctions.parser.asl.component.program.version import Version from moto.stepfunctions.parser.asl.component.state.state import CommonStateField -from moto.stepfunctions.parser.asl.component.states import States from moto.stepfunctions.parser.asl.eval.environment import Environment from moto.stepfunctions.parser.asl.eval.event.event_detail import EventDetails from moto.stepfunctions.parser.asl.eval.program_state import ( @@ -39,11 +40,13 @@ ) from moto.stepfunctions.parser.asl.utils.encoding import to_json_str from moto.stepfunctions.parser.utils import TMP_THREADS +from moto.utilities.collections import select_from_typed_dict LOG = logging.getLogger(__name__) class Program(EvalComponent): + query_language: QueryLanguage start_at: Final[StartAt] states: Final[States] timeout_seconds: Final[Optional[TimeoutSeconds]] @@ -52,12 +55,14 @@ class Program(EvalComponent): def __init__( self, + query_language: QueryLanguage, start_at: StartAt, states: States, timeout_seconds: Optional[TimeoutSeconds], comment: Optional[Comment] = None, version: Optional[Version] = None, ): + self.query_language = query_language self.start_at = start_at self.states = states self.timeout_seconds = timeout_seconds @@ -73,7 +78,7 @@ def _get_state(self, state_name: str) -> CommonStateField: def eval(self, env: Environment) -> None: timeout = self.timeout_seconds.timeout_seconds if self.timeout_seconds else None env.next_state_name = self.start_at.start_at_name - worker_thread = threading.Thread(target=super().eval, args=(env,)) + worker_thread = threading.Thread(target=super().eval, args=(env,), daemon=True) TMP_THREADS.append(worker_thread) worker_thread.start() worker_thread.join(timeout=timeout) @@ -95,11 +100,12 @@ def _eval_body(self, env: Environment) -> None: clear_heap_values = set(env.heap.keys()) - heap_values for heap_value in clear_heap_values: env.heap.pop(heap_value, None) + except FailureEventException as ex: env.set_error(error=ex.get_execution_failed_event_details()) except Exception as ex: cause = f"{type(ex).__name__}({str(ex)})" - LOG.error(f"Stepfunctions computation ended with exception '{cause}'.") + LOG.error("Stepfunctions computation ended with exception '%s'.", cause) env.set_error( ExecutionFailedEventDetails( error=StatesErrorName( @@ -115,40 +121,45 @@ def _eval_body(self, env: Environment) -> None: program_state: ProgramState = env.program_state() if isinstance(program_state, ProgramError): - exec_failed_event_details = program_state.error or dict() - env.event_history.add_event( + exec_failed_event_details = select_from_typed_dict( + typed_dict=ExecutionFailedEventDetails, + obj=program_state.error or dict(), + ) + env.event_manager.add_event( context=env.event_history_context, - hist_type_event=HistoryEventType.ExecutionFailed, - event_detail=EventDetails( + event_type=HistoryEventType.ExecutionFailed, + event_details=EventDetails( executionFailedEventDetails=exec_failed_event_details ), ) elif isinstance(program_state, ProgramStopped): env.event_history_context.source_event_id = 0 - env.event_history.add_event( + env.event_manager.add_event( context=env.event_history_context, - hist_type_event=HistoryEventType.ExecutionAborted, - event_detail=EventDetails( + event_type=HistoryEventType.ExecutionAborted, + event_details=EventDetails( executionAbortedEventDetails=ExecutionAbortedEventDetails( error=program_state.error, cause=program_state.cause ) ), ) elif isinstance(program_state, ProgramTimedOut): - env.event_history.add_event( + env.event_manager.add_event( context=env.event_history_context, - hist_type_event=HistoryEventType.ExecutionTimedOut, - event_detail=EventDetails( + event_type=HistoryEventType.ExecutionTimedOut, + event_details=EventDetails( executionTimedOutEventDetails=ExecutionTimedOutEventDetails() ), ) elif isinstance(program_state, ProgramEnded): - env.event_history.add_event( + env.event_manager.add_event( context=env.event_history_context, - hist_type_event=HistoryEventType.ExecutionSucceeded, - event_detail=EventDetails( + event_type=HistoryEventType.ExecutionSucceeded, + event_details=EventDetails( executionSucceededEventDetails=ExecutionSucceededEventDetails( - output=to_json_str(env.inp, separators=(",", ":")), + output=to_json_str( + env.states.get_input(), separators=(",", ":") + ), outputDetails=HistoryEventExecutionDataDetails( truncated=False # Always False for api calls. ), diff --git a/moto/stepfunctions/parser/asl/component/states.py b/moto/stepfunctions/parser/asl/component/program/states.py similarity index 100% rename from moto/stepfunctions/parser/asl/component/states.py rename to moto/stepfunctions/parser/asl/component/program/states.py diff --git a/moto/stepfunctions/parser/asl/component/common/version.py b/moto/stepfunctions/parser/asl/component/program/version.py similarity index 100% rename from moto/stepfunctions/parser/asl/component/common/version.py rename to moto/stepfunctions/parser/asl/component/program/version.py diff --git a/moto/stepfunctions/parser/asl/component/state/choice/choice_rule.py b/moto/stepfunctions/parser/asl/component/state/choice/choice_rule.py index 8df8c83a5517..bcd5f782d9ba 100644 --- a/moto/stepfunctions/parser/asl/component/state/choice/choice_rule.py +++ b/moto/stepfunctions/parser/asl/component/state/choice/choice_rule.py @@ -1,9 +1,10 @@ from typing import Final, Optional +from moto.stepfunctions.parser.asl.component.common.assign.assign_decl import AssignDecl from moto.stepfunctions.parser.asl.component.common.comment import Comment from moto.stepfunctions.parser.asl.component.common.flow.next import Next from moto.stepfunctions.parser.asl.component.eval_component import EvalComponent -from moto.stepfunctions.parser.asl.component.state.choice.comparison.comparison import ( +from moto.stepfunctions.parser.asl.component.state.choice.comparison.comparison_type import ( Comparison, ) from moto.stepfunctions.parser.asl.eval.environment import Environment @@ -13,16 +14,23 @@ class ChoiceRule(EvalComponent): comparison: Final[Optional[Comparison]] next_stmt: Final[Optional[Next]] comment: Final[Optional[Comment]] + assign: Final[Optional[AssignDecl]] def __init__( self, comparison: Optional[Comparison], next_stmt: Optional[Next], comment: Optional[Comment], + assign: Optional[AssignDecl], ): self.comparison = comparison self.next_stmt = next_stmt self.comment = comment + self.assign = assign def _eval_body(self, env: Environment) -> None: self.comparison.eval(env) + if self.assign: + is_condition_true: bool = env.stack[-1] + if is_condition_true: + self.assign.eval(env=env) diff --git a/moto/stepfunctions/parser/asl/component/state/choice/comparison/comparison.py b/moto/stepfunctions/parser/asl/component/state/choice/comparison/comparison.py index 726e99e7d51a..af95f6b9ff32 100644 --- a/moto/stepfunctions/parser/asl/component/state/choice/comparison/comparison.py +++ b/moto/stepfunctions/parser/asl/component/state/choice/comparison/comparison.py @@ -1,6 +1,138 @@ -from abc import ABC +from __future__ import annotations -from moto.stepfunctions.parser.asl.component.eval_component import EvalComponent +import abc +from enum import Enum +from typing import Any, Final, List +from moto.stepfunctions.parser.asl.antlr.runtime.ASLLexer import ASLLexer +from moto.stepfunctions.parser.asl.component.common.jsonata.jsonata_template_value_terminal import ( + JSONataTemplateValueTerminalExpression, +) +from moto.stepfunctions.parser.asl.component.state.choice.choice_rule import ( + ChoiceRule, +) +from moto.stepfunctions.parser.asl.component.state.choice.comparison.comparison_type import ( + Comparison, +) +from moto.stepfunctions.parser.asl.eval.environment import Environment +from moto.stepfunctions.parser.asl.parse.typed_props import TypedProps -class Comparison(EvalComponent, ABC): ... + +class ComparisonCompositeProps(TypedProps): + def add(self, instance: Any) -> None: + inst_type = type(instance) + + if issubclass(inst_type, ComparisonComposite): + super()._add(ComparisonComposite, instance) + return + + super().add(instance) + + +class ConditionJSONataLit(Comparison): + literal: bool + + def __init__(self, literal: bool): + self.literal = literal + + def _eval_body(self, env: Environment) -> None: + env.stack.append(self.literal) + + +class ConditionJSONataExpression(Comparison): + jsonata_template_value_terminal_expression: Final[ + JSONataTemplateValueTerminalExpression + ] + + def __init__( + self, + jsonata_template_value_terminal_expression: JSONataTemplateValueTerminalExpression, + ): + super().__init__() + self.jsonata_template_value_terminal_expression = ( + jsonata_template_value_terminal_expression + ) + + def _eval_body(self, env: Environment) -> None: + self.jsonata_template_value_terminal_expression.eval(env=env) + result = env.stack[-1] + if not isinstance(result, bool): + # TODO: add snapshot tests to verify AWS's behaviour about non boolean values. + raise RuntimeError( + f"Expected Condition to produce a boolean result but got result of type '{type(result)}' instead." + ) + + +class ComparisonComposite(Comparison, abc.ABC): + class ChoiceOp(Enum): + And = ASLLexer.AND + Or = ASLLexer.OR + Not = ASLLexer.NOT + + operator: ComparisonComposite.ChoiceOp + + def __init__(self, operator: ComparisonComposite.ChoiceOp): + self.operator = operator + + +class ComparisonCompositeSingle(ComparisonComposite, abc.ABC): + rule: ChoiceRule + + def __init__(self, operator: ComparisonComposite.ChoiceOp, rule: ChoiceRule): + super(ComparisonCompositeSingle, self).__init__(operator=operator) + self.rule = rule + + +class ComparisonCompositeMulti(ComparisonComposite, abc.ABC): + rules: List[ChoiceRule] + + def __init__(self, operator: ComparisonComposite.ChoiceOp, rules: List[ChoiceRule]): + super(ComparisonCompositeMulti, self).__init__(operator=operator) + self.rules = rules + + +class ComparisonCompositeNot(ComparisonCompositeSingle): + def __init__(self, rule: ChoiceRule): + super(ComparisonCompositeNot, self).__init__( + operator=ComparisonComposite.ChoiceOp.Not, rule=rule + ) + + def _eval_body(self, env: Environment) -> None: + self.rule.eval(env) + tmp: bool = env.stack.pop() + res = tmp is False + env.stack.append(res) + + +class ComparisonCompositeAnd(ComparisonCompositeMulti): + def __init__(self, rules: List[ChoiceRule]): + super(ComparisonCompositeAnd, self).__init__( + operator=ComparisonComposite.ChoiceOp.And, rules=rules + ) + + def _eval_body(self, env: Environment) -> None: + res = True + for rule in self.rules: + rule.eval(env) + rule_out = env.stack.pop() + if not rule_out: + res = False + break # TODO: Lazy evaluation? Can use all function instead? how's eval for that? + env.stack.append(res) + + +class ComparisonCompositeOr(ComparisonCompositeMulti): + def __init__(self, rules: List[ChoiceRule]): + super(ComparisonCompositeOr, self).__init__( + operator=ComparisonComposite.ChoiceOp.Or, rules=rules + ) + + def _eval_body(self, env: Environment) -> None: + res = False + for rule in self.rules: + rule.eval(env) + rule_out = env.stack.pop() + res = res or rule_out + if res: + break # TODO: Lazy evaluation? Can use all function instead? how's eval for that? + env.stack.append(res) diff --git a/moto/stepfunctions/parser/asl/component/state/choice/comparison/comparison_composite.py b/moto/stepfunctions/parser/asl/component/state/choice/comparison/comparison_composite.py deleted file mode 100644 index 9b46ac8e5edf..000000000000 --- a/moto/stepfunctions/parser/asl/component/state/choice/comparison/comparison_composite.py +++ /dev/null @@ -1,101 +0,0 @@ -from __future__ import annotations - -import abc -from enum import Enum -from typing import Any, Final, List - -from moto.stepfunctions.parser.asl.antlr.runtime.ASLLexer import ASLLexer -from moto.stepfunctions.parser.asl.component.state.choice.choice_rule import ( - ChoiceRule, -) -from moto.stepfunctions.parser.asl.component.state.choice.comparison.comparison import ( - Comparison, -) -from moto.stepfunctions.parser.asl.eval.environment import Environment -from moto.stepfunctions.parser.asl.parse.typed_props import TypedProps - - -class ComparisonCompositeProps(TypedProps): - def add(self, instance: Any) -> None: - inst_type = type(instance) - - if issubclass(inst_type, ComparisonComposite): - super()._add(ComparisonComposite, instance) - return - - super().add(instance) - - -class ComparisonComposite(Comparison, abc.ABC): - class ChoiceOp(Enum): - And = ASLLexer.AND - Or = ASLLexer.OR - Not = ASLLexer.NOT - - operator: Final[ComparisonComposite.ChoiceOp] - - def __init__(self, operator: ComparisonComposite.ChoiceOp): - self.operator = operator - - -class ComparisonCompositeSingle(ComparisonComposite, abc.ABC): - rule: Final[ChoiceRule] - - def __init__(self, operator: ComparisonComposite.ChoiceOp, rule: ChoiceRule): - super(ComparisonCompositeSingle, self).__init__(operator=operator) - self.rule = rule - - -class ComparisonCompositeMulti(ComparisonComposite, abc.ABC): - rules: Final[List[ChoiceRule]] - - def __init__(self, operator: ComparisonComposite.ChoiceOp, rules: List[ChoiceRule]): - super(ComparisonCompositeMulti, self).__init__(operator=operator) - self.rules = rules - - -class ComparisonCompositeNot(ComparisonCompositeSingle): - def __init__(self, rule: ChoiceRule): - super(ComparisonCompositeNot, self).__init__( - operator=ComparisonComposite.ChoiceOp.Not, rule=rule - ) - - def _eval_body(self, env: Environment) -> None: - self.rule.eval(env) - tmp: bool = env.stack.pop() - res = tmp is False - env.stack.append(res) - - -class ComparisonCompositeAnd(ComparisonCompositeMulti): - def __init__(self, rules: List[ChoiceRule]): - super(ComparisonCompositeAnd, self).__init__( - operator=ComparisonComposite.ChoiceOp.And, rules=rules - ) - - def _eval_body(self, env: Environment) -> None: - res = True - for rule in self.rules: - rule.eval(env) - rule_out = env.stack.pop() - if not rule_out: - res = False - break # TODO: Lazy evaluation? Can use all function instead? how's eval for that? - env.stack.append(res) - - -class ComparisonCompositeOr(ComparisonCompositeMulti): - def __init__(self, rules: List[ChoiceRule]): - super(ComparisonCompositeOr, self).__init__( - operator=ComparisonComposite.ChoiceOp.Or, rules=rules - ) - - def _eval_body(self, env: Environment) -> None: - res = False - for rule in self.rules: - rule.eval(env) - rule_out = env.stack.pop() - res = res or rule_out - if res: - break # TODO: Lazy evaluation? Can use all function instead? how's eval for that? - env.stack.append(res) diff --git a/moto/stepfunctions/parser/asl/component/state/choice/comparison/comparison_func.py b/moto/stepfunctions/parser/asl/component/state/choice/comparison/comparison_func.py index f1c455029daa..2c6f40c8ac94 100644 --- a/moto/stepfunctions/parser/asl/component/state/choice/comparison/comparison_func.py +++ b/moto/stepfunctions/parser/asl/component/state/choice/comparison/comparison_func.py @@ -1,12 +1,17 @@ from __future__ import annotations -import json -from typing import Final +import abc +from typing import Any -from moto.stepfunctions.parser.asl.component.eval_component import EvalComponent +from moto.stepfunctions.parser.asl.component.common.variable_sample import ( + VariableSample, +) from moto.stepfunctions.parser.asl.component.state.choice.comparison.comparison_operator_type import ( ComparisonOperatorType, ) +from moto.stepfunctions.parser.asl.component.state.choice.comparison.comparison_type import ( + Comparison, +) from moto.stepfunctions.parser.asl.component.state.choice.comparison.operator.factory import ( OperatorFactory, ) @@ -16,18 +21,40 @@ from moto.stepfunctions.parser.asl.eval.environment import Environment -class ComparisonFunc(EvalComponent): - def __init__(self, operator: ComparisonOperatorType, value: json): - self.operator_type: Final[ComparisonOperatorType] = operator - self.value: json = value +class ComparisonFunc(Comparison, abc.ABC): + operator_type: ComparisonOperatorType + + def __init__(self, operator_type: ComparisonOperatorType): + self.operator_type = operator_type + + +class ComparisonFuncValue(ComparisonFunc): + value: Any + + def __init__(self, operator_type: ComparisonOperatorType, value: Any): + super().__init__(operator_type=operator_type) + self.value = value def _eval_body(self, env: Environment) -> None: - value = self.value operator: Operator = OperatorFactory.get(self.operator_type) - operator.eval(env=env, value=value) + operator.eval(env=env, value=self.value) + + +class ComparisonFuncVar(ComparisonFuncValue): + _COMPARISON_FUNC_VAR_VALUE: str = "$" + variable_sample: VariableSample - @staticmethod - def _string_equals(env: Environment, value: json) -> None: - val = env.stack.pop() - res = str(val) == value - env.stack.append(res) + def __init__( + self, operator_type: ComparisonOperatorType, variable_sample: VariableSample + ): + super().__init__( + operator_type=operator_type, value=self._COMPARISON_FUNC_VAR_VALUE + ) + self.variable_sample = variable_sample + + def _eval_body(self, env: Environment) -> None: + self.variable_sample.eval(env=env) + super()._eval_body(env=env) + # Purge the outcome of the variable sampling form the + # stack as operators do not digest the input value. + del env.stack[-2] diff --git a/moto/stepfunctions/parser/asl/component/state/choice/comparison/comparison_type.py b/moto/stepfunctions/parser/asl/component/state/choice/comparison/comparison_type.py new file mode 100644 index 000000000000..345adedbf726 --- /dev/null +++ b/moto/stepfunctions/parser/asl/component/state/choice/comparison/comparison_type.py @@ -0,0 +1,8 @@ +from __future__ import annotations + +from abc import ABC + +from moto.stepfunctions.parser.asl.component.eval_component import EvalComponent + + +class Comparison(EvalComponent, ABC): ... diff --git a/moto/stepfunctions/parser/asl/component/state/choice/comparison/comparison_variable.py b/moto/stepfunctions/parser/asl/component/state/choice/comparison/comparison_variable.py index 58b0c8f33fad..9940140c9e55 100644 --- a/moto/stepfunctions/parser/asl/component/state/choice/comparison/comparison_variable.py +++ b/moto/stepfunctions/parser/asl/component/state/choice/comparison/comparison_variable.py @@ -1,11 +1,11 @@ from typing import Final -from moto.stepfunctions.parser.asl.component.state.choice.comparison.comparison import ( - Comparison, -) from moto.stepfunctions.parser.asl.component.state.choice.comparison.comparison_func import ( ComparisonFunc, ) +from moto.stepfunctions.parser.asl.component.state.choice.comparison.comparison_type import ( + Comparison, +) from moto.stepfunctions.parser.asl.component.state.choice.comparison.variable import ( Variable, ) diff --git a/moto/stepfunctions/parser/asl/component/state/choice/comparison/operator/factory.py b/moto/stepfunctions/parser/asl/component/state/choice/comparison/operator/factory.py index 8e9146c17e95..967c3171d77a 100644 --- a/moto/stepfunctions/parser/asl/component/state/choice/comparison/operator/factory.py +++ b/moto/stepfunctions/parser/asl/component/state/choice/comparison/operator/factory.py @@ -14,7 +14,7 @@ class OperatorFactory: @staticmethod def get(typ: ComparisonOperatorType) -> Operator: - op = Operator.get((str(typ))) + op = Operator.get((str(typ)), raise_if_missing=False) if op is None: raise NotImplementedError(f"{typ} is not supported.") return op diff --git a/moto/stepfunctions/parser/asl/component/state/choice/comparison/operator/implementations/boolean_equals.py b/moto/stepfunctions/parser/asl/component/state/choice/comparison/operator/implementations/boolean_equals.py index bafe16af2ad8..63b1f8fd7bbd 100644 --- a/moto/stepfunctions/parser/asl/component/state/choice/comparison/operator/implementations/boolean_equals.py +++ b/moto/stepfunctions/parser/asl/component/state/choice/comparison/operator/implementations/boolean_equals.py @@ -7,7 +7,7 @@ Operator, ) from moto.stepfunctions.parser.asl.eval.environment import Environment -from moto.stepfunctions.parser.asl.utils.json_path import JSONPathUtils +from moto.stepfunctions.parser.asl.utils.json_path import extract_json class BooleanEquals(Operator): @@ -34,7 +34,7 @@ def eval(env: Environment, value: Any) -> None: variable = env.stack.pop() inp = env.stack[-1] - comp_value: bool = JSONPathUtils.extract_json(value, inp) + comp_value: bool = extract_json(value, inp) if not isinstance(comp_value, bool): raise TypeError( f"Expected type bool, but got '{comp_value}' from path '{value}'." diff --git a/moto/stepfunctions/parser/asl/component/state/choice/comparison/operator/implementations/is_operator.py b/moto/stepfunctions/parser/asl/component/state/choice/comparison/operator/implementations/is_operator.py index 82f30f67d7b6..b2e7f570eae7 100644 --- a/moto/stepfunctions/parser/asl/component/state/choice/comparison/operator/implementations/is_operator.py +++ b/moto/stepfunctions/parser/asl/component/state/choice/comparison/operator/implementations/is_operator.py @@ -104,7 +104,9 @@ def is_timestamp(inp: Any) -> bool: def eval(env: Environment, value: Any) -> None: variable = env.stack.pop() LOG.warning( - f"State Choice's 'IsTimestamp' operator is not fully supported for input '{variable}' and target '{value}'." + "State Choice's 'IsTimestamp' operator is not fully supported for input '%s' and target '%s'.", + variable, + value, ) res = IsTimestamp.is_timestamp(variable) is value env.stack.append(res) diff --git a/moto/stepfunctions/parser/asl/component/state/choice/comparison/operator/implementations/numeric.py b/moto/stepfunctions/parser/asl/component/state/choice/comparison/operator/implementations/numeric.py index 9201fa46ceb4..53ff600b9084 100644 --- a/moto/stepfunctions/parser/asl/component/state/choice/comparison/operator/implementations/numeric.py +++ b/moto/stepfunctions/parser/asl/component/state/choice/comparison/operator/implementations/numeric.py @@ -7,7 +7,7 @@ Operator, ) from moto.stepfunctions.parser.asl.eval.environment import Environment -from moto.stepfunctions.parser.asl.utils.json_path import JSONPathUtils +from moto.stepfunctions.parser.asl.utils.json_path import extract_json def _is_numeric(variable: Any) -> bool: @@ -42,7 +42,7 @@ def impl_name() -> str: def eval(env: Environment, value: Any) -> None: variable = env.stack.pop() inp = env.stack[-1] - comp_value = JSONPathUtils.extract_json(value, inp) + comp_value = extract_json(value, inp) res = NumericEquals._compare(variable, comp_value) env.stack.append(res) @@ -75,7 +75,7 @@ def impl_name() -> str: def eval(env: Environment, value: Any) -> None: variable = env.stack.pop() inp = env.stack[-1] - comp_value = JSONPathUtils.extract_json(value, inp) + comp_value = extract_json(value, inp) res = NumericGreaterThanPath._compare(variable, comp_value) env.stack.append(res) @@ -108,7 +108,7 @@ def impl_name() -> str: def eval(env: Environment, value: Any) -> None: variable = env.stack.pop() inp = env.stack[-1] - comp_value = JSONPathUtils.extract_json(value, inp) + comp_value = extract_json(value, inp) res = NumericGreaterThanEqualsPath._compare(variable, comp_value) env.stack.append(res) @@ -141,7 +141,7 @@ def impl_name() -> str: def eval(env: Environment, value: Any) -> None: variable = env.stack.pop() inp = env.stack[-1] - comp_value = JSONPathUtils.extract_json(value, inp) + comp_value = extract_json(value, inp) res = NumericLessThanPath._compare(variable, comp_value) env.stack.append(res) @@ -174,6 +174,6 @@ def impl_name() -> str: def eval(env: Environment, value: Any) -> None: variable = env.stack.pop() inp = env.stack[-1] - comp_value = JSONPathUtils.extract_json(value, inp) + comp_value = extract_json(value, inp) res = NumericLessThanEqualsPath._compare(variable, comp_value) env.stack.append(res) diff --git a/moto/stepfunctions/parser/asl/component/state/choice/comparison/operator/implementations/string_operators.py b/moto/stepfunctions/parser/asl/component/state/choice/comparison/operator/implementations/string_operators.py index 5a02bc0b3fbe..11af25e83de6 100644 --- a/moto/stepfunctions/parser/asl/component/state/choice/comparison/operator/implementations/string_operators.py +++ b/moto/stepfunctions/parser/asl/component/state/choice/comparison/operator/implementations/string_operators.py @@ -8,7 +8,7 @@ Operator, ) from moto.stepfunctions.parser.asl.eval.environment import Environment -from moto.stepfunctions.parser.asl.utils.json_path import JSONPathUtils +from moto.stepfunctions.parser.asl.utils.json_path import extract_json class StringEquals(Operator): @@ -39,7 +39,7 @@ def impl_name() -> str: def eval(env: Environment, value: Any) -> None: variable = env.stack.pop() inp = env.stack[-1] - comp_value = JSONPathUtils.extract_json(value, inp) + comp_value = extract_json(value, inp) res = StringEqualsPath._compare(variable, comp_value) env.stack.append(res) @@ -72,7 +72,7 @@ def impl_name() -> str: def eval(env: Environment, value: Any) -> None: variable = env.stack.pop() inp = env.stack[-1] - comp_value = JSONPathUtils.extract_json(value, inp) + comp_value = extract_json(value, inp) res = StringGreaterThanPath._compare(variable, comp_value) env.stack.append(res) @@ -105,7 +105,7 @@ def impl_name() -> str: def eval(env: Environment, value: Any) -> None: variable = env.stack.pop() inp = env.stack[-1] - comp_value = JSONPathUtils.extract_json(value, inp) + comp_value = extract_json(value, inp) res = StringGreaterThanEqualsPath._compare(variable, comp_value) env.stack.append(res) @@ -138,7 +138,7 @@ def impl_name() -> str: def eval(env: Environment, value: Any) -> None: variable = env.stack.pop() inp = env.stack[-1] - comp_value = JSONPathUtils.extract_json(value, inp) + comp_value = extract_json(value, inp) res = StringLessThanPath._compare(variable, comp_value) env.stack.append(res) @@ -171,7 +171,7 @@ def impl_name() -> str: def eval(env: Environment, value: Any) -> None: variable = env.stack.pop() inp = env.stack[-1] - comp_value = JSONPathUtils.extract_json(value, inp) + comp_value = extract_json(value, inp) res = StringLessThanEqualsPath._compare(variable, comp_value) env.stack.append(res) diff --git a/moto/stepfunctions/parser/asl/component/state/choice/comparison/operator/implementations/timestamp_operators.py b/moto/stepfunctions/parser/asl/component/state/choice/comparison/operator/implementations/timestamp_operators.py index 7d32fdfcd528..aa5c01e3e406 100644 --- a/moto/stepfunctions/parser/asl/component/state/choice/comparison/operator/implementations/timestamp_operators.py +++ b/moto/stepfunctions/parser/asl/component/state/choice/comparison/operator/implementations/timestamp_operators.py @@ -10,7 +10,7 @@ Operator, ) from moto.stepfunctions.parser.asl.eval.environment import Environment -from moto.stepfunctions.parser.asl.utils.json_path import JSONPathUtils +from moto.stepfunctions.parser.asl.utils.json_path import extract_json class TimestampEquals(Operator): @@ -44,7 +44,7 @@ def impl_name() -> str: def eval(env: Environment, value: Any) -> None: variable = env.stack.pop() inp = env.stack[-1] - comp_value = JSONPathUtils.extract_json(value, inp) + comp_value = extract_json(value, inp) res = TimestampEqualsPath._compare(variable, comp_value) env.stack.append(res) @@ -80,7 +80,7 @@ def impl_name() -> str: def eval(env: Environment, value: Any) -> None: variable = env.stack.pop() inp = env.stack[-1] - comp_value = JSONPathUtils.extract_json(value, inp) + comp_value = extract_json(value, inp) res = TimestampGreaterThanPath._compare(variable, comp_value) env.stack.append(res) @@ -116,7 +116,7 @@ def impl_name() -> str: def eval(env: Environment, value: Any) -> None: variable = env.stack.pop() inp = env.stack[-1] - comp_value = JSONPathUtils.extract_json(value, inp) + comp_value = extract_json(value, inp) res = TimestampGreaterThanEqualsPath._compare(variable, comp_value) env.stack.append(res) @@ -152,7 +152,7 @@ def impl_name() -> str: def eval(env: Environment, value: Any) -> None: variable = env.stack.pop() inp = env.stack[-1] - comp_value = JSONPathUtils.extract_json(value, inp) + comp_value = extract_json(value, inp) res = TimestampLessThanPath._compare(variable, comp_value) env.stack.append(res) @@ -188,6 +188,6 @@ def impl_name() -> str: def eval(env: Environment, value: Any) -> None: variable = env.stack.pop() inp = env.stack[-1] - comp_value = JSONPathUtils.extract_json(value, inp) + comp_value = extract_json(value, inp) res = TimestampLessThanEqualsPath._compare(variable, comp_value) env.stack.append(res) diff --git a/moto/stepfunctions/parser/asl/component/state/choice/comparison/variable.py b/moto/stepfunctions/parser/asl/component/state/choice/comparison/variable.py index b600ebf58072..eed793764305 100644 --- a/moto/stepfunctions/parser/asl/component/state/choice/comparison/variable.py +++ b/moto/stepfunctions/parser/asl/component/state/choice/comparison/variable.py @@ -1,8 +1,12 @@ +import abc from typing import Final +from moto.stepfunctions.parser.asl.component.common.variable_sample import ( + VariableSample, +) from moto.stepfunctions.parser.asl.component.eval_component import EvalComponent from moto.stepfunctions.parser.asl.eval.environment import Environment -from moto.stepfunctions.parser.asl.utils.json_path import JSONPathUtils +from moto.stepfunctions.parser.asl.utils.json_path import extract_json class NoSuchVariable: @@ -10,14 +14,42 @@ def __init__(self, path: str): self.path: Final[str] = path -class Variable(EvalComponent): +class Variable(EvalComponent, abc.ABC): ... + + +class VariableBase(Variable): def __init__(self, value: str): self.value: Final[str] = value def _eval_body(self, env: Environment) -> None: try: inp = env.stack[-1] - value = JSONPathUtils.extract_json(self.value, inp) + value = extract_json(self.value, inp) + except Exception as ex: + value = NoSuchVariable(f"{self.value}, {ex}") + env.stack.append(value) + + +class VariableContextObject(VariableBase): + def __init__(self, value: str): + value_tail = value[1:] + super().__init__(value=value_tail) + + def _eval_body(self, env: Environment) -> None: + try: + value = extract_json( + self.value, env.states.context_object.context_object_data + ) except Exception as ex: value = NoSuchVariable(f"{self.value}, {ex}") env.stack.append(value) + + +class VariableVar(Variable): + variable_sample: VariableSample + + def __init__(self, variable_sample: VariableSample): + self.variable_sample = variable_sample + + def _eval_body(self, env: Environment) -> None: + self.variable_sample.eval(env=env) diff --git a/moto/stepfunctions/parser/asl/component/state/choice/state_choice.py b/moto/stepfunctions/parser/asl/component/state/choice/state_choice.py index eef4e9613b28..88a778995be6 100644 --- a/moto/stepfunctions/parser/asl/component/state/choice/state_choice.py +++ b/moto/stepfunctions/parser/asl/component/state/choice/state_choice.py @@ -16,20 +16,21 @@ class StateChoice(CommonStateField): choices_decl: ChoicesDecl + default_state: Optional[DefaultDecl] + _next_state_name: Optional[str] def __init__(self): super(StateChoice, self).__init__( state_entered_event_type=HistoryEventType.ChoiceStateEntered, state_exited_event_type=HistoryEventType.ChoiceStateExited, ) - self.default_state: Optional[DefaultDecl] = None - self._next_state_name: Optional[str] = None + self.default_state = None + self._next_state_name = None def from_state_props(self, state_props: StateProps) -> None: super(StateChoice, self).from_state_props(state_props) self.choices_decl = state_props.get(ChoicesDecl) self.default_state = state_props.get(DefaultDecl) - if state_props.get(Next) or state_props.get(End): raise ValueError( "Choice states don't support the End field. " @@ -46,7 +47,6 @@ def _eval_state(self, env: Environment) -> None: if self.default_state: self._next_state_name = self.default_state.state_name - # TODO: Lazy evaluation? for rule in self.choices_decl.rules: rule.eval(env) res = env.stack.pop() @@ -57,3 +57,6 @@ def _eval_state(self, env: Environment) -> None: ) self._next_state_name = rule.next_stmt.name break + + if self.assign_decl: + self.assign_decl.eval(env=env) diff --git a/moto/stepfunctions/parser/asl/component/state/exec/execute_state.py b/moto/stepfunctions/parser/asl/component/state/exec/execute_state.py index a37e756eaba3..2539ac03a549 100644 --- a/moto/stepfunctions/parser/asl/component/state/exec/execute_state.py +++ b/moto/stepfunctions/parser/asl/component/state/exec/execute_state.py @@ -41,6 +41,7 @@ from moto.stepfunctions.parser.asl.component.state.state_props import StateProps from moto.stepfunctions.parser.asl.eval.environment import Environment from moto.stepfunctions.parser.asl.eval.event.event_detail import EventDetails +from moto.stepfunctions.parser.utils import TMP_THREADS LOG = logging.getLogger(__name__) @@ -136,6 +137,7 @@ def _from_error(self, env: Environment, ex: Exception) -> FailureEvent: "State Task encountered an unhandled exception that lead to a State.Runtime error." ) return FailureEvent( + env=env, error_name=StatesErrorName(typ=StatesErrorNameType.StatesRuntime), event_type=HistoryEventType.TaskFailed, event_details=EventDetails( @@ -156,21 +158,17 @@ def _handle_retry( self.retry.eval(env) res: RetryOutcome = env.stack.pop() if res == RetryOutcome.CanRetry: - retry_count = env.context_object_manager.context_object["State"][ + retry_count = env.states.context_object.context_object_data["State"][ "RetryCount" ] - env.context_object_manager.context_object["State"]["RetryCount"] = ( + env.states.context_object.context_object_data["State"]["RetryCount"] = ( retry_count + 1 ) return res - def _handle_catch( - self, env: Environment, failure_event: FailureEvent - ) -> CatchOutcome: + def _handle_catch(self, env: Environment, failure_event: FailureEvent) -> None: env.stack.append(failure_event) self.catch.eval(env) - res: CatchOutcome = env.stack.pop() - return res def _handle_uncaught(self, env: Environment, failure_event: FailureEvent) -> None: self._terminate_with_event(env=env, failure_event=failure_event) @@ -184,7 +182,7 @@ def _evaluate_with_timeout(self, env: Environment) -> None: timeout_seconds: int = env.stack.pop() frame: Environment = env.open_frame() - frame.inp = copy.deepcopy(env.inp) + frame.states.reset(input_value=env.states.get_input()) frame.stack = copy.deepcopy(env.stack) execution_outputs: List[Any] = list() execution_exceptions: List[Optional[Exception]] = [None] @@ -198,8 +196,10 @@ def _exec_and_notify(): execution_exceptions.append(ex) terminated_event.set() - thread = Thread(target=_exec_and_notify) + thread = Thread(target=_exec_and_notify, daemon=True) + TMP_THREADS.append(thread) thread.start() + finished_on_time: bool = terminated_event.wait(timeout_seconds) frame.set_ended() env.close_frame(frame) @@ -214,6 +214,12 @@ def _exec_and_notify(): execution_output = execution_outputs.pop() env.stack.append(execution_output) + if not self._is_language_query_jsonpath(): + env.states.set_result(execution_output) + + if self.assign_decl: + self.assign_decl.eval(env=env) + if self.result_selector: self.result_selector.eval(env=env) @@ -221,24 +227,47 @@ def _exec_and_notify(): self.result_path.eval(env) else: res = env.stack.pop() - env.inp = res + env.states.reset(input_value=res) + + @staticmethod + def _construct_error_output_value(failure_event: FailureEvent) -> Any: + specs_event_details = list(failure_event.event_details.values()) + if ( + len(specs_event_details) != 1 + and "error" in specs_event_details + and "cause" in specs_event_details + ): + raise RuntimeError( + f"Internal Error: invalid event details declaration in FailureEvent: '{failure_event}'." + ) + spec_event_details: dict = list(failure_event.event_details.values())[0] + return { + # If no cause or error fields are given, AWS binds an empty string; otherwise it attaches the value. + "Error": spec_event_details.get("error", ""), + "Cause": spec_event_details.get("cause", ""), + } def _eval_state(self, env: Environment) -> None: # Initialise the retry counter for execution states. - env.context_object_manager.context_object["State"]["RetryCount"] = 0 + env.states.context_object.context_object_data["State"]["RetryCount"] = 0 # Attempt to evaluate the state's logic through until it's successful, caught, or retries have run out. - while True: + while env.is_running(): try: self._evaluate_with_timeout(env) break except Exception as ex: failure_event: FailureEvent = self._from_error(env=env, ex=ex) - env.event_history.add_event( + env.event_manager.add_event( context=env.event_history_context, - hist_type_event=failure_event.event_type, - event_detail=failure_event.event_details, + event_type=failure_event.event_type, + event_details=failure_event.event_details, ) + error_output = self._construct_error_output_value( + failure_event=failure_event + ) + env.states.set_error_output(error_output) + env.states.set_result(error_output) if self.retry: retry_outcome: RetryOutcome = self._handle_retry( @@ -248,9 +277,8 @@ def _eval_state(self, env: Environment) -> None: continue if self.catch: - catch_outcome: CatchOutcome = self._handle_catch( - env=env, failure_event=failure_event - ) + self._handle_catch(env=env, failure_event=failure_event) + catch_outcome: CatchOutcome = env.stack[-1] if catch_outcome == CatchOutcome.Caught: break diff --git a/moto/stepfunctions/parser/asl/component/state/exec/state_map/item_reader/eval/resource_output_transformer/transformer_csv.py b/moto/stepfunctions/parser/asl/component/state/exec/state_map/item_reader/eval/resource_output_transformer/transformer_csv.py index eee391101666..6e971ee4632d 100644 --- a/moto/stepfunctions/parser/asl/component/state/exec/state_map/item_reader/eval/resource_output_transformer/transformer_csv.py +++ b/moto/stepfunctions/parser/asl/component/state/exec/state_map/item_reader/eval/resource_output_transformer/transformer_csv.py @@ -47,6 +47,7 @@ def _eval_body(self, env: Environment) -> None: if len(set(headers)) < len(headers): error_name = StatesErrorName(typ=StatesErrorNameType.StatesItemReaderFailed) failure_event = FailureEvent( + env=env, error_name=error_name, event_type=HistoryEventType.TaskFailed, event_details=EventDetails( diff --git a/moto/stepfunctions/parser/asl/component/state/exec/state_map/item_reader/eval/resource_output_transformer/transformer_json.py b/moto/stepfunctions/parser/asl/component/state/exec/state_map/item_reader/eval/resource_output_transformer/transformer_json.py index c73f026d9ee8..7e4599c1ab9d 100644 --- a/moto/stepfunctions/parser/asl/component/state/exec/state_map/item_reader/eval/resource_output_transformer/transformer_json.py +++ b/moto/stepfunctions/parser/asl/component/state/exec/state_map/item_reader/eval/resource_output_transformer/transformer_json.py @@ -31,6 +31,7 @@ def _eval_body(self, env: Environment) -> None: if not isinstance(json_list, list): error_name = StatesErrorName(typ=StatesErrorNameType.StatesItemReaderFailed) failure_event = FailureEvent( + env=env, error_name=error_name, event_type=HistoryEventType.TaskFailed, event_details=EventDetails( diff --git a/moto/stepfunctions/parser/asl/component/state/exec/state_map/item_reader/item_reader_decl.py b/moto/stepfunctions/parser/asl/component/state/exec/state_map/item_reader/item_reader_decl.py index 6edd22022f05..f17a6b1bd141 100644 --- a/moto/stepfunctions/parser/asl/component/state/exec/state_map/item_reader/item_reader_decl.py +++ b/moto/stepfunctions/parser/asl/component/state/exec/state_map/item_reader/item_reader_decl.py @@ -1,7 +1,7 @@ import copy from typing import Final, Optional -from moto.stepfunctions.parser.asl.component.common.parameters import Parameters +from moto.stepfunctions.parser.asl.component.common.parargs import Parargs from moto.stepfunctions.parser.asl.component.eval_component import EvalComponent from moto.stepfunctions.parser.asl.component.state.exec.state_map.item_reader.eval.resource_eval import ( ResourceEval, @@ -26,18 +26,18 @@ class ItemReader(EvalComponent): resource_eval: Final[ResourceEval] - parameters: Final[Optional[Parameters]] + parargs: Final[Optional[Parargs]] reader_config: Final[Optional[ReaderConfig]] resource_output_transformer: Optional[ResourceOutputTransformer] def __init__( self, resource: Resource, - parameters: Optional[Parameters], + parargs: Optional[Parargs], reader_config: Optional[ReaderConfig], ): self.resource_eval = resource_eval_for(resource=resource) - self.parameters = parameters + self.parargs = parargs self.reader_config = reader_config self.resource_output_transformer = None @@ -61,8 +61,9 @@ def _eval_body(self, env: Environment) -> None: if self.reader_config: self.reader_config.eval(env=env) resource_config = env.stack.pop() - if self.parameters: - self.parameters.eval(env=env) + + if self.parargs: + self.parargs.eval(env=env) else: env.stack.append(dict()) diff --git a/moto/stepfunctions/parser/asl/component/state/exec/state_map/item_reader/reader_config/max_items_decl.py b/moto/stepfunctions/parser/asl/component/state/exec/state_map/item_reader/reader_config/max_items_decl.py index ab0f5c474f07..25681829094f 100644 --- a/moto/stepfunctions/parser/asl/component/state/exec/state_map/item_reader/reader_config/max_items_decl.py +++ b/moto/stepfunctions/parser/asl/component/state/exec/state_map/item_reader/reader_config/max_items_decl.py @@ -12,10 +12,16 @@ from moto.stepfunctions.parser.asl.component.common.error_name.states_error_name_type import ( StatesErrorNameType, ) +from moto.stepfunctions.parser.asl.component.common.jsonata.jsonata_template_value_terminal import ( + JSONataTemplateValueTerminalExpression, +) +from moto.stepfunctions.parser.asl.component.common.variable_sample import ( + VariableSample, +) from moto.stepfunctions.parser.asl.component.eval_component import EvalComponent from moto.stepfunctions.parser.asl.eval.environment import Environment from moto.stepfunctions.parser.asl.eval.event.event_detail import EventDetails -from moto.stepfunctions.parser.asl.utils.json_path import JSONPathUtils +from moto.stepfunctions.parser.asl.utils.json_path import extract_json class MaxItemsDecl(EvalComponent, abc.ABC): @@ -57,6 +63,41 @@ def _get_value(self, env: Environment) -> int: return self.max_items +class MaxItemsJSONata(MaxItemsDecl): + jsonata_template_value_terminal_expression: Final[ + JSONataTemplateValueTerminalExpression + ] + + def __init__( + self, + jsonata_template_value_terminal_expression: JSONataTemplateValueTerminalExpression, + ): + super().__init__() + self.jsonata_template_value_terminal_expression = ( + jsonata_template_value_terminal_expression + ) + + def _get_value(self, env: Environment) -> int: + # TODO: add snapshot tests to verify AWS's behaviour about non integer values. + self.jsonata_template_value_terminal_expression.eval(env=env) + max_items: int = int(env.stack.pop()) + return max_items + + +class MaxItemsPathVar(MaxItemsDecl): + variable_sample: VariableSample + + def __init__(self, variable_sample: VariableSample): + super().__init__() + self.variable_sample = variable_sample + + def _get_value(self, env: Environment) -> int: + self.variable_sample.eval(env=env) + # TODO: add snapshot tests to verify AWS's behaviour about non integer values. + max_items: int = int(env.stack.pop()) + return max_items + + class MaxItemsPath(MaxItemsDecl): """ "MaxItemsPath": computes a MaxItems value equal to the reference path it points to. @@ -104,6 +145,6 @@ def _validate_value(self, env: Environment, value: int) -> None: def _get_value(self, env: Environment) -> int: inp = env.stack[-1] - max_items = JSONPathUtils.extract_json(self.path, inp) + max_items = extract_json(self.path, inp) self._validate_value(env=env, value=max_items) return max_items diff --git a/moto/stepfunctions/parser/asl/component/state/exec/state_map/item_reader/reader_config/reader_config_props.py b/moto/stepfunctions/parser/asl/component/state/exec/state_map/item_reader/reader_config/reader_config_props.py index 944c4d124403..3effda125c46 100644 --- a/moto/stepfunctions/parser/asl/component/state/exec/state_map/item_reader/reader_config/reader_config_props.py +++ b/moto/stepfunctions/parser/asl/component/state/exec/state_map/item_reader/reader_config/reader_config_props.py @@ -1,4 +1,4 @@ -from typing import Any +from typing import Any, Set from moto.stepfunctions.parser.asl.component.state.exec.state_map.item_reader.reader_config.max_items_decl import ( MaxItemsDecl, @@ -7,7 +7,7 @@ class ReaderConfigProps(TypedProps): - _UNIQUE_SUB_INSTANCES = {MaxItemsDecl} + _UNIQUE_SUB_INSTANCES: Set[type] = {MaxItemsDecl} name: str def add(self, instance: Any) -> None: diff --git a/moto/stepfunctions/parser/asl/component/state/exec/state_map/items/__init__.py b/moto/stepfunctions/parser/asl/component/state/exec/state_map/items/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/moto/stepfunctions/parser/asl/component/state/exec/state_map/items/items.py b/moto/stepfunctions/parser/asl/component/state/exec/state_map/items/items.py new file mode 100644 index 000000000000..1971f701655a --- /dev/null +++ b/moto/stepfunctions/parser/asl/component/state/exec/state_map/items/items.py @@ -0,0 +1,98 @@ +import abc +from typing import Final, Tuple + +from moto.stepfunctions.parser.api import ( + EvaluationFailedEventDetails, + HistoryEventType, +) +from moto.stepfunctions.parser.asl.component.common.error_name.failure_event import ( + FailureEvent, + FailureEventException, +) +from moto.stepfunctions.parser.asl.component.common.error_name.states_error_name import ( + StatesErrorName, +) +from moto.stepfunctions.parser.asl.component.common.error_name.states_error_name_type import ( + StatesErrorNameType, +) +from moto.stepfunctions.parser.asl.component.common.jsonata.jsonata_template_value_array import ( + JSONataTemplateValueArray, +) +from moto.stepfunctions.parser.asl.component.common.jsonata.jsonata_template_value_terminal import ( + JSONataTemplateValueTerminalExpression, +) +from moto.stepfunctions.parser.asl.component.eval_component import EvalComponent +from moto.stepfunctions.parser.asl.eval.environment import Environment +from moto.stepfunctions.parser.asl.eval.event.event_detail import EventDetails +from moto.stepfunctions.parser.asl.utils.encoding import to_json_str + + +class Items(EvalComponent, abc.ABC): ... + + +class ItemsArray(Items): + jsonata_template_value_array: JSONataTemplateValueArray + + def __init__(self, jsonata_template_value_array: JSONataTemplateValueArray): + super().__init__() + self.jsonata_template_value_array = jsonata_template_value_array + + def _eval_body(self, env: Environment) -> None: + self.jsonata_template_value_array.eval(env=env) + + +class ItemsJSONata(Items): + jsonata_template_value_terminal_expression: Final[ + JSONataTemplateValueTerminalExpression + ] + + def __init__( + self, + jsonata_template_value_terminal_expression: JSONataTemplateValueTerminalExpression, + ): + self.jsonata_template_value_terminal_expression = ( + jsonata_template_value_terminal_expression + ) + + def _eval_body(self, env: Environment) -> None: + self.jsonata_template_value_terminal_expression.eval(env=env) + items = env.stack[-1] + if not isinstance(items, list): + # FIXME: If we pass in a 'function' type, the JSONata lib will return a dict and the + # 'unsupported result type state' wont be reached. + def _get_jsonata_value_type_pair(items) -> Tuple[str, str]: + if items is None: + return "null", "null" + elif isinstance(items, (int, float)): + if isinstance(items, bool): + return "true" if items else "false", "boolean" + return items, "number" + elif isinstance(items, str): + return f'"{items}"', "string" + elif isinstance(items, dict): + return to_json_str(items, separators=(",", ":")), "object" + + expr = self.jsonata_template_value_terminal_expression.expression + if jsonata_pair := _get_jsonata_value_type_pair(items): + jsonata_value, jsonata_type = jsonata_pair + error_cause = ( + f"The JSONata expression '{expr}' specified for the field 'Items' returned an unexpected result type. " + f"Expected 'array', but was '{jsonata_type}' for value: {jsonata_value}" + ) + else: + error_cause = f"The JSONata expression '{expr}' for the field 'Items' returned an unsupported result type." + + error_name = StatesErrorName( + typ=StatesErrorNameType.StatesQueryEvaluationError + ) + failure_event = FailureEvent( + env=env, + error_name=error_name, + event_type=HistoryEventType.EvaluationFailed, + event_details=EventDetails( + evaluationFailedEventDetails=EvaluationFailedEventDetails( + error=error_name.error_name, cause=error_cause, location="Items" + ) + ), + ) + raise FailureEventException(failure_event=failure_event) diff --git a/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/distributed_iteration_component.py b/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/distributed_iteration_component.py index 46359780c5a9..e2edf14fe5ed 100644 --- a/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/distributed_iteration_component.py +++ b/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/distributed_iteration_component.py @@ -3,7 +3,7 @@ import abc import json import threading -from typing import Any, Final, List, Optional +from typing import Any, List, Optional from moto.stepfunctions.parser.api import ( HistoryEventType, @@ -16,16 +16,26 @@ FailureEventException, ) from moto.stepfunctions.parser.asl.component.common.flow.start_at import StartAt +from moto.stepfunctions.parser.asl.component.common.parargs import Parameters +from moto.stepfunctions.parser.asl.component.common.query_language import QueryLanguage from moto.stepfunctions.parser.asl.component.program.program import Program +from moto.stepfunctions.parser.asl.component.program.states import States from moto.stepfunctions.parser.asl.component.state.exec.state_map.item_reader.item_reader_decl import ( ItemReader, ) +from moto.stepfunctions.parser.asl.component.state.exec.state_map.item_selector import ( + ItemSelector, +) from moto.stepfunctions.parser.asl.component.state.exec.state_map.iteration.inline_iteration_component import ( InlineIterationComponent, + InlineIterationComponentEvalInput, ) from moto.stepfunctions.parser.asl.component.state.exec.state_map.iteration.itemprocessor.map_run_record import ( MapRunRecord, ) +from moto.stepfunctions.parser.asl.component.state.exec.state_map.iteration.itemprocessor.processor_config import ( + ProcessorConfig, +) from moto.stepfunctions.parser.asl.component.state.exec.state_map.iteration.iteration_worker import ( IterationWorker, ) @@ -36,31 +46,63 @@ from moto.stepfunctions.parser.asl.component.state.exec.state_map.max_concurrency import ( DEFAULT_MAX_CONCURRENCY_VALUE, ) -from moto.stepfunctions.parser.asl.component.states import States from moto.stepfunctions.parser.asl.eval.environment import Environment from moto.stepfunctions.parser.asl.eval.event.event_detail import EventDetails -from moto.stepfunctions.parser.asl.eval.event.event_history import EventHistory - +from moto.stepfunctions.parser.asl.eval.event.event_manager import ( + EventManager, +) -class DistributedIterationComponentEvalInput: - state_name: Final[str] - max_concurrency: Final[int] - item_reader: Final[ItemReader] - def __init__(self, state_name: str, max_concurrency: int, item_reader: ItemReader): - self.state_name = state_name - self.max_concurrency = max_concurrency +class DistributedIterationComponentEvalInput(InlineIterationComponentEvalInput): + item_reader: Optional[ItemReader] + label: Optional[str] + + def __init__( + self, + state_name: str, + max_concurrency: int, + input_items: List[json], + parameters: Optional[Parameters], + item_selector: Optional[ItemSelector], + item_reader: Optional[ItemReader], + tolerated_failure_count: int, + tolerated_failure_percentage: float, + label: Optional[str], + ): + super().__init__( + state_name=state_name, + max_concurrency=max_concurrency, + input_items=input_items, + parameters=parameters, + item_selector=item_selector, + ) self.item_reader = item_reader + self.tolerated_failure_count = tolerated_failure_count + self.tolerated_failure_percentage = tolerated_failure_percentage + self.label = label class DistributedIterationComponent(InlineIterationComponent, abc.ABC): _eval_input: Optional[DistributedIterationComponentEvalInput] - _mutex: Final[threading.Lock] + _mutex: threading.Lock _map_run_record: Optional[MapRunRecord] _workers: List[IterationWorker] - def __init__(self, start_at: StartAt, states: States, comment: Comment): - super().__init__(start_at=start_at, states=states, comment=comment) + def __init__( + self, + query_language: QueryLanguage, + start_at: StartAt, + states: States, + comment: Comment, + processor_config: ProcessorConfig, + ): + super().__init__( + query_language=query_language, + start_at=start_at, + states=states, + comment=comment, + processor_config=processor_config, + ) self._mutex = threading.Lock() self._map_run_record = None self._workers = list() @@ -89,13 +131,8 @@ def _set_active_workers(self, workers_number: int, env: Environment) -> None: def _map_run(self, env: Environment) -> None: input_items: List[json] = env.stack.pop() - input_item_prog: Final[Program] = Program( - start_at=self._start_at, - states=self._states, - timeout_seconds=None, - comment=self._comment, - ) - self._job_pool = JobPool(job_program=input_item_prog, job_inputs=input_items) + input_item_program: Program = self._get_iteration_program() + self._job_pool = JobPool(job_program=input_item_program, job_inputs=input_items) # TODO: add watch on map_run_record update event and adjust the number of running workers accordingly. max_concurrency = self._map_run_record.max_concurrency @@ -121,29 +158,37 @@ def _eval_body(self, env: Environment) -> None: self._eval_input = env.stack.pop() self._map_run_record = MapRunRecord( - state_machine_arn=env.context_object_manager.context_object["StateMachine"][ + state_machine_arn=env.states.context_object.context_object_data[ + "StateMachine" + ]["Id"], + execution_arn=env.states.context_object.context_object_data["Execution"][ "Id" ], - execution_arn=env.context_object_manager.context_object["Execution"]["Id"], max_concurrency=self._eval_input.max_concurrency, + tolerated_failure_count=self._eval_input.tolerated_failure_count, + tolerated_failure_percentage=self._eval_input.tolerated_failure_percentage, + label=self._eval_input.label, ) env.map_run_record_pool_manager.add(self._map_run_record) - env.event_history.add_event( + env.event_manager.add_event( context=env.event_history_context, - hist_type_event=HistoryEventType.MapRunStarted, - event_detail=EventDetails( + event_type=HistoryEventType.MapRunStarted, + event_details=EventDetails( mapRunStartedEventDetails=MapRunStartedEventDetails( mapRunArn=self._map_run_record.map_run_arn ) ), ) - execution_event_history = env.event_history + parent_event_manager = env.event_manager try: - self._eval_input.item_reader.eval(env=env) - # TODO: investigate if this is truly propagated also to eventual sub programs in map run states. - env.event_history = EventHistory() + if self._eval_input.item_reader: + self._eval_input.item_reader.eval(env=env) + else: + env.stack.append(self._eval_input.input_items) + + env.event_manager = EventManager() self._map_run(env=env) except FailureEventException as failure_event_ex: @@ -157,11 +202,11 @@ def _eval_body(self, env: Environment) -> None: if cause: map_run_fail_event_detail["cause"] = cause - env.event_history = execution_event_history - env.event_history.add_event( + env.event_manager = parent_event_manager + env.event_manager.add_event( context=env.event_history_context, - hist_type_event=HistoryEventType.MapRunFailed, - event_detail=EventDetails( + event_type=HistoryEventType.MapRunFailed, + event_details=EventDetails( mapRunFailedEventDetails=map_run_fail_event_detail ), ) @@ -169,26 +214,26 @@ def _eval_body(self, env: Environment) -> None: raise failure_event_ex except Exception as ex: - env.event_history = execution_event_history - env.event_history.add_event( + env.event_manager = parent_event_manager + env.event_manager.add_event( context=env.event_history_context, - hist_type_event=HistoryEventType.MapRunFailed, - event_detail=EventDetails( + event_type=HistoryEventType.MapRunFailed, + event_details=EventDetails( mapRunFailedEventDetails=MapRunFailedEventDetails() ), ) self._map_run_record.set_stop(status=MapRunStatus.FAILED) raise ex finally: - env.event_history = execution_event_history + env.event_manager = parent_event_manager self._eval_input = None self._workers.clear() # TODO: review workflow of program stops and maprunstops # program_state = env.program_state() # if isinstance(program_state, ProgramSucceeded) - env.event_history.add_event( + env.event_manager.add_event( context=env.event_history_context, - hist_type_event=HistoryEventType.MapRunSucceeded, + event_type=HistoryEventType.MapRunSucceeded, ) self._map_run_record.set_stop(status=MapRunStatus.SUCCEEDED) diff --git a/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/inline_iteration_component.py b/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/inline_iteration_component.py index 4d51dadaa80a..61bcd8486e8c 100644 --- a/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/inline_iteration_component.py +++ b/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/inline_iteration_component.py @@ -7,7 +7,16 @@ from moto.stepfunctions.parser.asl.component.common.comment import Comment from moto.stepfunctions.parser.asl.component.common.flow.start_at import StartAt +from moto.stepfunctions.parser.asl.component.common.parargs import Parameters +from moto.stepfunctions.parser.asl.component.common.query_language import QueryLanguage from moto.stepfunctions.parser.asl.component.program.program import Program +from moto.stepfunctions.parser.asl.component.program.states import States +from moto.stepfunctions.parser.asl.component.state.exec.state_map.item_selector import ( + ItemSelector, +) +from moto.stepfunctions.parser.asl.component.state.exec.state_map.iteration.itemprocessor.processor_config import ( + ProcessorConfig, +) from moto.stepfunctions.parser.asl.component.state.exec.state_map.iteration.iteration_component import ( IterationComponent, ) @@ -21,7 +30,6 @@ from moto.stepfunctions.parser.asl.component.state.exec.state_map.max_concurrency import ( DEFAULT_MAX_CONCURRENCY_VALUE, ) -from moto.stepfunctions.parser.asl.component.states import States from moto.stepfunctions.parser.asl.eval.environment import Environment from moto.stepfunctions.parser.utils import TMP_THREADS @@ -30,24 +38,44 @@ class InlineIterationComponentEvalInput: state_name: Final[str] max_concurrency: Final[int] input_items: Final[List[json]] + parameters: Optional[Parameters] + item_selector: Optional[ItemSelector] - def __init__(self, state_name: str, max_concurrency: int, input_items: List[json]): + def __init__( + self, + state_name: str, + max_concurrency: int, + input_items: List[json], + parameters: Optional[Parameters], + item_selector: Optional[ItemSelector], + ): self.state_name = state_name self.max_concurrency = max_concurrency self.input_items = input_items + self.parameters = parameters + self.item_selector = item_selector class InlineIterationComponent(IterationComponent, abc.ABC): + _processor_config: ProcessorConfig _eval_input: Optional[InlineIterationComponentEvalInput] _job_pool: Optional[JobPool] def __init__( self, + query_language: QueryLanguage, start_at: StartAt, states: States, + processor_config: ProcessorConfig, comment: Optional[Comment], ): - super().__init__(start_at=start_at, states=states, comment=comment) + super().__init__( + query_language=query_language, + start_at=start_at, + states=states, + comment=comment, + ) + self._processor_config = processor_config self._eval_input = None self._job_pool = None @@ -56,7 +84,7 @@ def _create_worker(self, env: Environment) -> IterationWorker: ... def _launch_worker(self, env: Environment) -> IterationWorker: worker = self._create_worker(env=env) - worker_thread = threading.Thread(target=worker.eval) + worker_thread = threading.Thread(target=worker.eval, daemon=True) TMP_THREADS.append(worker_thread) worker_thread.start() return worker @@ -67,14 +95,9 @@ def _eval_body(self, env: Environment) -> None: max_concurrency: int = self._eval_input.max_concurrency input_items: List[json] = self._eval_input.input_items - input_item_prog: Final[Program] = Program( - start_at=self._start_at, - states=self._states, - timeout_seconds=None, - comment=self._comment, - ) + input_item_program: Program = self._get_iteration_program() self._job_pool = JobPool( - job_program=input_item_prog, job_inputs=self._eval_input.input_items + job_program=input_item_program, job_inputs=self._eval_input.input_items ) number_of_workers = ( diff --git a/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/itemprocessor/distributed_item_processor.py b/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/itemprocessor/distributed_item_processor.py index beca31b46b25..310ae98db2d9 100644 --- a/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/itemprocessor/distributed_item_processor.py +++ b/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/itemprocessor/distributed_item_processor.py @@ -1,15 +1,11 @@ from __future__ import annotations -from typing import Final, Optional +from typing import Optional from moto.stepfunctions.parser.asl.component.common.comment import Comment from moto.stepfunctions.parser.asl.component.common.flow.start_at import StartAt -from moto.stepfunctions.parser.asl.component.state.exec.state_map.item_reader.item_reader_decl import ( - ItemReader, -) -from moto.stepfunctions.parser.asl.component.state.exec.state_map.item_selector import ( - ItemSelector, -) +from moto.stepfunctions.parser.asl.component.common.query_language import QueryLanguage +from moto.stepfunctions.parser.asl.component.program.states import States from moto.stepfunctions.parser.asl.component.state.exec.state_map.iteration.distributed_iteration_component import ( DistributedIterationComponent, DistributedIterationComponentEvalInput, @@ -20,46 +16,21 @@ from moto.stepfunctions.parser.asl.component.state.exec.state_map.iteration.itemprocessor.processor_config import ( ProcessorConfig, ) -from moto.stepfunctions.parser.asl.component.states import States from moto.stepfunctions.parser.asl.eval.environment import Environment from moto.stepfunctions.parser.asl.parse.typed_props import TypedProps class DistributedItemProcessorEvalInput(DistributedIterationComponentEvalInput): - item_selector: Final[Optional[ItemSelector]] - - def __init__( - self, - state_name: str, - max_concurrency: int, - item_reader: ItemReader, - item_selector: Optional[ItemSelector], - ): - super().__init__( - state_name=state_name, - max_concurrency=max_concurrency, - item_reader=item_reader, - ) - self.item_selector = item_selector + pass class DistributedItemProcessor(DistributedIterationComponent): - _processor_config: Final[ProcessorConfig] _eval_input: Optional[DistributedItemProcessorEvalInput] - def __init__( - self, - start_at: StartAt, - states: States, - comment: Optional[Comment], - processor_config: ProcessorConfig, - ): - super().__init__(start_at=start_at, states=states, comment=comment) - self._processor_config = processor_config - @classmethod def from_props(cls, props: TypedProps) -> DistributedItemProcessor: item_processor = cls( + query_language=props.get(QueryLanguage) or QueryLanguage(), start_at=props.get( typ=StartAt, raise_on_missing=ValueError( @@ -73,7 +44,7 @@ def from_props(cls, props: TypedProps) -> DistributedItemProcessor: ), ), comment=props.get(Comment), - processor_config=props.get(ProcessorConfig), + processor_config=props.get(ProcessorConfig) or ProcessorConfig(), ) return item_processor @@ -83,6 +54,7 @@ def _create_worker(self, env: Environment) -> DistributedItemProcessorWorker: job_pool=self._job_pool, env=env, item_reader=self._eval_input.item_reader, + parameters=self._eval_input.parameters, item_selector=self._eval_input.item_selector, map_run_record=self._map_run_record, ) diff --git a/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/itemprocessor/distributed_item_processor_worker.py b/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/itemprocessor/distributed_item_processor_worker.py index a94ce1f073d9..6da5aad40f81 100644 --- a/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/itemprocessor/distributed_item_processor_worker.py +++ b/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/itemprocessor/distributed_item_processor_worker.py @@ -1,8 +1,10 @@ +import logging from typing import Final, Optional from moto.stepfunctions.parser.asl.component.common.error_name.failure_event import ( FailureEventException, ) +from moto.stepfunctions.parser.asl.component.common.parargs import Parameters from moto.stepfunctions.parser.asl.component.common.timeouts.timeout import ( EvalTimeoutError, ) @@ -22,13 +24,16 @@ Job, JobPool, ) -from moto.stepfunctions.parser.asl.eval.contextobject.contex_object import Item, Map from moto.stepfunctions.parser.asl.eval.environment import Environment from moto.stepfunctions.parser.asl.eval.program_state import ( ProgramError, ProgramState, ProgramStopped, ) +from moto.stepfunctions.parser.asl.eval.states import ItemData, MapData +from moto.stepfunctions.parser.asl.utils.encoding import to_json_str + +LOG = logging.getLogger(__name__) class DistributedItemProcessorWorker(InlineItemProcessorWorker): @@ -41,11 +46,16 @@ def __init__( job_pool: JobPool, env: Environment, item_reader: ItemReader, + parameters: Optional[Parameters], item_selector: Optional[ItemSelector], map_run_record: MapRunRecord, ): super().__init__( - work_name=work_name, job_pool=job_pool, env=env, item_selector=item_selector + work_name=work_name, + job_pool=job_pool, + env=env, + parameters=parameters, + item_selector=item_selector, ) self._item_reader = item_reader self._map_run_record = map_run_record @@ -59,12 +69,12 @@ def _eval_job(self, env: Environment, job: Job) -> None: job_output = None try: - env.context_object_manager.context_object["Map"] = Map( - Item=Item(Index=job.job_index, Value=job.job_input) + env.states.context_object.context_object_data["Map"] = MapData( + Item=ItemData(Index=job.job_index, Value=job.job_input) ) - env.inp = job.job_input - env.stack.append(env.inp) + env.states.reset(job.job_input) + env.stack.append(env.states.get_input()) self._eval_input(env_frame=env) job.job_program.eval(env) @@ -86,15 +96,30 @@ def _eval_job(self, env: Environment, job: Job) -> None: self._map_run_record.execution_counter.results_written.count() self._map_run_record.execution_counter.running.offset(-1) - job_output = env.inp + job_output = env.states.get_input() - except EvalTimeoutError: + except EvalTimeoutError as timeout_error: + LOG.debug( + "MapRun worker Timeout Error '%s' for input '%s'.", + timeout_error, + to_json_str(job.job_input), + ) self._map_run_record.item_counter.timed_out.count() - except FailureEventException: + except FailureEventException as failure_event_ex: + LOG.debug( + "MapRun worker Event Exception '%s' for input '%s'.", + to_json_str(failure_event_ex.failure_event), + to_json_str(job.job_input), + ) self._map_run_record.item_counter.failed.count() - except Exception: + except Exception as exception: + LOG.debug( + "MapRun worker Error '%s' for input '%s'.", + exception, + to_json_str(job.job_input), + ) self._map_run_record.item_counter.failed.count() finally: @@ -102,25 +127,17 @@ def _eval_job(self, env: Environment, job: Job) -> None: job.job_output = job_output def _eval_pool(self, job: Optional[Job], worker_frame: Environment) -> None: - # Note: the frame has to be closed before the job, to ensure the owner environment is correctly updated - # before the evaluation continues; map states await for job termination not workers termination. if job is None: self._env.delete_frame(worker_frame) return # Evaluate the job. - job_frame = worker_frame.open_frame() + job_frame = worker_frame.open_inner_frame() self._eval_job(env=job_frame, job=job) worker_frame.delete_frame(job_frame) - # Evaluation terminates here due to exception in job. - if isinstance(job.job_output, Exception): - self._env.delete_frame(worker_frame) - self._job_pool.close_job(job) - return - - # Worker was stopped. - if self.stopped(): + # Evaluation terminates here due to exception in job, or worker was stopped. + if isinstance(job.job_output, Exception) or self.stopped(): self._env.delete_frame(worker_frame) self._job_pool.close_job(job) return @@ -128,6 +145,8 @@ def _eval_pool(self, job: Optional[Job], worker_frame: Environment) -> None: next_job: Job = self._job_pool.next_job() # Iteration will terminate after this job. if next_job is None: + # The frame has to be closed before the job, to ensure the owner environment is correctly updated + # before the evaluation continues; map states await for job termination not workers termination. self._env.delete_frame(worker_frame) self._job_pool.close_job(job) return diff --git a/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/itemprocessor/inline_item_processor.py b/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/itemprocessor/inline_item_processor.py index 2ad7613f5006..5cfabf3233af 100644 --- a/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/itemprocessor/inline_item_processor.py +++ b/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/itemprocessor/inline_item_processor.py @@ -1,14 +1,12 @@ from __future__ import annotations -import json import logging -from typing import Final, List, Optional +from typing import Optional from moto.stepfunctions.parser.asl.component.common.comment import Comment from moto.stepfunctions.parser.asl.component.common.flow.start_at import StartAt -from moto.stepfunctions.parser.asl.component.state.exec.state_map.item_selector import ( - ItemSelector, -) +from moto.stepfunctions.parser.asl.component.common.query_language import QueryLanguage +from moto.stepfunctions.parser.asl.component.program.states import States from moto.stepfunctions.parser.asl.component.state.exec.state_map.iteration.inline_iteration_component import ( InlineIterationComponent, InlineIterationComponentEvalInput, @@ -19,7 +17,6 @@ from moto.stepfunctions.parser.asl.component.state.exec.state_map.iteration.itemprocessor.processor_config import ( ProcessorConfig, ) -from moto.stepfunctions.parser.asl.component.states import States from moto.stepfunctions.parser.asl.eval.environment import Environment from moto.stepfunctions.parser.asl.parse.typed_props import TypedProps @@ -27,37 +24,12 @@ class InlineItemProcessorEvalInput(InlineIterationComponentEvalInput): - item_selector: Final[Optional[ItemSelector]] - - def __init__( - self, - state_name: str, - max_concurrency: int, - input_items: List[json], - item_selector: Optional[ItemSelector], - ): - super().__init__( - state_name=state_name, - max_concurrency=max_concurrency, - input_items=input_items, - ) - self.item_selector = item_selector + pass class InlineItemProcessor(InlineIterationComponent): - _processor_config: Final[ProcessorConfig] _eval_input: Optional[InlineItemProcessorEvalInput] - def __init__( - self, - start_at: StartAt, - states: States, - comment: Optional[Comment], - processor_config: ProcessorConfig, - ): - super().__init__(start_at=start_at, states=states, comment=comment) - self._processor_config = processor_config - @classmethod def from_props(cls, props: TypedProps) -> InlineItemProcessor: if not props.get(States): @@ -65,10 +37,11 @@ def from_props(cls, props: TypedProps) -> InlineItemProcessor: if not props.get(StartAt): raise ValueError(f"Missing StartAt declaration in props '{props}'.") item_processor = cls( + query_language=props.get(QueryLanguage) or QueryLanguage(), start_at=props.get(StartAt), states=props.get(States), comment=props.get(Comment), - processor_config=props.get(ProcessorConfig), + processor_config=props.get(ProcessorConfig) or ProcessorConfig(), ) return item_processor @@ -78,4 +51,5 @@ def _create_worker(self, env: Environment) -> InlineItemProcessorWorker: job_pool=self._job_pool, env=env, item_selector=self._eval_input.item_selector, + parameters=self._eval_input.parameters, ) diff --git a/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/itemprocessor/inline_item_processor_worker.py b/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/itemprocessor/inline_item_processor_worker.py index 1efb7e91214b..2471af0e2ad6 100644 --- a/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/itemprocessor/inline_item_processor_worker.py +++ b/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/itemprocessor/inline_item_processor_worker.py @@ -1,7 +1,7 @@ -import copy import logging from typing import Final, Optional +from moto.stepfunctions.parser.asl.component.common.parargs import Parameters from moto.stepfunctions.parser.asl.component.state.exec.state_map.item_selector import ( ItemSelector, ) @@ -17,6 +17,7 @@ class InlineItemProcessorWorker(IterationWorker): + _parameters: Optional[Parameters] _item_selector: Final[Optional[ItemSelector]] def __init__( @@ -25,15 +26,24 @@ def __init__( job_pool: JobPool, env: Environment, item_selector: Optional[ItemSelector], + parameters: Optional[Parameters], ): super().__init__(work_name=work_name, job_pool=job_pool, env=env) self._item_selector = item_selector + self._parameters = parameters def _eval_input(self, env_frame: Environment) -> None: + if not self._parameters and not self._item_selector: + return + + map_state_input = self._env.stack[-1] + env_frame.states.reset(input_value=map_state_input) + env_frame.stack.append(map_state_input) + if self._item_selector: - map_state_input = self._env.stack[-1] - env_frame.inp = copy.deepcopy(map_state_input) - env_frame.stack.append(env_frame.inp) self._item_selector.eval(env_frame) - env_frame.inp = env_frame.stack.pop() - env_frame.stack.append(env_frame.inp) + elif self._parameters: + self._parameters.eval(env_frame) + + output_value = env_frame.stack[-1] + env_frame.states.reset(input_value=output_value) diff --git a/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/itemprocessor/item_processor_decl.py b/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/itemprocessor/item_processor_decl.py index 31f97a0813e1..711cf60222ff 100644 --- a/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/itemprocessor/item_processor_decl.py +++ b/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/itemprocessor/item_processor_decl.py @@ -1,25 +1,7 @@ -from typing import Final, Optional - -from moto.stepfunctions.parser.asl.component.common.comment import Comment -from moto.stepfunctions.parser.asl.component.common.flow.start_at import StartAt -from moto.stepfunctions.parser.asl.component.state.exec.state_map.iteration.itemprocessor.processor_config import ( - ProcessorConfig, -) from moto.stepfunctions.parser.asl.component.state.exec.state_map.iteration.iteration_declaration import ( IterationDecl, ) -from moto.stepfunctions.parser.asl.component.states import States class ItemProcessorDecl(IterationDecl): - processor_config: Final[ProcessorConfig] - - def __init__( - self, - comment: Optional[Comment], - start_at: StartAt, - states: States, - processor_config: Optional[ProcessorConfig], - ): - super().__init__(start_at=start_at, comment=comment, states=states) - self.processor_config = processor_config or ProcessorConfig() + pass diff --git a/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/itemprocessor/item_processor_factory.py b/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/itemprocessor/item_processor_factory.py index 0a229c22f693..d2f3e3de8398 100644 --- a/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/itemprocessor/item_processor_factory.py +++ b/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/itemprocessor/item_processor_factory.py @@ -20,6 +20,7 @@ def from_item_processor_decl( ) -> IterationComponent: if item_processor_decl.processor_config.mode == Mode.Inline: return InlineItemProcessor( + query_language=item_processor_decl.query_language, start_at=item_processor_decl.start_at, states=item_processor_decl.states, comment=item_processor_decl.comment, @@ -27,6 +28,7 @@ def from_item_processor_decl( ) elif item_processor_decl.processor_config.mode == Mode.Distributed: return DistributedItemProcessor( + query_language=item_processor_decl.query_language, start_at=item_processor_decl.start_at, states=item_processor_decl.states, comment=item_processor_decl.comment, @@ -34,5 +36,5 @@ def from_item_processor_decl( ) else: raise ValueError( - f"Unknown Mode value '{item_processor_decl.processor_config.mode}'." + f"Unknown Map state processing mode: '{item_processor_decl.processor_config.mode}'." ) diff --git a/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/itemprocessor/map_run_record.py b/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/itemprocessor/map_run_record.py index 3f271d8d51b2..4357ad680ce9 100644 --- a/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/itemprocessor/map_run_record.py +++ b/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/itemprocessor/map_run_record.py @@ -2,15 +2,20 @@ import datetime import threading from collections import OrderedDict -from typing import Any, Dict, Final, List, Optional, Tuple +from typing import Dict, Final, List, Optional, Tuple -from moto.moto_api._internal import mock_random +from moto.core.utils import iso_8601_datetime_with_milliseconds from moto.stepfunctions.parser.api import ( + Arn, + DescribeMapRunOutput, + LongArn, MapRunExecutionCounts, MapRunItemCounts, + MapRunListItem, MapRunStatus, Timestamp, ) +from moto.stepfunctions.parser.utils import long_uid class Counter: @@ -83,11 +88,12 @@ def describe(self) -> MapRunItemCounts: class MapRunRecord: - update_event: Final[threading.Event] - # This is the original state machine arn plut the map run arn postfix. - map_state_machine_arn: str - execution_arn: str - map_run_arn: str + update_event: threading.Event + map_state_machine_arn: Final[ + LongArn + ] # This is the original state machine arn plut the map run arn postfix. + execution_arn: Arn + map_run_arn: LongArn max_concurrency: int execution_counter: Final[ExecutionCounter] item_counter: Final[ItemCounter] @@ -99,13 +105,21 @@ class MapRunRecord: tolerated_failure_percentage: float def __init__( - self, state_machine_arn: str, execution_arn: str, max_concurrency: int + self, + state_machine_arn: Arn, + execution_arn: Arn, + max_concurrency: int, + tolerated_failure_count: int, + tolerated_failure_percentage: float, + label: Optional[str], ): self.update_event = threading.Event() ( map_state_machine_arn, map_run_arn, - ) = self._generate_map_run_arns(state_machine_arn=state_machine_arn) + ) = self._generate_map_run_arns( + state_machine_arn=state_machine_arn, label=label + ) self.map_run_arn = map_run_arn self.map_state_machine_arn = map_state_machine_arn self.execution_arn = execution_arn @@ -115,30 +129,32 @@ def __init__( self.start_date = datetime.datetime.now(tz=datetime.timezone.utc) self.status = MapRunStatus.RUNNING self.stop_date = None - self.tolerated_failure_count = 0 - self.tolerated_failure_percentage = 0.0 + self.tolerated_failure_count = tolerated_failure_count + self.tolerated_failure_percentage = tolerated_failure_percentage @staticmethod - def _generate_map_run_arns(state_machine_arn: str) -> Tuple[str, str]: + def _generate_map_run_arns( + state_machine_arn: Arn, label: Optional[str] + ) -> Tuple[LongArn, LongArn]: # Generate a new MapRunArn given the StateMachineArn, such that: # inp: arn:aws:states::111111111111:stateMachine: # MRA: arn:aws:states::111111111111:mapRun:/: # SMA: arn:aws:states::111111111111:mapRun:/ map_run_arn = state_machine_arn.replace(":stateMachine:", ":mapRun:") - part_1 = str(mock_random.uuid4()) - map_run_arn = f"{map_run_arn}/{part_1}:{str(mock_random.uuid4())}" + part_1 = long_uid() if label is None else label + map_run_arn = f"{map_run_arn}/{part_1}:{long_uid()}" return f"{state_machine_arn}/{part_1}", map_run_arn def set_stop(self, status: MapRunStatus): self.status = status self.stop_date = datetime.datetime.now(tz=datetime.timezone.utc) - def describe(self) -> Dict[str, Any]: - resp = dict( + def describe(self) -> DescribeMapRunOutput: + describe_output = DescribeMapRunOutput( mapRunArn=self.map_run_arn, executionArn=self.execution_arn, status=self.status, - startDate=self.start_date.isoformat(), + startDate=iso_8601_datetime_with_milliseconds(self.start_date), maxConcurrency=self.max_concurrency, toleratedFailurePercentage=self.tolerated_failure_percentage, toleratedFailureCount=self.tolerated_failure_count, @@ -147,19 +163,21 @@ def describe(self) -> Dict[str, Any]: ) stop_date = self.stop_date if stop_date is not None: - resp["stopDate"] = self.stop_date.isoformat() - return resp + describe_output["stopDate"] = iso_8601_datetime_with_milliseconds( + self.stop_date + ) + return describe_output - def to_json(self) -> Dict[str, Any]: - resp = dict( + def list_item(self) -> MapRunListItem: + list_item = MapRunListItem( executionArn=self.execution_arn, mapRunArn=self.map_run_arn, stateMachineArn=self.map_state_machine_arn, - startDate=self.start_date.isoformat(), + startDate=iso_8601_datetime_with_milliseconds(self.start_date), ) if self.stop_date: - resp["stopDate"] = self.stop_date.isoformat() - return resp + list_item["stopDate"] = iso_8601_datetime_with_milliseconds(self.stop_date) + return list_item def update( self, diff --git a/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/iteration_component.py b/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/iteration_component.py index 330130523814..6cf1442a1c59 100644 --- a/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/iteration_component.py +++ b/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/iteration_component.py @@ -5,21 +5,35 @@ from moto.stepfunctions.parser.asl.component.common.comment import Comment from moto.stepfunctions.parser.asl.component.common.flow.start_at import StartAt +from moto.stepfunctions.parser.asl.component.common.query_language import QueryLanguage from moto.stepfunctions.parser.asl.component.eval_component import EvalComponent -from moto.stepfunctions.parser.asl.component.states import States +from moto.stepfunctions.parser.asl.component.program.program import Program +from moto.stepfunctions.parser.asl.component.program.states import States class IterationComponent(EvalComponent, abc.ABC): + _query_language: QueryLanguage _start_at: Final[StartAt] _states: Final[States] _comment: Final[Optional[Comment]] def __init__( self, + query_language: QueryLanguage, start_at: StartAt, states: States, comment: Optional[Comment], ): + self._query_language = query_language self._start_at = start_at self._states = states self._comment = comment + + def _get_iteration_program(self) -> Program: + return Program( + query_language=self._query_language, + start_at=self._start_at, + states=self._states, + timeout_seconds=None, + comment=self._comment, + ) diff --git a/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/iteration_declaration.py b/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/iteration_declaration.py index 13add3576c39..8f3db90a1737 100644 --- a/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/iteration_declaration.py +++ b/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/iteration_declaration.py @@ -2,21 +2,31 @@ from moto.stepfunctions.parser.asl.component.common.comment import Comment from moto.stepfunctions.parser.asl.component.common.flow.start_at import StartAt +from moto.stepfunctions.parser.asl.component.common.query_language import QueryLanguage from moto.stepfunctions.parser.asl.component.component import Component -from moto.stepfunctions.parser.asl.component.states import States +from moto.stepfunctions.parser.asl.component.program.states import States +from moto.stepfunctions.parser.asl.component.state.exec.state_map.iteration.itemprocessor.processor_config import ( + ProcessorConfig, +) class IterationDecl(Component): comment: Final[Optional[Comment]] + query_language: QueryLanguage start_at: Final[StartAt] states: Final[States] + processor_config: ProcessorConfig def __init__( self, comment: Optional[Comment], + query_language: QueryLanguage, start_at: StartAt, states: States, + processor_config: ProcessorConfig, ): - self.start_at = start_at self.comment = comment + self.query_language = query_language + self.start_at = start_at self.states = states + self.processor_config = processor_config diff --git a/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/iteration_worker.py b/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/iteration_worker.py index c89a36932c27..bdc6b62a4253 100644 --- a/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/iteration_worker.py +++ b/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/iteration_worker.py @@ -14,7 +14,6 @@ Job, JobPool, ) -from moto.stepfunctions.parser.asl.eval.contextobject.contex_object import Item, Map from moto.stepfunctions.parser.asl.eval.environment import Environment from moto.stepfunctions.parser.asl.eval.event.event_detail import EventDetails from moto.stepfunctions.parser.asl.eval.program_state import ( @@ -22,12 +21,13 @@ ProgramState, ProgramStopped, ) +from moto.stepfunctions.parser.asl.eval.states import ItemData, MapData LOG = logging.getLogger(__name__) class IterationWorker(abc.ABC): - _work_name: Final[str] + _work_name: str _job_pool: Final[JobPool] _env: Final[Environment] _stop_signal_received: bool @@ -57,10 +57,10 @@ def _eval_job(self, env: Environment, job: Job) -> None: name=self._work_name, index=job.job_index ) - env.event_history.add_event( + env.event_manager.add_event( context=env.event_history_context, - hist_type_event=HistoryEventType.MapIterationStarted, - event_detail=EventDetails( + event_type=HistoryEventType.MapIterationStarted, + event_details=EventDetails( mapIterationStartedEventDetails=map_iteration_event_details ), ) @@ -69,11 +69,11 @@ def _eval_job(self, env: Environment, job: Job) -> None: f"Unexpected Runtime Error in ItemProcessor worker for input '{job.job_index}'." ) try: - env.context_object_manager.context_object["Map"] = Map( - Item=Item(Index=job.job_index, Value=job.job_input) + env.states.context_object.context_object_data["Map"] = MapData( + Item=ItemData(Index=job.job_index, Value=job.job_input) ) - env.inp = job.job_input + env.states.reset(input_value=job.job_input) self._eval_input(env_frame=env) job.job_program.eval(env) @@ -91,6 +91,7 @@ def _eval_job(self, env: Environment, job: Job) -> None: error_name = CustomErrorName(error_name=error_name) raise FailureEventException( failure_event=FailureEvent( + env=env, error_name=error_name, event_type=HistoryEventType.MapIterationFailed, event_details=EventDetails( @@ -102,6 +103,7 @@ def _eval_job(self, env: Environment, job: Job) -> None: elif isinstance(end_program_state, ProgramStopped): raise FailureEventException( failure_event=FailureEvent( + env=env, error_name=CustomErrorName( error_name=HistoryEventType.MapIterationAborted ), @@ -113,16 +115,16 @@ def _eval_job(self, env: Environment, job: Job) -> None: ) # Otherwise, execution succeeded and the output of this operation is available. - env.event_history.add_event( + env.event_manager.add_event( context=env.event_history_context, - hist_type_event=HistoryEventType.MapIterationSucceeded, - event_detail=EventDetails( + event_type=HistoryEventType.MapIterationSucceeded, + event_details=EventDetails( mapIterationSucceededEventDetails=map_iteration_event_details ), update_source_event_id=False, ) # Extract the output otherwise. - job_output = env.inp + job_output = env.states.get_input() except FailureEventException as failure_event_ex: # Extract the output to be this exception: this will trigger a failure workflow in the jobs pool. @@ -134,19 +136,19 @@ def _eval_job(self, env: Environment, job: Job) -> None: failure_event_ex.failure_event.event_type == HistoryEventType.MapIterationAborted ): - env.event_history.add_event( + env.event_manager.add_event( context=env.event_history_context, - hist_type_event=HistoryEventType.MapIterationAborted, - event_detail=EventDetails( + event_type=HistoryEventType.MapIterationAborted, + event_details=EventDetails( mapIterationAbortedEventDetails=map_iteration_event_details ), update_source_event_id=False, ) else: - env.event_history.add_event( + env.event_manager.add_event( context=env.event_history_context, - hist_type_event=HistoryEventType.MapIterationFailed, - event_detail=EventDetails( + event_type=HistoryEventType.MapIterationFailed, + event_details=EventDetails( mapIterationFailedEventDetails=map_iteration_event_details ), update_source_event_id=False, @@ -155,16 +157,17 @@ def _eval_job(self, env: Environment, job: Job) -> None: except Exception as ex: # Error case. LOG.warning( - f"Unhandled termination error in item processor worker for job '{job.job_index}'." + "Unhandled termination error in item processor worker for job '%s'.", + job.job_index, ) # Pass the exception upstream leading to evaluation halt. job_output = ex - env.event_history.add_event( + env.event_manager.add_event( context=env.event_history_context, - hist_type_event=HistoryEventType.MapIterationFailed, - event_detail=EventDetails( + event_type=HistoryEventType.MapIterationFailed, + event_details=EventDetails( mapIterationFailedEventDetails=map_iteration_event_details ), update_source_event_id=False, @@ -181,18 +184,12 @@ def _eval_pool(self, job: Optional[Job], worker_frame: Environment) -> None: return # Evaluate the job. - job_frame = worker_frame.open_frame() + job_frame = worker_frame.open_inner_frame() self._eval_job(env=job_frame, job=job) worker_frame.close_frame(job_frame) - # Evaluation terminates here due to exception in job. - if isinstance(job.job_output, Exception): - self._env.close_frame(worker_frame) - self._job_pool.close_job(job) - return - - # Worker was stopped. - if self.stopped(): + # Evaluation terminates here due to exception in job, or worker was stopped. + if isinstance(job.job_output, Exception) or self.stopped(): self._env.close_frame(worker_frame) self._job_pool.close_job(job) return diff --git a/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/iterator/distributed_iterator.py b/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/iterator/distributed_iterator.py new file mode 100644 index 000000000000..7e4b028dfb7d --- /dev/null +++ b/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/iterator/distributed_iterator.py @@ -0,0 +1,59 @@ +from __future__ import annotations + +from typing import Optional + +from moto.stepfunctions.parser.asl.component.common.comment import Comment +from moto.stepfunctions.parser.asl.component.common.flow.start_at import StartAt +from moto.stepfunctions.parser.asl.component.common.query_language import QueryLanguage +from moto.stepfunctions.parser.asl.component.program.states import States +from moto.stepfunctions.parser.asl.component.state.exec.state_map.iteration.distributed_iteration_component import ( + DistributedIterationComponent, + DistributedIterationComponentEvalInput, +) +from moto.stepfunctions.parser.asl.component.state.exec.state_map.iteration.itemprocessor.processor_config import ( + ProcessorConfig, +) +from moto.stepfunctions.parser.asl.component.state.exec.state_map.iteration.iterator.distributed_iterator_worker import ( + DistributedIteratorWorker, +) +from moto.stepfunctions.parser.asl.eval.environment import Environment +from moto.stepfunctions.parser.asl.parse.typed_props import TypedProps + + +class DistributedIteratorEvalInput(DistributedIterationComponentEvalInput): + pass + + +class DistributedIterator(DistributedIterationComponent): + _eval_input: Optional[DistributedIteratorEvalInput] + + @classmethod + def from_props(cls, props: TypedProps) -> DistributedIterator: + item_processor = cls( + query_language=props.get(QueryLanguage) or QueryLanguage(), + start_at=props.get( + typ=StartAt, + raise_on_missing=ValueError( + f"Missing StartAt declaration in props '{props}'." + ), + ), + states=props.get( + typ=States, + raise_on_missing=ValueError( + f"Missing States declaration in props '{props}'." + ), + ), + comment=props.get(Comment), + processor_config=props.get(ProcessorConfig), + ) + return item_processor + + def _create_worker(self, env: Environment) -> DistributedIteratorWorker: + return DistributedIteratorWorker( + work_name=self._eval_input.state_name, + job_pool=self._job_pool, + env=env, + parameters=self._eval_input.parameters, + map_run_record=self._map_run_record, + item_selector=self._eval_input.item_selector, + ) diff --git a/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/iterator/distributed_iterator_worker.py b/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/iterator/distributed_iterator_worker.py new file mode 100644 index 000000000000..5304514cd25b --- /dev/null +++ b/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/iterator/distributed_iterator_worker.py @@ -0,0 +1,133 @@ +from typing import Optional + +from moto.stepfunctions.parser.asl.component.common.error_name.failure_event import ( + FailureEventException, +) +from moto.stepfunctions.parser.asl.component.common.parargs import Parameters +from moto.stepfunctions.parser.asl.component.common.timeouts.timeout import ( + EvalTimeoutError, +) +from moto.stepfunctions.parser.asl.component.state.exec.state_map.item_selector import ( + ItemSelector, +) +from moto.stepfunctions.parser.asl.component.state.exec.state_map.iteration.itemprocessor.map_run_record import ( + MapRunRecord, +) +from moto.stepfunctions.parser.asl.component.state.exec.state_map.iteration.iterator.inline_iterator_worker import ( + InlineIteratorWorker, +) +from moto.stepfunctions.parser.asl.component.state.exec.state_map.iteration.job import ( + Job, + JobPool, +) +from moto.stepfunctions.parser.asl.eval.environment import Environment +from moto.stepfunctions.parser.asl.eval.program_state import ( + ProgramError, + ProgramState, + ProgramStopped, +) +from moto.stepfunctions.parser.asl.eval.states import ItemData, MapData + + +class DistributedIteratorWorker(InlineIteratorWorker): + _map_run_record: MapRunRecord + + def __init__( + self, + work_name: str, + job_pool: JobPool, + env: Environment, + parameters: Optional[Parameters], + map_run_record: MapRunRecord, + item_selector: Optional[ItemSelector], + ): + super().__init__( + work_name=work_name, + job_pool=job_pool, + env=env, + parameters=parameters, + item_selector=item_selector, + ) + self._map_run_record = map_run_record + + def _eval_job(self, env: Environment, job: Job) -> None: + self._map_run_record.item_counter.total.count() + self._map_run_record.item_counter.running.count() + + self._map_run_record.execution_counter.total.count() + self._map_run_record.execution_counter.running.count() + + job_output = None + try: + env.states.context_object.context_object_data["Map"] = MapData( + Item=ItemData(Index=job.job_index, Value=job.job_input) + ) + + env.states.reset(input_value=job.job_input) + env.stack.append(env.states.get_input()) + self._eval_input(env_frame=env) + + job.job_program.eval(env) + + # TODO: verify behaviour with all of these scenarios. + end_program_state: ProgramState = env.program_state() + if isinstance(end_program_state, ProgramError): + self._map_run_record.execution_counter.failed.count() + self._map_run_record.item_counter.failed.count() + job_output = None + elif isinstance(end_program_state, ProgramStopped): + self._map_run_record.execution_counter.aborted.count() + self._map_run_record.item_counter.aborted.count() + else: + self._map_run_record.item_counter.succeeded.count() + self._map_run_record.item_counter.results_written.count() + + self._map_run_record.execution_counter.succeeded.count() + self._map_run_record.execution_counter.results_written.count() + self._map_run_record.execution_counter.running.offset(-1) + + job_output = env.states.get_input() + + except EvalTimeoutError: + self._map_run_record.item_counter.timed_out.count() + + except FailureEventException: + self._map_run_record.item_counter.failed.count() + + except Exception: + self._map_run_record.item_counter.failed.count() + + finally: + self._map_run_record.item_counter.running.offset(-1) + job.job_output = job_output + + def _eval_pool(self, job: Optional[Job], worker_frame: Environment) -> None: + # Note: the frame has to be closed before the job, to ensure the owner environment is correctly updated + # before the evaluation continues; map states await for job termination not workers termination. + if job is None: + self._env.delete_frame(worker_frame) + return + + # Evaluate the job. + job_frame = worker_frame.open_frame() + self._eval_job(env=job_frame, job=job) + worker_frame.delete_frame(job_frame) + + # Evaluation terminates here due to exception in job, or worker was stopped. + if isinstance(job.job_output, Exception) or self.stopped(): + self._env.delete_frame(worker_frame) + self._job_pool.close_job(job) + return + + next_job: Job = self._job_pool.next_job() + # Iteration will terminate after this job. + if next_job is None: + self._env.delete_frame(worker_frame) + self._job_pool.close_job(job) + return + + self._job_pool.close_job(job) + self._eval_pool(job=next_job, worker_frame=worker_frame) + + def eval(self) -> None: + self._eval_pool(job=self._job_pool.next_job(), worker_frame=self._env) diff --git a/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/iterator/inline_iterator.py b/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/iterator/inline_iterator.py new file mode 100644 index 000000000000..8ead73016da5 --- /dev/null +++ b/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/iterator/inline_iterator.py @@ -0,0 +1,45 @@ +from __future__ import annotations + +import logging +from typing import Optional + +from moto.stepfunctions.parser.asl.component.state.exec.state_map.iteration.inline_iteration_component import ( + InlineIterationComponent, + InlineIterationComponentEvalInput, +) +from moto.stepfunctions.parser.asl.component.state.exec.state_map.iteration.iterator.inline_iterator_worker import ( + InlineIteratorWorker, +) +from moto.stepfunctions.parser.asl.component.state.exec.state_map.iteration.iterator.iterator_decl import ( + IteratorDecl, +) +from moto.stepfunctions.parser.asl.eval.environment import Environment + +LOG = logging.getLogger(__name__) + + +class InlineIteratorEvalInput(InlineIterationComponentEvalInput): + pass + + +class InlineIterator(InlineIterationComponent): + _eval_input: Optional[InlineIteratorEvalInput] + + def _create_worker(self, env: Environment) -> InlineIteratorWorker: + return InlineIteratorWorker( + work_name=self._eval_input.state_name, + job_pool=self._job_pool, + env=env, + parameters=self._eval_input.parameters, + item_selector=self._eval_input.item_selector, + ) + + @classmethod + def from_declaration(cls, iterator_decl: IteratorDecl): + return cls( + query_language=iterator_decl.query_language, + start_at=iterator_decl.start_at, + states=iterator_decl.states, + comment=iterator_decl.comment, + processor_config=iterator_decl.processor_config, + ) diff --git a/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/iterator/inline_iterator_worker.py b/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/iterator/inline_iterator_worker.py new file mode 100644 index 000000000000..5431feda879b --- /dev/null +++ b/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/iterator/inline_iterator_worker.py @@ -0,0 +1,48 @@ +import logging +from typing import Optional + +from moto.stepfunctions.parser.asl.component.common.parargs import Parameters +from moto.stepfunctions.parser.asl.component.state.exec.state_map.item_selector import ( + ItemSelector, +) +from moto.stepfunctions.parser.asl.component.state.exec.state_map.iteration.iteration_worker import ( + IterationWorker, +) +from moto.stepfunctions.parser.asl.component.state.exec.state_map.iteration.job import ( + JobPool, +) +from moto.stepfunctions.parser.asl.eval.environment import Environment + +LOG = logging.getLogger(__name__) + + +class InlineIteratorWorker(IterationWorker): + _parameters: Optional[Parameters] + _item_selector: Optional[ItemSelector] + + def __init__( + self, + work_name: str, + job_pool: JobPool, + env: Environment, + item_selector: Optional[ItemSelector], + parameters: Optional[Parameters], + ): + super().__init__(work_name=work_name, job_pool=job_pool, env=env) + self._item_selector = item_selector + self._parameters = parameters + + def _eval_input(self, env_frame: Environment) -> None: + if not self._parameters and not self._item_selector: + return + + map_state_input = self._env.stack[-1] + env_frame.states.reset(input_value=map_state_input) + env_frame.stack.append(env_frame.states.get_input()) + + if self._item_selector: + self._item_selector.eval(env_frame) + elif self._parameters: + self._parameters.eval(env_frame) + + env_frame.states.reset(input_value=env_frame.stack[-1]) diff --git a/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/iterator/iterator.py b/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/iterator/iterator.py deleted file mode 100644 index 642d71b5bbd4..000000000000 --- a/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/iterator/iterator.py +++ /dev/null @@ -1,61 +0,0 @@ -from __future__ import annotations - -import json -import logging -from typing import Final, List, Optional - -from moto.stepfunctions.parser.asl.component.common.parameters import Parameters -from moto.stepfunctions.parser.asl.component.state.exec.state_map.item_selector import ( - ItemSelector, -) -from moto.stepfunctions.parser.asl.component.state.exec.state_map.iteration.inline_iteration_component import ( - InlineIterationComponent, - InlineIterationComponentEvalInput, -) -from moto.stepfunctions.parser.asl.component.state.exec.state_map.iteration.iterator.iterator_decl import ( - IteratorDecl, -) -from moto.stepfunctions.parser.asl.component.state.exec.state_map.iteration.iterator.iterator_worker import ( - IteratorWorker, -) -from moto.stepfunctions.parser.asl.eval.environment import Environment - -LOG = logging.getLogger(__name__) - - -class IteratorEvalInput(InlineIterationComponentEvalInput): - parameters: Final[Optional[ItemSelector]] - - def __init__( - self, - state_name: str, - max_concurrency: int, - input_items: List[json], - parameters: Optional[Parameters], - ): - super().__init__( - state_name=state_name, - max_concurrency=max_concurrency, - input_items=input_items, - ) - self.parameters = parameters - - -class Iterator(InlineIterationComponent): - _eval_input: Optional[IteratorEvalInput] - - def _create_worker(self, env: Environment) -> IteratorWorker: - return IteratorWorker( - work_name=self._eval_input.state_name, - job_pool=self._job_pool, - env=env, - parameters=self._eval_input.parameters, - ) - - @classmethod - def from_declaration(cls, iterator_decl: IteratorDecl): - return cls( - start_at=iterator_decl.start_at, - states=iterator_decl.states, - comment=iterator_decl.comment, - ) diff --git a/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/iterator/iterator_factory.py b/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/iterator/iterator_factory.py new file mode 100644 index 000000000000..c2fe720e444b --- /dev/null +++ b/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/iterator/iterator_factory.py @@ -0,0 +1,38 @@ +from moto.stepfunctions.parser.asl.component.state.exec.state_map.iteration.iteration_component import ( + IterationComponent, +) +from moto.stepfunctions.parser.asl.component.state.exec.state_map.iteration.iterator.distributed_iterator import ( + DistributedIterator, +) +from moto.stepfunctions.parser.asl.component.state.exec.state_map.iteration.iterator.inline_iterator import ( + InlineIterator, +) +from moto.stepfunctions.parser.asl.component.state.exec.state_map.iteration.iterator.iterator_decl import ( + IteratorDecl, +) +from moto.stepfunctions.parser.asl.component.state.exec.state_map.mode import ( + Mode, +) + + +def from_iterator_decl(iterator_decl: IteratorDecl) -> IterationComponent: + if iterator_decl.processor_config.mode == Mode.Inline: + return InlineIterator( + query_language=iterator_decl.query_language, + start_at=iterator_decl.start_at, + states=iterator_decl.states, + comment=iterator_decl.comment, + processor_config=iterator_decl.processor_config, + ) + elif iterator_decl.processor_config.mode == Mode.Distributed: + return DistributedIterator( + query_language=iterator_decl.query_language, + start_at=iterator_decl.start_at, + states=iterator_decl.states, + comment=iterator_decl.comment, + processor_config=iterator_decl.processor_config, + ) + else: + raise ValueError( + f"Unknown Map state processing mode: '{iterator_decl.processor_config.mode}'." + ) diff --git a/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/iterator/iterator_worker.py b/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/iterator/iterator_worker.py deleted file mode 100644 index 0666ec816767..000000000000 --- a/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/iterator/iterator_worker.py +++ /dev/null @@ -1,37 +0,0 @@ -import copy -import logging -from typing import Final, Optional - -from moto.stepfunctions.parser.asl.component.common.parameters import Parameters -from moto.stepfunctions.parser.asl.component.state.exec.state_map.iteration.iteration_worker import ( - IterationWorker, -) -from moto.stepfunctions.parser.asl.component.state.exec.state_map.iteration.job import ( - JobPool, -) -from moto.stepfunctions.parser.asl.eval.environment import Environment - -LOG = logging.getLogger(__name__) - - -class IteratorWorker(IterationWorker): - _parameters: Final[Optional[Parameters]] - - def __init__( - self, - work_name: str, - job_pool: JobPool, - env: Environment, - parameters: Optional[Parameters], - ): - super().__init__(work_name=work_name, job_pool=job_pool, env=env) - self._parameters = parameters - - def _eval_input(self, env_frame: Environment) -> None: - if self._parameters: - map_state_input = self._env.stack[-1] - env_frame.inp = copy.deepcopy(map_state_input) - env_frame.stack.append(env_frame.inp) - self._parameters.eval(env_frame) - env_frame.inp = env_frame.stack.pop() - env_frame.stack.append(env_frame.inp) diff --git a/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/job.py b/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/job.py index d1e2109089ba..9c2d404a745b 100644 --- a/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/job.py +++ b/moto/stepfunctions/parser/asl/component/state/exec/state_map/iteration/job.py @@ -50,11 +50,7 @@ def __init__(self, job_program: Program, job_inputs: List[Any]): self._jobs_number = len(job_inputs) self._open_jobs = [ - Job( - job_index=job_index, - job_program=copy.deepcopy(job_program), - job_input=job_input, - ) + Job(job_index=job_index, job_program=job_program, job_input=job_input) for job_index, job_input in enumerate(job_inputs) ] self._open_jobs.reverse() @@ -89,7 +85,9 @@ def close_job(self, job: Job) -> None: if job in self._closed_jobs: LOG.warning( - f"Duplicate execution of Job with index '{job.job_index}' and input '{to_json_str(job.job_input)}'" + "Duplicate execution of Job with index '%s' and input '%s'", + job.job_index, + to_json_str(job.job_input), ) if isinstance(job.job_output, Exception): diff --git a/moto/stepfunctions/parser/asl/component/state/exec/state_map/max_concurrency.py b/moto/stepfunctions/parser/asl/component/state/exec/state_map/max_concurrency.py index 49309a4e2c7a..b1581bb97784 100644 --- a/moto/stepfunctions/parser/asl/component/state/exec/state_map/max_concurrency.py +++ b/moto/stepfunctions/parser/asl/component/state/exec/state_map/max_concurrency.py @@ -1,7 +1,7 @@ import abc from typing import Final -from moto.stepfunctions.parser.api import HistoryEventType +from moto.stepfunctions.parser.api import ExecutionFailedEventDetails, HistoryEventType from moto.stepfunctions.parser.asl.component.common.error_name.failure_event import ( FailureEvent, FailureEventException, @@ -12,13 +12,19 @@ from moto.stepfunctions.parser.asl.component.common.error_name.states_error_name_type import ( StatesErrorNameType, ) +from moto.stepfunctions.parser.asl.component.common.jsonata.jsonata_template_value_terminal import ( + JSONataTemplateValueTerminalExpression, +) +from moto.stepfunctions.parser.asl.component.common.variable_sample import ( + VariableSample, +) from moto.stepfunctions.parser.asl.component.eval_component import EvalComponent from moto.stepfunctions.parser.asl.eval.environment import Environment from moto.stepfunctions.parser.asl.eval.event.event_detail import EventDetails from moto.stepfunctions.parser.asl.utils.encoding import to_json_str -from moto.stepfunctions.parser.asl.utils.json_path import JSONPathUtils +from moto.stepfunctions.parser.asl.utils.json_path import extract_json -DEFAULT_MAX_CONCURRENCY_VALUE: Final[int] = 0 # No limit. +DEFAULT_MAX_CONCURRENCY_VALUE: int = 0 # No limit. class MaxConcurrencyDecl(EvalComponent, abc.ABC): @@ -31,7 +37,7 @@ def _eval_body(self, env: Environment) -> None: class MaxConcurrency(MaxConcurrencyDecl): - max_concurrency_value: Final[int] + max_concurrency_value: int def __init__(self, num: int = DEFAULT_MAX_CONCURRENCY_VALUE): super().__init__() @@ -41,8 +47,43 @@ def _eval_max_concurrency(self, env: Environment) -> int: return self.max_concurrency_value +class MaxConcurrencyJSONata(MaxConcurrencyDecl): + jsonata_template_value_terminal_expression: Final[ + JSONataTemplateValueTerminalExpression + ] + + def __init__( + self, + jsonata_template_value_terminal_expression: JSONataTemplateValueTerminalExpression, + ): + super().__init__() + self.jsonata_template_value_terminal_expression = ( + jsonata_template_value_terminal_expression + ) + + def _eval_max_concurrency(self, env: Environment) -> int: + self.jsonata_template_value_terminal_expression.eval(env=env) + # TODO: add snapshot tests to verify AWS's behaviour about non integer values. + seconds = int(env.stack.pop()) + return seconds + + +class MaxConcurrencyPathVar(MaxConcurrency): + variable_sample: VariableSample + + def __init__(self, variable_sample: VariableSample): + super().__init__() + self.variable_sample = variable_sample + + def _eval_max_concurrency(self, env: Environment) -> int: + self.variable_sample.eval(env=env) + # TODO: add snapshot tests to verify AWS's behaviour about non integer values. + max_concurrency: int = int(env.stack.pop()) + return max_concurrency + + class MaxConcurrencyPath(MaxConcurrency): - max_concurrency_path: Final[str] + max_concurrency_path: str def __init__(self, max_concurrency_path: str): super().__init__() @@ -50,9 +91,7 @@ def __init__(self, max_concurrency_path: str): def _eval_max_concurrency(self, env: Environment) -> int: inp = env.stack[-1] - max_concurrency_value = JSONPathUtils.extract_json( - self.max_concurrency_path, inp - ) + max_concurrency_value = extract_json(self.max_concurrency_path, inp) error_cause = None if not isinstance(max_concurrency_value, int): @@ -72,7 +111,10 @@ def _eval_max_concurrency(self, env: Environment) -> int: error_name=StatesErrorName(typ=StatesErrorNameType.StatesRuntime), event_type=HistoryEventType.ExecutionFailed, event_details=EventDetails( - executionFailedEventDetails=error_cause, + executionFailedEventDetails=ExecutionFailedEventDetails( + error=StatesErrorNameType.StatesRuntime.to_name(), + cause=error_cause, + ) ), ) ) diff --git a/moto/stepfunctions/parser/asl/component/state/exec/state_map/result_writer/__init__.py b/moto/stepfunctions/parser/asl/component/state/exec/state_map/result_writer/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/moto/stepfunctions/parser/asl/component/state/exec/state_map/result_writer/resource_eval/__init__.py b/moto/stepfunctions/parser/asl/component/state/exec/state_map/result_writer/resource_eval/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/moto/stepfunctions/parser/asl/component/state/exec/state_map/result_writer/resource_eval/resource_eval.py b/moto/stepfunctions/parser/asl/component/state/exec/state_map/result_writer/resource_eval/resource_eval.py new file mode 100644 index 000000000000..985dd42bd5d8 --- /dev/null +++ b/moto/stepfunctions/parser/asl/component/state/exec/state_map/result_writer/resource_eval/resource_eval.py @@ -0,0 +1,15 @@ +import abc + +from moto.stepfunctions.parser.asl.component.state.exec.state_task.service.resource import ( + ServiceResource, +) +from moto.stepfunctions.parser.asl.eval.environment import Environment + + +class ResourceEval(abc.ABC): + resource: ServiceResource + + def __init__(self, resource: ServiceResource): + self.resource = resource + + def eval_resource(self, env: Environment) -> None: ... diff --git a/moto/stepfunctions/parser/asl/component/state/exec/state_map/result_writer/resource_eval/resource_eval_factory.py b/moto/stepfunctions/parser/asl/component/state/exec/state_map/result_writer/resource_eval/resource_eval_factory.py new file mode 100644 index 000000000000..4dff20f6d4ef --- /dev/null +++ b/moto/stepfunctions/parser/asl/component/state/exec/state_map/result_writer/resource_eval/resource_eval_factory.py @@ -0,0 +1,19 @@ +from moto.stepfunctions.parser.asl.component.state.exec.state_map.result_writer.resource_eval.resource_eval import ( + ResourceEval, +) +from moto.stepfunctions.parser.asl.component.state.exec.state_map.result_writer.resource_eval.resource_eval_s3 import ( + ResourceEvalS3, +) +from moto.stepfunctions.parser.asl.component.state.exec.state_task.service.resource import ( + Resource, + ServiceResource, +) + + +def resource_eval_for(resource: Resource) -> ResourceEval: + if isinstance(resource, ServiceResource): + if resource.service_name == "s3": + return ResourceEvalS3(resource=resource) + raise ValueError( + f"ResultWriter's Resource fields must be states service resource, instead got '{resource.resource_arn}'." + ) diff --git a/moto/stepfunctions/parser/asl/component/state/exec/state_map/result_writer/resource_eval/resource_eval_s3.py b/moto/stepfunctions/parser/asl/component/state/exec/state_map/result_writer/resource_eval/resource_eval_s3.py new file mode 100644 index 000000000000..ed9e40f91af0 --- /dev/null +++ b/moto/stepfunctions/parser/asl/component/state/exec/state_map/result_writer/resource_eval/resource_eval_s3.py @@ -0,0 +1,75 @@ +from __future__ import annotations + +import json +from typing import Callable + +from moto.stepfunctions.parser.asl.component.state.exec.state_map.result_writer.resource_eval.resource_eval import ( + ResourceEval, +) +from moto.stepfunctions.parser.asl.component.state.exec.state_task.service.resource import ( + ResourceRuntimePart, +) +from moto.stepfunctions.parser.asl.eval.environment import Environment +from moto.stepfunctions.parser.asl.utils.boto_client import boto_client_for +from moto.stepfunctions.parser.utils import camel_to_snake_case + + +class ResourceEvalS3(ResourceEval): + _HANDLER_REFLECTION_PREFIX: str = "_handle_" + _API_ACTION_HANDLER_TYPE = Callable[[Environment, ResourceRuntimePart], None] + + @staticmethod + def _get_s3_client(resource_runtime_part: ResourceRuntimePart): + return boto_client_for( + region=resource_runtime_part.region, + account=resource_runtime_part.account, + service="s3", + ) + + @staticmethod + def _handle_put_object( + env: Environment, resource_runtime_part: ResourceRuntimePart + ) -> None: + parameters = env.stack.pop() + env.stack.pop() # TODO: results + + s3_client = ResourceEvalS3._get_s3_client( + resource_runtime_part=resource_runtime_part + ) + map_run_record = env.map_run_record_pool_manager.get_all().pop() + map_run_uuid = map_run_record.map_run_arn.split(":")[-1] + if parameters["Prefix"] != "" and not parameters["Prefix"].endswith("/"): + parameters["Prefix"] += "/" + + # TODO: generate result files and upload them to s3. + body = { + "DestinationBucket": parameters["Bucket"], + "MapRunArn": map_run_record.map_run_arn, + "ResultFiles": {"FAILED": [], "PENDING": [], "SUCCEEDED": []}, + } + key = parameters["Prefix"] + map_run_uuid + "/manifest.json" + s3_client.put_object( + Bucket=parameters["Bucket"], + Key=key, + Body=json.dumps(body, indent=2).encode("utf8"), + ) + env.stack.append( + { + "MapRunArn": map_run_record.map_run_arn, + "ResultWriterDetails": {"Bucket": parameters["Bucket"], "Key": key}, + } + ) + + def _get_api_action_handler(self) -> ResourceEvalS3._API_ACTION_HANDLER_TYPE: + api_action = camel_to_snake_case(self.resource.api_action).strip() + handler_name = ResourceEvalS3._HANDLER_REFLECTION_PREFIX + api_action + resolver_handler = getattr(self, handler_name) + if resolver_handler is None: + raise ValueError(f"Unknown s3 action '{api_action}'.") + return resolver_handler + + def eval_resource(self, env: Environment) -> None: + self.resource.eval(env=env) + resource_runtime_part: ResourceRuntimePart = env.stack.pop() + resolver_handler = self._get_api_action_handler() + resolver_handler(env, resource_runtime_part) diff --git a/moto/stepfunctions/parser/asl/component/state/exec/state_map/result_writer/result_writer_decl.py b/moto/stepfunctions/parser/asl/component/state/exec/state_map/result_writer/result_writer_decl.py new file mode 100644 index 000000000000..47c3e2592ad1 --- /dev/null +++ b/moto/stepfunctions/parser/asl/component/state/exec/state_map/result_writer/result_writer_decl.py @@ -0,0 +1,44 @@ +import copy +import logging + +from moto.stepfunctions.parser.asl.component.common.parargs import Parargs +from moto.stepfunctions.parser.asl.component.eval_component import EvalComponent +from moto.stepfunctions.parser.asl.component.state.exec.state_map.result_writer.resource_eval.resource_eval import ( + ResourceEval, +) +from moto.stepfunctions.parser.asl.component.state.exec.state_map.result_writer.resource_eval.resource_eval_factory import ( + resource_eval_for, +) +from moto.stepfunctions.parser.asl.component.state.exec.state_task.service.resource import ( + Resource, +) +from moto.stepfunctions.parser.asl.eval.environment import Environment + +LOG = logging.getLogger(__name__) + + +class ResultWriter(EvalComponent): + resource_eval: ResourceEval + parargs: Parargs + + def __init__( + self, + resource: Resource, + parargs: Parargs, + ): + self.resource_eval = resource_eval_for(resource=resource) + self.parargs = parargs + + @property + def resource(self): + return self.resource_eval.resource + + def __str__(self): + class_dict = copy.deepcopy(self.__dict__) + del class_dict["resource_eval"] + class_dict["resource"] = self.resource + return f"({self.__class__.__name__}| {class_dict})" + + def _eval_body(self, env: Environment) -> None: + self.parargs.eval(env=env) + self.resource_eval.eval_resource(env=env) diff --git a/moto/stepfunctions/parser/asl/component/state/exec/state_map/state_map.py b/moto/stepfunctions/parser/asl/component/state/exec/state_map/state_map.py index 7d13b3300d97..1bdb5761bc23 100644 --- a/moto/stepfunctions/parser/asl/component/state/exec/state_map/state_map.py +++ b/moto/stepfunctions/parser/asl/component/state/exec/state_map/state_map.py @@ -1,14 +1,26 @@ +import copy from typing import Optional -from moto.stepfunctions.parser.api import HistoryEventType, MapStateStartedEventDetails +from moto.stepfunctions.parser.api import ( + EvaluationFailedEventDetails, + HistoryEventType, + MapStateStartedEventDetails, +) from moto.stepfunctions.parser.asl.component.common.catch.catch_decl import CatchDecl from moto.stepfunctions.parser.asl.component.common.catch.catch_outcome import ( CatchOutcome, ) from moto.stepfunctions.parser.asl.component.common.error_name.failure_event import ( FailureEvent, + FailureEventException, +) +from moto.stepfunctions.parser.asl.component.common.error_name.states_error_name import ( + StatesErrorName, +) +from moto.stepfunctions.parser.asl.component.common.error_name.states_error_name_type import ( + StatesErrorNameType, ) -from moto.stepfunctions.parser.asl.component.common.parameters import Parameters +from moto.stepfunctions.parser.asl.component.common.parargs import Parameters, Parargs from moto.stepfunctions.parser.asl.component.common.path.items_path import ItemsPath from moto.stepfunctions.parser.asl.component.common.path.result_path import ResultPath from moto.stepfunctions.parser.asl.component.common.result_selector import ( @@ -27,6 +39,9 @@ from moto.stepfunctions.parser.asl.component.state.exec.state_map.item_selector import ( ItemSelector, ) +from moto.stepfunctions.parser.asl.component.state.exec.state_map.items.items import ( + Items, +) from moto.stepfunctions.parser.asl.component.state.exec.state_map.iteration.itemprocessor.distributed_item_processor import ( DistributedItemProcessor, DistributedItemProcessorEvalInput, @@ -44,33 +59,57 @@ from moto.stepfunctions.parser.asl.component.state.exec.state_map.iteration.iteration_component import ( IterationComponent, ) -from moto.stepfunctions.parser.asl.component.state.exec.state_map.iteration.iterator.iterator import ( - Iterator, - IteratorEvalInput, +from moto.stepfunctions.parser.asl.component.state.exec.state_map.iteration.iterator.distributed_iterator import ( + DistributedIterator, + DistributedIteratorEvalInput, +) +from moto.stepfunctions.parser.asl.component.state.exec.state_map.iteration.iterator.inline_iterator import ( + InlineIterator, + InlineIteratorEvalInput, ) from moto.stepfunctions.parser.asl.component.state.exec.state_map.iteration.iterator.iterator_decl import ( IteratorDecl, ) +from moto.stepfunctions.parser.asl.component.state.exec.state_map.iteration.iterator.iterator_factory import ( + from_iterator_decl, +) +from moto.stepfunctions.parser.asl.component.state.exec.state_map.label import ( + Label, +) from moto.stepfunctions.parser.asl.component.state.exec.state_map.max_concurrency import ( MaxConcurrency, MaxConcurrencyDecl, ) +from moto.stepfunctions.parser.asl.component.state.exec.state_map.result_writer.result_writer_decl import ( + ResultWriter, +) +from moto.stepfunctions.parser.asl.component.state.exec.state_map.tolerated_failure import ( + ToleratedFailureCount, + ToleratedFailureCountDecl, + ToleratedFailurePercentage, + ToleratedFailurePercentageDecl, +) from moto.stepfunctions.parser.asl.component.state.state_props import StateProps from moto.stepfunctions.parser.asl.eval.environment import Environment from moto.stepfunctions.parser.asl.eval.event.event_detail import EventDetails class StateMap(ExecutionState): - items_path: ItemsPath + items: Optional[Items] + items_path: Optional[ItemsPath] iteration_component: IterationComponent item_reader: Optional[ItemReader] item_selector: Optional[ItemSelector] parameters: Optional[Parameters] - max_concurrency: MaxConcurrency + max_concurrency_decl: MaxConcurrencyDecl + tolerated_failure_count_decl: ToleratedFailureCountDecl + tolerated_failure_percentage_decl: ToleratedFailurePercentage result_path: Optional[ResultPath] result_selector: ResultSelector retry: Optional[RetryDecl] catch: Optional[CatchDecl] + label: Optional[Label] + result_writer: Optional[ResultWriter] def __init__(self): super(StateMap, self).__init__( @@ -80,21 +119,34 @@ def __init__(self): def from_state_props(self, state_props: StateProps) -> None: super(StateMap, self).from_state_props(state_props) - self.items_path = state_props.get(ItemsPath) or ItemsPath() + if self._is_language_query_jsonpath(): + self.items = None + self.items_path = state_props.get(ItemsPath) or ItemsPath() + else: + # TODO: add snapshot test to assert what missing definitions of items means for a states map + self.items_path = None + self.items = state_props.get(Items) self.item_reader = state_props.get(ItemReader) self.item_selector = state_props.get(ItemSelector) - self.parameters = state_props.get(Parameters) + self.parameters = state_props.get(Parargs) self.max_concurrency_decl = ( state_props.get(MaxConcurrencyDecl) or MaxConcurrency() ) + self.tolerated_failure_count_decl = ( + state_props.get(ToleratedFailureCountDecl) or ToleratedFailureCount() + ) + self.tolerated_failure_percentage_decl = ( + state_props.get(ToleratedFailurePercentageDecl) + or ToleratedFailurePercentage() + ) self.result_path = state_props.get(ResultPath) or ResultPath( result_path_src=ResultPath.DEFAULT_PATH ) self.result_selector = state_props.get(ResultSelector) self.retry = state_props.get(RetryDecl) self.catch = state_props.get(CatchDecl) - - # TODO: add check for itemreader used in distributed mode only. + self.label = state_props.get(Label) + self.result_writer = state_props.get(ResultWriter) iterator_decl = state_props.get(typ=IteratorDecl) item_processor_decl = state_props.get(typ=ItemProcessorDecl) @@ -109,43 +161,98 @@ def from_state_props(self, state_props: StateProps) -> None: ) if isinstance(iteration_decl, IteratorDecl): - self.iteration_component = Iterator.from_declaration(iteration_decl) + self.iteration_component = from_iterator_decl(iteration_decl) elif isinstance(iteration_decl, ItemProcessorDecl): self.iteration_component = from_item_processor_decl(iteration_decl) else: raise ValueError(f"Unknown value for IteratorDecl '{iteration_decl}'.") def _eval_execution(self, env: Environment) -> None: + self.max_concurrency_decl.eval(env=env) max_concurrency_num = env.stack.pop() + label = self.label.label if self.label else None - self.items_path.eval(env) - if self.item_reader: - env.event_history.add_event( - context=env.event_history_context, - hist_type_event=HistoryEventType.MapStateStarted, - event_detail=EventDetails( - mapStateStartedEventDetails=MapStateStartedEventDetails(length=0) - ), - ) - input_items = None - else: - input_items = env.stack.pop() - env.event_history.add_event( - context=env.event_history_context, - hist_type_event=HistoryEventType.MapStateStarted, - event_detail=EventDetails( - mapStateStartedEventDetails=MapStateStartedEventDetails( - length=len(input_items) + # Despite MaxConcurrency and Tolerance fields being state level fields, AWS StepFunctions evaluates only + # MaxConcurrency as a state level field. In contrast, Tolerance is evaluated only after the state start + # event but is logged with event IDs coherent with state level fields. To adhere to this quirk, an evaluation + # frame from this point is created for the evaluation of Tolerance fields following the state start event. + frame: Environment = env.open_frame() + frame.states.reset(input_value=env.states.get_input()) + frame.stack = copy.deepcopy(env.stack) + + try: + if self.items_path: + self.items_path.eval(env=env) + + if self.items: + self.items.eval(env=env) + + if self.item_reader: + env.event_manager.add_event( + context=env.event_history_context, + event_type=HistoryEventType.MapStateStarted, + event_details=EventDetails( + mapStateStartedEventDetails=MapStateStartedEventDetails( + length=0 + ) + ), + ) + input_items = None + else: + input_items = env.stack.pop() + # TODO: This should probably be raised within an Items EvalComponent + if not isinstance(input_items, list): + error_name = StatesErrorName( + typ=StatesErrorNameType.StatesQueryEvaluationError ) - ), - ) + failure_event = FailureEvent( + env=env, + error_name=error_name, + event_type=HistoryEventType.EvaluationFailed, + event_details=EventDetails( + evaluationFailedEventDetails=EvaluationFailedEventDetails( + cause=f"Map state input must be an array but was: {type(input_items)}", + error=error_name.error_name, + ) + ), + ) + raise FailureEventException(failure_event=failure_event) + env.event_manager.add_event( + context=env.event_history_context, + event_type=HistoryEventType.MapStateStarted, + event_details=EventDetails( + mapStateStartedEventDetails=MapStateStartedEventDetails( + length=len(input_items) + ) + ), + ) + + self.tolerated_failure_count_decl.eval(env=frame) + tolerated_failure_count = frame.stack.pop() + self.tolerated_failure_percentage_decl.eval(env=frame) + tolerated_failure_percentage = frame.stack.pop() + finally: + env.close_frame(frame) - if isinstance(self.iteration_component, Iterator): - eval_input = IteratorEvalInput( + if isinstance(self.iteration_component, InlineIterator): + eval_input = InlineIteratorEvalInput( + state_name=self.name, + max_concurrency=max_concurrency_num, + input_items=input_items, + parameters=self.parameters, + item_selector=self.item_selector, + ) + elif isinstance(self.iteration_component, DistributedIterator): + eval_input = DistributedIteratorEvalInput( state_name=self.name, max_concurrency=max_concurrency_num, input_items=input_items, parameters=self.parameters, + item_selector=self.item_selector, + item_reader=self.item_reader, + tolerated_failure_count=tolerated_failure_count, + tolerated_failure_percentage=tolerated_failure_percentage, + label=label, ) elif isinstance(self.iteration_component, InlineItemProcessor): eval_input = InlineItemProcessorEvalInput( @@ -153,13 +260,19 @@ def _eval_execution(self, env: Environment) -> None: max_concurrency=max_concurrency_num, input_items=input_items, item_selector=self.item_selector, + parameters=self.parameters, ) elif isinstance(self.iteration_component, DistributedItemProcessor): eval_input = DistributedItemProcessorEvalInput( state_name=self.name, max_concurrency=max_concurrency_num, + input_items=input_items, item_reader=self.item_reader, item_selector=self.item_selector, + parameters=self.parameters, + tolerated_failure_count=tolerated_failure_count, + tolerated_failure_percentage=tolerated_failure_percentage, + label=label, ) else: raise RuntimeError( @@ -169,26 +282,31 @@ def _eval_execution(self, env: Environment) -> None: env.stack.append(eval_input) self.iteration_component.eval(env) - env.event_history.add_event( + if self.result_writer: + self.result_writer.eval(env) + + env.event_manager.add_event( context=env.event_history_context, - hist_type_event=HistoryEventType.MapStateSucceeded, + event_type=HistoryEventType.MapStateSucceeded, update_source_event_id=False, ) def _eval_state(self, env: Environment) -> None: # Initialise the retry counter for execution states. - env.context_object_manager.context_object["State"]["RetryCount"] = 0 - - # Evaluate state level properties. - self.max_concurrency_decl.eval(env=env) + env.states.context_object.context_object_data["State"]["RetryCount"] = 0 # Attempt to evaluate the state's logic through until it's successful, caught, or retries have run out. - while True: + while env.is_running(): try: self._evaluate_with_timeout(env) break except Exception as ex: failure_event: FailureEvent = self._from_error(env=env, ex=ex) + error_output = self._construct_error_output_value( + failure_event=failure_event + ) + env.states.set_error_output(error_output) + env.states.set_result(error_output) if self.retry: retry_outcome: RetryOutcome = self._handle_retry( @@ -197,15 +315,27 @@ def _eval_state(self, env: Environment) -> None: if retry_outcome == RetryOutcome.CanRetry: continue - env.event_history.add_event( - context=env.event_history_context, - hist_type_event=HistoryEventType.MapStateFailed, - ) + if failure_event.event_type != HistoryEventType.ExecutionFailed: + if ( + isinstance(ex, FailureEventException) + and failure_event.event_type + == HistoryEventType.EvaluationFailed + ): + env.event_manager.add_event( + context=env.event_history_context, + event_type=HistoryEventType.EvaluationFailed, + event_details=EventDetails( + evaluationFailedEventDetails=ex.get_evaluation_failed_event_details(), + ), + ) + env.event_manager.add_event( + context=env.event_history_context, + event_type=HistoryEventType.MapStateFailed, + ) if self.catch: - catch_outcome: CatchOutcome = self._handle_catch( - env=env, failure_event=failure_event - ) + self._handle_catch(env=env, failure_event=failure_event) + catch_outcome: CatchOutcome = env.stack[-1] if catch_outcome == CatchOutcome.Caught: break diff --git a/moto/stepfunctions/parser/asl/component/state/exec/state_map/tolerated_failure.py b/moto/stepfunctions/parser/asl/component/state/exec/state_map/tolerated_failure.py index a605cff15828..eb38ddb6ac17 100644 --- a/moto/stepfunctions/parser/asl/component/state/exec/state_map/tolerated_failure.py +++ b/moto/stepfunctions/parser/asl/component/state/exec/state_map/tolerated_failure.py @@ -12,17 +12,23 @@ from moto.stepfunctions.parser.asl.component.common.error_name.states_error_name_type import ( StatesErrorNameType, ) +from moto.stepfunctions.parser.asl.component.common.jsonata.jsonata_template_value_terminal import ( + JSONataTemplateValueTerminalExpression, +) +from moto.stepfunctions.parser.asl.component.common.variable_sample import ( + VariableSample, +) from moto.stepfunctions.parser.asl.component.eval_component import EvalComponent from moto.stepfunctions.parser.asl.eval.environment import Environment from moto.stepfunctions.parser.asl.eval.event.event_detail import EventDetails from moto.stepfunctions.parser.asl.utils.encoding import to_json_str -from moto.stepfunctions.parser.asl.utils.json_path import JSONPathUtils +from moto.stepfunctions.parser.asl.utils.json_path import extract_json -TOLERATED_FAILURE_COUNT_MIN: Final[int] = 0 -TOLERATED_FAILURE_COUNT_DEFAULT: Final[int] = 0 -TOLERATED_FAILURE_PERCENTAGE_MIN: Final[float] = 0.0 -TOLERATED_FAILURE_PERCENTAGE_DEFAULT: Final[float] = 0.0 -TOLERATED_FAILURE_PERCENTAGE_MAX: Final[float] = 100.0 +TOLERATED_FAILURE_COUNT_MIN: int = 0 +TOLERATED_FAILURE_COUNT_DEFAULT: int = 0 +TOLERATED_FAILURE_PERCENTAGE_MIN: float = 0.0 +TOLERATED_FAILURE_PERCENTAGE_DEFAULT: float = 0.0 +TOLERATED_FAILURE_PERCENTAGE_MAX: float = 100.0 class ToleratedFailureCountDecl(EvalComponent, abc.ABC): @@ -35,7 +41,7 @@ def _eval_body(self, env: Environment) -> None: class ToleratedFailureCount(ToleratedFailureCountDecl): - tolerated_failure_count: Final[int] + tolerated_failure_count: int def __init__(self, tolerated_failure_count: int = TOLERATED_FAILURE_COUNT_DEFAULT): self.tolerated_failure_count = tolerated_failure_count @@ -44,17 +50,50 @@ def _eval_tolerated_failure_count(self, env: Environment) -> int: return self.tolerated_failure_count +class ToleratedFailureCountJSONata(ToleratedFailureCountDecl): + jsonata_template_value_terminal_expression: Final[ + JSONataTemplateValueTerminalExpression + ] + + def __init__( + self, + jsonata_template_value_terminal_expression: JSONataTemplateValueTerminalExpression, + ): + super().__init__() + self.jsonata_template_value_terminal_expression = ( + jsonata_template_value_terminal_expression + ) + + def _eval_tolerated_failure_count(self, env: Environment) -> int: + # TODO: add snapshot tests to verify AWS's behaviour about non integer values. + self.jsonata_template_value_terminal_expression.eval(env=env) + failure_count: int = int(env.stack.pop()) + return failure_count + + +class ToleratedFailureCountPathVar(ToleratedFailureCountDecl): + variable_sample: VariableSample + + def __init__(self, variable_sample: VariableSample): + super().__init__() + self.variable_sample = variable_sample + + def _eval_tolerated_failure_count(self, env: Environment) -> int: + self.variable_sample.eval(env=env) + # TODO: add snapshot tests to verify AWS's behaviour about non integer values. + tolerated_failure_count: int = int(env.stack.pop()) + return tolerated_failure_count + + class ToleratedFailureCountPath(ToleratedFailureCountDecl): - tolerated_failure_count_path: Final[str] + tolerated_failure_count_path: str def __init__(self, tolerated_failure_count_path: str): self.tolerated_failure_count_path = tolerated_failure_count_path def _eval_tolerated_failure_count(self, env: Environment) -> int: inp = env.stack[-1] - tolerated_failure_count = JSONPathUtils.extract_json( - self.tolerated_failure_count_path, inp - ) + tolerated_failure_count = extract_json(self.tolerated_failure_count_path, inp) error_cause = None if not isinstance(tolerated_failure_count, int): @@ -99,7 +138,7 @@ def _eval_body(self, env: Environment) -> None: class ToleratedFailurePercentage(ToleratedFailurePercentageDecl): - tolerated_failure_percentage: Final[float] + tolerated_failure_percentage: float def __init__( self, tolerated_failure_percentage: float = TOLERATED_FAILURE_PERCENTAGE_DEFAULT @@ -110,15 +149,50 @@ def _eval_tolerated_failure_percentage(self, env: Environment) -> float: return self.tolerated_failure_percentage +class ToleratedFailurePercentageJSONata(ToleratedFailurePercentageDecl): + jsonata_template_value_terminal_expression: Final[ + JSONataTemplateValueTerminalExpression + ] + + def __init__( + self, + jsonata_template_value_terminal_expression: JSONataTemplateValueTerminalExpression, + ): + super().__init__() + self.jsonata_template_value_terminal_expression = ( + jsonata_template_value_terminal_expression + ) + + def _eval_tolerated_failure_percentage(self, env: Environment) -> float: + # TODO: add snapshot tests to verify AWS's behaviour about non floating values. + self.jsonata_template_value_terminal_expression.eval(env=env) + failure_percentage: int = int(env.stack.pop()) + return failure_percentage + + +class ToleratedFailurePercentagePathVar(ToleratedFailurePercentageDecl): + variable_sample: VariableSample + + def __init__(self, variable_sample: VariableSample): + super().__init__() + self.variable_sample = variable_sample + + def _eval_tolerated_failure_percentage(self, env: Environment) -> float: + self.variable_sample.eval(env=env) + # TODO: add snapshot tests to verify AWS's behaviour about non floating values. + tolerated_failure_percentage: float = float(env.stack.pop()) + return tolerated_failure_percentage + + class ToleratedFailurePercentagePath(ToleratedFailurePercentageDecl): - tolerate_failure_percentage_path: Final[str] + tolerate_failure_percentage_path: str def __init__(self, tolerate_failure_percentage_path: str): self.tolerate_failure_percentage_path = tolerate_failure_percentage_path def _eval_tolerated_failure_percentage(self, env: Environment) -> float: inp = env.stack[-1] - tolerated_failure_percentage = JSONPathUtils.extract_json( + tolerated_failure_percentage = extract_json( self.tolerate_failure_percentage_path, inp ) @@ -149,7 +223,12 @@ def _eval_tolerated_failure_percentage(self, env: Environment) -> float: env=env, error_name=StatesErrorName(typ=StatesErrorNameType.StatesRuntime), event_type=HistoryEventType.ExecutionFailed, - event_details=error_cause, + event_details=EventDetails( + executionFailedEventDetails=ExecutionFailedEventDetails( + error=StatesErrorNameType.StatesRuntime.to_name(), + cause=error_cause, + ) + ), ) ) diff --git a/moto/stepfunctions/parser/asl/component/state/exec/state_parallel/branch_worker.py b/moto/stepfunctions/parser/asl/component/state/exec/state_parallel/branch_worker.py index e023fd2898fc..af9c976e1b00 100644 --- a/moto/stepfunctions/parser/asl/component/state/exec/state_parallel/branch_worker.py +++ b/moto/stepfunctions/parser/asl/component/state/exec/state_parallel/branch_worker.py @@ -30,9 +30,9 @@ def __init__( self._worker_thread = None def _thread_routine(self) -> None: - LOG.info(f"[BranchWorker] [launched] [id: {self._worker_thread.native_id}]") + LOG.info("[BranchWorker] [launched] [id: %s]", self._worker_thread.native_id) self._program.eval(self.env) - LOG.info(f"[BranchWorker] [terminated] [id: {self._worker_thread.native_id}]") + LOG.info("[BranchWorker] [terminated] [id: %s]", self._worker_thread.native_id) self._branch_worker_comm.on_terminated(env=self.env) def start(self): @@ -42,7 +42,9 @@ def start(self): ) self._worker_thread = threading.Thread( - target=self._thread_routine, name=f"BranchWorker_${self._program}" + target=self._thread_routine, + name=f"BranchWorker_${self._program}", + daemon=True, ) TMP_THREADS.append(self._worker_thread) self._worker_thread.start() diff --git a/moto/stepfunctions/parser/asl/component/state/exec/state_parallel/branches_decl.py b/moto/stepfunctions/parser/asl/component/state/exec/state_parallel/branches_decl.py index 81e6bafa31c4..ae6a065c004b 100644 --- a/moto/stepfunctions/parser/asl/component/state/exec/state_parallel/branches_decl.py +++ b/moto/stepfunctions/parser/asl/component/state/exec/state_parallel/branches_decl.py @@ -1,4 +1,3 @@ -import copy import datetime import threading from typing import Final, List, Optional @@ -19,6 +18,7 @@ from moto.stepfunctions.parser.asl.eval.environment import Environment from moto.stepfunctions.parser.asl.eval.event.event_detail import EventDetails from moto.stepfunctions.parser.asl.eval.program_state import ProgramError, ProgramState +from moto.utilities.collections import select_from_typed_dict class BranchWorkerPool(BranchWorker.BranchWorkerComm): @@ -41,7 +41,10 @@ def on_terminated(self, env: Environment): with self._mutex: end_program_state: ProgramState = env.program_state() if isinstance(end_program_state, ProgramError): - self._terminated_with_error = end_program_state.error or dict() + self._terminated_with_error = select_from_typed_dict( + typed_dict=ExecutionFailedEventDetails, + obj=end_program_state.error or dict(), + ) self._termination_event.set() else: self._active_workers_num -= 1 @@ -68,8 +71,8 @@ def _eval_body(self, env: Environment) -> None: branch_workers: List[BranchWorker] = list() for program in self.programs: # Environment frame for this sub process. - env_frame: Environment = env.open_frame() - env_frame.inp = copy.deepcopy(input_val) + env_frame: Environment = env.open_inner_frame() + env_frame.states.reset(input_value=input_val) # Launch the worker. worker = BranchWorker( @@ -95,6 +98,7 @@ def _eval_body(self, env: Environment) -> None: exit_error_name = exit_event_details.get("error") raise FailureEventException( failure_event=FailureEvent( + env=env, error_name=CustomErrorName(error_name=exit_error_name), event_type=HistoryEventType.ExecutionFailed, event_details=EventDetails( @@ -108,7 +112,7 @@ def _eval_body(self, env: Environment) -> None: for worker in branch_workers: env_frame = worker.env - result_list.append(env_frame.inp) + result_list.append(env_frame.states.get_input()) env.close_frame(env_frame) env.stack.append(result_list) diff --git a/moto/stepfunctions/parser/asl/component/state/exec/state_parallel/state_parallel.py b/moto/stepfunctions/parser/asl/component/state/exec/state_parallel/state_parallel.py index 852d4fe89ae6..721aecf9e0f6 100644 --- a/moto/stepfunctions/parser/asl/component/state/exec/state_parallel/state_parallel.py +++ b/moto/stepfunctions/parser/asl/component/state/exec/state_parallel/state_parallel.py @@ -1,4 +1,5 @@ import copy +from typing import Optional from moto.stepfunctions.parser.api import HistoryEventType from moto.stepfunctions.parser.asl.component.common.catch.catch_outcome import ( @@ -8,6 +9,7 @@ FailureEvent, FailureEventException, ) +from moto.stepfunctions.parser.asl.component.common.parargs import Parargs from moto.stepfunctions.parser.asl.component.common.retry.retry_outcome import ( RetryOutcome, ) @@ -27,6 +29,7 @@ class StateParallel(ExecutionState): # machine object must have fields named States and StartAt, whose meanings are exactly # like those in the top level of a state machine. branches: BranchesDecl + parargs: Optional[Parargs] def __init__(self): super().__init__( @@ -42,34 +45,46 @@ def from_state_props(self, state_props: StateProps) -> None: f"Missing Branches definition in props '{state_props}'." ), ) + self.parargs = state_props.get(Parargs) def _eval_execution(self, env: Environment) -> None: - env.event_history.add_event( + env.event_manager.add_event( context=env.event_history_context, - hist_type_event=HistoryEventType.ParallelStateStarted, + event_type=HistoryEventType.ParallelStateStarted, ) self.branches.eval(env) - env.event_history.add_event( + env.event_manager.add_event( context=env.event_history_context, - hist_type_event=HistoryEventType.ParallelStateSucceeded, + event_type=HistoryEventType.ParallelStateSucceeded, update_source_event_id=False, ) def _eval_state(self, env: Environment) -> None: # Initialise the retry counter for execution states. - env.context_object_manager.context_object["State"]["RetryCount"] = 0 + env.states.context_object.context_object_data["State"]["RetryCount"] = 0 - # Cache the input, so it can be resubmitted in case of failure. + # Compute the branches' input: if declared this is the parameters, else the current memory state. + if self.parargs is not None: + self.parargs.eval(env=env) + # In both cases, the inputs are copied by value to the branches, to avoid cross branch state manipulation, and + # cached to allow them to be resubmitted in case of failure. input_value = copy.deepcopy(env.stack.pop()) # Attempt to evaluate the state's logic through until it's successful, caught, or retries have run out. - while True: + while env.is_running(): try: env.stack.append(input_value) self._evaluate_with_timeout(env) break except FailureEventException as failure_event_ex: - failure_event: FailureEvent = failure_event_ex.failure_event + failure_event: FailureEvent = self._from_error( + env=env, ex=failure_event_ex + ) + error_output = self._construct_error_output_value( + failure_event=failure_event + ) + env.states.set_error_output(error_output) + env.states.set_result(error_output) if self.retry is not None: retry_outcome: RetryOutcome = self._handle_retry( @@ -78,15 +93,14 @@ def _eval_state(self, env: Environment) -> None: if retry_outcome == RetryOutcome.CanRetry: continue - env.event_history.add_event( + env.event_manager.add_event( context=env.event_history_context, - hist_type_event=HistoryEventType.ParallelStateFailed, + event_type=HistoryEventType.ParallelStateFailed, ) if self.catch is not None: - catch_outcome: CatchOutcome = self._handle_catch( - env=env, failure_event=failure_event - ) + self._handle_catch(env=env, failure_event=failure_event) + catch_outcome: CatchOutcome = env.stack[-1] if catch_outcome == CatchOutcome.Caught: break diff --git a/moto/stepfunctions/parser/asl/component/state/exec/state_task/credentials.py b/moto/stepfunctions/parser/asl/component/state/exec/state_task/credentials.py new file mode 100644 index 000000000000..aee153887e8a --- /dev/null +++ b/moto/stepfunctions/parser/asl/component/state/exec/state_task/credentials.py @@ -0,0 +1,104 @@ +import abc +import copy +from typing import Final, Optional + +from moto.stepfunctions.parser.asl.component.common.jsonata.jsonata_template_value_terminal import ( + JSONataTemplateValueTerminalExpression, +) +from moto.stepfunctions.parser.asl.component.common.variable_sample import ( + VariableSample, +) +from moto.stepfunctions.parser.asl.component.eval_component import EvalComponent +from moto.stepfunctions.parser.asl.component.intrinsic.function.function import Function +from moto.stepfunctions.parser.asl.eval.environment import Environment +from moto.stepfunctions.parser.asl.parse.intrinsic.intrinsic_parser import ( + IntrinsicParser, +) +from moto.stepfunctions.parser.asl.utils.json_path import extract_json + +_CREDENTIALS_ROLE_ARN_KEY: str = "RoleArn" +ComputedCredentials = dict + + +class RoleArn(EvalComponent, abc.ABC): ... + + +class RoleArnConst(RoleArn): + value: str + + def __init__(self, value: str): + self.value = value + + def _eval_body(self, env: Environment) -> None: + env.stack.append(self.value) + + +class RoleArnJSONata(RoleArn): + jsonata_template_value_terminal_expression: Final[ + JSONataTemplateValueTerminalExpression + ] + + def __init__( + self, + jsonata_template_value_terminal_expression: JSONataTemplateValueTerminalExpression, + ): + super().__init__() + self.jsonata_template_value_terminal_expression = ( + jsonata_template_value_terminal_expression + ) + + def _eval_body(self, env: Environment) -> None: + self.jsonata_template_value_terminal_expression.eval(env=env) + + +class RoleArnVar(RoleArn): + variable_sample: VariableSample + + def __init__(self, variable_sample: VariableSample): + self.variable_sample = variable_sample + + def _eval_body(self, env: Environment) -> None: + self.variable_sample.eval(env=env) + + +class RoleArnPath(RoleArnConst): + def _eval_body(self, env: Environment) -> None: + current_output = env.stack[-1] + arn = extract_json(self.value, current_output) + env.stack.append(arn) + + +class RoleArnContextObject(RoleArnConst): + def _eval_body(self, env: Environment) -> None: + value = extract_json(self.value, env.states.context_object.context_object_data) + env.stack.append(copy.deepcopy(value)) + + +class RoleArnIntrinsicFunction(RoleArnConst): + function: Function + + def __init__(self, value: str) -> None: + super().__init__(value=value) + self.function, _ = IntrinsicParser.parse(value) + + def _eval_body(self, env: Environment) -> None: + self.function.eval(env=env) + + +class Credentials(EvalComponent): + role_arn: RoleArn + + def __init__(self, role_arn: RoleArn): + self.role_arn = role_arn + + @staticmethod + def get_role_arn_from(computed_credentials: ComputedCredentials) -> Optional[str]: + return computed_credentials.get(_CREDENTIALS_ROLE_ARN_KEY) + + def _eval_body(self, env: Environment) -> None: + self.role_arn.eval(env=env) + role_arn = env.stack.pop() + computes_credentials: ComputedCredentials = { + _CREDENTIALS_ROLE_ARN_KEY: role_arn + } + env.stack.append(computes_credentials) diff --git a/moto/stepfunctions/parser/asl/component/state/exec/state_task/lambda_eval_utils.py b/moto/stepfunctions/parser/asl/component/state/exec/state_task/lambda_eval_utils.py index 9c5fa56c8634..f98096be6764 100644 --- a/moto/stepfunctions/parser/asl/component/state/exec/state_task/lambda_eval_utils.py +++ b/moto/stepfunctions/parser/asl/component/state/exec/state_task/lambda_eval_utils.py @@ -17,7 +17,11 @@ def __init__(self, function_error: Optional[str], payload: str): def exec_lambda_function( - env: Environment, parameters: dict, region: str, account: str + env: Environment, + parameters: dict, + region: str, + account: str, + credentials: Any, ) -> None: lambda_client = boto_client_for(region=region, account=account, service="lambda") diff --git a/moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service.py b/moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service.py index ad535d16c876..9e4d459e8b2a 100644 --- a/moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service.py +++ b/moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service.py @@ -2,13 +2,16 @@ import abc import copy -from typing import Any, Dict, Final, List, Optional, Tuple +from typing import Any, Dict, List, Optional, Tuple -from botocore.model import StructureShape +from botocore.model import ListShape, Shape, StringShape, StructureShape +from botocore.response import StreamingBody from moto.stepfunctions.parser.api import ( HistoryEventExecutionDataDetails, HistoryEventType, + TaskCredentials, + TaskFailedEventDetails, TaskScheduledEventDetails, TaskStartedEventDetails, TaskSucceededEventDetails, @@ -16,6 +19,7 @@ ) from moto.stepfunctions.parser.asl.component.common.error_name.failure_event import ( FailureEvent, + FailureEventException, ) from moto.stepfunctions.parser.asl.component.common.error_name.states_error_name import ( StatesErrorName, @@ -23,6 +27,10 @@ from moto.stepfunctions.parser.asl.component.common.error_name.states_error_name_type import ( StatesErrorNameType, ) +from moto.stepfunctions.parser.asl.component.state.exec.state_task.credentials import ( + ComputedCredentials, + Credentials, +) from moto.stepfunctions.parser.asl.component.state.exec.state_task.service.resource import ( ResourceRuntimePart, ServiceResource, @@ -33,13 +41,19 @@ from moto.stepfunctions.parser.asl.eval.environment import Environment from moto.stepfunctions.parser.asl.eval.event.event_detail import EventDetails from moto.stepfunctions.parser.asl.utils.encoding import to_json_str -from moto.stepfunctions.parser.utils import camel_to_snake_case, snake_to_camel_case +from moto.stepfunctions.parser.quotas import is_within_size_quota +from moto.stepfunctions.parser.utils import ( + camel_to_snake_case, + snake_to_camel_case, + to_bytes, + to_str, +) class StateTaskService(StateTask, abc.ABC): resource: ServiceResource - _SERVICE_NAME_SFN_TO_BOTO_OVERRIDES: Final[Dict[str, str]] = { + _SERVICE_NAME_SFN_TO_BOTO_OVERRIDES: Dict[str, str] = { "sfn": "stepfunctions", "states": "stepfunctions", } @@ -50,8 +64,9 @@ def _get_sfn_resource(self) -> str: def _get_sfn_resource_type(self) -> str: return self.resource.service_name - def _get_timed_out_failure_event(self) -> FailureEvent: + def _get_timed_out_failure_event(self, env: Environment) -> FailureEvent: return FailureEvent( + env=env, error_name=StatesErrorName(typ=StatesErrorNameType.StatesTimeout), event_type=HistoryEventType.TaskTimedOut, event_details=EventDetails( @@ -63,13 +78,30 @@ def _get_timed_out_failure_event(self) -> FailureEvent: ), ) - def _to_boto_args(self, parameters: dict, structure_shape: StructureShape) -> None: + def _to_boto_request_value(self, request_value: Any, value_shape: Shape) -> Any: + boto_request_value = request_value + if isinstance(value_shape, StructureShape): + self._to_boto_request(request_value, value_shape) + elif isinstance(value_shape, ListShape) and isinstance(request_value, list): + for request_list_value in request_value: + self._to_boto_request_value(request_list_value, value_shape.member) # noqa + elif isinstance(value_shape, StringShape) and not isinstance( + request_value, str + ): + boto_request_value = to_json_str(request_value) + elif value_shape.type_name == "blob" and not isinstance( + boto_request_value, bytes + ): + boto_request_value = to_json_str(request_value, separators=(",", ":")) + boto_request_value = to_bytes(boto_request_value) + return boto_request_value + + def _to_boto_request( + self, parameters: dict, structure_shape: StructureShape + ) -> None: shape_members = structure_shape.members - norm_member_binds: Dict[str, Tuple[str, Optional[StructureShape]]] = { - camel_to_snake_case(member_key): ( - member_key, - member_value if isinstance(member_value, StructureShape) else None, - ) + norm_member_binds: Dict[str, Tuple[str, StructureShape]] = { + camel_to_snake_case(member_key): (member_key, member_value) for member_key, member_value in shape_members.items() } parameters_bind_keys: List[str] = list(parameters.keys()) @@ -81,8 +113,9 @@ def _to_boto_args(self, parameters: dict, structure_shape: StructureShape) -> No if norm_member_bind is not None: norm_member_bind_key, norm_member_bind_shape = norm_member_bind parameter_value = parameters.pop(parameter_key) - if norm_member_bind_shape is not None: - self._to_boto_args(parameter_value, norm_member_bind_shape) + parameter_value = self._to_boto_request_value( + parameter_value, norm_member_bind_shape + ) parameters[norm_member_bind_key] = parameter_value @staticmethod @@ -93,6 +126,13 @@ def _to_sfn_cased(member_key: str) -> str: norm_member_key = snake_to_camel_case(norm_member_key) return norm_member_key + @staticmethod + def _from_boto_response_value(response_value: Any) -> Any: + if isinstance(response_value, StreamingBody): + body_str = to_str(response_value.read()) + return body_str + return response_value + def _from_boto_response( self, response: Any, structure_shape: StructureShape ) -> None: @@ -107,8 +147,18 @@ def _from_boto_response( shape_member = shape_members[response_key] response_value = response.pop(response_key) + response_value = self._from_boto_response_value(response_value) + if isinstance(shape_member, StructureShape): self._from_boto_response(response_value, shape_member) + elif isinstance(shape_member, ListShape) and isinstance( + response_value, list + ): + for response_value_member in response_value: + self._from_boto_response( + response_value_member, shape_member.member + ) # noqa + response[norm_response_key] = response_value def _get_boto_service_name(self, boto_service_name: Optional[str] = None) -> str: @@ -137,12 +187,41 @@ def _normalise_response( ) -> None: pass + def _verify_size_quota(self, env: Environment, value: Any) -> None: + is_within: bool = is_within_size_quota(value) + if is_within: + return + resource_type = self._get_sfn_resource_type() + resource = self._get_sfn_resource() + cause = ( + f"The state/task '{resource_type}' returned a result with a size " + "exceeding the maximum number of bytes service limit." + ) + raise FailureEventException( + failure_event=FailureEvent( + env=env, + error_name=StatesErrorName( + typ=StatesErrorNameType.StatesStatesDataLimitExceeded + ), + event_type=HistoryEventType.TaskFailed, + event_details=EventDetails( + taskFailedEventDetails=TaskFailedEventDetails( + error=StatesErrorNameType.StatesStatesDataLimitExceeded.to_name(), + cause=cause, + resourceType=resource_type, + resource=resource, + ) + ), + ) + ) + @abc.abstractmethod def _eval_service_task( self, env: Environment, resource_runtime_part: ResourceRuntimePart, normalised_parameters: dict, + task_credentials: ComputedCredentials, ): ... def _before_eval_execution( @@ -150,6 +229,7 @@ def _before_eval_execution( env: Environment, resource_runtime_part: ResourceRuntimePart, raw_parameters: dict, + task_credentials: TaskCredentials, ) -> None: parameters_str = to_json_str(raw_parameters) @@ -167,18 +247,24 @@ def _before_eval_execution( self.heartbeat.eval(env=env) heartbeat_seconds = env.stack.pop() scheduled_event_details["heartbeatInSeconds"] = heartbeat_seconds - env.event_history.add_event( + if self.credentials: + scheduled_event_details["taskCredentials"] = TaskCredentials( + roleArn=Credentials.get_role_arn_from( + computed_credentials=task_credentials + ) + ) + env.event_manager.add_event( context=env.event_history_context, - hist_type_event=HistoryEventType.TaskScheduled, - event_detail=EventDetails( + event_type=HistoryEventType.TaskScheduled, + event_details=EventDetails( taskScheduledEventDetails=scheduled_event_details ), ) - env.event_history.add_event( + env.event_manager.add_event( context=env.event_history_context, - hist_type_event=HistoryEventType.TaskStarted, - event_detail=EventDetails( + event_type=HistoryEventType.TaskStarted, + event_details=EventDetails( taskStartedEventDetails=TaskStartedEventDetails( resource=self._get_sfn_resource(), resourceType=self._get_sfn_resource_type(), @@ -191,12 +277,14 @@ def _after_eval_execution( env: Environment, resource_runtime_part: ResourceRuntimePart, normalised_parameters: dict, + task_credentials: ComputedCredentials, ) -> None: output = env.stack[-1] - env.event_history.add_event( + self._verify_size_quota(env=env, value=output) + env.event_manager.add_event( context=env.event_history_context, - hist_type_event=HistoryEventType.TaskSucceeded, - event_detail=EventDetails( + event_type=HistoryEventType.TaskSucceeded, + event_details=EventDetails( taskSucceededEventDetails=TaskSucceededEventDetails( resource=self._get_sfn_resource(), resourceType=self._get_sfn_resource_type(), @@ -211,11 +299,13 @@ def _eval_execution(self, env: Environment) -> None: resource_runtime_part: ResourceRuntimePart = env.stack.pop() raw_parameters = self._eval_parameters(env=env) + task_credentials = self._eval_credentials(env=env) self._before_eval_execution( env=env, resource_runtime_part=resource_runtime_part, raw_parameters=raw_parameters, + task_credentials=task_credentials, ) normalised_parameters = copy.deepcopy(raw_parameters) @@ -225,6 +315,7 @@ def _eval_execution(self, env: Environment) -> None: env=env, resource_runtime_part=resource_runtime_part, normalised_parameters=normalised_parameters, + task_credentials=task_credentials, ) output_value = env.stack[-1] @@ -234,4 +325,5 @@ def _eval_execution(self, env: Environment) -> None: env=env, resource_runtime_part=resource_runtime_part, normalised_parameters=normalised_parameters, + task_credentials=task_credentials, ) diff --git a/moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service_api_gateway.py b/moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service_api_gateway.py index 4d27aa330e39..72be97217723 100644 --- a/moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service_api_gateway.py +++ b/moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service_api_gateway.py @@ -19,6 +19,7 @@ FailureEvent, ) from moto.stepfunctions.parser.asl.component.state.exec.state_task.service.resource import ( + ResourceCondition, ResourceRuntimePart, ) from moto.stepfunctions.parser.asl.component.state.exec.state_task.service.state_task_service_callback import ( @@ -29,6 +30,10 @@ LOG = logging.getLogger(__name__) +_SUPPORTED_INTEGRATION_PATTERNS: Set[ResourceCondition] = { + ResourceCondition.WaitForTaskToken, +} + APPLICATION_JSON = "application/json" HEADER_CONTENT_TYPE = "Content-Type" PATH_USER_REQUEST = "_user_request_" @@ -116,6 +121,9 @@ class StateTaskServiceApiGateway(StateTaskServiceCallback): "Www-Authenticate", } + def __init__(self): + super().__init__(supported_integration_patterns=_SUPPORTED_INTEGRATION_PATTERNS) + def _get_supported_parameters(self) -> Optional[Set[str]]: return self._SUPPORTED_API_PARAM_BINDINGS.get(self.resource.api_action.lower()) @@ -253,6 +261,7 @@ def _eval_service_task( env: Environment, resource_runtime_part: ResourceRuntimePart, normalised_parameters: dict, + task_credentials: Any, ): task_parameters: TaskParameters = normalised_parameters diff --git a/moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service_aws_sdk.py b/moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service_aws_sdk.py index e67700f41ef1..5483276cb2a0 100644 --- a/moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service_aws_sdk.py +++ b/moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service_aws_sdk.py @@ -1,4 +1,5 @@ import logging +from typing import Any, Set from botocore.exceptions import ClientError @@ -13,6 +14,7 @@ StatesErrorNameType, ) from moto.stepfunctions.parser.asl.component.state.exec.state_task.service.resource import ( + ResourceCondition, ResourceRuntimePart, ) from moto.stepfunctions.parser.asl.component.state.exec.state_task.service.state_task_service_callback import ( @@ -25,10 +27,17 @@ LOG = logging.getLogger(__name__) +_SUPPORTED_INTEGRATION_PATTERNS: Set[ResourceCondition] = { + ResourceCondition.WaitForTaskToken, +} + +# Defines bindings of lower-cased service names to the StepFunctions service name included in error messages. +_SERVICE_ERROR_NAMES = {"dynamodb": "DynamoDb", "sfn": "Sfn"} + class StateTaskServiceAwsSdk(StateTaskServiceCallback): - # Defines bindings of lower-cased service names to the StepFunctions service name included in error messages. - _SERVICE_ERROR_NAMES = {"dynamodb": "DynamoDb", "sfn": "Sfn"} + def __init__(self): + super().__init__(supported_integration_patterns=_SUPPORTED_INTEGRATION_PATTERNS) def from_state_props(self, state_props: StateProps) -> None: super().from_state_props(state_props=state_props) @@ -101,6 +110,7 @@ def _eval_service_task( env: Environment, resource_runtime_part: ResourceRuntimePart, normalised_parameters: dict, + task_credentials: Any, ): service_name = self._get_boto_service_name() api_action = self._get_boto_service_action() diff --git a/moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service_batch.py b/moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service_batch.py new file mode 100644 index 000000000000..af1f17d7e837 --- /dev/null +++ b/moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service_batch.py @@ -0,0 +1,207 @@ +from typing import Any, Callable, Dict, Optional, Set + +from botocore.exceptions import ClientError + +from moto.batch.utils import JobStatus +from moto.stepfunctions.parser.api import HistoryEventType, TaskFailedEventDetails +from moto.stepfunctions.parser.asl.component.common.error_name.custom_error_name import ( + CustomErrorName, +) +from moto.stepfunctions.parser.asl.component.common.error_name.failure_event import ( + FailureEvent, + FailureEventException, +) +from moto.stepfunctions.parser.asl.component.common.error_name.states_error_name import ( + StatesErrorName, +) +from moto.stepfunctions.parser.asl.component.common.error_name.states_error_name_type import ( + StatesErrorNameType, +) +from moto.stepfunctions.parser.asl.component.state.exec.state_task.credentials import ( + ComputedCredentials, +) +from moto.stepfunctions.parser.asl.component.state.exec.state_task.service.resource import ( + ResourceCondition, + ResourceRuntimePart, +) +from moto.stepfunctions.parser.asl.component.state.exec.state_task.service.state_task_service_callback import ( + StateTaskServiceCallback, +) +from moto.stepfunctions.parser.asl.eval.environment import Environment +from moto.stepfunctions.parser.asl.eval.event.event_detail import EventDetails +from moto.stepfunctions.parser.asl.utils.boto_client import boto_client_for +from moto.stepfunctions.parser.asl.utils.encoding import to_json_str + +_SUPPORTED_INTEGRATION_PATTERNS: Set[ResourceCondition] = { + ResourceCondition.WaitForTaskToken, + ResourceCondition.Sync, +} + +_BATCH_JOB_TERMINATION_STATUS_SET: Set[JobStatus] = { + JobStatus.SUCCEEDED, + JobStatus.FAILED, +} + +_ENVIRONMENT_VARIABLE_MANAGED_BY_AWS: str = "MANAGED_BY_AWS" +_ENVIRONMENT_VARIABLE_MANAGED_BY_AWS_VALUE: str = "STARTED_BY_STEP_FUNCTIONS" + +_SUPPORTED_API_PARAM_BINDINGS: Dict[str, Set[str]] = { + "submitjob": { + "ArrayProperties", + "ContainerOverrides", + "DependsOn", + "JobDefinition", + "JobName", + "JobQueue", + "Parameters", + "RetryStrategy", + "Timeout", + "Tags", + } +} + + +class StateTaskServiceBatch(StateTaskServiceCallback): + def __init__(self): + super().__init__(supported_integration_patterns=_SUPPORTED_INTEGRATION_PATTERNS) + + def _get_supported_parameters(self) -> Optional[Set[str]]: + return _SUPPORTED_API_PARAM_BINDINGS.get(self.resource.api_action.lower()) + + @staticmethod + def _attach_aws_environment_variables(parameters: dict) -> None: + # Attaches to the ContainerOverrides environment variables the AWS managed flags. + container_overrides = parameters.get("ContainerOverrides") + if container_overrides is None: + container_overrides = dict() + parameters["ContainerOverrides"] = container_overrides + + environment = container_overrides.get("Environment") + if environment is None: + environment = list() + container_overrides["Environment"] = environment + + environment.append( + { + "name": _ENVIRONMENT_VARIABLE_MANAGED_BY_AWS, + "value": _ENVIRONMENT_VARIABLE_MANAGED_BY_AWS_VALUE, + } + ) + + def _before_eval_execution( + self, + env: Environment, + resource_runtime_part: ResourceRuntimePart, + raw_parameters: dict, + task_credentials: ComputedCredentials, + ) -> None: + if self.resource.condition == ResourceCondition.Sync: + self._attach_aws_environment_variables(parameters=raw_parameters) + super()._before_eval_execution( + env=env, + resource_runtime_part=resource_runtime_part, + raw_parameters=raw_parameters, + task_credentials=task_credentials, + ) + + def _from_error(self, env: Environment, ex: Exception) -> FailureEvent: + if isinstance(ex, ClientError): + error_code = ex.response["Error"]["Code"] + error_name = f"Batch.{error_code}" + status_code = ex.response["ResponseMetadata"]["HTTPStatusCode"] + error_message = ex.response["Error"]["Message"] + request_id = ex.response["ResponseMetadata"]["RequestId"] + response_details = "; ".join( + [ + "Service: AWSBatch", + f"Status Code: {status_code}", + f"Error Code: {error_code}", + f"Request ID: {request_id}", + "Proxy: null", + ] + ) + cause = f"Error executing request, Exception : {error_message}, RequestId: {request_id} ({response_details})" + return FailureEvent( + env=env, + error_name=CustomErrorName(error_name), + event_type=HistoryEventType.TaskFailed, + event_details=EventDetails( + taskFailedEventDetails=TaskFailedEventDetails( + error=error_name, + cause=cause, + resource=self._get_sfn_resource(), + resourceType=self._get_sfn_resource_type(), + ) + ), + ) + return super()._from_error(env=env, ex=ex) + + def _build_sync_resolver( + self, + env: Environment, + resource_runtime_part: ResourceRuntimePart, + normalised_parameters: dict, + task_credentials: ComputedCredentials, + ) -> Callable[[], Optional[Any]]: + batch_client = boto_client_for( + region=resource_runtime_part.region, + account=resource_runtime_part.account, + service="batch", + ) + submission_output: dict = env.stack.pop() + job_id = submission_output["JobId"] + + def _sync_resolver() -> Optional[dict]: + describe_jobs_response = batch_client.describe_jobs(jobs=[job_id]) + describe_jobs = describe_jobs_response["jobs"] + if describe_jobs: + describe_job = describe_jobs[0] + describe_job_status: JobStatus = describe_job["status"] + # Add raise error if abnormal state + if describe_job_status in _BATCH_JOB_TERMINATION_STATUS_SET: + self._normalise_response( + response=describe_jobs_response, + service_action_name="describe_jobs", + ) + if describe_job_status == JobStatus.SUCCEEDED: + return describe_job + + raise FailureEventException( + FailureEvent( + env=env, + error_name=StatesErrorName( + typ=StatesErrorNameType.StatesTaskFailed + ), + event_type=HistoryEventType.TaskFailed, + event_details=EventDetails( + taskFailedEventDetails=TaskFailedEventDetails( + resource=self._get_sfn_resource(), + resourceType=self._get_sfn_resource_type(), + error=StatesErrorNameType.StatesTaskFailed.to_name(), + cause=to_json_str(describe_job), + ) + ), + ) + ) + return None + + return _sync_resolver + + def _eval_service_task( + self, + env: Environment, + resource_runtime_part: ResourceRuntimePart, + normalised_parameters: dict, + task_credentials: ComputedCredentials, + ): + service_name = self._get_boto_service_name() + api_action = self._get_boto_service_action() + batch_client = boto_client_for( + region=resource_runtime_part.region, + account=resource_runtime_part.account, + service=service_name, + credentials=task_credentials, + ) + response = getattr(batch_client, api_action)(**normalised_parameters) + response.pop("ResponseMetadata", None) + env.stack.append(response) diff --git a/moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service_callback.py b/moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service_callback.py index 7772bd581a93..6b77da91e315 100644 --- a/moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service_callback.py +++ b/moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service_callback.py @@ -1,6 +1,8 @@ import abc import json +import threading import time +from typing import Any, Callable, Optional, Set, Union from moto.stepfunctions.parser.api import ( HistoryEventExecutionDataDetails, @@ -14,6 +16,9 @@ from moto.stepfunctions.parser.asl.component.common.error_name.failure_event import ( FailureEvent, ) +from moto.stepfunctions.parser.asl.component.state.exec.state_task.credentials import ( + ComputedCredentials, +) from moto.stepfunctions.parser.asl.component.state.exec.state_task.service.resource import ( ResourceCondition, ResourceRuntimePart, @@ -22,61 +27,147 @@ StateTaskService, ) from moto.stepfunctions.parser.asl.eval.callback.callback import ( + CallbackEndpoint, + CallbackOutcome, CallbackOutcomeFailure, CallbackOutcomeFailureError, CallbackOutcomeSuccess, + CallbackOutcomeTimedOut, CallbackTimeoutError, HeartbeatEndpoint, + HeartbeatTimedOut, HeartbeatTimeoutError, ) from moto.stepfunctions.parser.asl.eval.environment import Environment from moto.stepfunctions.parser.asl.eval.event.event_detail import EventDetails from moto.stepfunctions.parser.asl.utils.encoding import to_json_str +from moto.stepfunctions.parser.utils import TMP_THREADS + +# TODO: consider implementing a polling pattern similar to that observable from AWS: +# https://repost.aws/questions/QUFFlHcbvIQFe-bS3RAi7TWA/a-glue-job-in-a-step-function-is-taking-so-long-to-continue-the-next-step +_DELAY_SECONDS_SYNC_CONDITION_CHECK: float = 0.5 class StateTaskServiceCallback(StateTaskService, abc.ABC): + _supported_integration_patterns: Set[ResourceCondition] + + def __init__(self, supported_integration_patterns: Set[ResourceCondition]): + super().__init__() + self._supported_integration_patterns = supported_integration_patterns + def _get_sfn_resource(self) -> str: resource = super()._get_sfn_resource() if self.resource.condition is not None: resource += f".{self.resource.condition}" return resource - def _wait_for_task_token( + def _build_sync_resolver( self, env: Environment, resource_runtime_part: ResourceRuntimePart, normalised_parameters: dict, - ) -> None: - # Discard the state evaluation output. - env.stack.pop() + task_credentials: ComputedCredentials, + ) -> Callable[[], Optional[Any]]: + raise RuntimeError( + f"Unsupported .sync callback procedure in resource {self.resource.resource_arn}" + ) - callback_id = env.context_object_manager.context_object.get("Task", {}).get( - "Token" + def _build_sync2_resolver( + self, + env: Environment, + resource_runtime_part: ResourceRuntimePart, + normalised_parameters: dict, + task_credentials: ComputedCredentials, + ) -> Callable[[], Optional[Any]]: + raise RuntimeError( + f"Unsupported .sync2 callback procedure in resource {self.resource.resource_arn}" ) - if callback_id is None: - # We never generated a TaskToken, so there's no point in waiting until we receive it - # AWS seems to just wait forever in this scenario- so let's do the same - timeout_seconds = self.timeout.timeout_seconds - mustend_at = time.time() + timeout_seconds - while time.time() < mustend_at: - if not env.is_running(): - return - time.sleep(1) - return - - callback_endpoint = env.callback_pool_manager.get(callback_id) - - # With Timeouts-only definition: - if not self.heartbeat: - self.timeout.eval(env=env) - timeout_seconds = env.stack.pop() - # Although the timeout is handled already be the superclass (ExecutionState), - # the timeout value is specified here too, to allow this child process to terminate earlier even if - # discarded by the main process. - # Note: although this is the same timeout value, this can only decay strictly after the first timeout - # started as it is invoked strictly later. - outcome = callback_endpoint.wait(timeout=timeout_seconds) + + def _eval_wait_for_task_token( + self, + env: Environment, + timeout_seconds: int, + callback_endpoint: CallbackEndpoint, + heartbeat_endpoint: Optional[HeartbeatEndpoint], + ) -> CallbackOutcome: + outcome: Optional[CallbackOutcome] + if heartbeat_endpoint is not None: + outcome = self._wait_for_task_token_heartbeat( + env, callback_endpoint, heartbeat_endpoint + ) else: + outcome = self._wait_for_task_token_timeout( + timeout_seconds, callback_endpoint + ) + if outcome is None: + return CallbackOutcomeTimedOut(callback_id=callback_endpoint.callback_id) + return outcome + + def _eval_sync( + self, + env: Environment, + sync_resolver: Callable[[], Optional[Any]], + timeout_seconds: Optional[int], + callback_endpoint: Optional[CallbackEndpoint], + heartbeat_endpoint: Optional[HeartbeatEndpoint], + ) -> Union[CallbackOutcome, Any]: + callback_output: Optional[CallbackOutcome] = None + + # Listen for WaitForTaskToken signals if an endpoint is provided. + if callback_endpoint is not None: + + def _local_update_wait_for_task_token(): + nonlocal callback_output + callback_output = self._eval_wait_for_task_token( + env=env, + timeout_seconds=timeout_seconds, + callback_endpoint=callback_endpoint, + heartbeat_endpoint=heartbeat_endpoint, + ) + + thread_wait_for_task_token = threading.Thread( + target=_local_update_wait_for_task_token, + name=f"WaitForTaskToken_SyncTask_{self.resource.resource_arn}", + daemon=True, + ) + TMP_THREADS.append(thread_wait_for_task_token) + thread_wait_for_task_token.start() + # Note: the stopping of this worker thread is handled indirectly through the state of env. + # an exception in this thread will invalidate env, and therefore the worker thread. + # hence why here there are no explicit stopping logic for thread_wait_for_task_token. + + sync_result: Optional[Any] = None + while env.is_running(): + sync_result = sync_resolver() + if callback_output or sync_result: + break + else: + time.sleep(_DELAY_SECONDS_SYNC_CONDITION_CHECK) + + return callback_output or sync_result + + def _eval_integration_pattern( + self, + env: Environment, + resource_runtime_part: ResourceRuntimePart, + normalised_parameters: dict, + task_credentials: ComputedCredentials, + ) -> None: + task_output = env.stack.pop() + + # Initialise the waitForTaskToken Callback endpoint for this task if supported. + callback_endpoint: Optional[CallbackEndpoint] = None + if ResourceCondition.WaitForTaskToken in self._supported_integration_patterns: + callback_id = env.states.context_object.context_object_data["Task"]["Token"] + callback_endpoint = env.callback_pool_manager.get(callback_id) + + # Setup resources for timeout control. + self.timeout.eval(env=env) + timeout_seconds = env.stack.pop() + + # Setup resources for heartbeat workloads if necessary. + heartbeat_endpoint: Optional[HeartbeatEndpoint] = None + if self.heartbeat: self.heartbeat.eval(env=env) heartbeat_seconds = env.stack.pop() heartbeat_endpoint: HeartbeatEndpoint = ( @@ -85,57 +176,125 @@ def _wait_for_task_token( ) ) - outcome = None - while ( - env.is_running() and outcome is None - ): # Until subprocess hasn't timed out or result wasn't received. - received = heartbeat_endpoint.clear_and_wait() - if not received and env.is_running(): # Heartbeat timed out. - raise HeartbeatTimeoutError() - outcome = callback_endpoint.get_outcome() + # Collect the output of the integration pattern. + outcome: Union[CallbackOutcome, Any] + try: + if self.resource.condition == ResourceCondition.WaitForTaskToken: + outcome = self._eval_wait_for_task_token( + env=env, + timeout_seconds=timeout_seconds, + callback_endpoint=callback_endpoint, + heartbeat_endpoint=heartbeat_endpoint, + ) + else: + # Sync operations require the task output as input. + env.stack.append(task_output) + if self.resource.condition == ResourceCondition.Sync: + sync_resolver = self._build_sync_resolver( + env=env, + resource_runtime_part=resource_runtime_part, + normalised_parameters=normalised_parameters, + task_credentials=task_credentials, + ) + else: + # The condition checks about the resource's condition is exhaustive leaving + # only Sync2 ResourceCondition types in this block. + sync_resolver = self._build_sync2_resolver( + env=env, + resource_runtime_part=resource_runtime_part, + normalised_parameters=normalised_parameters, + task_credentials=task_credentials, + ) - if outcome is None: + outcome = self._eval_sync( + env=env, + timeout_seconds=timeout_seconds, + callback_endpoint=callback_endpoint, + heartbeat_endpoint=heartbeat_endpoint, + sync_resolver=sync_resolver, + ) + except Exception as integration_exception: + outcome = integration_exception + finally: + # Now that the outcome is collected or the exception is about to be passed upstream, and the process has + # finished, ensure all waiting # threads on this endpoint (or task) will stop. This is in an effort to + # release resources sooner than when these would eventually synchronise with the updated environment + # state of this task. + callback_endpoint.interrupt_all() + + # Handle Callback outcome types. + if isinstance(outcome, CallbackOutcomeTimedOut): raise CallbackTimeoutError() - if isinstance(outcome, CallbackOutcomeSuccess): - outcome_output = json.loads(outcome.output) - env.stack.append(outcome_output) + elif isinstance(outcome, HeartbeatTimedOut): + raise HeartbeatTimeoutError() elif isinstance(outcome, CallbackOutcomeFailure): raise CallbackOutcomeFailureError(callback_outcome_failure=outcome) + elif isinstance(outcome, CallbackOutcomeSuccess): + outcome_output = json.loads(outcome.output) + env.stack.append(outcome_output) + # Pass evaluation exception upstream for error handling. + elif isinstance(outcome, Exception): + raise outcome + # Otherwise the outcome is the result of the integration pattern (sync, sync2) + # therefore push it onto the evaluation stack for the next operations. else: - raise NotImplementedError( - f"Unsupported CallbackOutcome type '{type(outcome)}'." - ) + env.stack.append(outcome) - def _sync( + def _wait_for_task_token_timeout( # noqa self, - env: Environment, - resource_runtime_part: ResourceRuntimePart, - normalised_parameters: dict, - ) -> None: - raise RuntimeError( - f"Unsupported .sync callback procedure in resource {self.resource.resource_arn}" + timeout_seconds: int, + callback_endpoint: CallbackEndpoint, + ) -> Optional[CallbackOutcome]: + # Awaits a callback notification and returns the outcome received. + # If the operation times out or is interrupted it returns None. + + # Although the timeout is handled already be the superclass (ExecutionState), + # the timeout value is specified here too, to allow this child process to terminate earlier even if + # discarded by the main process. + # Note: although this is the same timeout value, this can only decay strictly after the first timeout + # started as it is invoked strictly later. + outcome: Optional[CallbackOutcome] = callback_endpoint.wait( + timeout=timeout_seconds ) + return outcome - def _sync2( + def _wait_for_task_token_heartbeat( # noqa self, env: Environment, - resource_runtime_part: ResourceRuntimePart, - normalised_parameters: dict, - ) -> None: - raise RuntimeError( - f"Unsupported .sync:2 callback procedure in resource {self.resource.resource_arn}" - ) + callback_endpoint: CallbackEndpoint, + heartbeat_endpoint: HeartbeatEndpoint, + ) -> Optional[CallbackOutcome]: + outcome = None + while ( + env.is_running() + and outcome + is None # Note: the lifetime of this environment is this task's not the entire state machine program. + ): # Until subprocess hasn't timed out or result wasn't received. + received = heartbeat_endpoint.clear_and_wait() + if not received and env.is_running(): # Heartbeat timed out. + outcome = HeartbeatTimedOut() + else: + outcome = callback_endpoint.get_outcome() + return outcome - def _is_condition(self): + def _assert_integration_pattern_is_supported(self): + integration_pattern = self.resource.condition + if integration_pattern not in self._supported_integration_patterns: + raise RuntimeError( + f"Unsupported {integration_pattern} callback procedure in resource {self.resource.resource_arn}" + ) + + def _is_integration_pattern(self): return self.resource.condition is not None def _get_callback_outcome_failure_event( - self, ex: CallbackOutcomeFailureError + self, env: Environment, ex: CallbackOutcomeFailureError ) -> FailureEvent: callback_outcome_failure: CallbackOutcomeFailure = ex.callback_outcome_failure - error: str = callback_outcome_failure.error + error: Optional[str] = callback_outcome_failure.error return FailureEvent( - error_name=CustomErrorName(error_name=callback_outcome_failure.error), + env=env, + error_name=CustomErrorName(error_name=error), event_type=HistoryEventType.TaskFailed, event_details=EventDetails( taskFailedEventDetails=TaskFailedEventDetails( @@ -149,21 +308,39 @@ def _get_callback_outcome_failure_event( def _from_error(self, env: Environment, ex: Exception) -> FailureEvent: if isinstance(ex, CallbackOutcomeFailureError): - return self._get_callback_outcome_failure_event(ex=ex) + return self._get_callback_outcome_failure_event(env=env, ex=ex) return super()._from_error(env=env, ex=ex) + def _eval_body(self, env: Environment) -> None: + # Generate a TaskToken uuid within the context object, if this task resources has a callback condition. + # https://docs.aws.amazon.com/step-functions/latest/dg/connect-to-resource.html#connect-wait-token + if ( + self._is_integration_pattern() + and ResourceCondition.WaitForTaskToken + in self._supported_integration_patterns + ): + self._assert_integration_pattern_is_supported() + task_token = env.states.context_object.update_task_token() + env.callback_pool_manager.add(task_token) + + super()._eval_body(env=env) + + # Ensure the TaskToken field is reset, as this is only available during waitForTaskToken task evaluations. + env.states.context_object.context_object_data.pop("Task", None) + def _after_eval_execution( self, env: Environment, resource_runtime_part: ResourceRuntimePart, normalised_parameters: dict, + task_credentials: ComputedCredentials, ) -> None: - if self._is_condition(): + if self._is_integration_pattern(): output = env.stack[-1] - env.event_history.add_event( + env.event_manager.add_event( context=env.event_history_context, - hist_type_event=HistoryEventType.TaskSubmitted, - event_detail=EventDetails( + event_type=HistoryEventType.TaskSubmitted, + event_details=EventDetails( taskSubmittedEventDetails=TaskSubmittedEventDetails( resource=self._get_sfn_resource(), resourceType=self._get_sfn_resource_type(), @@ -172,31 +349,16 @@ def _after_eval_execution( ) ), ) - if self.resource.condition == ResourceCondition.WaitForTaskToken: - self._wait_for_task_token( - env=env, - resource_runtime_part=resource_runtime_part, - normalised_parameters=normalised_parameters, - ) - elif self.resource.condition == ResourceCondition.Sync: - self._sync( - env=env, - resource_runtime_part=resource_runtime_part, - normalised_parameters=normalised_parameters, - ) - elif self.resource.condition == ResourceCondition.Sync2: - self._sync2( - env=env, - resource_runtime_part=resource_runtime_part, - normalised_parameters=normalised_parameters, - ) - else: - raise NotImplementedError( - f"Unsupported callback type '{self.resource.condition}'." - ) + self._eval_integration_pattern( + env=env, + resource_runtime_part=resource_runtime_part, + normalised_parameters=normalised_parameters, + task_credentials=task_credentials, + ) super()._after_eval_execution( env=env, resource_runtime_part=resource_runtime_part, normalised_parameters=normalised_parameters, + task_credentials=task_credentials, ) diff --git a/moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service_dynamodb.py b/moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service_dynamodb.py index 7051edee636a..01457d37cf31 100644 --- a/moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service_dynamodb.py +++ b/moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service_dynamodb.py @@ -1,4 +1,4 @@ -from typing import Dict, Final, Optional, Set, Tuple +from typing import Dict, Optional, Set, Tuple from botocore.exceptions import ClientError @@ -9,6 +9,9 @@ from moto.stepfunctions.parser.asl.component.common.error_name.failure_event import ( FailureEvent, ) +from moto.stepfunctions.parser.asl.component.state.exec.state_task.credentials import ( + ComputedCredentials, +) from moto.stepfunctions.parser.asl.component.state.exec.state_task.service.resource import ( ResourceRuntimePart, ) @@ -19,62 +22,62 @@ from moto.stepfunctions.parser.asl.eval.event.event_detail import EventDetails from moto.stepfunctions.parser.asl.utils.boto_client import boto_client_for +_ERROR_NAME_AWS: str = "DynamoDB.AmazonDynamoDBException" -class StateTaskServiceDynamoDB(StateTaskService): - _ERROR_NAME_AWS: Final[str] = "DynamoDB.AmazonDynamoDBException" +_SUPPORTED_API_PARAM_BINDINGS: Dict[str, Set[str]] = { + "getitem": { + "Key", + "TableName", + "AttributesToGet", + "ConsistentRead", + "ExpressionAttributeNames", + "ProjectionExpression", + "ReturnConsumedCapacity", + }, + "putitem": { + "Item", + "TableName", + "ConditionalOperator", + "ConditionExpression", + "Expected", + "ExpressionAttributeNames", + "ExpressionAttributeValues", + "ReturnConsumedCapacity", + "ReturnItemCollectionMetrics", + "ReturnValues", + }, + "deleteitem": { + "Key", + "TableName", + "ConditionalOperator", + "ConditionExpression", + "Expected", + "ExpressionAttributeNames", + "ExpressionAttributeValues", + "ReturnConsumedCapacity", + "ReturnItemCollectionMetrics", + "ReturnValues", + }, + "updateitem": { + "Key", + "TableName", + "AttributeUpdates", + "ConditionalOperator", + "ConditionExpression", + "Expected", + "ExpressionAttributeNames", + "ExpressionAttributeValues", + "ReturnConsumedCapacity", + "ReturnItemCollectionMetrics", + "ReturnValues", + "UpdateExpression", + }, +} - _SUPPORTED_API_PARAM_BINDINGS: Final[Dict[str, Set[str]]] = { - "getitem": { - "Key", - "TableName", - "AttributesToGet", - "ConsistentRead", - "ExpressionAttributeNames", - "ProjectionExpression", - "ReturnConsumedCapacity", - }, - "putitem": { - "Item", - "TableName", - "ConditionalOperator", - "ConditionExpression", - "Expected", - "ExpressionAttributeNames", - "ExpressionAttributeValues", - "ReturnConsumedCapacity", - "ReturnItemCollectionMetrics", - "ReturnValues", - }, - "deleteitem": { - "Key", - "TableName", - "ConditionalOperator", - "ConditionExpression", - "Expected", - "ExpressionAttributeNames", - "ExpressionAttributeValues", - "ReturnConsumedCapacity", - "ReturnItemCollectionMetrics", - "ReturnValues", - }, - "updateitem": { - "Key", - "TableName", - "AttributeUpdates", - "ConditionalOperator", - "ConditionExpression", - "Expected", - "ExpressionAttributeNames", - "ExpressionAttributeValues", - "ReturnConsumedCapacity", - "ReturnItemCollectionMetrics", - "ReturnValues", - "UpdateExpression", - }, - } +class StateTaskServiceDynamoDB(StateTaskService): def _get_supported_parameters(self) -> Optional[Set[str]]: - return self._SUPPORTED_API_PARAM_BINDINGS.get(self.resource.api_action.lower()) + return _SUPPORTED_API_PARAM_BINDINGS.get(self.resource.api_action.lower()) @staticmethod def _error_cause_from_client_error(client_error: ClientError) -> Tuple[str, str]: @@ -98,6 +101,7 @@ def _from_error(self, env: Environment, ex: Exception) -> FailureEvent: error, cause = self._error_cause_from_client_error(ex) error_name = CustomErrorName(error) return FailureEvent( + env=env, error_name=error_name, event_type=HistoryEventType.TaskFailed, event_details=EventDetails( @@ -111,11 +115,12 @@ def _from_error(self, env: Environment, ex: Exception) -> FailureEvent: ) else: return FailureEvent( - error_name=CustomErrorName(self._ERROR_NAME_AWS), + env=env, + error_name=CustomErrorName(_ERROR_NAME_AWS), event_type=HistoryEventType.TaskFailed, event_details=EventDetails( taskFailedEventDetails=TaskFailedEventDetails( - error=self._ERROR_NAME_AWS, + error=_ERROR_NAME_AWS, cause=str(ex), # TODO: update to report expected cause. resource=self._get_sfn_resource(), resourceType=self._get_sfn_resource_type(), @@ -128,6 +133,7 @@ def _eval_service_task( env: Environment, resource_runtime_part: ResourceRuntimePart, normalised_parameters: dict, + task_credentials: ComputedCredentials, ): service_name = self._get_boto_service_name() api_action = self._get_boto_service_action() @@ -135,6 +141,7 @@ def _eval_service_task( region=resource_runtime_part.region, account=resource_runtime_part.account, service=service_name, + credentials=task_credentials, ) response = getattr(dynamodb_client, api_action)(**normalised_parameters) response.pop("ResponseMetadata", None) diff --git a/moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service_ecs.py b/moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service_ecs.py new file mode 100644 index 000000000000..228b655569e4 --- /dev/null +++ b/moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service_ecs.py @@ -0,0 +1,130 @@ +from typing import Any, Callable, Dict, Optional, Set + +from moto.stepfunctions.parser.asl.component.state.exec.state_task.credentials import ( + ComputedCredentials, +) +from moto.stepfunctions.parser.asl.component.state.exec.state_task.service.resource import ( + ResourceCondition, + ResourceRuntimePart, +) +from moto.stepfunctions.parser.asl.component.state.exec.state_task.service.state_task_service_callback import ( + StateTaskServiceCallback, +) +from moto.stepfunctions.parser.asl.eval.environment import Environment +from moto.stepfunctions.parser.asl.utils.boto_client import boto_client_for + +_SUPPORTED_INTEGRATION_PATTERNS: Set[ResourceCondition] = { + ResourceCondition.WaitForTaskToken, + ResourceCondition.Sync, +} + +_SUPPORTED_API_PARAM_BINDINGS: Dict[str, Set[str]] = { + "runtask": { + "Cluster", + "Group", + "LaunchType", + "NetworkConfiguration", + "Overrides", + "PlacementConstraints", + "PlacementStrategy", + "PlatformVersion", + "PropagateTags", + "TaskDefinition", + "EnableExecuteCommand", + } +} + +_STARTED_BY_PARAMETER_RAW_KEY: str = "StartedBy" +_STARTED_BY_PARAMETER_VALUE: str = "AWS Step Functions" + + +class StateTaskServiceEcs(StateTaskServiceCallback): + def __init__(self): + super().__init__(supported_integration_patterns=_SUPPORTED_INTEGRATION_PATTERNS) + + def _get_supported_parameters(self) -> Optional[Set[str]]: + return _SUPPORTED_API_PARAM_BINDINGS.get(self.resource.api_action.lower()) + + def _before_eval_execution( + self, + env: Environment, + resource_runtime_part: ResourceRuntimePart, + raw_parameters: dict, + task_credentials: ComputedCredentials, + ) -> None: + if self.resource.condition == ResourceCondition.Sync: + raw_parameters[_STARTED_BY_PARAMETER_RAW_KEY] = _STARTED_BY_PARAMETER_VALUE + super()._before_eval_execution( + env=env, + resource_runtime_part=resource_runtime_part, + raw_parameters=raw_parameters, + task_credentials=task_credentials, + ) + + def _eval_service_task( + self, + env: Environment, + resource_runtime_part: ResourceRuntimePart, + normalised_parameters: dict, + task_credentials: ComputedCredentials, + ): + service_name = self._get_boto_service_name() + api_action = self._get_boto_service_action() + ecs_client = boto_client_for( + region=resource_runtime_part.region, + account=resource_runtime_part.account, + service=service_name, + credentials=task_credentials, + ) + response = getattr(ecs_client, api_action)(**normalised_parameters) + response.pop("ResponseMetadata", None) + + # AWS outputs the description of the task, not the output of run_task. + if self._get_boto_service_action() == "run_task": + self._normalise_response(response=response, service_action_name="run_task") + cluster_arn: str = response["Tasks"][0]["ClusterArn"] + task_arn: str = response["Tasks"][0]["TaskArn"] + describe_tasks_output = ecs_client.describe_tasks( + cluster=cluster_arn, tasks=[task_arn] + ) + describe_tasks_output.pop("ResponseMetadata", None) + self._normalise_response( + response=describe_tasks_output, service_action_name="describe_tasks" + ) + env.stack.append(describe_tasks_output) + return + + env.stack.append(response) + + def _build_sync_resolver( + self, + env: Environment, + resource_runtime_part: ResourceRuntimePart, + normalised_parameters: dict, + task_credentials: ComputedCredentials, + ) -> Callable[[], Optional[Any]]: + ecs_client = boto_client_for( + region=resource_runtime_part.region, + account=resource_runtime_part.account, + service="ecs", + credentials=task_credentials, + ) + submission_output: dict = env.stack.pop() + task_arn: str = submission_output["Tasks"][0]["TaskArn"] + cluster_arn: str = submission_output["Tasks"][0]["ClusterArn"] + + def _sync_resolver() -> Optional[dict]: + describe_tasks_output = ecs_client.describe_tasks( + cluster=cluster_arn, tasks=[task_arn] + ) + last_status: str = describe_tasks_output["tasks"][0]["lastStatus"] + + if last_status == "STOPPED": + self._normalise_response( + response=describe_tasks_output, service_action_name="describe_tasks" + ) + return describe_tasks_output["Tasks"][0] # noqa + + return None + + return _sync_resolver diff --git a/moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service_events.py b/moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service_events.py index 9c6d78f235de..dd6b0e3f1875 100644 --- a/moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service_events.py +++ b/moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service_events.py @@ -11,7 +11,11 @@ from moto.stepfunctions.parser.asl.component.common.error_name.failure_event import ( FailureEvent, ) +from moto.stepfunctions.parser.asl.component.state.exec.state_task.credentials import ( + ComputedCredentials, +) from moto.stepfunctions.parser.asl.component.state.exec.state_task.service.resource import ( + ResourceCondition, ResourceRuntimePart, ) from moto.stepfunctions.parser.asl.component.state.exec.state_task.service.state_task_service_callback import ( @@ -22,6 +26,15 @@ from moto.stepfunctions.parser.asl.utils.boto_client import boto_client_for from moto.stepfunctions.parser.asl.utils.encoding import to_json_str +_SUPPORTED_INTEGRATION_PATTERNS: Set[ResourceCondition] = { + ResourceCondition.WaitForTaskToken, +} +_FAILED_ENTRY_ERROR_NAME: ErrorName = CustomErrorName( + error_name="EventBridge.FailedEntry" +) + +_SUPPORTED_API_PARAM_BINDINGS: Dict[str, Set[str]] = {"putevents": {"Entries"}} + class SfnFailedEntryCountException(RuntimeError): cause: Final[Optional[dict]] @@ -32,25 +45,21 @@ def __init__(self, cause: Optional[dict]): class StateTaskServiceEvents(StateTaskServiceCallback): - _FAILED_ENTRY_ERROR_NAME: Final[ErrorName] = CustomErrorName( - error_name="EventBridge.FailedEntry" - ) - - _SUPPORTED_API_PARAM_BINDINGS: Final[Dict[str, Set[str]]] = { - "putevents": {"Entries"} - } + def __init__(self): + super().__init__(supported_integration_patterns=_SUPPORTED_INTEGRATION_PATTERNS) def _get_supported_parameters(self) -> Optional[Set[str]]: - return self._SUPPORTED_API_PARAM_BINDINGS.get(self.resource.api_action.lower()) + return _SUPPORTED_API_PARAM_BINDINGS.get(self.resource.api_action.lower()) def _from_error(self, env: Environment, ex: Exception) -> FailureEvent: if isinstance(ex, SfnFailedEntryCountException): return FailureEvent( - error_name=self._FAILED_ENTRY_ERROR_NAME, + env=env, + error_name=_FAILED_ENTRY_ERROR_NAME, event_type=HistoryEventType.TaskFailed, event_details=EventDetails( taskFailedEventDetails=TaskFailedEventDetails( - error=self._FAILED_ENTRY_ERROR_NAME.error_name, + error=_FAILED_ENTRY_ERROR_NAME.error_name, cause=ex.cause, resource=self._get_sfn_resource(), resourceType=self._get_sfn_resource_type(), @@ -76,10 +85,10 @@ def _normalised_request_parameters(env: Environment, parameters: dict): # field of each PutEventsRequestEntry. resources = entry.get("Resources", []) resources.append( - env.context_object_manager.context_object["StateMachine"]["Id"] + env.states.context_object.context_object_data["StateMachine"]["Id"] ) resources.append( - env.context_object_manager.context_object["Execution"]["Id"] + env.states.context_object.context_object_data["Execution"]["Id"] ) entry["Resources"] = resources @@ -88,6 +97,7 @@ def _eval_service_task( env: Environment, resource_runtime_part: ResourceRuntimePart, normalised_parameters: dict, + task_credentials: ComputedCredentials, ): self._normalised_request_parameters(env=env, parameters=normalised_parameters) service_name = self._get_boto_service_name() @@ -96,17 +106,18 @@ def _eval_service_task( region=resource_runtime_part.region, account=resource_runtime_part.account, service=service_name, + credentials=task_credentials, ) response = getattr(events_client, api_action)(**normalised_parameters) response.pop("ResponseMetadata", None) # If the response from PutEvents contains a non-zero FailedEntryCount then the # Task state fails with the error EventBridge.FailedEntry. - if self.resource.api_action == "putevents": + if self.resource.api_action == "putEvents": failed_entry_count = response.get("FailedEntryCount", 0) if failed_entry_count > 0: # TODO: pipe events' cause in the exception object. At them moment # LS events does not update this field. - raise SfnFailedEntryCountException(cause={"Cause": "Unsupported"}) + raise SfnFailedEntryCountException(cause=response) env.stack.append(response) diff --git a/moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service_factory.py b/moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service_factory.py index 292c78c0d7e3..9bb3a026d90f 100644 --- a/moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service_factory.py +++ b/moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service_factory.py @@ -1,5 +1,9 @@ from __future__ import annotations +from typing import Set + +from antlr4 import RecognitionException + from moto.stepfunctions.parser.asl.component.state.exec.state_task.service.state_task_service import ( StateTaskService, ) @@ -9,12 +13,21 @@ from moto.stepfunctions.parser.asl.component.state.exec.state_task.service.state_task_service_aws_sdk import ( StateTaskServiceAwsSdk, ) +from moto.stepfunctions.parser.asl.component.state.exec.state_task.service.state_task_service_batch import ( + StateTaskServiceBatch, +) from moto.stepfunctions.parser.asl.component.state.exec.state_task.service.state_task_service_dynamodb import ( StateTaskServiceDynamoDB, ) +from moto.stepfunctions.parser.asl.component.state.exec.state_task.service.state_task_service_ecs import ( + StateTaskServiceEcs, +) from moto.stepfunctions.parser.asl.component.state.exec.state_task.service.state_task_service_events import ( StateTaskServiceEvents, ) +from moto.stepfunctions.parser.asl.component.state.exec.state_task.service.state_task_service_glue import ( + StateTaskServiceGlue, +) from moto.stepfunctions.parser.asl.component.state.exec.state_task.service.state_task_service_lambda import ( StateTaskServiceLambda, ) @@ -27,6 +40,22 @@ from moto.stepfunctions.parser.asl.component.state.exec.state_task.service.state_task_service_sqs import ( StateTaskServiceSqs, ) +from moto.stepfunctions.parser.asl.component.state.exec.state_task.service.state_task_service_unsupported import ( + StateTaskServiceUnsupported, +) + +_UNSUPPORTED_SERVICE_NAMES: Set[str] = { + "athena", + "bedrock", + "codebuild", + "eks", + "elasticmapreduce", + "emr-containers", + "emr-serverless", + "databrew", + "mediaconvert", + "sagemaker", +} # TODO: improve on factory constructor (don't use SubtypeManager: cannot reuse state task instances). @@ -47,5 +76,12 @@ def state_task_service_for(service_name: str) -> StateTaskService: return StateTaskServiceSns() if service_name == "events": return StateTaskServiceEvents() - else: - raise NotImplementedError(f"Unsupported service: '{service_name}'.") # noqa + if service_name == "ecs": + return StateTaskServiceEcs() + if service_name == "glue": + return StateTaskServiceGlue() + if service_name == "batch": + return StateTaskServiceBatch() + if service_name in _UNSUPPORTED_SERVICE_NAMES: + return StateTaskServiceUnsupported() + raise RecognitionException(f"Unknown service '{service_name}'") diff --git a/moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service_glue.py b/moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service_glue.py new file mode 100644 index 000000000000..649551231685 --- /dev/null +++ b/moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service_glue.py @@ -0,0 +1,233 @@ +from typing import Any, Callable, Optional, Set + +import boto3 +from botocore.exceptions import ClientError + +from moto.stepfunctions.parser.api import HistoryEventType, TaskFailedEventDetails +from moto.stepfunctions.parser.asl.component.common.error_name.custom_error_name import ( + CustomErrorName, +) +from moto.stepfunctions.parser.asl.component.common.error_name.failure_event import ( + FailureEvent, + FailureEventException, +) +from moto.stepfunctions.parser.asl.component.common.error_name.states_error_name import ( + StatesErrorName, +) +from moto.stepfunctions.parser.asl.component.common.error_name.states_error_name_type import ( + StatesErrorNameType, +) +from moto.stepfunctions.parser.asl.component.state.exec.state_task.credentials import ( + ComputedCredentials, +) +from moto.stepfunctions.parser.asl.component.state.exec.state_task.service.resource import ( + ResourceCondition, + ResourceRuntimePart, +) +from moto.stepfunctions.parser.asl.component.state.exec.state_task.service.state_task_service_callback import ( + StateTaskServiceCallback, +) +from moto.stepfunctions.parser.asl.eval.environment import Environment +from moto.stepfunctions.parser.asl.eval.event.event_detail import EventDetails +from moto.stepfunctions.parser.asl.utils.boto_client import boto_client_for +from moto.stepfunctions.parser.asl.utils.encoding import to_json_str + +_SUPPORTED_INTEGRATION_PATTERNS: Set[ResourceCondition] = { + ResourceCondition.Sync, +} + +# Set of JobRunState value that indicate the JobRun had terminated in an abnormal state. +_JOB_RUN_STATE_ABNORMAL_TERMINAL_VALUE: Set[str] = {"FAILED", "TIMEOUT", "ERROR"} + +# Set of JobRunState values that indicate the JobRun has terminated. +_JOB_RUN_STATE_TERMINAL_VALUES: Set[str] = { + "STOPPED", + "SUCCEEDED", + *_JOB_RUN_STATE_ABNORMAL_TERMINAL_VALUE, +} + +# The handler function name prefix for StateTaskServiceGlue objects. +_HANDLER_REFLECTION_PREFIX: str = "_handle_" +# The sync handler function name prefix for StateTaskServiceGlue objects. +_SYNC_HANDLER_REFLECTION_PREFIX: str = "_sync_to_" +# The type of (sync)handler function for StateTaskServiceGlue objects. +_API_ACTION_HANDLER_TYPE = Callable[ + [Environment, ResourceRuntimePart, dict, ComputedCredentials], None +] +# The type of (sync)handler builder function for StateTaskServiceGlue objects. +_API_ACTION_HANDLER_BUILDER_TYPE = Callable[ + [Environment, ResourceRuntimePart, dict, ComputedCredentials], + Callable[[], Optional[Any]], +] + + +class StateTaskServiceGlue(StateTaskServiceCallback): + def __init__(self): + super().__init__(supported_integration_patterns=_SUPPORTED_INTEGRATION_PATTERNS) + + def _get_api_action_handler(self) -> _API_ACTION_HANDLER_TYPE: + api_action = self._get_boto_service_action() + handler_name = _HANDLER_REFLECTION_PREFIX + api_action + resolver_handler = getattr(self, handler_name) + if resolver_handler is None: + raise ValueError(f"Unknown or unsupported glue action '{api_action}'.") + return resolver_handler + + def _get_api_action_sync_builder_handler(self) -> _API_ACTION_HANDLER_BUILDER_TYPE: + api_action = self._get_boto_service_action() + handler_name = _SYNC_HANDLER_REFLECTION_PREFIX + api_action + resolver_handler = getattr(self, handler_name) + if resolver_handler is None: + raise ValueError(f"Unknown or unsupported glue action '{api_action}'.") + return resolver_handler + + @staticmethod + def _get_glue_client( + resource_runtime_part: ResourceRuntimePart, + task_credentials: ComputedCredentials, + ) -> boto3.client: + return boto_client_for( + region=resource_runtime_part.region, + account=resource_runtime_part.account, + service="glue", + credentials=task_credentials, + ) + + def _from_error(self, env: Environment, ex: Exception) -> FailureEvent: + if isinstance(ex, ClientError): + error_code = ex.response["Error"]["Code"] + error_name: str = f"Glue.{error_code}" + return FailureEvent( + env=env, + error_name=CustomErrorName(error_name), + event_type=HistoryEventType.TaskFailed, + event_details=EventDetails( + taskFailedEventDetails=TaskFailedEventDetails( + error=error_name, + cause=ex.response["Error"]["Message"], + resource=self._get_sfn_resource(), + resourceType=self._get_sfn_resource_type(), + ) + ), + ) + return super()._from_error(env=env, ex=ex) + + def _wait_for_task_token( + self, + env: Environment, + resource_runtime_part: ResourceRuntimePart, + normalised_parameters: dict, + ) -> None: + raise RuntimeError( + f"Unsupported .waitForTaskToken callback procedure in resource {self.resource.resource_arn}" + ) + + def _handle_start_job_run( + self, + env: Environment, + resource_runtime_part: ResourceRuntimePart, + normalised_parameters: dict, + computed_credentials: ComputedCredentials, + ): + glue_client = self._get_glue_client( + resource_runtime_part=resource_runtime_part, + task_credentials=computed_credentials, + ) + response = glue_client.start_job_run(**normalised_parameters) + response.pop("ResponseMetadata", None) + # AWS StepFunctions extracts the JobName from the request and inserts it into the response, which + # normally only contains JobRunID; as this is a required field for start_job_run, the access at + # this depth is safe. + response["JobName"] = normalised_parameters.get("JobName") + env.stack.append(response) + + def _eval_service_task( + self, + env: Environment, + resource_runtime_part: ResourceRuntimePart, + normalised_parameters: dict, + task_credentials: ComputedCredentials, + ): + # Source the action handler and delegate the evaluation. + api_action_handler = self._get_api_action_handler() + api_action_handler( + env, resource_runtime_part, normalised_parameters, task_credentials + ) + + def _sync_to_start_job_run( + self, + env: Environment, + resource_runtime_part: ResourceRuntimePart, + normalised_parameters: dict, + task_credentials: ComputedCredentials, + ) -> Callable[[], Optional[Any]]: + # Poll the job run state from glue, using GetJobRun until the job has terminated. Hence, append the output + # of GetJobRun to the state. + + # Access the JobName and the JobRunId from the StartJobRun output call that must + # have occurred before this point. + start_job_run_output: dict = env.stack.pop() + job_name: str = start_job_run_output["JobName"] + job_run_id: str = start_job_run_output["JobRunId"] + + glue_client = self._get_glue_client( + resource_runtime_part=resource_runtime_part, + task_credentials=task_credentials, + ) + + def _sync_resolver() -> Optional[Any]: + # Sample GetJobRun until completion. + get_job_run_response: dict = glue_client.get_job_run( + JobName=job_name, RunId=job_run_id + ) + job_run: dict = get_job_run_response["JobRun"] + job_run_state: str = job_run["JobRunState"] + + # If the job run has not terminated, continue and check later. + is_terminated: bool = job_run_state in _JOB_RUN_STATE_TERMINAL_VALUES + if not is_terminated: + return None + + # AWS StepFunctions appears to append attach the JobName to the output both in case of error or success. + job_run["JobName"] = job_name + + # If the job run terminated in a normal state, return the result. + is_abnormal_termination = ( + job_run_state in _JOB_RUN_STATE_ABNORMAL_TERMINAL_VALUE + ) + if not is_abnormal_termination: + return job_run + + # If the job run has terminated with an abnormal state, raise the error in stepfunctions. + raise FailureEventException( + FailureEvent( + env=env, + error_name=StatesErrorName( + typ=StatesErrorNameType.StatesTaskFailed + ), + event_type=HistoryEventType.TaskFailed, + event_details=EventDetails( + taskFailedEventDetails=TaskFailedEventDetails( + resource=self._get_sfn_resource(), + resourceType=self._get_sfn_resource_type(), + error=StatesErrorNameType.StatesTaskFailed.to_name(), + cause=to_json_str(job_run), + ) + ), + ) + ) + + return _sync_resolver + + def _build_sync_resolver( + self, + env: Environment, + resource_runtime_part: ResourceRuntimePart, + normalised_parameters: dict, + task_credentials: ComputedCredentials, + ) -> Callable[[], Optional[Any]]: + sync_resolver_builder = self._get_api_action_sync_builder_handler() + sync_resolver = sync_resolver_builder( + env, resource_runtime_part, normalised_parameters, task_credentials + ) + return sync_resolver diff --git a/moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service_lambda.py b/moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service_lambda.py index 7e3d0f8b57f1..19f5264acd92 100644 --- a/moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service_lambda.py +++ b/moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service_lambda.py @@ -1,4 +1,6 @@ -from typing import Dict, Final, Optional, Set, Tuple +import json +import logging +from typing import Dict, Optional, Set, Tuple from botocore.exceptions import ClientError @@ -12,7 +14,11 @@ from moto.stepfunctions.parser.asl.component.state.exec.state_task import ( lambda_eval_utils, ) +from moto.stepfunctions.parser.asl.component.state.exec.state_task.credentials import ( + ComputedCredentials, +) from moto.stepfunctions.parser.asl.component.state.exec.state_task.service.resource import ( + ResourceCondition, ResourceRuntimePart, ) from moto.stepfunctions.parser.asl.component.state.exec.state_task.service.state_task_service_callback import ( @@ -21,22 +27,30 @@ from moto.stepfunctions.parser.asl.eval.environment import Environment from moto.stepfunctions.parser.asl.eval.event.event_detail import EventDetails +LOG = logging.getLogger(__name__) -class StateTaskServiceLambda(StateTaskServiceCallback): - _SUPPORTED_API_PARAM_BINDINGS: Final[Dict[str, Set[str]]] = { - "invoke": { - "ClientContext", - "FunctionName", - "InvocationType", - "Qualifier", - "Payload", - # Outside the specification, but supported in practice: - "LogType", - } + +_SUPPORTED_INTEGRATION_PATTERNS: Set[ResourceCondition] = { + ResourceCondition.WaitForTaskToken, +} +_SUPPORTED_API_PARAM_BINDINGS: Dict[str, Set[str]] = { + "invoke": { + "ClientContext", + "FunctionName", + "Qualifier", + "Payload", + # Outside the specification, but supported in practice: + "LogType", } +} + + +class StateTaskServiceLambda(StateTaskServiceCallback): + def __init__(self): + super().__init__(supported_integration_patterns=_SUPPORTED_INTEGRATION_PATTERNS) def _get_supported_parameters(self) -> Optional[Set[str]]: - return self._SUPPORTED_API_PARAM_BINDINGS.get(self.resource.api_action.lower()) + return _SUPPORTED_API_PARAM_BINDINGS.get(self.resource.api_action.lower()) @staticmethod def _error_cause_from_client_error(client_error: ClientError) -> Tuple[str, str]: @@ -57,15 +71,24 @@ def _error_cause_from_client_error(client_error: ClientError) -> Tuple[str, str] def _from_error(self, env: Environment, ex: Exception) -> FailureEvent: if isinstance(ex, lambda_eval_utils.LambdaFunctionErrorException): - error = "Exception" - error_name = CustomErrorName(error) cause = ex.payload + try: + cause_object = json.loads(cause) + error = cause_object["errorType"] + except Exception as ex: + LOG.warning( + "Could not retrieve 'errorType' field from LambdaFunctionErrorException object: %s", + ex, + ) + error = "Exception" + error_name = CustomErrorName(error) elif isinstance(ex, ClientError): error, cause = self._error_cause_from_client_error(ex) error_name = CustomErrorName(error) else: return super()._from_error(env=env, ex=ex) return FailureEvent( + env=env, error_name=error_name, event_type=HistoryEventType.TaskFailed, event_details=EventDetails( @@ -78,19 +101,34 @@ def _from_error(self, env: Environment, ex: Exception) -> FailureEvent: ), ) + def _normalise_parameters( + self, + parameters: dict, + boto_service_name: Optional[str] = None, + service_action_name: Optional[str] = None, + ) -> None: + # Run Payload value casting before normalisation. + if "Payload" in parameters: + parameters["Payload"] = lambda_eval_utils.to_payload_type( + parameters["Payload"] + ) + super()._normalise_parameters( + parameters=parameters, + boto_service_name=boto_service_name, + service_action_name=service_action_name, + ) + def _eval_service_task( self, env: Environment, resource_runtime_part: ResourceRuntimePart, normalised_parameters: dict, + task_credentials: ComputedCredentials, ): - if "Payload" in normalised_parameters: - normalised_parameters["Payload"] = lambda_eval_utils.to_payload_type( - normalised_parameters["Payload"] - ) lambda_eval_utils.exec_lambda_function( env=env, parameters=normalised_parameters, region=resource_runtime_part.region, account=resource_runtime_part.account, + credentials=task_credentials, ) diff --git a/moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service_sfn.py b/moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service_sfn.py index df7ecaa7bf87..8d4660827f12 100644 --- a/moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service_sfn.py +++ b/moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service_sfn.py @@ -1,5 +1,5 @@ import json -from typing import Dict, Final, Optional, Set +from typing import Any, Callable, Dict, Optional, Set from botocore.exceptions import ClientError @@ -22,7 +22,11 @@ from moto.stepfunctions.parser.asl.component.common.error_name.states_error_name_type import ( StatesErrorNameType, ) +from moto.stepfunctions.parser.asl.component.state.exec.state_task.credentials import ( + ComputedCredentials, +) from moto.stepfunctions.parser.asl.component.state.exec.state_task.service.resource import ( + ResourceCondition, ResourceRuntimePart, ) from moto.stepfunctions.parser.asl.component.state.exec.state_task.service.state_task_service_callback import ( @@ -32,15 +36,24 @@ from moto.stepfunctions.parser.asl.eval.event.event_detail import EventDetails from moto.stepfunctions.parser.asl.utils.boto_client import boto_client_for from moto.stepfunctions.parser.asl.utils.encoding import to_json_str +from moto.utilities.collections import select_from_typed_dict + +_SUPPORTED_INTEGRATION_PATTERNS: Set[ResourceCondition] = { + ResourceCondition.WaitForTaskToken, + ResourceCondition.Sync, + ResourceCondition.Sync2, +} +_SUPPORTED_API_PARAM_BINDINGS: Dict[str, Set[str]] = { + "startexecution": {"Input", "Name", "StateMachineArn"} +} class StateTaskServiceSfn(StateTaskServiceCallback): - _SUPPORTED_API_PARAM_BINDINGS: Final[Dict[str, Set[str]]] = { - "startexecution": {"Input", "Name", "StateMachineArn"} - } + def __init__(self): + super().__init__(supported_integration_patterns=_SUPPORTED_INTEGRATION_PATTERNS) def _get_supported_parameters(self) -> Optional[Set[str]]: - return self._SUPPORTED_API_PARAM_BINDINGS.get(self.resource.api_action.lower()) + return _SUPPORTED_API_PARAM_BINDINGS.get(self.resource.api_action.lower()) def _from_error(self, env: Environment, ex: Exception) -> FailureEvent: if isinstance(ex, ClientError): @@ -61,6 +74,7 @@ def _from_error(self, env: Environment, ex: Exception) -> FailureEvent: f"{ex.response['Error']['Message']} ({'; '.join(error_cause_details)})" ) return FailureEvent( + env=env, error_name=CustomErrorName(error_name), event_type=HistoryEventType.TaskFailed, event_details=EventDetails( @@ -97,6 +111,61 @@ def _normalise_parameters( service_action_name=service_action_name, ) + def _build_sync_resolver( + self, + env: Environment, + resource_runtime_part: ResourceRuntimePart, + normalised_parameters: dict, + task_credentials: ComputedCredentials, + ) -> Callable[[], Optional[Any]]: + sfn_client = boto_client_for( + region=resource_runtime_part.region, + account=resource_runtime_part.account, + service="stepfunctions", + credentials=task_credentials, + ) + submission_output: dict = env.stack.pop() + execution_arn: str = submission_output["ExecutionArn"] + + def _sync_resolver() -> Optional[Any]: + describe_execution_output = sfn_client.describe_execution( + executionArn=execution_arn + ) + describe_execution_output: DescribeExecutionOutput = select_from_typed_dict( + DescribeExecutionOutput, describe_execution_output + ) + execution_status: ExecutionStatus = describe_execution_output["status"] + + if execution_status == ExecutionStatus.RUNNING: + return None + + self._normalise_response( + response=describe_execution_output, + service_action_name="describe_execution", + ) + if execution_status == ExecutionStatus.SUCCEEDED: + return describe_execution_output + else: + raise FailureEventException( + FailureEvent( + env=env, + error_name=StatesErrorName( + typ=StatesErrorNameType.StatesTaskFailed + ), + event_type=HistoryEventType.TaskFailed, + event_details=EventDetails( + taskFailedEventDetails=TaskFailedEventDetails( + resource=self._get_sfn_resource(), + resourceType=self._get_sfn_resource_type(), + error=StatesErrorNameType.StatesTaskFailed.to_name(), + cause=to_json_str(describe_execution_output), + ) + ), + ) + ) + + return _sync_resolver + @staticmethod def _sync2_api_output_of(typ: type, value: json) -> None: def _replace_with_json_if_str(key: str) -> None: @@ -108,113 +177,79 @@ def _replace_with_json_if_str(key: str) -> None: _replace_with_json_if_str("input") _replace_with_json_if_str("output") - def _eval_service_task( + def _build_sync2_resolver( self, env: Environment, resource_runtime_part: ResourceRuntimePart, normalised_parameters: dict, - ): - service_name = self._get_boto_service_name() - api_action = self._get_boto_service_action() - sfn_client = boto_client_for( - region=resource_runtime_part.region, - account=resource_runtime_part.account, - service=service_name, - ) - response = getattr(sfn_client, api_action)(**normalised_parameters) - response.pop("ResponseMetadata", None) - env.stack.append(response) - - def _sync_to_start_machine( - self, - env: Environment, - resource_runtime_part: ResourceRuntimePart, - sync2_response: bool, - ) -> None: + task_credentials: ComputedCredentials, + ) -> Callable[[], Optional[Any]]: sfn_client = boto_client_for( region=resource_runtime_part.region, account=resource_runtime_part.account, service="stepfunctions", + credentials=task_credentials, ) submission_output: dict = env.stack.pop() execution_arn: str = submission_output["ExecutionArn"] - def _has_terminated() -> Optional[dict]: + def _sync2_resolver() -> Optional[Any]: describe_execution_output = sfn_client.describe_execution( executionArn=execution_arn ) + describe_execution_output: DescribeExecutionOutput = select_from_typed_dict( + DescribeExecutionOutput, describe_execution_output + ) execution_status: ExecutionStatus = describe_execution_output["status"] - if execution_status != ExecutionStatus.RUNNING: - if sync2_response: - self._sync2_api_output_of( - typ=DescribeExecutionOutput, value=describe_execution_output - ) - self._normalise_response( - response=describe_execution_output, - service_action_name="describe_execution", - ) - if execution_status == ExecutionStatus.SUCCEEDED: - return describe_execution_output - else: - raise FailureEventException( - FailureEvent( - error_name=StatesErrorName( - typ=StatesErrorNameType.StatesTaskFailed - ), - event_type=HistoryEventType.TaskFailed, - event_details=EventDetails( - taskFailedEventDetails=TaskFailedEventDetails( - resource=self._get_sfn_resource(), - resourceType=self._get_sfn_resource_type(), - error=StatesErrorNameType.StatesTaskFailed.to_name(), - cause=to_json_str(describe_execution_output), - ) - ), - ) - ) - return None - - termination_output: Optional[dict] = None - while env.is_running() and not termination_output: - termination_output: Optional[dict] = _has_terminated() + if execution_status == ExecutionStatus.RUNNING: + return None - env.stack.append(termination_output) - - def _sync( - self, - env: Environment, - resource_runtime_part: ResourceRuntimePart, - normalised_parameters: dict, - ) -> None: - if self._get_boto_service_action() == "start_execution": - return self._sync_to_start_machine( - env=env, - resource_runtime_part=resource_runtime_part, - sync2_response=False, + self._sync2_api_output_of( + typ=DescribeExecutionOutput, value=describe_execution_output ) - else: - super()._sync( - env=env, - resource_runtime_part=resource_runtime_part, - normalised_parameters=normalised_parameters, + self._normalise_response( + response=describe_execution_output, + service_action_name="describe_execution", ) + if execution_status == ExecutionStatus.SUCCEEDED: + return describe_execution_output + else: + raise FailureEventException( + FailureEvent( + env=env, + error_name=StatesErrorName( + typ=StatesErrorNameType.StatesTaskFailed + ), + event_type=HistoryEventType.TaskFailed, + event_details=EventDetails( + taskFailedEventDetails=TaskFailedEventDetails( + resource=self._get_sfn_resource(), + resourceType=self._get_sfn_resource_type(), + error=StatesErrorNameType.StatesTaskFailed.to_name(), + cause=to_json_str(describe_execution_output), + ) + ), + ) + ) + + return _sync2_resolver - def _sync2( + def _eval_service_task( self, env: Environment, resource_runtime_part: ResourceRuntimePart, normalised_parameters: dict, - ) -> None: - if self._get_boto_service_action() == "start_execution": - return self._sync_to_start_machine( - env=env, - resource_runtime_part=resource_runtime_part, - sync2_response=True, - ) - else: - super()._sync2( - env=env, - resource_runtime_part=resource_runtime_part, - normalised_parameters=normalised_parameters, - ) + task_credentials: ComputedCredentials, + ): + service_name = self._get_boto_service_name() + api_action = self._get_boto_service_action() + sfn_client = boto_client_for( + region=resource_runtime_part.region, + account=resource_runtime_part.account, + service=service_name, + credentials=task_credentials, + ) + response = getattr(sfn_client, api_action)(**normalised_parameters) + response.pop("ResponseMetadata", None) + env.stack.append(response) diff --git a/moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service_sns.py b/moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service_sns.py index da9d4985ee89..3a33c72e0b63 100644 --- a/moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service_sns.py +++ b/moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service_sns.py @@ -1,4 +1,4 @@ -from typing import Dict, Final, Optional, Set +from typing import Dict, Optional, Set from botocore.exceptions import ClientError @@ -9,7 +9,11 @@ from moto.stepfunctions.parser.asl.component.common.error_name.failure_event import ( FailureEvent, ) +from moto.stepfunctions.parser.asl.component.state.exec.state_task.credentials import ( + ComputedCredentials, +) from moto.stepfunctions.parser.asl.component.state.exec.state_task.service.resource import ( + ResourceCondition, ResourceRuntimePart, ) from moto.stepfunctions.parser.asl.component.state.exec.state_task.service.state_task_service_callback import ( @@ -20,22 +24,30 @@ from moto.stepfunctions.parser.asl.utils.boto_client import boto_client_for from moto.stepfunctions.parser.asl.utils.encoding import to_json_str +_SUPPORTED_INTEGRATION_PATTERNS: Set[ResourceCondition] = { + ResourceCondition.WaitForTaskToken, +} +_SUPPORTED_API_PARAM_BINDINGS: Dict[str, Set[str]] = { + "publish": { + "Message", + "MessageAttributes", + "MessageStructure", + "MessageDeduplicationId", + "MessageGroupId", + "PhoneNumber", + "Subject", + "TargetArn", + "TopicArn", + } +} + class StateTaskServiceSns(StateTaskServiceCallback): - _SUPPORTED_API_PARAM_BINDINGS: Final[Dict[str, Set[str]]] = { - "publish": { - "Message", - "MessageAttributes", - "MessageStructure", - "PhoneNumber", - "Subject", - "TargetArn", - "TopicArn", - } - } + def __init__(self): + super().__init__(supported_integration_patterns=_SUPPORTED_INTEGRATION_PATTERNS) def _get_supported_parameters(self) -> Optional[Set[str]]: - return self._SUPPORTED_API_PARAM_BINDINGS.get(self.resource.api_action.lower()) + return _SUPPORTED_API_PARAM_BINDINGS.get(self.resource.api_action.lower()) def _from_error(self, env: Environment, ex: Exception) -> FailureEvent: if isinstance(ex, ClientError): @@ -59,6 +71,7 @@ def _from_error(self, env: Environment, ex: Exception) -> FailureEvent: ) return FailureEvent( + env=env, error_name=CustomErrorName(error_name=error_name), event_type=HistoryEventType.TaskFailed, event_details=EventDetails( @@ -77,6 +90,7 @@ def _eval_service_task( env: Environment, resource_runtime_part: ResourceRuntimePart, normalised_parameters: dict, + task_credentials: ComputedCredentials, ): service_name = self._get_boto_service_name() api_action = self._get_boto_service_action() @@ -84,6 +98,7 @@ def _eval_service_task( region=resource_runtime_part.region, account=resource_runtime_part.account, service=service_name, + credentials=task_credentials, ) # Optimised integration automatically stringifies diff --git a/moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service_sqs.py b/moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service_sqs.py index 3a55c884c00c..0222f08c44ca 100644 --- a/moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service_sqs.py +++ b/moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service_sqs.py @@ -1,4 +1,4 @@ -from typing import Any, Dict, Final, Optional, Set +from typing import Any, Dict, Optional, Set from botocore.exceptions import ClientError @@ -9,7 +9,11 @@ from moto.stepfunctions.parser.asl.component.common.error_name.failure_event import ( FailureEvent, ) +from moto.stepfunctions.parser.asl.component.state.exec.state_task.credentials import ( + ComputedCredentials, +) from moto.stepfunctions.parser.asl.component.state.exec.state_task.service.resource import ( + ResourceCondition, ResourceRuntimePart, ) from moto.stepfunctions.parser.asl.component.state.exec.state_task.service.state_task_service_callback import ( @@ -20,33 +24,39 @@ from moto.stepfunctions.parser.asl.utils.boto_client import boto_client_for from moto.stepfunctions.parser.asl.utils.encoding import to_json_str +_SUPPORTED_INTEGRATION_PATTERNS: Set[ResourceCondition] = { + ResourceCondition.WaitForTaskToken, +} +_ERROR_NAME_CLIENT: str = "SQS.SdkClientException" +_ERROR_NAME_AWS: str = "SQS.AmazonSQSException" +_SUPPORTED_API_PARAM_BINDINGS: Dict[str, Set[str]] = { + "sendmessage": { + "DelaySeconds", + "MessageAttributes", + "MessageBody", + "MessageDeduplicationId", + "MessageGroupId", + "QueueUrl", + } +} -class StateTaskServiceSqs(StateTaskServiceCallback): - _ERROR_NAME_CLIENT: Final[str] = "SQS.SdkClientException" - _ERROR_NAME_AWS: Final[str] = "SQS.AmazonSQSException" - _SUPPORTED_API_PARAM_BINDINGS: Final[Dict[str, Set[str]]] = { - "sendmessage": { - "DelaySeconds", - "MessageAttribute", - "MessageBody", - "MessageDeduplicationId", - "MessageGroupId", - "QueueUrl", - } - } +class StateTaskServiceSqs(StateTaskServiceCallback): + def __init__(self): + super().__init__(supported_integration_patterns=_SUPPORTED_INTEGRATION_PATTERNS) def _get_supported_parameters(self) -> Optional[Set[str]]: - return self._SUPPORTED_API_PARAM_BINDINGS.get(self.resource.api_action.lower()) + return _SUPPORTED_API_PARAM_BINDINGS.get(self.resource.api_action.lower()) def _from_error(self, env: Environment, ex: Exception) -> FailureEvent: if isinstance(ex, ClientError): return FailureEvent( - error_name=CustomErrorName(self._ERROR_NAME_CLIENT), + env=env, + error_name=CustomErrorName(_ERROR_NAME_CLIENT), event_type=HistoryEventType.TaskFailed, event_details=EventDetails( taskFailedEventDetails=TaskFailedEventDetails( - error=self._ERROR_NAME_CLIENT, + error=_ERROR_NAME_CLIENT, cause=ex.response["Error"][ "Message" ], # TODO: update to report expected cause. @@ -68,16 +78,21 @@ def _normalise_response( boto_service_name=boto_service_name, service_action_name=service_action_name, ) - # Normalise output value key to SFN standard for Md5OfMessageBody. + # Normalise output value keys to SFN standard for Md5OfMessageBody and Md5OfMessageAttributes if response and "Md5OfMessageBody" in response: md5_message_body = response.pop("Md5OfMessageBody") response["MD5OfMessageBody"] = md5_message_body + if response and "Md5OfMessageAttributes" in response: + md5_message_attributes = response.pop("Md5OfMessageAttributes") + response["MD5OfMessageAttributes"] = md5_message_attributes + def _eval_service_task( self, env: Environment, resource_runtime_part: ResourceRuntimePart, normalised_parameters: dict, + task_credentials: ComputedCredentials, ): # TODO: Stepfunctions automatically dumps to json MessageBody's definitions. # Are these other similar scenarios? @@ -92,6 +107,7 @@ def _eval_service_task( region=resource_runtime_part.region, account=resource_runtime_part.account, service=service_name, + credentials=task_credentials, ) response = getattr(sqs_client, api_action)(**normalised_parameters) response.pop("ResponseMetadata", None) diff --git a/moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service_unsupported.py b/moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service_unsupported.py new file mode 100644 index 000000000000..704beb5a539f --- /dev/null +++ b/moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service_unsupported.py @@ -0,0 +1,60 @@ +import logging +from typing import Set + +from moto.stepfunctions.parser.asl.component.state.exec.state_task.credentials import ( + ComputedCredentials, +) +from moto.stepfunctions.parser.asl.component.state.exec.state_task.service.resource import ( + ResourceCondition, + ResourceRuntimePart, +) +from moto.stepfunctions.parser.asl.component.state.exec.state_task.service.state_task_service_callback import ( + StateTaskServiceCallback, +) +from moto.stepfunctions.parser.asl.eval.environment import Environment +from moto.stepfunctions.parser.asl.utils.boto_client import boto_client_for + +LOG = logging.getLogger(__name__) + +_SUPPORTED_INTEGRATION_PATTERNS: Set[ResourceCondition] = { + ResourceCondition.WaitForTaskToken, +} + + +class StateTaskServiceUnsupported(StateTaskServiceCallback): + def __init__(self): + super().__init__(supported_integration_patterns=_SUPPORTED_INTEGRATION_PATTERNS) + + def _log_unsupported_warning(self): + # Logs that the optimised service integration is not supported, + # however the request is being forwarded to the service. + service_name = self._get_boto_service_name() + resource_arn = self.resource.resource_arn + LOG.warning( + "Unsupported Optimised service integration for service_name '%s' in resource: '%s'. " + "Attempting to forward request to service.", + service_name, + resource_arn, + ) + + def _eval_service_task( + self, + env: Environment, + resource_runtime_part: ResourceRuntimePart, + normalised_parameters: dict, + task_credentials: ComputedCredentials, + ): + # Logs that the evaluation of this optimised service integration is not supported + # and relays the call to the target service with the computed parameters. + self._log_unsupported_warning() + service_name = self._get_boto_service_name() + boto_action = self._get_boto_service_action() + boto_client = boto_client_for( + region=resource_runtime_part.region, + account=resource_runtime_part.account, + service=service_name, + credentials=task_credentials, + ) + response = getattr(boto_client, boto_action)(**normalised_parameters) + response.pop("ResponseMetadata", None) + env.stack.append(response) diff --git a/moto/stepfunctions/parser/asl/component/state/exec/state_task/state_task.py b/moto/stepfunctions/parser/asl/component/state/exec/state_task/state_task.py index 4c3defc6b841..9202a013e4fd 100644 --- a/moto/stepfunctions/parser/asl/component/state/exec/state_task/state_task.py +++ b/moto/stepfunctions/parser/asl/component/state/exec/state_task/state_task.py @@ -13,10 +13,14 @@ from moto.stepfunctions.parser.asl.component.common.error_name.states_error_name_type import ( StatesErrorNameType, ) -from moto.stepfunctions.parser.asl.component.common.parameters import Parameters +from moto.stepfunctions.parser.asl.component.common.parargs import Parargs from moto.stepfunctions.parser.asl.component.state.exec.execute_state import ( ExecutionState, ) +from moto.stepfunctions.parser.asl.component.state.exec.state_task.credentials import ( + ComputedCredentials, + Credentials, +) from moto.stepfunctions.parser.asl.component.state.exec.state_task.service.resource import ( Resource, ) @@ -27,22 +31,20 @@ class StateTask(ExecutionState, abc.ABC): resource: Resource - parameters: Optional[Parameters] + parargs: Optional[Parargs] + credentials: Optional[Credentials] def __init__(self): super(StateTask, self).__init__( state_entered_event_type=HistoryEventType.TaskStateEntered, state_exited_event_type=HistoryEventType.TaskStateExited, ) - # Parameters (Optional) - # Used to state_pass information to the API actions of connected resources. The parameters can use a mix of static - # JSON and JsonPath. - self.parameters = None def from_state_props(self, state_props: StateProps) -> None: super(StateTask, self).from_state_props(state_props) - self.parameters = state_props.get(Parameters) self.resource = state_props.get(Resource) + self.parargs = state_props.get(Parargs) + self.credentials = state_props.get(Credentials) def _get_supported_parameters(self) -> Optional[Set[str]]: # noqa return None @@ -50,8 +52,8 @@ def _get_supported_parameters(self) -> Optional[Set[str]]: # noqa def _eval_parameters(self, env: Environment) -> dict: # Eval raw parameters. parameters = dict() - if self.parameters: - self.parameters.eval(env=env) + if self.parargs is not None: + self.parargs.eval(env=env) parameters = env.stack.pop() # Handle supported parameters. @@ -67,8 +69,17 @@ def _eval_parameters(self, env: Environment) -> dict: return parameters - def _get_timed_out_failure_event(self) -> FailureEvent: + def _eval_credentials(self, env: Environment) -> ComputedCredentials: + if not self.credentials: + task_credentials = dict() + else: + self.credentials.eval(env=env) + task_credentials = env.stack.pop() + return task_credentials + + def _get_timed_out_failure_event(self, env: Environment) -> FailureEvent: return FailureEvent( + env=env, error_name=StatesErrorName(typ=StatesErrorNameType.StatesTimeout), event_type=HistoryEventType.TaskTimedOut, event_details=EventDetails( @@ -80,9 +91,5 @@ def _get_timed_out_failure_event(self) -> FailureEvent: def _from_error(self, env: Environment, ex: Exception) -> FailureEvent: if isinstance(ex, TimeoutError): - return self._get_timed_out_failure_event() + return self._get_timed_out_failure_event(env) return super()._from_error(env=env, ex=ex) - - def _eval_body(self, env: Environment) -> None: - super(StateTask, self)._eval_body(env=env) - env.context_object_manager.context_object["Task"] = None diff --git a/moto/stepfunctions/parser/asl/component/state/exec/state_task/state_task_activitiy.py b/moto/stepfunctions/parser/asl/component/state/exec/state_task/state_task_activitiy.py new file mode 100644 index 000000000000..fe80d25f0d97 --- /dev/null +++ b/moto/stepfunctions/parser/asl/component/state/exec/state_task/state_task_activitiy.py @@ -0,0 +1,223 @@ +import json + +from botocore.exceptions import ClientError + +from moto.stepfunctions.parser.api import ( + ActivityDoesNotExist, + ActivityFailedEventDetails, + ActivityScheduledEventDetails, + ActivityStartedEventDetails, + ActivitySucceededEventDetails, + ActivityTimedOutEventDetails, + ExecutionFailedEventDetails, + HistoryEventExecutionDataDetails, + HistoryEventType, +) +from moto.stepfunctions.parser.asl.component.common.error_name.custom_error_name import ( + CustomErrorName, +) +from moto.stepfunctions.parser.asl.component.common.error_name.failure_event import ( + FailureEvent, + FailureEventException, +) +from moto.stepfunctions.parser.asl.component.common.error_name.states_error_name import ( + StatesErrorName, +) +from moto.stepfunctions.parser.asl.component.common.error_name.states_error_name_type import ( + StatesErrorNameType, +) +from moto.stepfunctions.parser.asl.component.common.timeouts.timeout import ( + EvalTimeoutError, + TimeoutSeconds, +) +from moto.stepfunctions.parser.asl.component.state.exec.state_task.service.resource import ( + ActivityResource, +) +from moto.stepfunctions.parser.asl.component.state.exec.state_task.state_task import ( + StateTask, +) +from moto.stepfunctions.parser.asl.eval.callback.callback import ( + ActivityTaskStartOutcome, + CallbackOutcomeFailure, + CallbackOutcomeFailureError, + CallbackOutcomeSuccess, + CallbackTimeoutError, + HeartbeatTimeoutError, +) +from moto.stepfunctions.parser.asl.eval.environment import Environment +from moto.stepfunctions.parser.asl.eval.event.event_detail import EventDetails +from moto.stepfunctions.parser.asl.utils.encoding import to_json_str + + +class StateTaskActivity(StateTask): + resource: ActivityResource + + def _from_error(self, env: Environment, ex: Exception) -> FailureEvent: + if isinstance(ex, TimeoutError): + return FailureEvent( + env=env, + error_name=StatesErrorName(typ=StatesErrorNameType.StatesTimeout), + event_type=HistoryEventType.ActivityTimedOut, + event_details=EventDetails( + activityTimedOutEventDetails=ActivityTimedOutEventDetails( + error=StatesErrorNameType.StatesTimeout.to_name(), + ) + ), + ) + + if isinstance(ex, FailureEventException): + raise ex + + if isinstance(ex, CallbackOutcomeFailureError): + error = ex.callback_outcome_failure.error + error_name = CustomErrorName(error) + cause = ex.callback_outcome_failure.cause + else: + error_name = StatesErrorName(typ=StatesErrorNameType.StatesRuntime) + error = error_name.error_name + cause = ( + ex.response["Error"]["Message"] + if isinstance(ex, ClientError) + else str(ex) + ) + return FailureEvent( + env=env, + error_name=error_name, + event_type=HistoryEventType.ActivityFailed, + event_details=EventDetails( + activityFailedEventDetails=ActivityFailedEventDetails( + error=error, cause=cause + ) + ), + ) + + def _eval_parameters(self, env: Environment) -> dict: + if self.parargs: + self.parargs.eval(env=env) + activity_input = env.stack.pop() + return activity_input + + def _eval_execution(self, env: Environment) -> None: + # Compute the task input. + activity_task_input = self._eval_parameters(env=env) + if not isinstance(activity_task_input, str): + activity_task_input = to_json_str(activity_task_input) + + # Compute the timeout and heartbeat for this task. + timeout_seconds = TimeoutSeconds.DEFAULT_TIMEOUT_SECONDS + + if not self.timeout.is_default_value(): + self.timeout.eval(env=env) + timeout_seconds = env.stack.pop() + + heartbeat_seconds = None + if self.heartbeat: + self.heartbeat.eval(env=env) + heartbeat_seconds = env.stack.pop() + + # Publish the activity task on the callback manager. + task_token = env.states.context_object.update_task_token() + try: + callback_endpoint = env.callback_pool_manager.add_activity_task( + callback_id=task_token, + activity_arn=self.resource.resource_arn, + activity_input=activity_task_input, + ) + except ActivityDoesNotExist: + failure_event = FailureEvent( + env=env, + error_name=StatesErrorName(typ=StatesErrorNameType.StatesRuntime), + event_type=HistoryEventType.ExecutionFailed, + event_details=EventDetails( + executionFailedEventDetails=ExecutionFailedEventDetails( + error=StatesErrorNameType.StatesRuntime.to_name(), + cause="The activity activity_arn does not exist.", + ) + ), + ) + raise FailureEventException(failure_event=failure_event) + + # Log the task is scheduled. + scheduled_event_details = ActivityScheduledEventDetails( + resource=self.resource.resource_arn, + input=activity_task_input, + inputDetails=HistoryEventExecutionDataDetails( + truncated=False # Always False for api calls. + ), + ) + if timeout_seconds != TimeoutSeconds.DEFAULT_TIMEOUT_SECONDS: + scheduled_event_details["timeoutInSeconds"] = timeout_seconds + if heartbeat_seconds is not None: + scheduled_event_details["heartbeatInSeconds"] = heartbeat_seconds + env.event_manager.add_event( + context=env.event_history_context, + event_type=HistoryEventType.ActivityScheduled, + event_details=EventDetails( + activityScheduledEventDetails=scheduled_event_details + ), + ) + + # Await for the task to be sampled with timeout. + activity_task_start_endpoint = ( + callback_endpoint.get_activity_task_start_endpoint() + ) + task_start_outcome = activity_task_start_endpoint.wait( + timeout_seconds=timeout_seconds + ) + # Log the task was sampled or timeout error if not. + if isinstance(task_start_outcome, ActivityTaskStartOutcome): + started_event_details = ActivityStartedEventDetails() + if task_start_outcome.worker_name is not None: + started_event_details["workerName"] = task_start_outcome.worker_name + env.event_manager.add_event( + context=env.event_history_context, + event_type=HistoryEventType.ActivityStarted, + event_details=EventDetails( + activityStartedEventDetails=started_event_details + ), + ) + else: + raise EvalTimeoutError() + + # Await for the task outcome, with a heartbeat or timeout strategy. + outcome = None + if heartbeat_seconds is None: + # Total timeout is already handled upstream. Here we specify a timeout to allow this child operation to + # terminate gracefully sooner. This is why we don't compute the residual outcome. + outcome = callback_endpoint.wait(timeout=timeout_seconds) + else: + heartbeat_endpoint = callback_endpoint.setup_heartbeat_endpoint( + heartbeat_seconds=heartbeat_seconds + ) + while ( + env.is_running() and outcome is None + ): # Until subprocess hasn't timed out or result wasn't received. + received = heartbeat_endpoint.clear_and_wait() + if not received and env.is_running(): # Heartbeat timed out. + raise HeartbeatTimeoutError() + outcome = callback_endpoint.get_outcome() + + if outcome is None: + raise CallbackTimeoutError() + if isinstance(outcome, CallbackOutcomeSuccess): + outcome_output = json.loads(outcome.output) + env.stack.append(outcome_output) + elif isinstance(outcome, CallbackOutcomeFailure): + raise CallbackOutcomeFailureError(callback_outcome_failure=outcome) + else: + raise NotImplementedError( + f"Unsupported CallbackOutcome type '{type(outcome)}'." + ) + + env.event_manager.add_event( + context=env.event_history_context, + event_type=HistoryEventType.ActivitySucceeded, + event_details=EventDetails( + activitySucceededEventDetails=ActivitySucceededEventDetails( + output=outcome.output, + outputDetails=HistoryEventExecutionDataDetails( + truncated=False # Always False for api calls. + ), + ) + ), + ) diff --git a/moto/stepfunctions/parser/asl/component/state/exec/state_task/state_task_factory.py b/moto/stepfunctions/parser/asl/component/state/exec/state_task/state_task_factory.py index 8a30686f5f1a..35019bc02614 100644 --- a/moto/stepfunctions/parser/asl/component/state/exec/state_task/state_task_factory.py +++ b/moto/stepfunctions/parser/asl/component/state/exec/state_task/state_task_factory.py @@ -1,4 +1,5 @@ from moto.stepfunctions.parser.asl.component.state.exec.state_task.service.resource import ( + ActivityResource, LambdaResource, Resource, ServiceResource, @@ -9,6 +10,9 @@ from moto.stepfunctions.parser.asl.component.state.exec.state_task.state_task import ( StateTask, ) +from moto.stepfunctions.parser.asl.component.state.exec.state_task.state_task_activitiy import ( + StateTaskActivity, +) from moto.stepfunctions.parser.asl.component.state.exec.state_task.state_task_lambda import ( StateTaskLambda, ) @@ -17,10 +21,12 @@ def state_task_for(resource: Resource) -> StateTask: if not resource: raise ValueError("No Resource declaration in State Task.") - if isinstance(resource, LambdaResource): - state = StateTaskLambda() - elif isinstance(resource, ServiceResource): + if isinstance(resource, ServiceResource): state = state_task_service_for(service_name=resource.service_name) + elif isinstance(resource, LambdaResource): + state = StateTaskLambda() + elif isinstance(resource, ActivityResource): + state = StateTaskActivity() else: raise NotImplementedError( f"Resource of type '{type(resource)}' are not supported: '{resource}'." diff --git a/moto/stepfunctions/parser/asl/component/state/exec/state_task/state_task_lambda.py b/moto/stepfunctions/parser/asl/component/state/exec/state_task/state_task_lambda.py index 1d8c1060ea82..66cc60a200d2 100644 --- a/moto/stepfunctions/parser/asl/component/state/exec/state_task/state_task_lambda.py +++ b/moto/stepfunctions/parser/asl/component/state/exec/state_task/state_task_lambda.py @@ -1,3 +1,7 @@ +import json +import logging +from typing import Any + from botocore.exceptions import ClientError from moto.stepfunctions.parser.api import ( @@ -7,12 +11,14 @@ LambdaFunctionScheduledEventDetails, LambdaFunctionSucceededEventDetails, LambdaFunctionTimedOutEventDetails, + TaskCredentials, ) from moto.stepfunctions.parser.asl.component.common.error_name.custom_error_name import ( CustomErrorName, ) from moto.stepfunctions.parser.asl.component.common.error_name.failure_event import ( FailureEvent, + FailureEventException, ) from moto.stepfunctions.parser.asl.component.common.error_name.states_error_name import ( StatesErrorName, @@ -23,6 +29,9 @@ from moto.stepfunctions.parser.asl.component.state.exec.state_task import ( lambda_eval_utils, ) +from moto.stepfunctions.parser.asl.component.state.exec.state_task.credentials import ( + Credentials, +) from moto.stepfunctions.parser.asl.component.state.exec.state_task.service.resource import ( LambdaResource, ResourceRuntimePart, @@ -33,6 +42,9 @@ from moto.stepfunctions.parser.asl.eval.environment import Environment from moto.stepfunctions.parser.asl.eval.event.event_detail import EventDetails from moto.stepfunctions.parser.asl.utils.encoding import to_json_str +from moto.stepfunctions.parser.quotas import is_within_size_quota + +LOG = logging.getLogger(__name__) class StateTaskLambda(StateTask): @@ -41,6 +53,7 @@ class StateTaskLambda(StateTask): def _from_error(self, env: Environment, ex: Exception) -> FailureEvent: if isinstance(ex, TimeoutError): return FailureEvent( + env=env, error_name=StatesErrorName(typ=StatesErrorNameType.StatesTimeout), event_type=HistoryEventType.LambdaFunctionTimedOut, event_details=EventDetails( @@ -49,19 +62,30 @@ def _from_error(self, env: Environment, ex: Exception) -> FailureEvent: ) ), ) + if isinstance(ex, FailureEventException): + return ex.failure_event error = "Exception" - if isinstance(ex, lambda_eval_utils.LambdaFunctionErrorException): + if isinstance(ex, ClientError): error_name = CustomErrorName(error) + cause = ex.response["Error"]["Message"] + elif isinstance(ex, lambda_eval_utils.LambdaFunctionErrorException): cause = ex.payload - elif isinstance(ex, ClientError): + try: + cause_object = json.loads(cause) + error = cause_object["errorType"] + except Exception as ex: + LOG.warning( + "Could not retrieve 'errorType' field from LambdaFunctionErrorException object: %s", + ex, + ) error_name = CustomErrorName(error) - cause = ex.response["Error"]["Message"] else: error_name = StatesErrorName(StatesErrorNameType.StatesTaskFailed) cause = str(ex) return FailureEvent( + env=env, error_name=error_name, event_type=HistoryEventType.LambdaFunctionFailed, event_details=EventDetails( @@ -72,19 +96,43 @@ def _from_error(self, env: Environment, ex: Exception) -> FailureEvent: ), ) + def _verify_size_quota(self, env: Environment, value: Any) -> None: + is_within: bool = is_within_size_quota(value=value) + if is_within: + return + error_type = StatesErrorNameType.StatesStatesDataLimitExceeded + cause = ( + f"The state/task '{self.resource.resource_arn}' returned a result " + "with a size exceeding the maximum number of bytes service limit." + ) + raise FailureEventException( + failure_event=FailureEvent( + env=env, + error_name=StatesErrorName(typ=error_type), + event_type=HistoryEventType.LambdaFunctionFailed, + event_details=EventDetails( + lambdaFunctionFailedEventDetails=LambdaFunctionFailedEventDetails( + error=error_type.to_name(), + cause=cause, + ) + ), + ) + ) + def _eval_parameters(self, env: Environment) -> dict: - if self.parameters: - self.parameters.eval(env=env) + if self.parargs: + self.parargs.eval(env=env) + payload = env.stack.pop() parameters = dict( FunctionName=self.resource.resource_arn, - InvocationType="RequestResponse", Payload=payload, ) return parameters def _eval_execution(self, env: Environment) -> None: parameters = self._eval_parameters(env=env) + task_credentials = self._eval_credentials(env=env) payload = parameters["Payload"] scheduled_event_details = LambdaFunctionScheduledEventDetails( @@ -98,17 +146,23 @@ def _eval_execution(self, env: Environment) -> None: self.timeout.eval(env=env) timeout_seconds = env.stack.pop() scheduled_event_details["timeoutInSeconds"] = timeout_seconds - env.event_history.add_event( + if self.credentials: + scheduled_event_details["taskCredentials"] = TaskCredentials( + roleArn=Credentials.get_role_arn_from( + computed_credentials=task_credentials + ) + ) + env.event_manager.add_event( context=env.event_history_context, - hist_type_event=HistoryEventType.LambdaFunctionScheduled, - event_detail=EventDetails( + event_type=HistoryEventType.LambdaFunctionScheduled, + event_details=EventDetails( lambdaFunctionScheduledEventDetails=scheduled_event_details ), ) - env.event_history.add_event( + env.event_manager.add_event( context=env.event_history_context, - hist_type_event=HistoryEventType.LambdaFunctionStarted, + event_type=HistoryEventType.LambdaFunctionStarted, ) self.resource.eval(env=env) @@ -120,17 +174,20 @@ def _eval_execution(self, env: Environment) -> None: parameters=parameters, region=resource_runtime_part.region, account=resource_runtime_part.account, + credentials=task_credentials, ) # In lambda invocations, only payload is passed on as output. output = env.stack.pop() + self._verify_size_quota(env=env, value=output) + output_payload = output["Payload"] env.stack.append(output_payload) - env.event_history.add_event( + env.event_manager.add_event( context=env.event_history_context, - hist_type_event=HistoryEventType.LambdaFunctionSucceeded, - event_detail=EventDetails( + event_type=HistoryEventType.LambdaFunctionSucceeded, + event_details=EventDetails( lambdaFunctionSucceededEventDetails=LambdaFunctionSucceededEventDetails( output=to_json_str(output_payload), outputDetails=HistoryEventExecutionDataDetails( diff --git a/moto/stepfunctions/parser/asl/component/state/fail/cause_decl.py b/moto/stepfunctions/parser/asl/component/state/fail/cause_decl.py index 941a4b3ac6ca..01365d46540e 100644 --- a/moto/stepfunctions/parser/asl/component/state/fail/cause_decl.py +++ b/moto/stepfunctions/parser/asl/component/state/fail/cause_decl.py @@ -1,14 +1,99 @@ -from typing import Final +import abc +import copy +from typing import Set +from moto.stepfunctions.parser.asl.component.common.jsonata.jsonata_template_value_terminal import ( + JSONataTemplateValueTerminalExpression, +) +from moto.stepfunctions.parser.asl.component.common.variable_sample import ( + VariableSample, +) from moto.stepfunctions.parser.asl.component.eval_component import EvalComponent +from moto.stepfunctions.parser.asl.component.intrinsic.function.function import Function +from moto.stepfunctions.parser.asl.component.intrinsic.functionname.state_function_name_types import ( + StatesFunctionNameType, +) from moto.stepfunctions.parser.asl.eval.environment import Environment +from moto.stepfunctions.parser.asl.parse.intrinsic.intrinsic_parser import ( + IntrinsicParser, +) +from moto.stepfunctions.parser.asl.utils.json_path import extract_json -class CauseDecl(EvalComponent): - value: Final[str] +class CauseDecl(EvalComponent, abc.ABC): ... + + +class CauseConst(CauseDecl): + value: str def __init__(self, value: str): self.value = value def _eval_body(self, env: Environment) -> None: env.stack.append(self.value) + + +class CauseJSONata(CauseDecl): + def __init__( + self, + jsonata_template_value_terminal_expression: JSONataTemplateValueTerminalExpression, + ): + super().__init__() + self.jsonata_template_value_terminal_expression = ( + jsonata_template_value_terminal_expression + ) + + def _eval_body(self, env: Environment) -> None: + self.jsonata_template_value_terminal_expression.eval(env=env) + + +class CauseVar(CauseDecl): + variable_sample: VariableSample + + def __init__(self, variable_sample: VariableSample): + self.variable_sample = variable_sample + + def _eval_body(self, env: Environment) -> None: + self.variable_sample.eval(env=env) + + +_STRING_RETURN_FUNCTIONS: Set[str] = { + typ.name() + for typ in [ + StatesFunctionNameType.Format, + StatesFunctionNameType.JsonToString, + StatesFunctionNameType.ArrayGetItem, + StatesFunctionNameType.Base64Decode, + StatesFunctionNameType.Base64Encode, + StatesFunctionNameType.Hash, + StatesFunctionNameType.UUID, + ] +} + + +class CausePathJsonPath(CauseConst): + def _eval_body(self, env: Environment) -> None: + current_output = env.stack[-1] + cause = extract_json(self.value, current_output) + env.stack.append(cause) + + +class CausePathContextObject(CauseConst): + def _eval_body(self, env: Environment) -> None: + value = extract_json(self.value, env.states.context_object.context_object_data) + env.stack.append(copy.deepcopy(value)) + + +class CausePathIntrinsicFunction(CauseConst): + function: Function + + def __init__(self, value: str) -> None: + super().__init__(value=value) + self.function, _ = IntrinsicParser.parse(value) + if self.function.name.name not in _STRING_RETURN_FUNCTIONS: + raise ValueError( + f"Unsupported Intrinsic Function for CausePath declaration: '{self.value}'." + ) + + def _eval_body(self, env: Environment) -> None: + self.function.eval(env=env) diff --git a/moto/stepfunctions/parser/asl/component/state/fail/cause_path.py b/moto/stepfunctions/parser/asl/component/state/fail/cause_path.py deleted file mode 100644 index b1e6ad8645e5..000000000000 --- a/moto/stepfunctions/parser/asl/component/state/fail/cause_path.py +++ /dev/null @@ -1,50 +0,0 @@ -from typing import Final - -from moto.stepfunctions.parser.asl.component.intrinsic.function.function import Function -from moto.stepfunctions.parser.asl.component.intrinsic.functionname.state_function_name_types import ( - StatesFunctionNameType, -) -from moto.stepfunctions.parser.asl.component.state.fail.cause_decl import CauseDecl -from moto.stepfunctions.parser.asl.eval.environment import Environment -from moto.stepfunctions.parser.asl.parse.intrinsic.intrinsic_parser import ( - IntrinsicParser, -) -from moto.stepfunctions.parser.asl.utils.json_path import JSONPathUtils - -_STRING_RETURN_FUNCTIONS = { - typ.name() - for typ in [ - StatesFunctionNameType.Format, - StatesFunctionNameType.JsonToString, - StatesFunctionNameType.ArrayGetItem, - StatesFunctionNameType.Base64Decode, - StatesFunctionNameType.Base64Encode, - StatesFunctionNameType.Hash, - StatesFunctionNameType.UUID, - ] -} - - -class CausePath(CauseDecl): ... - - -class CausePathJsonPath(CausePath): - def _eval_body(self, env: Environment) -> None: - current_output = env.stack[-1] - cause = JSONPathUtils.extract_json(self.value, current_output) - env.stack.append(cause) - - -class CausePathIntrinsicFunction(CausePath): - function: Final[Function] - - def __init__(self, value: str) -> None: - super().__init__(value=value) - self.function = IntrinsicParser.parse(value) - if self.function.name.name not in _STRING_RETURN_FUNCTIONS: - raise ValueError( - f"Unsupported Intrinsic Function for CausePath declaration: '{self.value}'." - ) - - def _eval_body(self, env: Environment) -> None: - self.function.eval(env=env) diff --git a/moto/stepfunctions/parser/asl/component/state/fail/error_decl.py b/moto/stepfunctions/parser/asl/component/state/fail/error_decl.py index cc9dc94ed2ea..b6ee97797a76 100644 --- a/moto/stepfunctions/parser/asl/component/state/fail/error_decl.py +++ b/moto/stepfunctions/parser/asl/component/state/fail/error_decl.py @@ -1,14 +1,99 @@ -from typing import Final +import abc +import copy +from typing import Set +from moto.stepfunctions.parser.asl.component.common.jsonata.jsonata_template_value_terminal import ( + JSONataTemplateValueTerminalExpression, +) +from moto.stepfunctions.parser.asl.component.common.variable_sample import ( + VariableSample, +) from moto.stepfunctions.parser.asl.component.eval_component import EvalComponent +from moto.stepfunctions.parser.asl.component.intrinsic.function.function import Function +from moto.stepfunctions.parser.asl.component.intrinsic.functionname.state_function_name_types import ( + StatesFunctionNameType, +) from moto.stepfunctions.parser.asl.eval.environment import Environment +from moto.stepfunctions.parser.asl.parse.intrinsic.intrinsic_parser import ( + IntrinsicParser, +) +from moto.stepfunctions.parser.asl.utils.json_path import extract_json -class ErrorDecl(EvalComponent): - value: Final[str] +class ErrorDecl(EvalComponent, abc.ABC): ... + + +class ErrorConst(ErrorDecl): + value: str def __init__(self, value: str): self.value = value def _eval_body(self, env: Environment) -> None: env.stack.append(self.value) + + +class ErrorVar(ErrorDecl): + variable_sample: VariableSample + + def __init__(self, variable_sample: VariableSample): + self.variable_sample = variable_sample + + def _eval_body(self, env: Environment) -> None: + self.variable_sample.eval(env=env) + + +class ErrorJSONata(ErrorDecl): + def __init__( + self, + jsonata_template_value_terminal_expression: JSONataTemplateValueTerminalExpression, + ): + super().__init__() + self.jsonata_template_value_terminal_expression = ( + jsonata_template_value_terminal_expression + ) + + def _eval_body(self, env: Environment) -> None: + self.jsonata_template_value_terminal_expression.eval(env=env) + + +_STRING_RETURN_FUNCTIONS: Set[str] = { + typ.name() + for typ in [ + StatesFunctionNameType.Format, + StatesFunctionNameType.JsonToString, + StatesFunctionNameType.ArrayGetItem, + StatesFunctionNameType.Base64Decode, + StatesFunctionNameType.Base64Encode, + StatesFunctionNameType.Hash, + StatesFunctionNameType.UUID, + ] +} + + +class ErrorPathJsonPath(ErrorConst): + def _eval_body(self, env: Environment) -> None: + current_output = env.stack[-1] + cause = extract_json(self.value, current_output) + env.stack.append(cause) + + +class ErrorPathContextObject(ErrorConst): + def _eval_body(self, env: Environment) -> None: + value = extract_json(self.value, env.states.context_object.context_object_data) + env.stack.append(copy.deepcopy(value)) + + +class ErrorPathIntrinsicFunction(ErrorConst): + function: Function + + def __init__(self, value: str) -> None: + super().__init__(value=value) + self.function, _ = IntrinsicParser.parse(value) + if self.function.name.name not in _STRING_RETURN_FUNCTIONS: + raise ValueError( + f"Unsupported Intrinsic Function for ErrorPath declaration: '{self.value}'." + ) + + def _eval_body(self, env: Environment) -> None: + self.function.eval(env=env) diff --git a/moto/stepfunctions/parser/asl/component/state/fail/error_path.py b/moto/stepfunctions/parser/asl/component/state/fail/error_path.py deleted file mode 100644 index a149cdf5601b..000000000000 --- a/moto/stepfunctions/parser/asl/component/state/fail/error_path.py +++ /dev/null @@ -1,50 +0,0 @@ -from typing import Final - -from moto.stepfunctions.parser.asl.component.intrinsic.function.function import Function -from moto.stepfunctions.parser.asl.component.intrinsic.functionname.state_function_name_types import ( - StatesFunctionNameType, -) -from moto.stepfunctions.parser.asl.component.state.fail.error_decl import ErrorDecl -from moto.stepfunctions.parser.asl.eval.environment import Environment -from moto.stepfunctions.parser.asl.parse.intrinsic.intrinsic_parser import ( - IntrinsicParser, -) -from moto.stepfunctions.parser.asl.utils.json_path import JSONPathUtils - -_STRING_RETURN_FUNCTIONS = { - typ.name() - for typ in [ - StatesFunctionNameType.Format, - StatesFunctionNameType.JsonToString, - StatesFunctionNameType.ArrayGetItem, - StatesFunctionNameType.Base64Decode, - StatesFunctionNameType.Base64Encode, - StatesFunctionNameType.Hash, - StatesFunctionNameType.UUID, - ] -} - - -class ErrorPath(ErrorDecl): ... - - -class ErrorPathJsonPath(ErrorPath): - def _eval_body(self, env: Environment) -> None: - current_output = env.stack[-1] - cause = JSONPathUtils.extract_json(self.value, current_output) - env.stack.append(cause) - - -class ErrorPathIntrinsicFunction(ErrorPath): - function: Final[Function] - - def __init__(self, value: str) -> None: - super().__init__(value=value) - self.function = IntrinsicParser.parse(value) - if self.function.name.name not in _STRING_RETURN_FUNCTIONS: - raise ValueError( - f"Unsupported Intrinsic Function for ErrorPath declaration: '{self.value}'." - ) - - def _eval_body(self, env: Environment) -> None: - self.function.eval(env=env) diff --git a/moto/stepfunctions/parser/asl/component/state/fail/state_fail.py b/moto/stepfunctions/parser/asl/component/state/fail/state_fail.py index 44edde6794ab..2666cf8db87e 100644 --- a/moto/stepfunctions/parser/asl/component/state/fail/state_fail.py +++ b/moto/stepfunctions/parser/asl/component/state/fail/state_fail.py @@ -8,14 +8,13 @@ FailureEvent, FailureEventException, ) +from moto.stepfunctions.parser.asl.component.state.fail.cause_decl import CauseDecl +from moto.stepfunctions.parser.asl.component.state.fail.error_decl import ErrorDecl from moto.stepfunctions.parser.asl.component.state.state import CommonStateField from moto.stepfunctions.parser.asl.component.state.state_props import StateProps from moto.stepfunctions.parser.asl.eval.environment import Environment from moto.stepfunctions.parser.asl.eval.event.event_detail import EventDetails -from .cause_decl import CauseDecl -from .error_decl import ErrorDecl - class StateFail(CommonStateField): def __init__(self): @@ -33,6 +32,7 @@ def from_state_props(self, state_props: StateProps) -> None: def _eval_state(self, env: Environment) -> None: task_failed_event_details = TaskFailedEventDetails() + error_value = None if self.error: self.error.eval(env=env) @@ -46,6 +46,7 @@ def _eval_state(self, env: Environment) -> None: error_name = CustomErrorName(error_value) if error_value else None failure_event = FailureEvent( + env=env, error_name=error_name, event_type=HistoryEventType.TaskFailed, event_details=EventDetails( diff --git a/moto/stepfunctions/parser/asl/component/state/state.py b/moto/stepfunctions/parser/asl/component/state/state.py index 52d407fffeba..e58afa1519c5 100644 --- a/moto/stepfunctions/parser/asl/component/state/state.py +++ b/moto/stepfunctions/parser/asl/component/state/state.py @@ -4,19 +4,45 @@ import datetime import logging from abc import ABC -from typing import Final, Optional +from typing import Any, Optional from moto.stepfunctions.parser.api import ( + ExecutionFailedEventDetails, HistoryEventExecutionDataDetails, HistoryEventType, StateEnteredEventDetails, StateExitedEventDetails, ) +from moto.stepfunctions.parser.asl.component.common.assign.assign_decl import AssignDecl +from moto.stepfunctions.parser.asl.component.common.catch.catch_outcome import ( + CatchOutcome, +) from moto.stepfunctions.parser.asl.component.common.comment import Comment +from moto.stepfunctions.parser.asl.component.common.error_name.failure_event import ( + FailureEvent, + FailureEventException, +) +from moto.stepfunctions.parser.asl.component.common.error_name.states_error_name import ( + StatesErrorName, +) +from moto.stepfunctions.parser.asl.component.common.error_name.states_error_name_type import ( + StatesErrorNameType, +) from moto.stepfunctions.parser.asl.component.common.flow.end import End from moto.stepfunctions.parser.asl.component.common.flow.next import Next -from moto.stepfunctions.parser.asl.component.common.path.input_path import InputPath -from moto.stepfunctions.parser.asl.component.common.path.output_path import OutputPath +from moto.stepfunctions.parser.asl.component.common.outputdecl import Output +from moto.stepfunctions.parser.asl.component.common.path.input_path import ( + InputPath, + InputPathBase, +) +from moto.stepfunctions.parser.asl.component.common.path.output_path import ( + OutputPath, + OutputPathBase, +) +from moto.stepfunctions.parser.asl.component.common.query_language import ( + QueryLanguage, + QueryLanguageMode, +) from moto.stepfunctions.parser.asl.component.eval_component import EvalComponent from moto.stepfunctions.parser.asl.component.state.state_continue_with import ( ContinueWith, @@ -25,11 +51,12 @@ ) from moto.stepfunctions.parser.asl.component.state.state_props import StateProps from moto.stepfunctions.parser.asl.component.state.state_type import StateType -from moto.stepfunctions.parser.asl.eval.contextobject.contex_object import State from moto.stepfunctions.parser.asl.eval.environment import Environment from moto.stepfunctions.parser.asl.eval.event.event_detail import EventDetails from moto.stepfunctions.parser.asl.eval.program_state import ProgramRunning +from moto.stepfunctions.parser.asl.eval.states import StateData from moto.stepfunctions.parser.asl.utils.encoding import to_json_str +from moto.stepfunctions.parser.quotas import is_within_size_quota LOG = logging.getLogger(__name__) @@ -37,6 +64,8 @@ class CommonStateField(EvalComponent, ABC): name: str + query_language: QueryLanguage + # The state's type. state_type: StateType @@ -44,31 +73,38 @@ class CommonStateField(EvalComponent, ABC): # be used in a state. Some state types, such as Choice, don't support or use the End field. continue_with: ContinueWith + # Holds a human-readable description of the state. + comment: Optional[Comment] + + # A path that selects a portion of the state's input to be passed to the state's state_task for processing. + # If omitted, it has the value $ which designates the entire input. + input_path: Optional[InputPath] + + # A path that selects a portion of the state's output to be passed to the next state. + # If omitted, it has the value $ which designates the entire output. + output_path: Optional[OutputPath] + + assign_decl: Optional[AssignDecl] + + output: Optional[Output] + + state_entered_event_type: HistoryEventType + state_exited_event_type: Optional[HistoryEventType] + def __init__( self, state_entered_event_type: HistoryEventType, state_exited_event_type: Optional[HistoryEventType], ): - # Holds a human-readable description of the state. - self.comment: Optional[Comment] = None - - # A path that selects a portion of the state's input to be passed to the state's state_task for processing. - # If omitted, it has the value $ which designates the entire input. - self.input_path: InputPath = InputPath(InputPath.DEFAULT_PATH) - - # A path that selects a portion of the state's output to be passed to the next state. - # If omitted, it has the value $ which designates the entire output. - self.output_path: OutputPath = OutputPath(OutputPath.DEFAULT_PATH) - - self.state_entered_event_type: Final[HistoryEventType] = ( - state_entered_event_type - ) - self.state_exited_event_type: Final[Optional[HistoryEventType]] = ( - state_exited_event_type - ) + self.comment = None + self.input_path = InputPathBase(InputPathBase.DEFAULT_PATH) + self.output_path = OutputPathBase(OutputPathBase.DEFAULT_PATH) + self.state_entered_event_type = state_entered_event_type + self.state_exited_event_type = state_exited_event_type def from_state_props(self, state_props: StateProps) -> None: self.name = state_props.name + self.query_language = state_props.get(QueryLanguage) or QueryLanguage() self.state_type = state_props.get(StateType) self.continue_with = ( ContinueWithEnd() @@ -76,16 +112,25 @@ def from_state_props(self, state_props: StateProps) -> None: else ContinueWithNext(state_props.get(Next)) ) self.comment = state_props.get(Comment) - self.input_path = state_props.get(InputPath) or InputPath( - InputPath.DEFAULT_PATH - ) - self.output_path = state_props.get(OutputPath) or OutputPath( - OutputPath.DEFAULT_PATH - ) + self.assign_decl = state_props.get(AssignDecl) + # JSONPath sub-productions. + if self.query_language.query_language_mode == QueryLanguageMode.JSONPath: + self.input_path = state_props.get(InputPath) or InputPathBase( + InputPathBase.DEFAULT_PATH + ) + self.output_path = state_props.get(OutputPath) or OutputPathBase( + OutputPathBase.DEFAULT_PATH + ) + self.output = None + # JSONata sub-productions. + else: + self.input_path = None + self.output_path = None + self.output = state_props.get(Output) def _set_next(self, env: Environment) -> None: if env.next_state_name != self.name: - # Next was already overriden. + # Next was already overridden. return if isinstance(self.continue_with, ContinueWithNext): @@ -96,15 +141,18 @@ def _set_next(self, env: Environment) -> None: env.set_ended() else: LOG.error( - f"Could not handle ContinueWith type of '{type(self.continue_with)}'." + "Could not handle ContinueWith type of '%s'.", type(self.continue_with) ) + def _is_language_query_jsonpath(self) -> bool: + return self.query_language.query_language_mode == QueryLanguageMode.JSONPath + def _get_state_entered_event_details( self, env: Environment ) -> StateEnteredEventDetails: return StateEnteredEventDetails( name=self.name, - input=to_json_str(env.inp, separators=(",", ":")), + input=to_json_str(env.states.get_input(), separators=(",", ":")), inputDetails=HistoryEventExecutionDataDetails( truncated=False # Always False for api calls. ), @@ -113,27 +161,57 @@ def _get_state_entered_event_details( def _get_state_exited_event_details( self, env: Environment ) -> StateExitedEventDetails: - return StateExitedEventDetails( + event_details = StateExitedEventDetails( name=self.name, - output=to_json_str(env.inp, separators=(",", ":")), + output=to_json_str(env.states.get_input(), separators=(",", ":")), outputDetails=HistoryEventExecutionDataDetails( truncated=False # Always False for api calls. ), ) + # TODO add typing when these become available in boto. + assigned_variables = env.variable_store.get_assigned_variables() + env.variable_store.reset_tracing() + if assigned_variables: + event_details["assignedVariables"] = assigned_variables # noqa + event_details["assignedVariablesDetails"] = {"truncated": False} # noqa + return event_details + + def _verify_size_quota(self, env: Environment, value: Any) -> None: + is_within: bool = is_within_size_quota(value) + if is_within: + return + error_type = StatesErrorNameType.StatesStatesDataLimitExceeded + cause = ( + f"The state/task '{self.name}' returned a result with a size exceeding " + f"the maximum number of bytes service limit." + ) + raise FailureEventException( + failure_event=FailureEvent( + env=env, + error_name=StatesErrorName(typ=error_type), + event_type=HistoryEventType.TaskFailed, + event_details=EventDetails( + executionFailedEventDetails=ExecutionFailedEventDetails( + error=error_type.to_name(), + cause=cause, + ) + ), + ) + ) @abc.abstractmethod def _eval_state(self, env: Environment) -> None: ... def _eval_body(self, env: Environment) -> None: - env.event_history.add_event( + env.event_manager.add_event( context=env.event_history_context, - hist_type_event=self.state_entered_event_type, - event_detail=EventDetails( + event_type=self.state_entered_event_type, + event_details=EventDetails( stateEnteredEventDetails=self._get_state_entered_event_details(env=env) ), ) - env.context_object_manager.context_object["State"] = State( + env.states.context_object.context_object_data["State"] = StateData( EnteredTime=datetime.datetime.now(tz=datetime.timezone.utc).isoformat(), Name=self.name, ) @@ -141,6 +219,8 @@ def _eval_body(self, env: Environment) -> None: # Filter the input onto the stack. if self.input_path: self.input_path.eval(env) + else: + env.stack.append(env.states.get_input()) # Exec the state's logic. self._eval_state(env) @@ -148,20 +228,34 @@ def _eval_body(self, env: Environment) -> None: if not isinstance(env.program_state(), ProgramRunning): return - # Filter the input onto the input. - if self.output_path: - self.output_path.eval(env) + # Obtain a reference to the state output. + output = env.stack[-1] + + # CatcherOutputs (i.e. outputs of Catch blocks) are never subjects of output normalisers, + # the entire value is instead passed by value as input to the next state, or program output. + if not isinstance(output, CatchOutcome): + # Ensure the state's output is within state size quotas. + self._verify_size_quota(env=env, value=output) + + # Process output value as next state input. + if self.output_path: + self.output_path.eval(env=env) + elif self.output: + self.output.eval(env=env) + else: + current_output = env.stack.pop() + env.states.reset(input_value=current_output) + + # Set next state or halt (end). + self._set_next(env) if self.state_exited_event_type is not None: - env.event_history.add_event( + env.event_manager.add_event( context=env.event_history_context, - hist_type_event=self.state_exited_event_type, - event_detail=EventDetails( + event_type=self.state_exited_event_type, + event_details=EventDetails( stateExitedEventDetails=self._get_state_exited_event_details( env=env ), ), ) - - # Set next state or halt (end). - self._set_next(env) diff --git a/moto/stepfunctions/parser/asl/component/state/state_pass/result.py b/moto/stepfunctions/parser/asl/component/state/state_pass/result.py index b9d6edea488a..224ec3d415f9 100644 --- a/moto/stepfunctions/parser/asl/component/state/state_pass/result.py +++ b/moto/stepfunctions/parser/asl/component/state/state_pass/result.py @@ -1,8 +1,14 @@ import json -from moto.stepfunctions.parser.asl.component.component import Component +from moto.stepfunctions.parser.asl.component.eval_component import EvalComponent +from moto.stepfunctions.parser.asl.eval.environment import Environment -class Result(Component): +class Result(EvalComponent): + result_obj: json + def __init__(self, result_obj: json): - self.result_obj: json = result_obj + self.result_obj = result_obj + + def _eval_body(self, env: Environment) -> None: + env.stack.append(self.result_obj) diff --git a/moto/stepfunctions/parser/asl/component/state/state_pass/state_pass.py b/moto/stepfunctions/parser/asl/component/state/state_pass/state_pass.py index 106845a23097..ef638957579f 100644 --- a/moto/stepfunctions/parser/asl/component/state/state_pass/state_pass.py +++ b/moto/stepfunctions/parser/asl/component/state/state_pass/state_pass.py @@ -1,18 +1,14 @@ from typing import Optional from moto.stepfunctions.parser.api import ( - HistoryEventExecutionDataDetails, HistoryEventType, - StateEnteredEventDetails, - StateExitedEventDetails, ) -from moto.stepfunctions.parser.asl.component.common.parameters import Parameters +from moto.stepfunctions.parser.asl.component.common.parargs import Parameters, Parargs from moto.stepfunctions.parser.asl.component.common.path.result_path import ResultPath from moto.stepfunctions.parser.asl.component.state.state import CommonStateField from moto.stepfunctions.parser.asl.component.state.state_pass.result import Result from moto.stepfunctions.parser.asl.component.state.state_props import StateProps from moto.stepfunctions.parser.asl.eval.environment import Environment -from moto.stepfunctions.parser.asl.utils.encoding import to_json_str class StatePass(CommonStateField): @@ -43,36 +39,21 @@ def from_state_props(self, state_props: StateProps) -> None: self.result_path = state_props.get(ResultPath) or ResultPath( result_path_src=ResultPath.DEFAULT_PATH ) - self.parameters = state_props.get(Parameters) - - def _get_state_entered_event_details( - self, env: Environment - ) -> StateEnteredEventDetails: - return StateEnteredEventDetails( - name=self.name, - input=to_json_str(env.inp, separators=(",", ":")), - inputDetails=HistoryEventExecutionDataDetails( - truncated=False # Always False for api calls. - ), - ) - - def _get_state_exited_event_details( - self, env: Environment - ) -> StateExitedEventDetails: - return StateExitedEventDetails( - name=self.name, - output=to_json_str(env.inp, separators=(",", ":")), - outputDetails=HistoryEventExecutionDataDetails( - truncated=False # Always False for api calls. - ), - ) + self.parameters = state_props.get(Parargs) def _eval_state(self, env: Environment) -> None: if self.parameters: self.parameters.eval(env=env) if self.result: - env.stack.append(self.result.result_obj) + self.result.eval(env=env) + + if not self._is_language_query_jsonpath(): + output_value = env.stack[-1] + env.states.set_result(output_value) + + if self.assign_decl: + self.assign_decl.eval(env=env) if self.result_path: self.result_path.eval(env) diff --git a/moto/stepfunctions/parser/asl/component/state/state_props.py b/moto/stepfunctions/parser/asl/component/state/state_props.py index daa30861dcad..9a0aa655c07d 100644 --- a/moto/stepfunctions/parser/asl/component/state/state_props.py +++ b/moto/stepfunctions/parser/asl/component/state/state_props.py @@ -1,15 +1,32 @@ -from typing import Any +from typing import Any, Set from moto.stepfunctions.parser.asl.component.common.flow.end import End from moto.stepfunctions.parser.asl.component.common.flow.next import Next +from moto.stepfunctions.parser.asl.component.common.parargs import Parargs +from moto.stepfunctions.parser.asl.component.common.path.input_path import InputPath +from moto.stepfunctions.parser.asl.component.common.path.items_path import ItemsPath +from moto.stepfunctions.parser.asl.component.common.path.output_path import OutputPath from moto.stepfunctions.parser.asl.component.common.timeouts.heartbeat import Heartbeat from moto.stepfunctions.parser.asl.component.common.timeouts.timeout import Timeout +from moto.stepfunctions.parser.asl.component.state.choice.comparison.comparison_type import ( + Comparison, +) +from moto.stepfunctions.parser.asl.component.state.choice.comparison.variable import ( + Variable, +) from moto.stepfunctions.parser.asl.component.state.exec.state_map.item_reader.reader_config.max_items_decl import ( MaxItemsDecl, ) +from moto.stepfunctions.parser.asl.component.state.exec.state_map.items.items import ( + Items, +) from moto.stepfunctions.parser.asl.component.state.exec.state_map.max_concurrency import ( MaxConcurrencyDecl, ) +from moto.stepfunctions.parser.asl.component.state.exec.state_map.tolerated_failure import ( + ToleratedFailureCountDecl, + ToleratedFailurePercentageDecl, +) from moto.stepfunctions.parser.asl.component.state.exec.state_task.service.resource import ( Resource, ) @@ -20,15 +37,24 @@ ) from moto.stepfunctions.parser.asl.parse.typed_props import TypedProps -UNIQUE_SUBINSTANCES = { +UNIQUE_SUBINSTANCES: Set[type] = { + InputPath, + Items, + ItemsPath, + OutputPath, Resource, WaitFunction, Timeout, Heartbeat, MaxItemsDecl, MaxConcurrencyDecl, + ToleratedFailureCountDecl, + ToleratedFailurePercentageDecl, ErrorDecl, CauseDecl, + Variable, + Parargs, + Comparison, } diff --git a/moto/stepfunctions/parser/asl/component/state/state_succeed/__init__.py b/moto/stepfunctions/parser/asl/component/state/state_succeed/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/moto/stepfunctions/parser/asl/component/state/state_succeed.py b/moto/stepfunctions/parser/asl/component/state/state_succeed/state_succeed.py similarity index 100% rename from moto/stepfunctions/parser/asl/component/state/state_succeed.py rename to moto/stepfunctions/parser/asl/component/state/state_succeed/state_succeed.py diff --git a/moto/stepfunctions/parser/asl/component/state/wait/state_wait.py b/moto/stepfunctions/parser/asl/component/state/wait/state_wait.py index 03c294e94c7a..824c2de00f9e 100644 --- a/moto/stepfunctions/parser/asl/component/state/wait/state_wait.py +++ b/moto/stepfunctions/parser/asl/component/state/wait/state_wait.py @@ -29,3 +29,5 @@ def from_state_props(self, state_props: StateProps) -> None: def _eval_state(self, env: Environment) -> None: self.wait_function.eval(env) + if self.assign_decl: + self.assign_decl.eval(env=env) diff --git a/moto/stepfunctions/parser/asl/component/state/wait/wait_function/seconds.py b/moto/stepfunctions/parser/asl/component/state/wait/wait_function/seconds.py index 42dca9159768..4ba834b1972f 100644 --- a/moto/stepfunctions/parser/asl/component/state/wait/wait_function/seconds.py +++ b/moto/stepfunctions/parser/asl/component/state/wait/wait_function/seconds.py @@ -1,5 +1,8 @@ from typing import Final +from moto.stepfunctions.parser.asl.component.common.jsonata.jsonata_template_value_terminal import ( + JSONataTemplateValueTerminalExpression, +) from moto.stepfunctions.parser.asl.component.state.wait.wait_function.wait_function import ( WaitFunction, ) @@ -12,7 +15,28 @@ class Seconds(WaitFunction): # field. You must specify time as a positive, integer value. def __init__(self, seconds: int): - self.seconds: Final[int] = seconds + self.seconds: int = seconds def _get_wait_seconds(self, env: Environment) -> int: return self.seconds + + +class SecondsJSONata(WaitFunction): + jsonata_template_value_terminal_expression: Final[ + JSONataTemplateValueTerminalExpression + ] + + def __init__( + self, + jsonata_template_value_terminal_expression: JSONataTemplateValueTerminalExpression, + ): + super().__init__() + self.jsonata_template_value_terminal_expression = ( + jsonata_template_value_terminal_expression + ) + + def _get_wait_seconds(self, env: Environment) -> int: + # TODO: add snapshot tests to verify AWS's behaviour about non integer values. + self.jsonata_template_value_terminal_expression.eval(env=env) + max_items: int = int(env.stack.pop()) + return max_items diff --git a/moto/stepfunctions/parser/asl/component/state/wait/wait_function/seconds_path.py b/moto/stepfunctions/parser/asl/component/state/wait/wait_function/seconds_path.py index 766fd97eca4c..72e64a479b46 100644 --- a/moto/stepfunctions/parser/asl/component/state/wait/wait_function/seconds_path.py +++ b/moto/stepfunctions/parser/asl/component/state/wait/wait_function/seconds_path.py @@ -1,11 +1,25 @@ -from typing import Final - -from jsonpath_ng import parse +from typing import Any +from moto.stepfunctions.parser.api import ExecutionFailedEventDetails, HistoryEventType +from moto.stepfunctions.parser.asl.component.common.error_name.failure_event import ( + FailureEvent, + FailureEventException, +) +from moto.stepfunctions.parser.asl.component.common.error_name.states_error_name import ( + StatesErrorName, +) +from moto.stepfunctions.parser.asl.component.common.error_name.states_error_name_type import ( + StatesErrorNameType, +) +from moto.stepfunctions.parser.asl.component.common.variable_sample import ( + VariableSample, +) from moto.stepfunctions.parser.asl.component.state.wait.wait_function.wait_function import ( WaitFunction, ) from moto.stepfunctions.parser.asl.eval.environment import Environment +from moto.stepfunctions.parser.asl.eval.event.event_detail import EventDetails +from moto.stepfunctions.parser.asl.utils.json_path import extract_json class SecondsPath(WaitFunction): @@ -15,9 +29,48 @@ class SecondsPath(WaitFunction): # You must specify an integer value for this field. def __init__(self, path: str): - self.path: Final[str] = path + self.path: str = path + + def _validate_seconds_value(self, env: Environment, seconds: Any): + if isinstance(seconds, int) and seconds >= 0: + return + error_type = StatesErrorNameType.StatesRuntime + + assignment_description = f"{self.path} == {seconds}" + if not isinstance(seconds, int): + cause = f"The SecondsPath parameter cannot be parsed as a long value: {assignment_description}" + else: # seconds < 0 + cause = f"The SecondsPath parameter references a negative value: {assignment_description}" + + raise FailureEventException( + failure_event=FailureEvent( + env=env, + error_name=StatesErrorName(typ=error_type), + event_type=HistoryEventType.ExecutionFailed, + event_details=EventDetails( + executionFailedEventDetails=ExecutionFailedEventDetails( + error=error_type.to_name(), cause=cause + ) + ), + ) + ) + + def _get_wait_seconds(self, env: Environment) -> int: + inp = env.stack[-1] + seconds = extract_json(self.path, inp) + self._validate_seconds_value(env=env, seconds=seconds) + return seconds + + +class SecondsPathVar(SecondsPath): + variable_sample: VariableSample + + def __init__(self, variable_sample: VariableSample): + super().__init__(path=variable_sample.expression) + self.variable_sample = variable_sample def _get_wait_seconds(self, env: Environment) -> int: - input_expr = parse(self.path) - seconds = input_expr.find(env.inp) + self.variable_sample.eval(env=env) + seconds = env.stack.pop() + self._validate_seconds_value(env=env, seconds=seconds) return seconds diff --git a/moto/stepfunctions/parser/asl/component/state/wait/wait_function/timestamp.py b/moto/stepfunctions/parser/asl/component/state/wait/wait_function/timestamp.py index 7b3bc0fed7f7..91f3ea8bbee5 100644 --- a/moto/stepfunctions/parser/asl/component/state/wait/wait_function/timestamp.py +++ b/moto/stepfunctions/parser/asl/component/state/wait/wait_function/timestamp.py @@ -1,11 +1,23 @@ import datetime from typing import Final +from moto.stepfunctions.parser.asl.component.common.jsonata.jsonata_template_value_terminal import ( + JSONataTemplateValueTerminalExpression, +) from moto.stepfunctions.parser.asl.component.state.wait.wait_function.wait_function import ( WaitFunction, ) from moto.stepfunctions.parser.asl.eval.environment import Environment +TIMESTAMP_FORMAT: str = "%Y-%m-%dT%H:%M:%SZ" +# TODO: could be a bit more exact (e.g. 90 shouldn't be a valid minute) +TIMESTAMP_PATTERN: str = r"^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?Z$" + + +def parse_timestamp(timestamp: str) -> datetime.datetime: + # TODO: need to fix this like we're doing for TimestampPath & add a test + return datetime.datetime.strptime(timestamp, TIMESTAMP_FORMAT) + class Timestamp(WaitFunction): # Timestamp @@ -18,16 +30,34 @@ class Timestamp(WaitFunction): # Currently, if you specify the state_wait time as a timestamp, Step Functions considers # the time value up to seconds and truncates milliseconds. - TIMESTAMP_FORMAT: Final[str] = "%Y-%m-%dT%H:%M:%SZ" + def __init__(self, timestamp_literal: str): + self.timestamp: datetime.datetime = parse_timestamp(timestamp_literal) + + def _get_wait_seconds(self, env: Environment) -> int: + delta = self.timestamp - datetime.datetime.now() + delta_sec = int(delta.total_seconds()) + return delta_sec + - def __init__(self, timestamp): - self.timestamp: Final[datetime.datetime] = timestamp +class TimestampJSONata(WaitFunction): + jsonata_template_value_terminal_expression: Final[ + JSONataTemplateValueTerminalExpression + ] - @staticmethod - def parse_timestamp(timestamp: str) -> datetime.datetime: - return datetime.datetime.strptime(timestamp, Timestamp.TIMESTAMP_FORMAT) + def __init__( + self, + jsonata_template_value_terminal_expression: JSONataTemplateValueTerminalExpression, + ): + super().__init__() + self.jsonata_template_value_terminal_expression = ( + jsonata_template_value_terminal_expression + ) def _get_wait_seconds(self, env: Environment) -> int: - delta = self.timestamp - datetime.datetime.today() + # TODO: add snapshot tests to verify AWS's behaviour about invalid values. + self.jsonata_template_value_terminal_expression.eval(env=env) + timestamp_str: str = env.stack.pop() + timestamp_datetime = parse_timestamp(timestamp_str) + delta = timestamp_datetime - datetime.datetime.now() delta_sec = int(delta.total_seconds()) return delta_sec diff --git a/moto/stepfunctions/parser/asl/component/state/wait/wait_function/timestamp_path.py b/moto/stepfunctions/parser/asl/component/state/wait/wait_function/timestamp_path.py index 578a220b7e3d..ed9e99afef94 100644 --- a/moto/stepfunctions/parser/asl/component/state/wait/wait_function/timestamp_path.py +++ b/moto/stepfunctions/parser/asl/component/state/wait/wait_function/timestamp_path.py @@ -1,14 +1,30 @@ import datetime -from typing import Final +import re +from moto.stepfunctions.parser.api import ExecutionFailedEventDetails, HistoryEventType +from moto.stepfunctions.parser.asl.component.common.error_name.failure_event import ( + FailureEvent, + FailureEventException, +) +from moto.stepfunctions.parser.asl.component.common.error_name.states_error_name import ( + StatesErrorName, +) +from moto.stepfunctions.parser.asl.component.common.error_name.states_error_name_type import ( + StatesErrorNameType, +) +from moto.stepfunctions.parser.asl.component.common.variable_sample import ( + VariableSample, +) from moto.stepfunctions.parser.asl.component.state.wait.wait_function.timestamp import ( - Timestamp, + TIMESTAMP_FORMAT, + TIMESTAMP_PATTERN, ) from moto.stepfunctions.parser.asl.component.state.wait.wait_function.wait_function import ( WaitFunction, ) from moto.stepfunctions.parser.asl.eval.environment import Environment -from moto.stepfunctions.parser.asl.utils.json_path import JSONPathUtils +from moto.stepfunctions.parser.asl.eval.event.event_detail import EventDetails +from moto.stepfunctions.parser.asl.utils.json_path import extract_json class TimestampPath(WaitFunction): @@ -17,14 +33,61 @@ class TimestampPath(WaitFunction): # specified using a path from the state's input data. def __init__(self, path: str): - self.path: Final[str] = path + self.path: str = path - def _get_wait_seconds(self, env: Environment) -> int: - inp = env.stack[-1] - timestamp_str = JSONPathUtils.extract_json(self.path, inp) - timestamp = datetime.datetime.strptime( - timestamp_str, Timestamp.TIMESTAMP_FORMAT + def _create_failure_event( + self, env: Environment, timestamp_str: str + ) -> FailureEvent: + return FailureEvent( + env=env, + error_name=StatesErrorName(typ=StatesErrorNameType.StatesRuntime), + event_type=HistoryEventType.ExecutionFailed, + event_details=EventDetails( + executionFailedEventDetails=ExecutionFailedEventDetails( + error=StatesErrorNameType.StatesRuntime.to_name(), + cause=f"The TimestampPath parameter does not reference a valid ISO-8601 extended offset date-time format string: {self.path} == {timestamp_str}", + ) + ), ) - delta = timestamp - datetime.datetime.today() + + def _compute_delta_seconds(self, env: Environment, timestamp_str: str): + try: + if not re.match(TIMESTAMP_PATTERN, timestamp_str): + raise FailureEventException( + self._create_failure_event(env, timestamp_str) + ) + + # anything lower than seconds is truncated + processed_timestamp = timestamp_str.rsplit(".", 2)[0] + # add back the "Z" suffix if we removed it + if not processed_timestamp.endswith("Z"): + processed_timestamp = f"{processed_timestamp}Z" + timestamp = datetime.datetime.strptime( + processed_timestamp, TIMESTAMP_FORMAT + ) + except Exception: + raise FailureEventException(self._create_failure_event(env, timestamp_str)) + + delta = timestamp - datetime.datetime.now() delta_sec = int(delta.total_seconds()) return delta_sec + + def _get_wait_seconds(self, env: Environment) -> int: + inp = env.stack[-1] + timestamp_str: str = extract_json(self.path, inp) + delta_sec = self._compute_delta_seconds(env=env, timestamp_str=timestamp_str) + return delta_sec + + +class TimestampPathVar(TimestampPath): + variable_sample: VariableSample + + def __init__(self, variable_sample: VariableSample): + super().__init__(path=variable_sample.expression) + self.variable_sample = variable_sample + + def _get_wait_seconds(self, env: Environment) -> int: + self.variable_sample.eval(env=env) + timestamp_str = env.stack.pop() + delta_sec = self._compute_delta_seconds(env=env, timestamp_str=timestamp_str) + return delta_sec diff --git a/moto/stepfunctions/parser/asl/component/state/wait/wait_function/wait_function.py b/moto/stepfunctions/parser/asl/component/state/wait/wait_function/wait_function.py index 0adec4e012ff..8239c4bb7479 100644 --- a/moto/stepfunctions/parser/asl/component/state/wait/wait_function/wait_function.py +++ b/moto/stepfunctions/parser/asl/component/state/wait/wait_function/wait_function.py @@ -24,13 +24,16 @@ def _wait_interval(self, env: Environment, wait_seconds: int) -> None: elif env.is_running(): # Unrelated interrupt: continue waiting. LOG.warning( - f"Wait function '{self}' successfully reentered waiting for " - f"another '{wait_seconds_delta}' seconds." + "Wait function '%s' successfully reentered waiting for another '%s' seconds.", + self, + wait_seconds_delta, ) return self._wait_interval(env=env, wait_seconds=wait_seconds_delta) else: LOG.info( - f"Wait function '{self}' successfully interrupted after '{round_sec_waited}' seconds." + "Wait function '%s' successfully interrupted after '%s' seconds.", + self, + round_sec_waited, ) def _eval_body(self, env: Environment) -> None: diff --git a/moto/stepfunctions/parser/asl/component/test_state/__init__.py b/moto/stepfunctions/parser/asl/component/test_state/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/moto/stepfunctions/parser/asl/component/test_state/program/__init__.py b/moto/stepfunctions/parser/asl/component/test_state/program/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/moto/stepfunctions/parser/asl/component/test_state/program/test_state_program.py b/moto/stepfunctions/parser/asl/component/test_state/program/test_state_program.py new file mode 100644 index 000000000000..3af18156b5af --- /dev/null +++ b/moto/stepfunctions/parser/asl/component/test_state/program/test_state_program.py @@ -0,0 +1,64 @@ +import logging +import threading + +from moto.stepfunctions.parser.api import ( + ExecutionFailedEventDetails, +) +from moto.stepfunctions.parser.asl.component.common.error_name.failure_event import ( + FailureEventException, +) +from moto.stepfunctions.parser.asl.component.common.error_name.states_error_name import ( + StatesErrorName, +) +from moto.stepfunctions.parser.asl.component.common.error_name.states_error_name_type import ( + StatesErrorNameType, +) +from moto.stepfunctions.parser.asl.component.eval_component import EvalComponent +from moto.stepfunctions.parser.asl.component.state.state import CommonStateField +from moto.stepfunctions.parser.asl.eval.test_state.environment import ( + TestStateEnvironment, +) +from moto.stepfunctions.parser.asl.utils.encoding import to_json_str +from moto.stepfunctions.parser.utils import TMP_THREADS + +LOG = logging.getLogger(__name__) + +TEST_CASE_EXECUTION_TIMEOUT_SECONDS: int = 300 # 5 minutes. + + +class TestStateProgram(EvalComponent): + test_state: CommonStateField + + def __init__( + self, + test_state: CommonStateField, + ): + self.test_state = test_state + + def eval(self, env: TestStateEnvironment) -> None: + env.next_state_name = self.test_state.name + worker_thread = threading.Thread(target=super().eval, args=(env,), daemon=True) + TMP_THREADS.append(worker_thread) + worker_thread.start() + worker_thread.join(timeout=TEST_CASE_EXECUTION_TIMEOUT_SECONDS) + is_timeout = worker_thread.is_alive() + if is_timeout: + env.set_timed_out() + + def _eval_body(self, env: TestStateEnvironment) -> None: + try: + env.inspection_data["input"] = to_json_str(env.states.get_input()) + self.test_state.eval(env=env) + except FailureEventException as ex: + env.set_error(error=ex.get_execution_failed_event_details()) + except Exception as ex: + cause = f"{type(ex).__name__}({str(ex)})" + LOG.error("Stepfunctions computation ended with exception '%s'.", cause) + env.set_error( + ExecutionFailedEventDetails( + error=StatesErrorName( + typ=StatesErrorNameType.StatesRuntime + ).error_name, + cause=cause, + ) + ) diff --git a/moto/stepfunctions/parser/asl/component/test_state/state/__init__.py b/moto/stepfunctions/parser/asl/component/test_state/state/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/moto/stepfunctions/parser/asl/component/test_state/state/test_state_state_props.py b/moto/stepfunctions/parser/asl/component/test_state/state/test_state_state_props.py new file mode 100644 index 000000000000..1f872b462fd1 --- /dev/null +++ b/moto/stepfunctions/parser/asl/component/test_state/state/test_state_state_props.py @@ -0,0 +1,29 @@ +from typing import Any, List + +from moto.stepfunctions.parser.asl.component.common.parargs import Parargs +from moto.stepfunctions.parser.asl.component.common.path.input_path import InputPath +from moto.stepfunctions.parser.asl.component.common.path.result_path import ResultPath +from moto.stepfunctions.parser.asl.component.common.result_selector import ( + ResultSelector, +) +from moto.stepfunctions.parser.asl.component.state.state_pass.result import Result +from moto.stepfunctions.parser.asl.component.state.state_props import StateProps + +EQUAL_SUBTYPES: List[type] = [ + InputPath, + Parargs, + ResultSelector, + ResultPath, + Result, +] + + +class TestStateStateProps(StateProps): + def add(self, instance: Any) -> None: + inst_type = type(instance) + # Subclasses + for typ in EQUAL_SUBTYPES: + if issubclass(inst_type, typ): + self._add(typ, instance) + return + super().add(instance=instance) diff --git a/moto/stepfunctions/parser/asl/eval/aws_execution_details.py b/moto/stepfunctions/parser/asl/eval/aws_execution_details.py deleted file mode 100644 index 495d870ae2d4..000000000000 --- a/moto/stepfunctions/parser/asl/eval/aws_execution_details.py +++ /dev/null @@ -1,12 +0,0 @@ -from typing import Final - - -class AWSExecutionDetails: - account: Final[str] - region: Final[str] - role_arn: Final[str] - - def __init__(self, account: str, region: str, role_arn: str): - self.account = account - self.region = region - self.role_arn = role_arn diff --git a/moto/stepfunctions/parser/asl/eval/callback/callback.py b/moto/stepfunctions/parser/asl/eval/callback/callback.py index 739161b2a11f..2b214f0b9713 100644 --- a/moto/stepfunctions/parser/asl/eval/callback/callback.py +++ b/moto/stepfunctions/parser/asl/eval/callback/callback.py @@ -1,22 +1,24 @@ import abc from collections import OrderedDict -from threading import Event -from typing import Dict, Final, Optional +from threading import Event, Lock +from typing import Dict, Optional -from moto.moto_api._internal import mock_random +from moto.stepfunctions.parser.api import ActivityDoesNotExist, Arn +from moto.stepfunctions.parser.backend.activity import Activity, ActivityTask +from moto.stepfunctions.parser.utils import long_uid CallbackId = str class CallbackOutcome(abc.ABC): - callback_id: Final[CallbackId] + callback_id: CallbackId def __init__(self, callback_id: str): self.callback_id = callback_id class CallbackOutcomeSuccess(CallbackOutcome): - output: Final[str] + output: str def __init__(self, callback_id: CallbackId, output: str): super().__init__(callback_id=callback_id) @@ -24,15 +26,21 @@ def __init__(self, callback_id: CallbackId, output: str): class CallbackOutcomeFailure(CallbackOutcome): - error: Final[str] - cause: Final[str] + error: Optional[str] + cause: Optional[str] - def __init__(self, callback_id: CallbackId, error: str, cause: str): + def __init__( + self, callback_id: CallbackId, error: Optional[str], cause: Optional[str] + ): super().__init__(callback_id=callback_id) self.error = error self.cause = cause +class CallbackOutcomeTimedOut(CallbackOutcome): + pass + + class CallbackTimeoutError(TimeoutError): pass @@ -49,28 +57,61 @@ class CallbackConsumerLeft(CallbackConsumerError): class HeartbeatEndpoint: - _next_heartbeat_event: Final[Event] - _heartbeat_seconds: Final[int] + _mutex: Lock + _next_heartbeat_event: Event + _heartbeat_seconds: int def __init__(self, heartbeat_seconds: int): + self._mutex = Lock() self._next_heartbeat_event = Event() self._heartbeat_seconds = heartbeat_seconds def clear_and_wait(self) -> bool: - self._next_heartbeat_event.clear() + with self._mutex: + if self._next_heartbeat_event.is_set(): + self._next_heartbeat_event.clear() + return True return self._next_heartbeat_event.wait(timeout=self._heartbeat_seconds) def notify(self): - self._next_heartbeat_event.set() + with self._mutex: + self._next_heartbeat_event.set() class HeartbeatTimeoutError(TimeoutError): pass +class HeartbeatTimedOut(CallbackConsumerError): + pass + + +class ActivityTaskStartOutcome: + worker_name: Optional[str] + + def __init__(self, worker_name: Optional[str] = None): + self.worker_name = worker_name + + +class ActivityTaskStartEndpoint: + _next_activity_task_start_event: Event + _outcome: Optional[ActivityTaskStartOutcome] + + def __init__(self): + self._next_activity_task_start_event = Event() + + def wait(self, timeout_seconds: float) -> Optional[ActivityTaskStartOutcome]: + self._next_activity_task_start_event.wait(timeout=timeout_seconds) + return self._outcome + + def notify(self, activity_task: ActivityTaskStartOutcome) -> None: + self._outcome = activity_task + self._next_activity_task_start_event.set() + + class CallbackEndpoint: - callback_id: Final[CallbackId] - _notify_event: Final[Event] + callback_id: CallbackId + _notify_event: Event _outcome: Optional[CallbackOutcome] consumer_error: Optional[CallbackConsumerError] _heartbeat_endpoint: Optional[HeartbeatEndpoint] @@ -88,6 +129,13 @@ def setup_heartbeat_endpoint(self, heartbeat_seconds: int) -> HeartbeatEndpoint: ) return self._heartbeat_endpoint + def interrupt_all(self) -> None: + # Interrupts all waiting processes on this endpoint. + self._notify_event.set() + heartbeat_endpoint = self._heartbeat_endpoint + if heartbeat_endpoint is not None: + heartbeat_endpoint.notify() + def notify(self, outcome: CallbackOutcome): self._outcome = outcome self._notify_event.set() @@ -111,6 +159,27 @@ def report(self, consumer_error: CallbackConsumerError) -> None: self.consumer_error = consumer_error +class ActivityCallbackEndpoint(CallbackEndpoint): + _activity_task_start_endpoint: ActivityTaskStartEndpoint + _activity_input: str + + def __init__(self, callback_id: str, activity_input: str): + super().__init__(callback_id=callback_id) + self._activity_input = activity_input + self._activity_task_start_endpoint = ActivityTaskStartEndpoint() + + def get_activity_input(self) -> str: + return self._activity_input + + def get_activity_task_start_endpoint(self) -> ActivityTaskStartEndpoint: + return self._activity_task_start_endpoint + + def notify_activity_task_start(self, worker_name: Optional[str]) -> None: + self._activity_task_start_endpoint.notify( + ActivityTaskStartOutcome(worker_name=worker_name) + ) + + class CallbackNotifyConsumerError(RuntimeError): callback_consumer_error: CallbackConsumerError @@ -126,9 +195,11 @@ def __init__(self, callback_outcome_failure: CallbackOutcomeFailure): class CallbackPoolManager: + _activity_store: Dict[CallbackId, Activity] _pool: Dict[CallbackId, CallbackEndpoint] - def __init__(self): + def __init__(self, activity_store: Dict[Arn, Activity]): + self._activity_store = activity_store self._pool = OrderedDict() def get(self, callback_id: CallbackId) -> Optional[CallbackEndpoint]: @@ -141,8 +212,28 @@ def add(self, callback_id: CallbackId) -> CallbackEndpoint: self._pool[callback_id] = callback_endpoint return callback_endpoint + def add_activity_task( + self, callback_id: CallbackId, activity_arn: Arn, activity_input: str + ) -> ActivityCallbackEndpoint: + if callback_id in self._pool: + raise ValueError("Duplicate callback token id value.") + + maybe_activity: Optional[Activity] = self._activity_store.get(activity_arn) + if maybe_activity is None: + raise ActivityDoesNotExist() + + maybe_activity.add_task( + ActivityTask(task_token=callback_id, task_input=activity_input) + ) + + callback_endpoint = ActivityCallbackEndpoint( + callback_id=callback_id, activity_input=activity_input + ) + self._pool[callback_id] = callback_endpoint + return callback_endpoint + def generate(self) -> CallbackEndpoint: - return self.add(str(mock_random.uuid4())) + return self.add(long_uid()) def notify(self, callback_id: CallbackId, outcome: CallbackOutcome) -> bool: callback_endpoint = self._pool.get(callback_id, None) diff --git a/moto/stepfunctions/parser/asl/eval/contex_object.py b/moto/stepfunctions/parser/asl/eval/contex_object.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/moto/stepfunctions/parser/asl/eval/contextobject/contex_object.py b/moto/stepfunctions/parser/asl/eval/contextobject/contex_object.py deleted file mode 100644 index 96538aea0d3d..000000000000 --- a/moto/stepfunctions/parser/asl/eval/contextobject/contex_object.py +++ /dev/null @@ -1,62 +0,0 @@ -from typing import Any, Final, Optional, TypedDict - -from moto.moto_api._internal import mock_random - - -class Execution(TypedDict): - Id: str - Input: Optional[dict] - Name: str - RoleArn: str - StartTime: str # Format: ISO 8601. - - -class State(TypedDict): - EnteredTime: str # Format: ISO 8601. - Name: str - RetryCount: int - - -class StateMachine(TypedDict): - Id: str - Name: str - - -class Task(TypedDict): - Token: str - - -class Item(TypedDict): - # Contains the index number for the array item that is being currently processed. - Index: int - # Contains the array item being processed. - Value: Optional[Any] - - -class Map(TypedDict): - Item: Item - - -class ContextObject(TypedDict): - Execution: Execution - State: Optional[State] - StateMachine: StateMachine - Task: Optional[Task] # Null if the Parameters field is outside a task state. - Map: Optional[Map] # Only available when processing a Map state. - - -class ContextObjectManager: - context_object: Final[ContextObject] - - def __init__(self, context_object: ContextObject): - self.context_object = context_object - - def update_task_token(self) -> str: - new_token = str(mock_random.uuid4()) - self.context_object["Task"] = Task(Token=new_token) - return new_token - - -class ContextObjectInitData(TypedDict): - Execution: Execution - StateMachine: StateMachine diff --git a/moto/stepfunctions/parser/asl/eval/environment.py b/moto/stepfunctions/parser/asl/eval/environment.py index cf56ab77fee0..79a27f634f01 100644 --- a/moto/stepfunctions/parser/asl/eval/environment.py +++ b/moto/stepfunctions/parser/asl/eval/environment.py @@ -5,20 +5,23 @@ import threading from typing import Any, Dict, Final, List, Optional -from moto.stepfunctions.parser.api import ExecutionFailedEventDetails, Timestamp +from moto.stepfunctions.parser.api import ( + Arn, + ExecutionFailedEventDetails, + StateMachineType, + Timestamp, +) from moto.stepfunctions.parser.asl.component.state.exec.state_map.iteration.itemprocessor.map_run_record import ( MapRunRecordPoolManager, ) -from moto.stepfunctions.parser.asl.eval.aws_execution_details import AWSExecutionDetails from moto.stepfunctions.parser.asl.eval.callback.callback import CallbackPoolManager -from moto.stepfunctions.parser.asl.eval.contextobject.contex_object import ( - ContextObject, - ContextObjectInitData, - ContextObjectManager, -) -from moto.stepfunctions.parser.asl.eval.event.event_history import ( - EventHistory, +from moto.stepfunctions.parser.asl.eval.evaluation_details import AWSExecutionDetails +from moto.stepfunctions.parser.asl.eval.event.event_manager import ( EventHistoryContext, + EventManager, +) +from moto.stepfunctions.parser.asl.eval.event.logging import ( + CloudWatchLoggingSession, ) from moto.stepfunctions.parser.asl.eval.program_state import ( ProgramEnded, @@ -28,6 +31,9 @@ ProgramStopped, ProgramTimedOut, ) +from moto.stepfunctions.parser.asl.eval.states import ContextObjectData, States +from moto.stepfunctions.parser.asl.eval.variable_store import VariableStore +from moto.stepfunctions.parser.backend.activity import Activity LOG = logging.getLogger(__name__) @@ -37,68 +43,106 @@ class Environment: _program_state: Optional[ProgramState] program_state_event: Final[threading.Event()] - event_history: EventHistory + event_manager: EventManager event_history_context: Final[EventHistoryContext] + cloud_watch_logging_session: Optional[CloudWatchLoggingSession] aws_execution_details: Final[AWSExecutionDetails] + execution_type: StateMachineType callback_pool_manager: CallbackPoolManager map_run_record_pool_manager: MapRunRecordPoolManager - context_object_manager: Final[ContextObjectManager] + activity_store: Dict[Arn, Activity] _frames: Final[List[Environment]] _is_frame: bool = False heap: Dict[str, Any] = dict() stack: List[Any] = list() - inp: Optional[Any] = None + states: States + variable_store: VariableStore def __init__( self, aws_execution_details: AWSExecutionDetails, - context_object_init: ContextObjectInitData, + execution_type: StateMachineType, + context: ContextObjectData, event_history_context: EventHistoryContext, + cloud_watch_logging_session: Optional[CloudWatchLoggingSession], + activity_store: Dict[Arn, Activity], + variable_store: Optional[VariableStore] = None, ): super(Environment, self).__init__() self._state_mutex = threading.RLock() self._program_state = None self.program_state_event = threading.Event() - self.event_history = EventHistory() + self.cloud_watch_logging_session = cloud_watch_logging_session + self.event_manager = EventManager( + cloud_watch_logging_session=cloud_watch_logging_session + ) self.event_history_context = event_history_context + self.aws_execution_details = aws_execution_details - self.callback_pool_manager = CallbackPoolManager() + self.execution_type = execution_type + self.callback_pool_manager = CallbackPoolManager(activity_store=activity_store) self.map_run_record_pool_manager = MapRunRecordPoolManager() - self.context_object_manager = ContextObjectManager( - context_object=ContextObject( - Execution=context_object_init["Execution"], - StateMachine=context_object_init["StateMachine"], - ) - ) + + self.activity_store = activity_store self._frames = list() self._is_frame = False self.heap = dict() self.stack = list() - self.inp = None + self.states = States(context=context) + self.variable_store = variable_store or VariableStore() @classmethod def as_frame_of( - cls, env: Environment, event_history_frame_cache: EventHistoryContext - ): - context_object_init = ContextObjectInitData( - Execution=env.context_object_manager.context_object["Execution"], - StateMachine=env.context_object_manager.context_object["StateMachine"], + cls, + env: Environment, + event_history_frame_cache: Optional[EventHistoryContext] = None, + ) -> Environment: + return Environment.as_inner_frame_of( + env=env, + variable_store=env.variable_store, + event_history_frame_cache=event_history_frame_cache, + ) + + @classmethod + def as_inner_frame_of( + cls, + env: Environment, + variable_store: VariableStore, + event_history_frame_cache: Optional[EventHistoryContext] = None, + ) -> Environment: + # Construct the frame's context object data. + context = ContextObjectData( + Execution=env.states.context_object.context_object_data["Execution"], + StateMachine=env.states.context_object.context_object_data["StateMachine"], ) + if "Task" in env.states.context_object.context_object_data: + context["Task"] = env.states.context_object.context_object_data["Task"] + + # The default logic provisions for child frame to extend the source frame event id. + if event_history_frame_cache is None: + event_history_frame_cache = EventHistoryContext( + previous_event_id=env.event_history_context.source_event_id + ) + frame = cls( aws_execution_details=env.aws_execution_details, - context_object_init=context_object_init, + execution_type=env.execution_type, + context=context, event_history_context=event_history_frame_cache, + cloud_watch_logging_session=env.cloud_watch_logging_session, + activity_store=env.activity_store, + variable_store=variable_store, ) frame._is_frame = True - frame.event_history = env.event_history - if "State" in env.context_object_manager.context_object: - frame.context_object_manager.context_object["State"] = copy.deepcopy( - env.context_object_manager.context_object["State"] + frame.event_manager = env.event_manager + if "State" in env.states.context_object.context_object_data: + frame.states.context_object.context_object_data["State"] = copy.deepcopy( + env.states.context_object.context_object_data["State"] ) frame.callback_pool_manager = env.callback_pool_manager frame.map_run_record_pool_manager = env.map_run_record_pool_manager @@ -168,20 +212,29 @@ def set_stop( frame.set_stop(stop_date=stop_date, cause=cause, error=error) self.program_state_event.set() self.program_state_event.clear() - else: - raise RuntimeError("Cannot stop non running ProgramState.") def open_frame( self, event_history_context: Optional[EventHistoryContext] = None ) -> Environment: with self._state_mutex: - # The default logic provisions for child frame to extend the source frame event id. - if event_history_context is None: - event_history_context = EventHistoryContext( - previous_event_id=self.event_history_context.source_event_id - ) + frame = self.as_frame_of( + env=self, event_history_frame_cache=event_history_context + ) + self._frames.append(frame) + return frame - frame = Environment.as_frame_of(self, event_history_context) + def open_inner_frame( + self, event_history_context: Optional[EventHistoryContext] = None + ) -> Environment: + with self._state_mutex: + variable_store = VariableStore.as_inner_scope_of( + outer_variable_store=self.variable_store + ) + frame = self.as_inner_frame_of( + env=self, + variable_store=variable_store, + event_history_frame_cache=event_history_context, + ) self._frames.append(frame) return frame @@ -198,3 +251,6 @@ def delete_frame(self, frame: Environment) -> None: def is_frame(self) -> bool: return self._is_frame + + def is_standard_workflow(self) -> bool: + return self.execution_type == StateMachineType.STANDARD diff --git a/moto/stepfunctions/parser/asl/eval/evaluation_details.py b/moto/stepfunctions/parser/asl/eval/evaluation_details.py new file mode 100644 index 000000000000..0169f79f9769 --- /dev/null +++ b/moto/stepfunctions/parser/asl/eval/evaluation_details.py @@ -0,0 +1,65 @@ +from typing import Any, Optional + +from moto.stepfunctions.parser.api import Arn, Definition, LongArn, StateMachineType + + +class AWSExecutionDetails: + account: str + region: str + role_arn: str + + def __init__(self, account: str, region: str, role_arn: str): + self.account = account + self.region = region + self.role_arn = role_arn + + +class ExecutionDetails: + arn: LongArn + name: str + role_arn: Arn + inpt: Optional[Any] + start_time: str + + def __init__( + self, + arn: LongArn, + name: str, + role_arn: Arn, + inpt: Optional[Any], + start_time: str, + ): + self.arn = arn + self.name = name + self.role_arn = role_arn + self.inpt = inpt + self.start_time = start_time + + +class StateMachineDetails: + arn: Arn + name: str + typ: StateMachineType + definition: Definition + + def __init__(self, arn: Arn, name: str, typ: StateMachineType, definition: str): + self.arn = arn + self.name = name + self.typ = typ + self.definition = definition + + +class EvaluationDetails: + aws_execution_details: AWSExecutionDetails + execution_details: ExecutionDetails + state_machine_details: StateMachineDetails + + def __init__( + self, + aws_execution_details: AWSExecutionDetails, + execution_details: ExecutionDetails, + state_machine_details: StateMachineDetails, + ): + self.aws_execution_details = aws_execution_details + self.execution_details = execution_details + self.state_machine_details = state_machine_details diff --git a/moto/stepfunctions/parser/asl/eval/event/event_detail.py b/moto/stepfunctions/parser/asl/eval/event/event_detail.py index 62305043bb51..11b69bc6de5e 100644 --- a/moto/stepfunctions/parser/asl/eval/event/event_detail.py +++ b/moto/stepfunctions/parser/asl/eval/event/event_detail.py @@ -7,6 +7,7 @@ ActivityStartedEventDetails, ActivitySucceededEventDetails, ActivityTimedOutEventDetails, + EvaluationFailedEventDetails, ExecutionAbortedEventDetails, ExecutionFailedEventDetails, ExecutionStartedEventDetails, @@ -50,6 +51,7 @@ class EventDetails(TypedDict): taskSubmittedEventDetails: Optional[TaskSubmittedEventDetails] taskSucceededEventDetails: Optional[TaskSucceededEventDetails] taskTimedOutEventDetails: Optional[TaskTimedOutEventDetails] + evaluationFailedEventDetails: Optional[EvaluationFailedEventDetails] executionFailedEventDetails: Optional[ExecutionFailedEventDetails] executionStartedEventDetails: Optional[ExecutionStartedEventDetails] executionSucceededEventDetails: Optional[ExecutionSucceededEventDetails] diff --git a/moto/stepfunctions/parser/asl/eval/event/event_history.py b/moto/stepfunctions/parser/asl/eval/event/event_history.py deleted file mode 100644 index a23daece2718..000000000000 --- a/moto/stepfunctions/parser/asl/eval/event/event_history.py +++ /dev/null @@ -1,88 +0,0 @@ -from __future__ import annotations - -import copy -import threading -from typing import Final, Optional - -from moto.core.utils import iso_8601_datetime_with_milliseconds -from moto.stepfunctions.parser.api import ( - HistoryEvent, - HistoryEventList, - HistoryEventType, - Timestamp, -) -from moto.stepfunctions.parser.asl.eval.event.event_detail import EventDetails - - -class EventHistoryContext: - # The '0' event is the source event id of the program execution. - _PROGRAM_START_EVENT_ID: Final[int] = 0 - - source_event_id: int - last_published_event_id: int - - def __init__(self, previous_event_id: int): - self.source_event_id = previous_event_id - self.last_published_event_id = previous_event_id - - @classmethod - def of_program_start(cls) -> EventHistoryContext: - return cls(previous_event_id=cls._PROGRAM_START_EVENT_ID) - - def integrate(self, other: EventHistoryContext) -> None: - self.source_event_id = max(self.source_event_id, other.source_event_id) - self.last_published_event_id = max( - self.last_published_event_id, other.last_published_event_id - ) - - -class EventIdGenerator: - _next_id: int - - def __init__(self): - self._next_id = 1 - - def get(self) -> int: - next_id = self._next_id - self._next_id += 1 - return next_id - - -class EventHistory: - _mutex: Final[threading.Lock] - _history_event_list: Final[HistoryEventList] - _event_id_gen: EventIdGenerator - - def __init__(self): - self._mutex = threading.Lock() - self._history_event_list = list() - self._event_id_gen = EventIdGenerator() - - def add_event( - self, - context: EventHistoryContext, - hist_type_event: HistoryEventType, - event_detail: Optional[EventDetails] = None, - timestamp: Timestamp = None, - update_source_event_id: bool = True, - ) -> int: - with self._mutex: - event_id: int = self._event_id_gen.get() - history_event = HistoryEvent() - if event_detail: - history_event.update(event_detail) - history_event["id"] = event_id - history_event["previousEventId"] = context.source_event_id - history_event["type"] = hist_type_event - history_event["timestamp"] = ( - timestamp or iso_8601_datetime_with_milliseconds() - ) - self._history_event_list.append(history_event) - context.last_published_event_id = event_id - if update_source_event_id: - context.source_event_id = event_id - return event_id - - def get_event_history(self) -> HistoryEventList: - with self._mutex: - return copy.deepcopy(self._history_event_list) diff --git a/moto/stepfunctions/parser/asl/eval/event/event_manager.py b/moto/stepfunctions/parser/asl/eval/event/event_manager.py new file mode 100644 index 000000000000..a4f1b4a6f20b --- /dev/null +++ b/moto/stepfunctions/parser/asl/eval/event/event_manager.py @@ -0,0 +1,216 @@ +from __future__ import annotations + +import copy +import datetime +import logging +import threading +from typing import Optional + +from moto.core.utils import iso_8601_datetime_with_milliseconds +from moto.stepfunctions.parser.api import ( + HistoryEvent, + HistoryEventList, + HistoryEventType, + LongArn, + Timestamp, +) +from moto.stepfunctions.parser.asl.eval.event.event_detail import EventDetails +from moto.stepfunctions.parser.asl.eval.event.logging import ( + CloudWatchLoggingSession, + HistoryLog, +) +from moto.stepfunctions.parser.asl.utils.encoding import to_json_str + +LOG = logging.getLogger(__name__) + + +class EventHistoryContext: + # The '0' event is the source event id of the program execution. + _PROGRAM_START_EVENT_ID: int = 0 + + source_event_id: int + last_published_event_id: int + + def __init__(self, previous_event_id: int): + self.source_event_id = previous_event_id + self.last_published_event_id = previous_event_id + + @classmethod + def of_program_start(cls) -> EventHistoryContext: + return cls(previous_event_id=cls._PROGRAM_START_EVENT_ID) + + def integrate(self, other: EventHistoryContext) -> None: + self.source_event_id = max(self.source_event_id, other.source_event_id) + self.last_published_event_id = max( + self.last_published_event_id, other.last_published_event_id + ) + + +class EventIdGenerator: + _next_id: int + + def __init__(self): + self._next_id = 1 + + def get(self) -> int: + next_id = self._next_id + self._next_id += 1 + return next_id + + +class EventManager: + _mutex: threading.Lock + _event_id_gen: EventIdGenerator + _history_event_list: HistoryEventList + _cloud_watch_logging_session: Optional[CloudWatchLoggingSession] + + def __init__( + self, cloud_watch_logging_session: Optional[CloudWatchLoggingSession] = None + ): + self._mutex = threading.Lock() + self._event_id_gen = EventIdGenerator() + self._history_event_list = list() + self._cloud_watch_logging_session = cloud_watch_logging_session + + def add_event( + self, + context: EventHistoryContext, + event_type: HistoryEventType, + event_details: Optional[EventDetails] = None, + timestamp: Timestamp = None, + update_source_event_id: bool = True, + ) -> int: + with self._mutex: + event_id: int = self._event_id_gen.get() + source_event_id: int = context.source_event_id + timestamp = timestamp or self._get_current_timestamp() + timestamp = iso_8601_datetime_with_milliseconds(timestamp) + + context.last_published_event_id = event_id + if update_source_event_id: + context.source_event_id = event_id + + self._publish_history_event( + event_id=event_id, + source_event_id=source_event_id, + event_type=event_type, + timestamp=timestamp, + event_details=event_details, + ) + self._publish_history_log( + event_id=event_id, + source_event_id=source_event_id, + event_type=event_type, + timestamp=timestamp, + event_details=event_details, + ) + + return event_id + + @staticmethod + def _get_current_timestamp() -> datetime.datetime: + return datetime.datetime.now(tz=datetime.timezone.utc) + + @staticmethod + def _create_history_event( + event_id: int, + source_event_id: int, + event_type: HistoryEventType, + timestamp: datetime.datetime, + event_details: Optional[EventDetails], + ) -> HistoryEvent: + history_event = HistoryEvent() + if event_details is not None: + history_event.update(event_details) + history_event["id"] = event_id + history_event["previousEventId"] = source_event_id + history_event["type"] = event_type + history_event["timestamp"] = timestamp + return history_event + + def _publish_history_event( + self, + event_id: int, + source_event_id: int, + event_type: HistoryEventType, + timestamp: datetime.datetime, + event_details: Optional[EventDetails], + ): + history_event = self._create_history_event( + event_id=event_id, + source_event_id=source_event_id, + event_type=event_type, + timestamp=timestamp, + event_details=event_details, + ) + self._history_event_list.append(history_event) + + @staticmethod + def _remove_data_from_history_log(details_body: dict) -> None: + remove_keys = ["input", "inputDetails", "output", "outputDetails"] + for remove_key in remove_keys: + details_body.pop(remove_key, None) + + @staticmethod + def _create_history_log( + event_id: int, + source_event_id: int, + event_type: HistoryEventType, + timestamp: datetime.datetime, + execution_arn: LongArn, + event_details: Optional[EventDetails], + include_execution_data: bool, + ) -> HistoryLog: + log = HistoryLog( + id=str(event_id), + previous_event_id=str(source_event_id), + event_timestamp=timestamp, + type=event_type, + execution_arn=execution_arn, + ) + if event_details: + if len(event_details) > 1: + LOG.warning( + "Event details with multiple bindings: %s", + to_json_str(event_details), + ) + details_body = next(iter(event_details.values())) + if not include_execution_data: + # clone the object before modifying it as the change is limited to the history log value. + details_body = copy.deepcopy(details_body) + EventManager._remove_data_from_history_log(details_body=details_body) + log["details"] = details_body + return log + + def _publish_history_log( + self, + event_id: int, + source_event_id: int, + event_type: HistoryEventType, + timestamp: datetime.datetime, + event_details: Optional[EventDetails], + ): + # No logging session for this execution. + if self._cloud_watch_logging_session is None: + return + + # This event is not recorded by this execution's logging configuration. + if not self._cloud_watch_logging_session.log_level_filter( + history_event_type=event_type + ): + return + + history_log = self._create_history_log( + event_id=event_id, + source_event_id=source_event_id, + event_type=event_type, + timestamp=timestamp, + execution_arn=self._cloud_watch_logging_session.execution_arn, + event_details=event_details, + include_execution_data=self._cloud_watch_logging_session.configuration.include_execution_data, + ) + self._cloud_watch_logging_session.publish_history_log(history_log=history_log) + + def get_event_history(self) -> HistoryEventList: + with self._mutex: + return copy.deepcopy(self._history_event_list) diff --git a/moto/stepfunctions/parser/asl/eval/event/logging.py b/moto/stepfunctions/parser/asl/eval/event/logging.py new file mode 100644 index 000000000000..ea3fd82ef4c8 --- /dev/null +++ b/moto/stepfunctions/parser/asl/eval/event/logging.py @@ -0,0 +1,271 @@ +from __future__ import annotations + +import logging +from datetime import datetime +from typing import Any, List, Optional, Set, Tuple, TypedDict + +from botocore.client import BaseClient +from botocore.exceptions import ClientError + +from moto.stepfunctions.parser.api import ( + HistoryEventType, + LoggingConfiguration, + LogLevel, + LongArn, +) +from moto.utilities.arns import ( + parse_arn, +) + +LOG = logging.getLogger(__name__) + +ExecutionEventLogDetails = dict + +# The following event type sets are compiled according to AWS's +# log level definitions: https://docs.aws.amazon.com/step-functions/latest/dg/cloudwatch-log-level.html +_ERROR_LOG_EVENT_TYPES: Set[HistoryEventType] = { + HistoryEventType.ExecutionAborted, + HistoryEventType.ExecutionFailed, + HistoryEventType.ExecutionTimedOut, + HistoryEventType.FailStateEntered, + HistoryEventType.LambdaFunctionFailed, + HistoryEventType.LambdaFunctionScheduleFailed, + HistoryEventType.LambdaFunctionStartFailed, + HistoryEventType.LambdaFunctionTimedOut, + HistoryEventType.MapStateAborted, + HistoryEventType.MapStateFailed, + HistoryEventType.MapIterationAborted, + HistoryEventType.MapIterationFailed, + HistoryEventType.MapRunAborted, + HistoryEventType.MapRunFailed, + HistoryEventType.ParallelStateAborted, + HistoryEventType.ParallelStateFailed, + HistoryEventType.TaskFailed, + HistoryEventType.TaskStartFailed, + HistoryEventType.TaskStateAborted, + HistoryEventType.TaskSubmitFailed, + HistoryEventType.TaskTimedOut, + HistoryEventType.WaitStateAborted, +} +_FATAL_LOG_EVENT_TYPES: Set[HistoryEventType] = { + HistoryEventType.ExecutionAborted, + HistoryEventType.ExecutionFailed, + HistoryEventType.ExecutionTimedOut, +} + + +# The LogStreamName used when creating the empty Log Stream when validating the logging configuration. +VALIDATION_LOG_STREAM_NAME: str = ( + "log_stream_created_by_aws_to_validate_log_delivery_subscriptions" +) + + +def is_logging_enabled_for( + log_level: LogLevel, history_event_type: HistoryEventType +) -> bool: + # Checks whether the history event type is in the context of a give LogLevel. + if log_level == LogLevel.ALL: + return True + elif log_level == LogLevel.OFF: + return False + elif log_level == LogLevel.ERROR: + return history_event_type in _ERROR_LOG_EVENT_TYPES + elif log_level == LogLevel.FATAL: + return history_event_type in _FATAL_LOG_EVENT_TYPES + else: + LOG.error("Unknown LogLevel '%s'", log_level) + + +class CloudWatchLoggingConfiguration: + state_machine_arn: LongArn + log_level: LogLevel + log_account_id: str + log_region: str + log_group_name: str + log_stream_name: str + include_execution_data: bool + + def __init__( + self, + state_machine_arn: LongArn, + log_account_id: str, + log_region: str, + log_group_name: str, + log_level: LogLevel, + include_execution_data: bool, + ): + self.state_machine_arn = state_machine_arn + self.log_level = log_level + self.log_group_name = log_group_name + self.log_account_id = log_account_id + self.log_region = log_region + # TODO: AWS appears to append a date and a serial number to the log + # stream name: more investigations are needed in this area. + self.log_stream_name = f"states/{state_machine_arn}" + self.include_execution_data = include_execution_data + + @staticmethod + def extract_log_arn_parts_from( + logging_configuration: LoggingConfiguration, + ) -> Optional[Tuple[str, str, str]]: + # Returns a tuple with: account_id, region, and log group name if the logging configuration + # specifies a valid cloud watch log group arn, none otherwise. + + destinations = logging_configuration.get("destinations") + if ( + not destinations or len(destinations) > 1 + ): # Only one destination can be defined. + return None + + log_group = destinations[0].get("cloudWatchLogsLogGroup") + if not log_group: + return None + + log_group_arn = log_group.get("logGroupArn") + if not log_group_arn: + return None + + try: + arn_data = parse_arn(log_group_arn) + except IndexError: + return None + + log_region = arn_data.region + if log_region is None: + return None + + log_account_id = arn_data.account + if log_account_id is None: + return None + + log_resource = arn_data.resource_id + if log_resource is None: + return None + + log_resource_parts = log_resource.split("log-group:") + if not log_resource_parts: + return None + + log_group_name = log_resource_parts[-1].split(":")[0] + return log_account_id, log_region, log_group_name + + @staticmethod + def from_logging_configuration( + state_machine_arn: LongArn, + logging_configuration: LoggingConfiguration, + ) -> Optional[CloudWatchLoggingConfiguration]: + log_level = logging_configuration.get("level", LogLevel.OFF) + if log_level == LogLevel.OFF: + return None + + log_arn_parts = CloudWatchLoggingConfiguration.extract_log_arn_parts_from( + logging_configuration=logging_configuration + ) + if not log_arn_parts: + return None + log_account_id, log_region, log_group_name = log_arn_parts + + include_execution_data = logging_configuration["includeExecutionData"] + + return CloudWatchLoggingConfiguration( + state_machine_arn=state_machine_arn, + log_account_id=log_account_id, + log_region=log_region, + log_group_name=log_group_name, + log_level=log_level, + include_execution_data=include_execution_data, + ) + + def validate(self) -> None: + pass + + +class HistoryLog(TypedDict): + id: str + previous_event_id: str + event_timestamp: datetime + type: HistoryEventType + execution_arn: LongArn + details: Optional[ExecutionEventLogDetails] + + +class CloudWatchLoggingSession: + execution_arn: LongArn + configuration: CloudWatchLoggingConfiguration + _logs_client: BaseClient + _is_log_stream_available: bool + + def __init__( + self, execution_arn: LongArn, configuration: CloudWatchLoggingConfiguration + ): + self.execution_arn = execution_arn + self.configuration = configuration + self._logs_client = None + + def log_level_filter(self, history_event_type: HistoryEventType) -> bool: + # Checks whether the history event type should be logged in this session. + return is_logging_enabled_for( + log_level=self.configuration.log_level, + history_event_type=history_event_type, + ) + + def publish_history_log(self, history_log: HistoryLog) -> None: + pass + + def _publish_history_log_or_setup(self, log_events: List[Any]): + # Attempts to put the events into the given log group and stream, and attempts to create the stream if + # this does not already exist. + is_events_put = self._put_events(log_events=log_events) + if is_events_put: + return + + is_setup = self._setup() + if not is_setup: + LOG.debug( + "CloudWatch Log was not published due to setup errors encountered " + "while creating the LogStream for execution '%s'.", + self.execution_arn, + ) + return + + self._put_events(log_events=log_events) + + def _put_events(self, log_events: List[Any]) -> bool: + # Puts the events to the targe log group and stream, and returns false if the LogGroup or LogStream could + # not be found, true otherwise. + try: + self._logs_client.put_log_events( + logGroupName=self.configuration.log_group_name, + logStreamName=self.configuration.log_stream_name, + logEvents=log_events, + ) + except ClientError as error: + error_code = error.response["Error"]["Code"] + if error_code == "ResourceNotFoundException": + return False + except Exception as ignored: + LOG.warning( + "State Machine execution log event could not be published due to an error: '%s'", + ignored, + ) + return True + + def _setup(self) -> bool: + # Create the log stream if one does not exist already. + # TODO: enhance the verification logic to match AWS's logic to ensure IAM features work as expected. + # https://docs.aws.amazon.com/step-functions/latest/dg/cw-logs.html#cloudwatch-iam-policy + try: + self._logs_client.create_log_stream( + logGroupName=self.configuration.log_group_name, + logStreamName=self.configuration.log_stream_name, + ) + except ClientError as error: + error_code = error.response["Error"]["Code"] + if error_code != "ResourceAlreadyExistsException": + LOG.error( + "Could not create execution log stream for execution '%s' due to %s", + self.execution_arn, + error, + ) + return False + return True diff --git a/moto/stepfunctions/parser/asl/eval/states.py b/moto/stepfunctions/parser/asl/eval/states.py new file mode 100644 index 000000000000..5594c377e208 --- /dev/null +++ b/moto/stepfunctions/parser/asl/eval/states.py @@ -0,0 +1,157 @@ +import copy +from typing import Any, Optional, Set, TypedDict + +from moto.stepfunctions.parser.asl.jsonata.jsonata import ( + VariableDeclarations, + VariableReference, + encode_jsonata_variable_declarations, +) +from moto.stepfunctions.parser.asl.utils.json_path import extract_json +from moto.stepfunctions.parser.utils import long_uid + +_STATES_PREFIX: str = "$states" +_STATES_INPUT_PREFIX: str = "$states.input" +_STATES_CONTEXT_PREFIX: str = "$states.context" +_STATES_RESULT_PREFIX: str = "$states.result" +_STATES_ERROR_OUTPUT_PREFIX: str = "$states.errorOutput" + + +class ExecutionData(TypedDict): + Id: str + Input: Optional[Any] + Name: str + RoleArn: str + StartTime: str # Format: ISO 8601. + + +class StateData(TypedDict): + EnteredTime: str # Format: ISO 8601. + Name: str + RetryCount: int + + +class StateMachineData(TypedDict): + Id: str + Name: str + + +class TaskData(TypedDict): + Token: str + + +class ItemData(TypedDict): + # Contains the index number for the array item that is being currently processed. + Index: int + # Contains the array item being processed. + Value: Optional[Any] + + +class MapData(TypedDict): + Item: ItemData + + +class ContextObjectData(TypedDict): + Execution: ExecutionData + State: Optional[StateData] + StateMachine: StateMachineData + Task: Optional[TaskData] # Null if the Parameters field is outside a task state. + Map: Optional[MapData] # Only available when processing a Map state. + + +class ContextObject: + context_object_data: ContextObjectData + + def __init__(self, context_object: ContextObjectData): + self.context_object_data = context_object + + def update_task_token(self) -> str: + new_token = long_uid() + self.context_object_data["Task"] = TaskData(Token=new_token) + return new_token + + +class StatesData(TypedDict): + input: Any + context: ContextObjectData + result: Optional[Optional[Any]] + errorOutput: Optional[Optional[Any]] + + +class States: + _states_data: StatesData + context_object: ContextObject + + def __init__(self, context: ContextObjectData): + input_value = context["Execution"]["Input"] + self._states_data = StatesData(input=input_value, context=context) + self.context_object = ContextObject(context_object=context) + + @staticmethod + def _extract(query: Optional[str], data: Any) -> Any: + if query is None: + result = data + else: + result = extract_json(query, data) + return copy.deepcopy(result) + + def extract(self, query: str) -> Any: + if not query.startswith(_STATES_PREFIX): + raise RuntimeError(f"No such variable {query} in $states") + jsonpath_states_query = "$." + query[1:] + return self._extract(jsonpath_states_query, self._states_data) + + def get_input(self, query: Optional[str] = None) -> Any: + return self._extract(query, self._states_data["input"]) + + def reset(self, input_value: Any) -> None: + clone_input_value = copy.deepcopy(input_value) + self._states_data["input"] = clone_input_value + self._states_data["result"] = None + self._states_data["errorOutput"] = None + + def get_context(self, query: Optional[str] = None) -> Any: + return self._extract(query, self._states_data["context"]) + + def get_result(self, query: Optional[str] = None) -> Any: + if "result" not in self._states_data: + raise RuntimeError("Illegal access to $states.result") + return self._extract(query, self._states_data["result"]) + + def set_result(self, result: Any) -> Any: + clone_result = copy.deepcopy(result) + self._states_data["result"] = clone_result + + def get_error_output(self, query: Optional[str] = None) -> Any: + if "errorOutput" not in self._states_data: + raise RuntimeError("Illegal access to $states.errorOutput") + return self._extract(query, self._states_data["errorOutput"]) + + def set_error_output(self, error_output: Any) -> None: + clone_error_output = copy.deepcopy(error_output) + self._states_data["errorOutput"] = clone_error_output + + def to_variable_declarations( + self, variable_references: Optional[Set[VariableReference]] = None + ) -> VariableDeclarations: + if not variable_references or _STATES_PREFIX in variable_references: + return encode_jsonata_variable_declarations( + bindings={_STATES_PREFIX: self._states_data} + ) + candidate_sub_states = { + "input": _STATES_INPUT_PREFIX, + "context": _STATES_CONTEXT_PREFIX, + "result": _STATES_RESULT_PREFIX, + "errorOutput": _STATES_ERROR_OUTPUT_PREFIX, + } + sub_states = dict() + for variable_reference in variable_references: + if not candidate_sub_states: + break + for sub_states_key, sub_states_prefix in candidate_sub_states.items(): + if variable_reference.startswith(sub_states_prefix): + sub_states[sub_states_key] = self._states_data[sub_states_key] # noqa + del candidate_sub_states[sub_states_key] + break + return encode_jsonata_variable_declarations( + bindings={_STATES_PREFIX: sub_states} + ) diff --git a/moto/stepfunctions/parser/asl/eval/test_state/__init__.py b/moto/stepfunctions/parser/asl/eval/test_state/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/moto/stepfunctions/parser/asl/eval/test_state/environment.py b/moto/stepfunctions/parser/asl/eval/test_state/environment.py new file mode 100644 index 000000000000..266e518251d0 --- /dev/null +++ b/moto/stepfunctions/parser/asl/eval/test_state/environment.py @@ -0,0 +1,83 @@ +from __future__ import annotations + +from typing import Dict, Optional + +from moto.stepfunctions.parser.api import Arn, InspectionData, StateMachineType +from moto.stepfunctions.parser.asl.eval.environment import Environment +from moto.stepfunctions.parser.asl.eval.evaluation_details import AWSExecutionDetails +from moto.stepfunctions.parser.asl.eval.event.event_manager import ( + EventHistoryContext, +) +from moto.stepfunctions.parser.asl.eval.event.logging import ( + CloudWatchLoggingSession, +) +from moto.stepfunctions.parser.asl.eval.program_state import ( + ProgramRunning, +) +from moto.stepfunctions.parser.asl.eval.states import ContextObjectData +from moto.stepfunctions.parser.asl.eval.test_state.program_state import ( + ProgramChoiceSelected, +) +from moto.stepfunctions.parser.asl.eval.variable_store import VariableStore +from moto.stepfunctions.parser.backend.activity import Activity + + +class TestStateEnvironment(Environment): + inspection_data: InspectionData + + def __init__( + self, + aws_execution_details: AWSExecutionDetails, + execution_type: StateMachineType, + context: ContextObjectData, + event_history_context: EventHistoryContext, + activity_store: Dict[Arn, Activity], + cloud_watch_logging_session: Optional[CloudWatchLoggingSession] = None, + ): + super().__init__( + aws_execution_details=aws_execution_details, + execution_type=execution_type, + context=context, + event_history_context=event_history_context, + cloud_watch_logging_session=cloud_watch_logging_session, + activity_store=activity_store, + ) + self.inspection_data = InspectionData() + + def as_frame_of( # pylint: disable=arguments-renamed + cls, + env: TestStateEnvironment, + event_history_frame_cache: Optional[EventHistoryContext] = None, + ) -> Environment: + frame = super().as_frame_of( + env=env, event_history_frame_cache=event_history_frame_cache + ) + frame.inspection_data = env.inspection_data + return frame + + def as_inner_frame_of( # pylint: disable=arguments-renamed + cls, + env: TestStateEnvironment, + variable_store: VariableStore, + event_history_frame_cache: Optional[EventHistoryContext] = None, + ) -> Environment: + frame = super().as_inner_frame_of( + env=env, + event_history_frame_cache=event_history_frame_cache, + variable_store=variable_store, + ) + frame.inspection_data = env.inspection_data + return frame + + def set_choice_selected(self, next_state_name: str) -> None: + with self._state_mutex: + if isinstance(self._program_state, ProgramRunning): + self._program_state = ProgramChoiceSelected( + next_state_name=next_state_name + ) + self.program_state_event.set() + self.program_state_event.clear() + else: + raise RuntimeError( + "Cannot set choice selected for non running ProgramState." + ) diff --git a/moto/stepfunctions/parser/asl/eval/test_state/program_state.py b/moto/stepfunctions/parser/asl/eval/test_state/program_state.py new file mode 100644 index 000000000000..c03cf647e730 --- /dev/null +++ b/moto/stepfunctions/parser/asl/eval/test_state/program_state.py @@ -0,0 +1,9 @@ +from moto.stepfunctions.parser.asl.eval.program_state import ProgramState + + +class ProgramChoiceSelected(ProgramState): + next_state_name: str + + def __init__(self, next_state_name: str): + super().__init__() + self.next_state_name = next_state_name diff --git a/moto/stepfunctions/parser/asl/eval/variable_store.py b/moto/stepfunctions/parser/asl/eval/variable_store.py new file mode 100644 index 000000000000..335629cef59d --- /dev/null +++ b/moto/stepfunctions/parser/asl/eval/variable_store.py @@ -0,0 +1,129 @@ +from __future__ import annotations + +from typing import Any, Dict, Optional, Set + +from moto.stepfunctions.parser.asl.jsonata.jsonata import ( + VariableDeclarations, + encode_jsonata_variable_declarations, +) +from moto.stepfunctions.parser.asl.utils.encoding import to_json_str + +VariableIdentifier = str +VariableValue = Any + + +class VariableStoreError(RuntimeError): + message: str + + def __init__(self, message: str): + self.message = message + + def __str__(self): + return f"{self.__class__.__name__} {self.message}" + + def __repr__(self): + return str(self) + + +class NoSuchVariable(VariableStoreError): + variable_identifier: VariableIdentifier + + def __init__(self, variable_identifier: VariableIdentifier): + super().__init__(message=f"No such variable '{variable_identifier}' in scope") + self.variable_identifier = variable_identifier + + +class IllegalOuterScopeWrite(VariableStoreError): + variable_identifier: VariableIdentifier + variable_value: VariableValue + + def __init__( + self, variable_identifier: VariableIdentifier, variable_value: VariableValue + ): + super().__init__( + message=f"Cannot bind value '{variable_value}' to variable '{variable_identifier}' as it belongs to an outer scope." + ) + self.variable_identifier = variable_identifier + self.variable_value = variable_value + + +class VariableStore: + _outer_scope: dict + _inner_scope: dict + + _declaration_tracing: Set[str] + + _outer_variable_declaration_cache: Optional[VariableDeclarations] + _variable_declarations_cache: Optional[VariableDeclarations] + + def __init__(self): + self._outer_scope = dict() + self._inner_scope = dict() + self._declaration_tracing = set() + self._outer_variable_declaration_cache = None + self._variable_declarations_cache = None + + @classmethod + def as_inner_scope_of(cls, outer_variable_store: VariableStore) -> VariableStore: + inner_variable_store = cls() + inner_variable_store._outer_scope.update(outer_variable_store._outer_scope) + inner_variable_store._outer_scope.update(outer_variable_store._inner_scope) + return inner_variable_store + + def reset_tracing(self) -> None: + self._declaration_tracing.clear() + + # TODO: add typing when this available in service init. + def get_assigned_variables(self) -> Dict[str, str]: + assigned_variables: Dict[str, str] = dict() + for traced_declaration_identifier in self._declaration_tracing: + traced_declaration_value = self.get(traced_declaration_identifier) + if isinstance(traced_declaration_value, str): + traced_declaration_value_json_str = f'"{traced_declaration_value}"' + else: + traced_declaration_value_json_str: str = to_json_str( + traced_declaration_value, separators=(",", ":") + ) + assigned_variables[traced_declaration_identifier] = ( + traced_declaration_value_json_str + ) + return assigned_variables + + def get(self, variable_identifier: VariableIdentifier) -> VariableValue: + if variable_identifier in self._inner_scope: + return self._inner_scope[variable_identifier] + if variable_identifier in self._outer_scope: + return self._outer_scope[variable_identifier] + raise NoSuchVariable(variable_identifier=variable_identifier) + + def set( + self, variable_identifier: VariableIdentifier, variable_value: VariableValue + ) -> None: + if variable_identifier in self._outer_scope: + raise IllegalOuterScopeWrite( + variable_identifier=variable_identifier, variable_value=variable_value + ) + self._declaration_tracing.add(variable_identifier) + self._inner_scope[variable_identifier] = variable_value + self._variable_declarations_cache = None + + @staticmethod + def _to_variable_declarations(bindings: Dict[str, Any]) -> VariableDeclarations: + variables = {f"${key}": value for key, value in bindings.items()} + encoded = encode_jsonata_variable_declarations(variables) + return encoded + + def get_variable_declarations(self) -> VariableDeclarations: + if self._variable_declarations_cache is not None: + return self._variable_declarations_cache + if self._outer_variable_declaration_cache is None: + self._outer_variable_declaration_cache = self._to_variable_declarations( + self._outer_scope + ) + inner_variable_declarations_cache = self._to_variable_declarations( + self._inner_scope + ) + self._variable_declarations_cache = "".join( + [self._outer_variable_declaration_cache, inner_variable_declarations_cache] + ) + return self._variable_declarations_cache diff --git a/moto/stepfunctions/parser/asl/jsonata/__init__.py b/moto/stepfunctions/parser/asl/jsonata/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/moto/stepfunctions/parser/asl/jsonata/jsonata.py b/moto/stepfunctions/parser/asl/jsonata/jsonata.py new file mode 100644 index 000000000000..154b7f3ca3a0 --- /dev/null +++ b/moto/stepfunctions/parser/asl/jsonata/jsonata.py @@ -0,0 +1,129 @@ +from __future__ import annotations + +import json +import re +from typing import Any, Callable, Dict, List, Optional, Set + +from moto.stepfunctions.parser.asl.utils.encoding import to_json_str + +JSONataExpression = str +VariableReference = str +VariableDeclarations = str + +_PATTERN_VARIABLE_REFERENCE: re.Pattern = re.compile( + r"\$\$|\$[a-zA-Z0-9_$]+(?:\.[a-zA-Z0-9_][a-zA-Z0-9_$]*)*|\$" +) +_ILLEGAL_VARIABLE_REFERENCES: Set[str] = {"$", "$$"} +_VARIABLE_REFERENCE_ASSIGNMENT_OPERATOR: str = ":=" +_VARIABLE_REFERENCE_ASSIGNMENT_STOP_SYMBOL: str = ";" +_EXPRESSION_OPEN_SYMBOL: str = "(" +_EXPRESSION_CLOSE_SYMBOL: str = ")" + + +class JSONataException(Exception): + error: str + details: Optional[str] + + def __init__(self, error: str, details: Optional[str]): + self.error = error + self.details = details + + +class _JSONataJVMBridge: + _java_OBJECT_MAPPER: "com.fasterxml.jackson.databind.ObjectMapper" # noqa + _java_JSONATA: "com.dashjoin.jsonata.Jsonata.jsonata" # noqa + + def __init__(self): + pass + + @staticmethod + def get() -> _JSONataJVMBridge: + return _JSONataJVMBridge() + + def eval_jsonata(self, jsonata_expression: JSONataExpression) -> Any: + try: + # Evaluate the JSONata expression with the JVM. + # TODO: Investigate whether it is worth moving this chain of statements (java_*) to a + # Java program to reduce i/o between the JVM and this runtime. + java_expression = self._java_JSONATA(jsonata_expression) + java_output = java_expression.evaluate(None) + java_output_string = self._java_OBJECT_MAPPER.writeValueAsString( + java_output + ) + + # Compute a Python json object from the java string, this is to: + # 1. Ensure we fully end interactions with the JVM about this value here; + # 2. The output object may undergo under operations that are not compatible + # with jpype objects (such as json.dumps, equality, instanceof, etc.). + result_str: str = str(java_output_string) + result_json = json.loads(result_str) + + return result_json + except Exception as ex: + raise JSONataException("UNKNOWN", str(ex)) + + +# Final reference to the java evaluation function. +_eval_jsonata: Callable[[JSONataExpression], Any] = None + + +def eval_jsonata_expression(jsonata_expression: JSONataExpression) -> Any: + return _eval_jsonata(jsonata_expression) + + +class IllegalJSONataVariableReference(ValueError): + variable_reference: VariableReference + + def __init__(self, variable_reference: VariableReference): + self.variable_reference = variable_reference + + +def extract_jsonata_variable_references( + jsonata_expression: JSONataExpression, +) -> set[VariableReference]: + if not jsonata_expression: + return set() + variable_references: List[VariableReference] = _PATTERN_VARIABLE_REFERENCE.findall( + jsonata_expression + ) + for variable_reference in variable_references: + if variable_reference in _ILLEGAL_VARIABLE_REFERENCES: + raise IllegalJSONataVariableReference(variable_reference=variable_reference) + return set(variable_references) + + +def encode_jsonata_variable_declarations( + bindings: Dict[VariableReference, Any], +) -> VariableDeclarations: + declarations_parts: List[str] = list() + for variable_reference, value in bindings.items(): + if isinstance(value, str): + value_str_lit = f'"{value}"' + else: + value_str_lit = to_json_str(value, separators=(",", ":")) + declarations_parts.extend( + [ + variable_reference, + _VARIABLE_REFERENCE_ASSIGNMENT_OPERATOR, + value_str_lit, + _VARIABLE_REFERENCE_ASSIGNMENT_STOP_SYMBOL, + ] + ) + return "".join(declarations_parts) + + +def compose_jsonata_expression( + final_jsonata_expression: JSONataExpression, + variable_declarations_list: List[VariableDeclarations], +) -> JSONataExpression: + # TODO: should be expanded to pack the intrinsic functions too. + variable_declarations = "".join(variable_declarations_list) + expression = "".join( + [ + _EXPRESSION_OPEN_SYMBOL, + variable_declarations, + final_jsonata_expression, + _EXPRESSION_CLOSE_SYMBOL, + ] + ) + return expression diff --git a/moto/stepfunctions/parser/asl/jsonata/validations.py b/moto/stepfunctions/parser/asl/jsonata/validations.py new file mode 100644 index 000000000000..50379b802dd1 --- /dev/null +++ b/moto/stepfunctions/parser/asl/jsonata/validations.py @@ -0,0 +1,93 @@ +from typing import Set + +from moto.stepfunctions.parser.api import ( + EvaluationFailedEventDetails, + HistoryEventType, +) +from moto.stepfunctions.parser.asl.component.common.error_name.failure_event import ( + FailureEvent, + FailureEventException, +) +from moto.stepfunctions.parser.asl.component.common.error_name.states_error_name import ( + StatesErrorName, +) +from moto.stepfunctions.parser.asl.component.common.error_name.states_error_name_type import ( + StatesErrorNameType, +) +from moto.stepfunctions.parser.asl.eval.environment import Environment +from moto.stepfunctions.parser.asl.eval.event.event_detail import EventDetails +from moto.stepfunctions.parser.asl.jsonata.jsonata import ( + eval_jsonata_expression, +) + +_SUPPORTED_JSONATA_TYPES: Set[str] = { + "null", + "number", + "string", + "boolean", + "array", + "object", +} + + +def _validate_null_output( + env: Environment, expression: str, rich_jsonata_expression: str +) -> None: + exists: bool = eval_jsonata_expression(f"$exists({rich_jsonata_expression})") + if exists: + return + error_name = StatesErrorName(typ=StatesErrorNameType.StatesQueryEvaluationError) + failure_event = FailureEvent( + env=env, + error_name=error_name, + event_type=HistoryEventType.EvaluationFailed, + event_details=EventDetails( + evaluationFailedEventDetails=EvaluationFailedEventDetails( + # TODO: Add snapshot test to investigate behaviour for field string + cause=f"The JSONata expression '{expression}' returned nothing (undefined).", + error=error_name.error_name, + ) + ), + ) + raise FailureEventException(failure_event=failure_event) + + +def _validate_string_output( + env: Environment, expression: str, rich_jsonata_expression: str +) -> None: + jsonata_type: str = eval_jsonata_expression(f"$type({rich_jsonata_expression})") + if jsonata_type in _SUPPORTED_JSONATA_TYPES: + return + error_name = StatesErrorName(typ=StatesErrorNameType.StatesQueryEvaluationError) + failure_event = FailureEvent( + env=env, + error_name=error_name, + event_type=HistoryEventType.EvaluationFailed, + event_details=EventDetails( + evaluationFailedEventDetails=EvaluationFailedEventDetails( + # TODO: Add snapshot test to investigate behaviour for field string + cause=f"The JSONata expression '{expression}' returned an unsupported result type.", + error=error_name.error_name, + ) + ), + ) + raise FailureEventException(failure_event=failure_event) + + +def validate_jsonata_expression_output( + env: Environment, expression: str, rich_jsonata_expression: str, jsonata_result: str +) -> None: + try: + if jsonata_result is None: + _validate_null_output(env, expression, rich_jsonata_expression) + if isinstance(jsonata_result, str): + _validate_string_output(env, expression, rich_jsonata_expression) + except FailureEventException as ex: + env.event_manager.add_event( + context=env.event_history_context, + event_type=HistoryEventType.EvaluationFailed, + event_details=EventDetails( + evaluationFailedEventDetails=ex.get_evaluation_failed_event_details() + ), + ) + raise ex diff --git a/moto/stepfunctions/parser/asl/parse/asl_parser.py b/moto/stepfunctions/parser/asl/parse/asl_parser.py index e328a066ba6d..de5deaa8d667 100644 --- a/moto/stepfunctions/parser/asl/parse/asl_parser.py +++ b/moto/stepfunctions/parser/asl/parse/asl_parser.py @@ -1,12 +1,12 @@ import abc -from typing import Final, List +from typing import Final, List, Tuple -from antlr4 import CommonTokenStream, InputStream +from antlr4 import CommonTokenStream, InputStream, ParserRuleContext from antlr4.error.ErrorListener import ErrorListener from moto.stepfunctions.parser.asl.antlr.runtime.ASLLexer import ASLLexer from moto.stepfunctions.parser.asl.antlr.runtime.ASLParser import ASLParser -from moto.stepfunctions.parser.asl.component.program.program import Program +from moto.stepfunctions.parser.asl.component.eval_component import EvalComponent from moto.stepfunctions.parser.asl.parse.preprocessor import Preprocessor @@ -17,12 +17,14 @@ def __init__(self): super().__init__() self.errors = list() - def syntaxError(self, recognizer, offendingSymbol, line, column, msg, e): + def syntaxError( # pylint: disable=arguments-renamed + self, recognizer, offending_symbol, line, column, message, exception + ): log_parts = [f"line {line}:{column}"] - if offendingSymbol is not None and offendingSymbol.text: - log_parts.append(f"at {offendingSymbol.text}") - if msg: - log_parts.append(msg) + if offending_symbol is not None and offending_symbol.text: + log_parts.append(f"at {offending_symbol.text}") + if message: + log_parts.append(message) error_log = ", ".join(log_parts) self.errors.append(error_log) @@ -48,11 +50,11 @@ def __repr__(self): class AmazonStateLanguageParser(abc.ABC): @staticmethod - def parse(src: str) -> Program: + def parse(definition: str) -> Tuple[EvalComponent, ParserRuleContext]: # Attempt to build the AST and look out for syntax errors. syntax_error_listener = SyntaxErrorListener() - input_stream = InputStream(src) + input_stream = InputStream(definition) lexer = ASLLexer(input_stream) stream = CommonTokenStream(lexer) parser = ASLParser(stream) @@ -68,4 +70,4 @@ def parse(src: str) -> Program: preprocessor = Preprocessor() program = preprocessor.visit(tree) - return program + return program, tree diff --git a/moto/stepfunctions/parser/asl/parse/intrinsic/intrinsic_parser.py b/moto/stepfunctions/parser/asl/parse/intrinsic/intrinsic_parser.py index c37de49f9a12..1a1030f43d30 100644 --- a/moto/stepfunctions/parser/asl/parse/intrinsic/intrinsic_parser.py +++ b/moto/stepfunctions/parser/asl/parse/intrinsic/intrinsic_parser.py @@ -1,6 +1,8 @@ import abc +from typing import Tuple from antlr4 import CommonTokenStream, InputStream +from antlr4.ParserRuleContext import ParserRuleContext from moto.stepfunctions.parser.asl.antlr.runtime.ASLIntrinsicLexer import ( ASLIntrinsicLexer, @@ -14,7 +16,7 @@ class IntrinsicParser(abc.ABC): @staticmethod - def parse(src: str) -> Function: + def parse(src: str) -> Tuple[Function, ParserRuleContext]: input_stream = InputStream(src) lexer = ASLIntrinsicLexer(input_stream) stream = CommonTokenStream(lexer) @@ -22,4 +24,4 @@ def parse(src: str) -> Function: tree = parser.func_decl() preprocessor = Preprocessor() function: Function = preprocessor.visit(tree) - return function + return function, tree diff --git a/moto/stepfunctions/parser/asl/parse/intrinsic/preprocessor.py b/moto/stepfunctions/parser/asl/parse/intrinsic/preprocessor.py index 22abe201646e..ff6a273205ea 100644 --- a/moto/stepfunctions/parser/asl/parse/intrinsic/preprocessor.py +++ b/moto/stepfunctions/parser/asl/parse/intrinsic/preprocessor.py @@ -13,6 +13,12 @@ ASLIntrinsicParserVisitor, ) from moto.stepfunctions.parser.asl.antlt4utils.antlr4utils import Antlr4Utils +from moto.stepfunctions.parser.asl.component.common.query_language import ( + QueryLanguageMode, +) +from moto.stepfunctions.parser.asl.component.common.variable_sample import ( + VariableSample, +) from moto.stepfunctions.parser.asl.component.component import Component from moto.stepfunctions.parser.asl.component.intrinsic.argument.function_argument import ( FunctionArgument, @@ -41,6 +47,9 @@ from moto.stepfunctions.parser.asl.component.intrinsic.argument.function_argument_string import ( FunctionArgumentString, ) +from moto.stepfunctions.parser.asl.component.intrinsic.argument.function_argument_var import ( + FunctionArgumentVar, +) from moto.stepfunctions.parser.asl.component.intrinsic.function.function import Function from moto.stepfunctions.parser.asl.component.intrinsic.function.statesfunction.factory import ( StatesFunctionFactory, @@ -110,6 +119,15 @@ def visitFunc_arg_json_path( json_path: str = ctx.JSON_PATH_STRING().getText() return FunctionArgumentJsonPath(json_path=json_path) + def visitFunc_arg_var( + self, ctx: ASLIntrinsicParser.Func_arg_varContext + ) -> FunctionArgumentVar: + expression: str = ctx.STRING_VARIABLE().getText() + variable_sample = VariableSample( + query_language_mode=QueryLanguageMode.JSONPath, expression=expression + ) + return FunctionArgumentVar(variable_sample=variable_sample) + def visitFunc_arg_func_decl( self, ctx: ASLIntrinsicParser.Func_arg_func_declContext ) -> FunctionArgumentFunction: diff --git a/moto/stepfunctions/parser/asl/parse/preprocessor.py b/moto/stepfunctions/parser/asl/parse/preprocessor.py index c32d98512eec..832b6ffbd905 100644 --- a/moto/stepfunctions/parser/asl/parse/preprocessor.py +++ b/moto/stepfunctions/parser/asl/parse/preprocessor.py @@ -1,5 +1,6 @@ import json -from typing import List, Optional +import logging +from typing import Any, List, Optional from antlr4 import ParserRuleContext from antlr4.tree.Tree import ParseTree, TerminalNodeImpl @@ -10,6 +11,32 @@ ASLParserVisitor, ) from moto.stepfunctions.parser.asl.antlt4utils.antlr4utils import Antlr4Utils +from moto.stepfunctions.parser.asl.component.common.assign.assign_decl import AssignDecl +from moto.stepfunctions.parser.asl.component.common.assign.assign_decl_binding import ( + AssignDeclBinding, +) +from moto.stepfunctions.parser.asl.component.common.assign.assign_template_binding import ( + AssignTemplateBinding, + AssignTemplateBindingIntrinsicFunction, + AssignTemplateBindingPath, + AssignTemplateBindingPathContext, + AssignTemplateBindingValue, + AssignTemplateBindingVar, +) +from moto.stepfunctions.parser.asl.component.common.assign.assign_template_value import ( + AssignTemplateValue, +) +from moto.stepfunctions.parser.asl.component.common.assign.assign_template_value_array import ( + AssignTemplateValueArray, +) +from moto.stepfunctions.parser.asl.component.common.assign.assign_template_value_object import ( + AssignTemplateValueObject, +) +from moto.stepfunctions.parser.asl.component.common.assign.assign_template_value_terminal import ( + AssignTemplateValueTerminal, + AssignTemplateValueTerminalExpression, + AssignTemplateValueTerminalLit, +) from moto.stepfunctions.parser.asl.component.common.catch.catch_decl import CatchDecl from moto.stepfunctions.parser.asl.component.common.catch.catcher_decl import ( CatcherDecl, @@ -36,10 +63,43 @@ from moto.stepfunctions.parser.asl.component.common.flow.end import End from moto.stepfunctions.parser.asl.component.common.flow.next import Next from moto.stepfunctions.parser.asl.component.common.flow.start_at import StartAt -from moto.stepfunctions.parser.asl.component.common.parameters import Parameters -from moto.stepfunctions.parser.asl.component.common.path.input_path import InputPath -from moto.stepfunctions.parser.asl.component.common.path.items_path import ItemsPath -from moto.stepfunctions.parser.asl.component.common.path.output_path import OutputPath +from moto.stepfunctions.parser.asl.component.common.jsonata.jsonata_template_binding import ( + JSONataTemplateBinding, +) +from moto.stepfunctions.parser.asl.component.common.jsonata.jsonata_template_value import ( + JSONataTemplateValue, +) +from moto.stepfunctions.parser.asl.component.common.jsonata.jsonata_template_value_array import ( + JSONataTemplateValueArray, +) +from moto.stepfunctions.parser.asl.component.common.jsonata.jsonata_template_value_object import ( + JSONataTemplateValueObject, +) +from moto.stepfunctions.parser.asl.component.common.jsonata.jsonata_template_value_terminal import ( + JSONataTemplateValueTerminalExpression, + JSONataTemplateValueTerminalLit, +) +from moto.stepfunctions.parser.asl.component.common.outputdecl import Output +from moto.stepfunctions.parser.asl.component.common.parargs import ( + Arguments, + Parameters, + Parargs, +) +from moto.stepfunctions.parser.asl.component.common.path.input_path import ( + InputPathBase, + InputPathContextObject, + InputPathVar, +) +from moto.stepfunctions.parser.asl.component.common.path.items_path import ( + ItemsPath, + ItemsPathContextObject, + ItemsPathVar, +) +from moto.stepfunctions.parser.asl.component.common.path.output_path import ( + OutputPathBase, + OutputPathContextObject, + OutputPathVar, +) from moto.stepfunctions.parser.asl.component.common.path.result_path import ResultPath from moto.stepfunctions.parser.asl.component.common.payload.payloadvalue.payload_value import ( PayloadValue, @@ -62,6 +122,9 @@ from moto.stepfunctions.parser.asl.component.common.payload.payloadvalue.payloadbinding.payload_binding_value import ( PayloadBindingValue, ) +from moto.stepfunctions.parser.asl.component.common.payload.payloadvalue.payloadbinding.payload_binding_var import ( + PayloadBindingVar, +) from moto.stepfunctions.parser.asl.component.common.payload.payloadvalue.payloadtmpl.payload_tmpl import ( PayloadTmpl, ) @@ -80,6 +143,10 @@ from moto.stepfunctions.parser.asl.component.common.payload.payloadvalue.payloadvaluelit.payload_value_str import ( PayloadValueStr, ) +from moto.stepfunctions.parser.asl.component.common.query_language import ( + QueryLanguage, + QueryLanguageMode, +) from moto.stepfunctions.parser.asl.component.common.result_selector import ( ResultSelector, ) @@ -108,39 +175,57 @@ from moto.stepfunctions.parser.asl.component.common.retry.retry_decl import RetryDecl from moto.stepfunctions.parser.asl.component.common.timeouts.heartbeat import ( HeartbeatSeconds, + HeartbeatSecondsJSONata, HeartbeatSecondsPath, + HeartbeatSecondsPathVar, ) from moto.stepfunctions.parser.asl.component.common.timeouts.timeout import ( TimeoutSeconds, + TimeoutSecondsJSONata, TimeoutSecondsPath, + TimeoutSecondsPathVar, +) +from moto.stepfunctions.parser.asl.component.common.variable_sample import ( + VariableSample, ) -from moto.stepfunctions.parser.asl.component.common.version import Version from moto.stepfunctions.parser.asl.component.component import Component from moto.stepfunctions.parser.asl.component.program.program import Program +from moto.stepfunctions.parser.asl.component.program.states import States +from moto.stepfunctions.parser.asl.component.program.version import Version from moto.stepfunctions.parser.asl.component.state.choice.choice_rule import ( ChoiceRule, ) from moto.stepfunctions.parser.asl.component.state.choice.choices_decl import ( ChoicesDecl, ) -from moto.stepfunctions.parser.asl.component.state.choice.comparison.comparison_composite import ( +from moto.stepfunctions.parser.asl.component.state.choice.comparison.comparison import ( ComparisonComposite, ComparisonCompositeAnd, ComparisonCompositeNot, ComparisonCompositeOr, ComparisonCompositeProps, + ConditionJSONataExpression, + ConditionJSONataLit, ) from moto.stepfunctions.parser.asl.component.state.choice.comparison.comparison_func import ( ComparisonFunc, + ComparisonFuncValue, + ComparisonFuncVar, ) from moto.stepfunctions.parser.asl.component.state.choice.comparison.comparison_operator_type import ( ComparisonOperatorType, ) +from moto.stepfunctions.parser.asl.component.state.choice.comparison.comparison_type import ( + Comparison, +) from moto.stepfunctions.parser.asl.component.state.choice.comparison.comparison_variable import ( ComparisonVariable, ) from moto.stepfunctions.parser.asl.component.state.choice.comparison.variable import ( Variable, + VariableBase, + VariableContextObject, + VariableVar, ) from moto.stepfunctions.parser.asl.component.state.choice.default_decl import ( DefaultDecl, @@ -166,7 +251,9 @@ from moto.stepfunctions.parser.asl.component.state.exec.state_map.item_reader.reader_config.max_items_decl import ( MaxItems, MaxItemsDecl, + MaxItemsJSONata, MaxItemsPath, + MaxItemsPathVar, ) from moto.stepfunctions.parser.asl.component.state.exec.state_map.item_reader.reader_config.reader_config_decl import ( ReaderConfig, @@ -177,6 +264,10 @@ from moto.stepfunctions.parser.asl.component.state.exec.state_map.item_selector import ( ItemSelector, ) +from moto.stepfunctions.parser.asl.component.state.exec.state_map.items.items import ( + ItemsArray, + ItemsJSONata, +) from moto.stepfunctions.parser.asl.component.state.exec.state_map.iteration.itemprocessor.item_processor_decl import ( ItemProcessorDecl, ) @@ -186,22 +277,33 @@ from moto.stepfunctions.parser.asl.component.state.exec.state_map.iteration.iterator.iterator_decl import ( IteratorDecl, ) -from moto.stepfunctions.parser.asl.component.state.exec.state_map.label import Label +from moto.stepfunctions.parser.asl.component.state.exec.state_map.label import ( + Label, +) from moto.stepfunctions.parser.asl.component.state.exec.state_map.max_concurrency import ( MaxConcurrency, + MaxConcurrencyJSONata, MaxConcurrencyPath, + MaxConcurrencyPathVar, ) from moto.stepfunctions.parser.asl.component.state.exec.state_map.mode import ( Mode, ) +from moto.stepfunctions.parser.asl.component.state.exec.state_map.result_writer.result_writer_decl import ( + ResultWriter, +) from moto.stepfunctions.parser.asl.component.state.exec.state_map.state_map import ( StateMap, ) from moto.stepfunctions.parser.asl.component.state.exec.state_map.tolerated_failure import ( ToleratedFailureCount, + ToleratedFailureCountJSONata, ToleratedFailureCountPath, + ToleratedFailureCountPathVar, ToleratedFailurePercentage, + ToleratedFailurePercentageJSONata, ToleratedFailurePercentagePath, + ToleratedFailurePercentagePathVar, ) from moto.stepfunctions.parser.asl.component.state.exec.state_parallel.branches_decl import ( BranchesDecl, @@ -209,57 +311,135 @@ from moto.stepfunctions.parser.asl.component.state.exec.state_parallel.state_parallel import ( StateParallel, ) +from moto.stepfunctions.parser.asl.component.state.exec.state_task.credentials import ( + Credentials, + RoleArn, + RoleArnConst, + RoleArnContextObject, + RoleArnIntrinsicFunction, + RoleArnJSONata, + RoleArnPath, + RoleArnVar, +) from moto.stepfunctions.parser.asl.component.state.exec.state_task.service.resource import ( Resource, ) from moto.stepfunctions.parser.asl.component.state.exec.state_task.state_task_factory import ( state_task_for, ) -from moto.stepfunctions.parser.asl.component.state.fail.cause_decl import CauseDecl -from moto.stepfunctions.parser.asl.component.state.fail.cause_path import ( - CausePath, +from moto.stepfunctions.parser.asl.component.state.fail.cause_decl import ( + CauseConst, + CauseDecl, + CauseJSONata, + CausePathContextObject, CausePathIntrinsicFunction, CausePathJsonPath, + CauseVar, ) -from moto.stepfunctions.parser.asl.component.state.fail.error_decl import ErrorDecl -from moto.stepfunctions.parser.asl.component.state.fail.error_path import ( - ErrorPath, +from moto.stepfunctions.parser.asl.component.state.fail.error_decl import ( + ErrorConst, + ErrorDecl, + ErrorJSONata, + ErrorPathContextObject, ErrorPathIntrinsicFunction, ErrorPathJsonPath, + ErrorVar, ) -from moto.stepfunctions.parser.asl.component.state.fail.state_fail import ( - StateFail, -) +from moto.stepfunctions.parser.asl.component.state.fail.state_fail import StateFail from moto.stepfunctions.parser.asl.component.state.state import CommonStateField from moto.stepfunctions.parser.asl.component.state.state_pass.result import Result from moto.stepfunctions.parser.asl.component.state.state_pass.state_pass import ( StatePass, ) from moto.stepfunctions.parser.asl.component.state.state_props import StateProps -from moto.stepfunctions.parser.asl.component.state.state_succeed import ( +from moto.stepfunctions.parser.asl.component.state.state_succeed.state_succeed import ( StateSucceed, ) from moto.stepfunctions.parser.asl.component.state.state_type import StateType -from moto.stepfunctions.parser.asl.component.state.wait.state_wait import ( - StateWait, -) +from moto.stepfunctions.parser.asl.component.state.wait.state_wait import StateWait from moto.stepfunctions.parser.asl.component.state.wait.wait_function.seconds import ( Seconds, + SecondsJSONata, ) from moto.stepfunctions.parser.asl.component.state.wait.wait_function.seconds_path import ( SecondsPath, + SecondsPathVar, ) from moto.stepfunctions.parser.asl.component.state.wait.wait_function.timestamp import ( Timestamp, + TimestampJSONata, ) from moto.stepfunctions.parser.asl.component.state.wait.wait_function.timestamp_path import ( TimestampPath, + TimestampPathVar, ) -from moto.stepfunctions.parser.asl.component.states import States from moto.stepfunctions.parser.asl.parse.typed_props import TypedProps +LOG = logging.getLogger(__name__) + class Preprocessor(ASLParserVisitor): + _query_language_per_scope: List[QueryLanguage] = list() + + def _get_current_query_language(self) -> QueryLanguage: + return self._query_language_per_scope[-1] + + def _open_query_language_scope(self, parse_tree: ParseTree) -> None: + production = Antlr4Utils.is_production(parse_tree) + if production is None: + raise RuntimeError( + f"Cannot expect QueryLanguage definition at depth: {parse_tree}" + ) + + # Extract the QueryLanguage declaration at this ParseTree level, if any. + query_language = None + for child in production.children: + sub_production = Antlr4Utils.is_production( + child, ASLParser.RULE_top_layer_stmt + ) or Antlr4Utils.is_production(child, ASLParser.RULE_state_stmt) + if sub_production is not None: + child = sub_production.children[0] + sub_production = Antlr4Utils.is_production( + child, ASLParser.RULE_query_language_decl + ) + if sub_production is not None: + query_language = self.visit(sub_production) + break + + # Check this is the initial scope, if so set the initial value to the declaration or the default. + if not self._query_language_per_scope: + if query_language is None: + query_language = QueryLanguage() + # Otherwise, check for logical conflicts and add the latest or inherited value to as the next scope. + else: + current_query_language = self._get_current_query_language() + if query_language is None: + query_language = current_query_language + if ( + current_query_language.query_language_mode == QueryLanguageMode.JSONata + and query_language.query_language_mode == QueryLanguageMode.JSONPath + ): + raise ValueError( + f"Cannot downgrade from JSONata context to a JSONPath context at: {parse_tree}" + ) + + self._query_language_per_scope.append(query_language) + + def _close_query_language_scope(self) -> None: + self._query_language_per_scope.pop() + + def _is_query_language(self, query_language_mode: QueryLanguageMode) -> bool: + current_query_language = self._get_current_query_language() + return current_query_language.query_language_mode == query_language_mode + + def _raise_if_query_language_is_not( + self, query_language_mode: QueryLanguageMode, ctx: ParserRuleContext + ) -> None: + if not self._is_query_language(query_language_mode=query_language_mode): + raise ValueError( + f"Unsupported declaration in QueryLanguage={query_language_mode} block: {ctx.getText()}" + ) + @staticmethod def _inner_string_of(parse_tree: ParseTree) -> Optional[str]: if Antlr4Utils.is_terminal(parse_tree, ASLLexer.NULL): @@ -272,6 +452,17 @@ def _inner_string_of(parse_tree: ParseTree) -> Optional[str]: inner_str = inner_str[1:-1] return inner_str + def _inner_jsonata_expr(self, ctx: ParserRuleContext) -> str: + self._raise_if_query_language_is_not( + query_language_mode=QueryLanguageMode.JSONata, ctx=ctx + ) + inner_string_value = self._inner_string_of(parse_tree=ctx) + # Strip the start and end jsonata symbols {%%} + expression_body = inner_string_value[2:-2] + # Often leading and trailing spaces are used around the body: remove. + expression = expression_body.strip() + return expression + def visitComment_decl(self, ctx: ASLParser.Comment_declContext) -> Comment: inner_str = self._inner_string_of(parse_tree=ctx.keyword_or_string()) return Comment(comment=inner_str) @@ -326,16 +517,59 @@ def visitNext_decl(self, ctx: ASLParser.Next_declContext) -> Next: def visitResult_path_decl( self, ctx: ASLParser.Result_path_declContext ) -> ResultPath: + self._raise_if_query_language_is_not( + query_language_mode=QueryLanguageMode.JSONPath, ctx=ctx + ) inner_str = self._inner_string_of(parse_tree=ctx.children[-1]) return ResultPath(result_path_src=inner_str) - def visitInput_path_decl(self, ctx: ASLParser.Input_path_declContext) -> InputPath: + def visitInput_path_decl_path( + self, ctx: ASLParser.Input_path_decl_pathContext + ) -> InputPathBase: + self._raise_if_query_language_is_not( + query_language_mode=QueryLanguageMode.JSONPath, ctx=ctx + ) inner_str = self._inner_string_of(parse_tree=ctx.children[-1]) - return InputPath(input_path_src=inner_str) + return InputPathBase(path=inner_str) - def visitOutput_path_decl(self, ctx: ASLParser.Output_path_declContext): + def visitInput_path_decl_path_context_object( + self, ctx: ASLParser.Input_path_decl_path_context_objectContext + ) -> InputPathContextObject: + self._raise_if_query_language_is_not( + query_language_mode=QueryLanguageMode.JSONPath, ctx=ctx + ) + inner_str = self._inner_string_of(parse_tree=ctx.children[-1]) + return InputPathContextObject(path=inner_str) + + def visitInput_path_decl_var( + self, ctx: ASLParser.Input_path_decl_varContext + ) -> InputPathVar: + variable_sample: VariableSample = self.visit(ctx.variable_sample()) + return InputPathVar(variable_sample=variable_sample) + + def visitOutput_path_decl_path( + self, ctx: ASLParser.Output_path_decl_pathContext + ) -> OutputPathBase: + self._raise_if_query_language_is_not( + query_language_mode=QueryLanguageMode.JSONPath, ctx=ctx + ) + inner_str = self._inner_string_of(parse_tree=ctx.children[-1]) + return OutputPathBase(output_path=inner_str) + + def visitOutput_path_decl_path_context_object( + self, ctx: ASLParser.Output_path_decl_path_context_objectContext + ) -> OutputPathContextObject: + self._raise_if_query_language_is_not( + query_language_mode=QueryLanguageMode.JSONPath, ctx=ctx + ) inner_str = self._inner_string_of(parse_tree=ctx.children[-1]) - return OutputPath(output_path=inner_str) + return OutputPathContextObject(output_path=inner_str) + + def visitOutput_path_decl_var( + self, ctx: ASLParser.Output_path_decl_varContext + ) -> OutputPathVar: + variable_sample: VariableSample = self.visit(ctx.variable_sample()) + return OutputPathVar(variable_sample=variable_sample) def visitResult_decl(self, ctx: ASLParser.Result_declContext) -> Result: json_decl = ctx.json_value_decl() @@ -344,36 +578,75 @@ def visitResult_decl(self, ctx: ASLParser.Result_declContext) -> Result: return Result(result_obj=json_obj) def visitParameters_decl(self, ctx: ASLParser.Parameters_declContext) -> Parameters: + self._raise_if_query_language_is_not( + query_language_mode=QueryLanguageMode.JSONPath, ctx=ctx + ) payload_tmpl: PayloadTmpl = self.visit(ctx.payload_tmpl_decl()) return Parameters(payload_tmpl=payload_tmpl) - def visitTimeout_seconds_decl( - self, ctx: ASLParser.Timeout_seconds_declContext + def visitTimeout_seconds_int( + self, ctx: ASLParser.Timeout_seconds_intContext ) -> TimeoutSeconds: seconds = int(ctx.INT().getText()) return TimeoutSeconds(timeout_seconds=seconds) - def visitTimeout_seconds_path_decl( - self, ctx: ASLParser.Timeout_seconds_path_declContext + def visitTimeout_seconds_jsonata( + self, ctx: ASLParser.Timeout_seconds_jsonataContext + ) -> TimeoutSecondsJSONata: + expression: str = self._inner_jsonata_expr(ctx=ctx.STRINGJSONATA()) + ja_terminal_expr = JSONataTemplateValueTerminalExpression(expression=expression) + return TimeoutSecondsJSONata( + jsonata_template_value_terminal_expression=ja_terminal_expr + ) + + def visitTimeout_seconds_path_decl_path( + self, ctx: ASLParser.Timeout_seconds_path_decl_pathContext ) -> TimeoutSecondsPath: + self._raise_if_query_language_is_not( + query_language_mode=QueryLanguageMode.JSONPath, ctx=ctx + ) path: str = self._inner_string_of(parse_tree=ctx.STRINGPATH()) return TimeoutSecondsPath(path=path) - def visitHeartbeat_seconds_decl( - self, ctx: ASLParser.Heartbeat_seconds_declContext + def visitHeartbeat_seconds_int( + self, ctx: ASLParser.Heartbeat_seconds_intContext ) -> HeartbeatSeconds: seconds = int(ctx.INT().getText()) return HeartbeatSeconds(heartbeat_seconds=seconds) - def visitHeartbeat_seconds_path_decl( - self, ctx: ASLParser.Heartbeat_seconds_path_declContext + def visitHeartbeat_seconds_jsonata( + self, ctx: ASLParser.Heartbeat_seconds_jsonataContext + ) -> HeartbeatSecondsJSONata: + expression: str = self._inner_jsonata_expr(ctx=ctx.STRINGJSONATA()) + ja_terminal_expr = JSONataTemplateValueTerminalExpression(expression=expression) + return HeartbeatSecondsJSONata( + jsonata_template_value_terminal_expression=ja_terminal_expr + ) + + def visitHeartbeat_seconds_path_decl_path( + self, ctx: ASLParser.Heartbeat_seconds_path_decl_pathContext ) -> HeartbeatSecondsPath: + self._raise_if_query_language_is_not( + query_language_mode=QueryLanguageMode.JSONPath, ctx=ctx + ) path: str = self._inner_string_of(parse_tree=ctx.STRINGPATH()) return HeartbeatSecondsPath(path=path) + def visitHeartbeat_seconds_path_decl_var( + self, ctx: ASLParser.Heartbeat_seconds_path_decl_varContext + ) -> HeartbeatSecondsPathVar: + self._raise_if_query_language_is_not( + query_language_mode=QueryLanguageMode.JSONPath, ctx=ctx + ) + variable_sample: VariableSample = self.visit(ctx.variable_sample()) + return HeartbeatSecondsPathVar(variable_sample=variable_sample) + def visitResult_selector_decl( self, ctx: ASLParser.Result_selector_declContext ) -> ResultSelector: + self._raise_if_query_language_is_not( + query_language_mode=QueryLanguageMode.JSONPath, ctx=ctx + ) payload_tmpl: PayloadTmpl = self.visit(ctx.payload_tmpl_decl()) return ResultSelector(payload_tmpl=payload_tmpl) @@ -386,54 +659,114 @@ def visitBranches_decl(self, ctx: ASLParser.Branches_declContext) -> BranchesDec return BranchesDecl(programs=programs) def visitState_decl_body(self, ctx: ASLParser.State_decl_bodyContext) -> StateProps: + self._open_query_language_scope(ctx) state_props = StateProps() for child in ctx.children: cmp: Optional[Component] = self.visit(child) state_props.add(cmp) + if state_props.get(QueryLanguage) is None: + state_props.add(self._get_current_query_language()) + self._close_query_language_scope() return state_props def visitState_decl(self, ctx: ASLParser.State_declContext) -> CommonStateField: state_name = self._inner_string_of(parse_tree=ctx.state_name()) state_props: StateProps = self.visit(ctx.state_decl_body()) state_props.name = state_name - return self._common_state_field_of(state_props=state_props) + common_state_field = self._common_state_field_of(state_props=state_props) + return common_state_field @staticmethod def _common_state_field_of(state_props: StateProps) -> CommonStateField: # TODO: use subtype loading strategy. - if state_props.get(StateType) == StateType.Task: + state_type = state_props.get(StateType) + if state_type == StateType.Task: resource: Resource = state_props.get(Resource) state = state_task_for(resource) - elif state_props.get(StateType) == StateType.Pass: + elif state_type == StateType.Pass: state = StatePass() - elif state_props.get(StateType) == StateType.Choice: + elif state_type == StateType.Choice: state = StateChoice() - elif state_props.get(StateType) == StateType.Fail: + elif state_type == StateType.Fail: state = StateFail() - elif state_props.get(StateType) == StateType.Succeed: + elif state_type == StateType.Succeed: state = StateSucceed() - elif state_props.get(StateType) == StateType.Wait: + elif state_type == StateType.Wait: state = StateWait() - elif state_props.get(StateType) == StateType.Map: + elif state_type == StateType.Map: state = StateMap() - elif state_props.get(StateType) == StateType.Parallel: + elif state_type == StateType.Parallel: state = StateParallel() - elif state_props.get(StateType) is None: + elif state_type is None: raise TypeError("No Type declaration for State in context.") else: raise TypeError( - f"Unknown StateType value '{state_props.get(StateType)}' in StateProps object in context." # noqa + f"Unknown StateType value '{unknown}' in StateProps object in context." # noqa ) state.from_state_props(state_props) return state - def visitVariable_decl(self, ctx: ASLParser.Variable_declContext) -> Variable: - value: str = self._inner_string_of(parse_tree=ctx.keyword_or_string()) - return Variable(value=value) + def visitCondition_lit( + self, ctx: ASLParser.Condition_litContext + ) -> ConditionJSONataLit: + self._raise_if_query_language_is_not( + query_language_mode=QueryLanguageMode.JSONata, ctx=ctx + ) + bool_child: ParseTree = ctx.children[-1] + bool_term: Optional[TerminalNodeImpl] = Antlr4Utils.is_terminal(bool_child) + if bool_term is None: + raise ValueError( + f"Could not derive boolean literal from declaration context '{ctx.getText()}'." + ) + bool_term_rule: int = bool_term.getSymbol().type + bool_val: bool = bool_term_rule == ASLLexer.TRUE + return ConditionJSONataLit(literal=bool_val) + + def visitCondition_expr( + self, ctx: ASLParser.Condition_exprContext + ) -> ConditionJSONataExpression: + self._raise_if_query_language_is_not( + query_language_mode=QueryLanguageMode.JSONata, ctx=ctx + ) + expression: str = self._inner_jsonata_expr(ctx=ctx.STRINGJSONATA()) + ja_terminal_expr = JSONataTemplateValueTerminalExpression(expression=expression) + return ConditionJSONataExpression( + jsonata_template_value_terminal_expression=ja_terminal_expr + ) + + def visitVariable_decl_path( + self, ctx: ASLParser.Variable_decl_pathContext + ) -> VariableBase: + self._raise_if_query_language_is_not( + query_language_mode=QueryLanguageMode.JSONPath, ctx=ctx + ) + value: str = self._inner_string_of(parse_tree=ctx.children[-1]) + return VariableBase(value=value) + + def visitVariable_decl_path_context_object( + self, ctx: ASLParser.Variable_decl_path_context_objectContext + ) -> VariableContextObject: + self._raise_if_query_language_is_not( + query_language_mode=QueryLanguageMode.JSONPath, ctx=ctx + ) + value: str = self._inner_string_of(parse_tree=ctx.children[-1]) + return VariableContextObject(value=value) + + def visitVariable_decl_var( + self, ctx: ASLParser.Variable_decl_varContext + ) -> VariableVar: + self._raise_if_query_language_is_not( + query_language_mode=QueryLanguageMode.JSONPath, ctx=ctx + ) + variable_sample: VariableSample = self.visit(ctx.variable_sample()) + return VariableVar(variable_sample=variable_sample) def visitComparison_op( self, ctx: ASLParser.Comparison_opContext ) -> ComparisonOperatorType: + self._raise_if_query_language_is_not( + query_language_mode=QueryLanguageMode.JSONPath, ctx=ctx + ) try: operator_type: int = ctx.children[0].symbol.type return ComparisonOperatorType(operator_type) @@ -442,16 +775,29 @@ def visitComparison_op( f"Could not derive ComparisonOperator from context '{ctx.getText()}'." ) - def visitComparison_func( - self, ctx: ASLParser.Comparison_funcContext - ) -> ComparisonFunc: + def visitComparison_func_value( + self, ctx: ASLParser.Comparison_func_valueContext + ) -> ComparisonFuncValue: + self._raise_if_query_language_is_not( + query_language_mode=QueryLanguageMode.JSONPath, ctx=ctx + ) comparison_op: ComparisonOperatorType = self.visit(ctx.comparison_op()) - json_decl = ctx.json_value_decl() json_str: str = json_decl.getText() - json_obj: json = json.loads(json_str) - - return ComparisonFunc(operator=comparison_op, value=json_obj) + json_obj: Any = json.loads(json_str) + return ComparisonFuncValue(operator_type=comparison_op, value=json_obj) + + def visitComparison_func_var( + self, ctx: ASLParser.Comparison_func_varContext + ) -> ComparisonFuncVar: + self._raise_if_query_language_is_not( + query_language_mode=QueryLanguageMode.JSONPath, ctx=ctx + ) + comparison_op: ComparisonOperatorType = self.visit(ctx.comparison_op()) + variable_sample: VariableSample = self.visit(ctx.variable_sample()) + return ComparisonFuncVar( + operator_type=comparison_op, variable_sample=variable_sample + ) def visitDefault_decl(self, ctx: ASLParser.Default_declContext) -> DefaultDecl: state_name = self._inner_string_of(parse_tree=ctx.keyword_or_string()) @@ -460,6 +806,9 @@ def visitDefault_decl(self, ctx: ASLParser.Default_declContext) -> DefaultDecl: def visitChoice_operator( self, ctx: ASLParser.Choice_operatorContext ) -> ComparisonComposite.ChoiceOp: + self._raise_if_query_language_is_not( + query_language_mode=QueryLanguageMode.JSONPath, ctx=ctx + ) pt: Optional[TerminalNodeImpl] = Antlr4Utils.is_terminal(ctx.children[0]) if not pt: raise ValueError( @@ -506,35 +855,55 @@ def visitChoice_rule_comparison_composite( ), next_stmt=composite_stmts.get(Next), comment=composite_stmts.get(Comment), + assign=composite_stmts.get(AssignDecl), ) def visitChoice_rule_comparison_variable( self, ctx: ASLParser.Choice_rule_comparison_variableContext ) -> ChoiceRule: - comparison_stmts = TypedProps() + comparison_stmts = StateProps() for child in ctx.children: cmp: Optional[Component] = self.visit(child) comparison_stmts.add(cmp) - variable: Variable = comparison_stmts.get( - typ=Variable, - raise_on_missing=ValueError( - f"Expected a Variable declaration in '{ctx.getText()}'." - ), - ) - comparison_func: ComparisonFunc = comparison_stmts.get( - typ=ComparisonFunc, - raise_on_missing=ValueError( - f"Expected a ComparisonFunc declaration in '{ctx.getText()}'." - ), - ) - comparison_variable = ComparisonVariable( - variable=variable, func=comparison_func - ) - return ChoiceRule( - comparison=comparison_variable, - next_stmt=comparison_stmts.get(Next), - comment=comparison_stmts.get(Comment), - ) + if self._is_query_language(query_language_mode=QueryLanguageMode.JSONPath): + variable: Variable = comparison_stmts.get( + typ=Variable, + raise_on_missing=ValueError( + f"Expected a Variable declaration in '{ctx.getText()}'." + ), + ) + comparison_func: Comparison = comparison_stmts.get( + typ=Comparison, + raise_on_missing=ValueError( + f"Expected a ComparisonFunction declaration in '{ctx.getText()}'." + ), + ) + if not isinstance(comparison_func, ComparisonFunc): + raise ValueError( + f"Expected a ComparisonFunction declaration in '{ctx.getText()}'" + ) + comparison_variable = ComparisonVariable( + variable=variable, func=comparison_func + ) + return ChoiceRule( + comparison=comparison_variable, + next_stmt=comparison_stmts.get(Next), + comment=comparison_stmts.get(Comment), + assign=comparison_stmts.get(AssignDecl), + ) + else: + condition: Comparison = comparison_stmts.get( + typ=Comparison, + raise_on_missing=ValueError( + f"Expected a Condition declaration in '{ctx.getText()}'" + ), + ) + return ChoiceRule( + comparison=condition, + next_stmt=comparison_stmts.get(Next), + comment=comparison_stmts.get(Comment), + assign=comparison_stmts.get(AssignDecl), + ) def visitChoices_decl(self, ctx: ASLParser.Choices_declContext) -> ChoicesDecl: rules: List[ChoiceRule] = list() @@ -546,59 +915,241 @@ def visitChoices_decl(self, ctx: ASLParser.Choices_declContext) -> ChoicesDecl: rules.append(cmp) return ChoicesDecl(rules=rules) - def visitError_decl(self, ctx: ASLParser.Error_declContext) -> ErrorDecl: + def visitError_string(self, ctx: ASLParser.Error_stringContext) -> ErrorDecl: error = self._inner_string_of(parse_tree=ctx.keyword_or_string()) - return ErrorDecl(value=error) + return ErrorConst(value=error) + + def visitError_jsonata(self, ctx: ASLParser.Error_jsonataContext) -> ErrorDecl: + expression: str = self._inner_jsonata_expr(ctx=ctx.STRINGJSONATA()) + ja_terminal_expr = JSONataTemplateValueTerminalExpression(expression=expression) + return ErrorJSONata(jsonata_template_value_terminal_expression=ja_terminal_expr) + + def visitError_path_decl_var( + self, ctx: ASLParser.Error_path_decl_varContext + ) -> ErrorDecl: + self._raise_if_query_language_is_not( + query_language_mode=QueryLanguageMode.JSONPath, ctx=ctx + ) + variable_sample: VariableSample = self.visit(ctx.variable_sample()) + return ErrorVar(variable_sample=variable_sample) def visitError_path_decl_path( self, ctx: ASLParser.Error_path_decl_pathContext - ) -> ErrorPath: + ) -> ErrorDecl: + self._raise_if_query_language_is_not( + query_language_mode=QueryLanguageMode.JSONPath, ctx=ctx + ) path: str = self._inner_string_of(parse_tree=ctx.STRINGPATH()) return ErrorPathJsonPath(value=path) + def visitError_path_decl_context( + self, ctx: ASLParser.Error_path_decl_contextContext + ) -> ErrorDecl: + self._raise_if_query_language_is_not( + query_language_mode=QueryLanguageMode.JSONPath, ctx=ctx + ) + path = self._inner_string_of(parse_tree=ctx.STRINGPATHCONTEXTOBJ()) + path_tail = path[1:] + return ErrorPathContextObject(path_tail) + def visitError_path_decl_intrinsic( self, ctx: ASLParser.Error_path_decl_intrinsicContext - ) -> ErrorPath: - intrinsic_func: str = self._inner_string_of(parse_tree=ctx.intrinsic_func()) + ) -> ErrorDecl: + self._raise_if_query_language_is_not( + query_language_mode=QueryLanguageMode.JSONPath, ctx=ctx + ) + intrinsic_func: str = self._inner_string_of( + parse_tree=ctx.STRINGINTRINSICFUNC() + ) return ErrorPathIntrinsicFunction(value=intrinsic_func) - def visitCause_decl(self, ctx: ASLParser.Cause_declContext) -> CauseDecl: + def visitCause_string(self, ctx: ASLParser.Cause_stringContext) -> CauseDecl: cause = self._inner_string_of(parse_tree=ctx.keyword_or_string()) - return CauseDecl(value=cause) + return CauseConst(value=cause) + + def visitCause_jsonata(self, ctx: ASLParser.Cause_jsonataContext) -> CauseDecl: + expression: str = self._inner_jsonata_expr(ctx=ctx.STRINGJSONATA()) + ja_terminal_expr = JSONataTemplateValueTerminalExpression(expression=expression) + return CauseJSONata(jsonata_template_value_terminal_expression=ja_terminal_expr) + + def visitCause_path_decl_var( + self, ctx: ASLParser.Cause_path_decl_varContext + ) -> CauseDecl: + self._raise_if_query_language_is_not( + query_language_mode=QueryLanguageMode.JSONPath, ctx=ctx + ) + variable_sample: VariableSample = self.visit(ctx.variable_sample()) + return CauseVar(variable_sample=variable_sample) def visitCause_path_decl_path( self, ctx: ASLParser.Cause_path_decl_pathContext - ) -> CausePath: + ) -> CauseDecl: + self._raise_if_query_language_is_not( + query_language_mode=QueryLanguageMode.JSONPath, ctx=ctx + ) path: str = self._inner_string_of(parse_tree=ctx.STRINGPATH()) return CausePathJsonPath(value=path) + def visitCause_path_decl_context( + self, ctx: ASLParser.Cause_path_decl_contextContext + ) -> CauseDecl: + self._raise_if_query_language_is_not( + query_language_mode=QueryLanguageMode.JSONPath, ctx=ctx + ) + path = self._inner_string_of(parse_tree=ctx.STRINGPATHCONTEXTOBJ()) + path_tail = path[1:] + return CausePathContextObject(path_tail) + def visitCause_path_decl_intrinsic( self, ctx: ASLParser.Cause_path_decl_intrinsicContext - ) -> CausePath: - intrinsic_func: str = self._inner_string_of(parse_tree=ctx.intrinsic_func()) + ) -> CauseDecl: + self._raise_if_query_language_is_not( + query_language_mode=QueryLanguageMode.JSONPath, ctx=ctx + ) + intrinsic_func: str = self._inner_string_of( + parse_tree=ctx.STRINGINTRINSICFUNC() + ) return CausePathIntrinsicFunction(value=intrinsic_func) - def visitSeconds_decl(self, ctx: ASLParser.Seconds_declContext) -> Seconds: + def visitRole_arn_str(self, ctx: ASLParser.Role_arn_strContext) -> RoleArn: + role_arn = self._inner_string_of(parse_tree=ctx.keyword_or_string()) + return RoleArnConst(role_arn) + + def visitRole_arn_path(self, ctx: ASLParser.Role_arn_pathContext) -> RoleArn: + self._raise_if_query_language_is_not( + query_language_mode=QueryLanguageMode.JSONPath, ctx=ctx + ) + ctx.STRINGPATH() + path = self._inner_string_of(parse_tree=ctx.STRINGPATH()) + return RoleArnPath(path) + + def visitRole_arn_path_context_obj( + self, ctx: ASLParser.Role_arn_path_context_objContext + ) -> RoleArn: + self._raise_if_query_language_is_not( + query_language_mode=QueryLanguageMode.JSONPath, ctx=ctx + ) + path = self._inner_string_of(parse_tree=ctx.STRINGPATHCONTEXTOBJ()) + path_tail = path[1:] + return RoleArnContextObject(path_tail) + + def visitRole_arn_intrinsic_func( + self, ctx: ASLParser.Role_arn_intrinsic_funcContext + ) -> RoleArn: + self._raise_if_query_language_is_not( + query_language_mode=QueryLanguageMode.JSONPath, ctx=ctx + ) + intrinsic_func: str = self._inner_string_of( + parse_tree=ctx.STRINGINTRINSICFUNC() + ) + return RoleArnIntrinsicFunction(value=intrinsic_func) + + def visitRole_arn_var(self, ctx: ASLParser.Role_arn_varContext) -> RoleArn: + self._raise_if_query_language_is_not( + query_language_mode=QueryLanguageMode.JSONPath, ctx=ctx + ) + variable_sample: VariableSample = self.visit(ctx.variable_sample()) + return RoleArnVar(variable_sample=variable_sample) + + def visitRole_arn_jsonata(self, ctx: ASLParser.Role_arn_jsonataContext) -> RoleArn: + expression: str = self._inner_jsonata_expr(ctx=ctx.STRINGJSONATA()) + ja_terminal_expr = JSONataTemplateValueTerminalExpression(expression=expression) + return RoleArnJSONata( + jsonata_template_value_terminal_expression=ja_terminal_expr + ) + + def visitCredentials_decl( + self, ctx: ASLParser.Credentials_declContext + ) -> Credentials: + role_arn: RoleArn = self.visit(ctx.role_arn_decl()) + return Credentials(role_arn=role_arn) + + def visitSeconds_int(self, ctx: ASLParser.Seconds_intContext) -> Seconds: return Seconds(seconds=int(ctx.INT().getText())) - def visitSeconds_path_decl( - self, ctx: ASLParser.Seconds_path_declContext + def visitSeconds_jsonata( + self, ctx: ASLParser.Seconds_jsonataContext + ) -> SecondsJSONata: + expression: str = self._inner_jsonata_expr(ctx=ctx.STRINGJSONATA()) + ja_terminal_expr = JSONataTemplateValueTerminalExpression(expression=expression) + return SecondsJSONata( + jsonata_template_value_terminal_expression=ja_terminal_expr + ) + + def visitSeconds_path_decl_value( + self, ctx: ASLParser.Seconds_path_decl_valueContext ) -> SecondsPath: + self._raise_if_query_language_is_not( + query_language_mode=QueryLanguageMode.JSONPath, ctx=ctx + ) path = self._inner_string_of(parse_tree=ctx.keyword_or_string()) return SecondsPath(path=path) - def visitItems_path_decl(self, ctx: ASLParser.Items_path_declContext) -> ItemsPath: + def visitSeconds_path_decl_var( + self, ctx: ASLParser.Seconds_path_decl_varContext + ) -> SecondsPathVar: + self._raise_if_query_language_is_not( + query_language_mode=QueryLanguageMode.JSONPath, ctx=ctx + ) + variable_sample: VariableSample = self.visit(ctx.variable_sample()) + return SecondsPathVar(variable_sample=variable_sample) + + def visitItems_path_decl_path( + self, ctx: ASLParser.Items_path_decl_pathContext + ) -> ItemsPath: + self._raise_if_query_language_is_not( + query_language_mode=QueryLanguageMode.JSONPath, ctx=ctx + ) path = self._inner_string_of(parse_tree=ctx.keyword_or_string()) - return ItemsPath(items_path_src=path) + return ItemsPath(path=path) + + def visitItems_path_decl_path_context_object( + self, ctx: ASLParser.Items_path_decl_path_context_objectContext + ) -> ItemsPathContextObject: + self._raise_if_query_language_is_not( + query_language_mode=QueryLanguageMode.JSONPath, ctx=ctx + ) + path = self._inner_string_of(parse_tree=ctx.children[-1]) + return ItemsPathContextObject(path=path) + + def visitItems_path_decl_path_var( + self, ctx: ASLParser.Items_path_decl_path_varContext + ) -> ItemsPathVar: + self._raise_if_query_language_is_not( + query_language_mode=QueryLanguageMode.JSONPath, ctx=ctx + ) + path = self._inner_string_of(parse_tree=ctx.children[-1]) + return ItemsPathVar(path=path) - def visitMax_concurrency_decl( - self, ctx: ASLParser.Max_concurrency_declContext + def visitMax_concurrency_int( + self, ctx: ASLParser.Max_concurrency_intContext ) -> MaxConcurrency: return MaxConcurrency(num=int(ctx.INT().getText())) - def visitMax_concurrency_path_decl( - self, ctx: ASLParser.Max_concurrency_path_declContext - ): + def visitMax_concurrency_jsonata( + self, ctx: ASLParser.Max_concurrency_jsonataContext + ) -> MaxConcurrencyJSONata: + expression: str = self._inner_jsonata_expr(ctx=ctx.STRINGJSONATA()) + ja_terminal_expr = JSONataTemplateValueTerminalExpression(expression=expression) + return MaxConcurrencyJSONata( + jsonata_template_value_terminal_expression=ja_terminal_expr + ) + + def visitMax_concurrency_path_var( + self, ctx: ASLParser.Max_concurrency_path_varContext + ) -> MaxConcurrencyPathVar: + self._raise_if_query_language_is_not( + query_language_mode=QueryLanguageMode.JSONPath, ctx=ctx + ) + variable_sample: VariableSample = self.visit(ctx.variable_sample()) + return MaxConcurrencyPathVar(variable_sample=variable_sample) + + def visitMax_concurrency_path( + self, ctx: ASLParser.Max_concurrency_pathContext + ) -> MaxConcurrencyPath: + self._raise_if_query_language_is_not( + query_language_mode=QueryLanguageMode.JSONPath, ctx=ctx + ) max_concurrency_path: str = self._inner_string_of(parse_tree=ctx.STRINGPATH()) return MaxConcurrencyPath(max_concurrency_path=max_concurrency_path) @@ -618,17 +1169,50 @@ def visitExecution_decl( def visitExecution_type(self, ctx: ASLParser.Execution_typeContext) -> int: return ctx.children[0].symbol.type - def visitTimestamp_decl(self, ctx: ASLParser.Seconds_path_declContext) -> Timestamp: - timestamp_str = self._inner_string_of(parse_tree=ctx.keyword_or_string()) - timestamp = Timestamp.parse_timestamp(timestamp_str) - return Timestamp(timestamp=timestamp) + def visitTimestamp_string( + self, ctx: ASLParser.Timestamp_stringContext + ) -> Timestamp: + timestamp_literal: str = self._inner_string_of( + parse_tree=ctx.keyword_or_string() + ) + return Timestamp(timestamp_literal=timestamp_literal) + + def visitTimestamp_jsonata( + self, ctx: ASLParser.Timestamp_jsonataContext + ) -> TimestampJSONata: + expression: str = self._inner_jsonata_expr(ctx=ctx.STRINGJSONATA()) + ja_terminal_expr = JSONataTemplateValueTerminalExpression(expression=expression) + return TimestampJSONata( + jsonata_template_value_terminal_expression=ja_terminal_expr + ) - def visitTimestamp_path_decl( - self, ctx: ASLParser.Timestamp_path_declContext + def visitTimestamp_path_decl_value( + self, ctx: ASLParser.Timestamp_path_decl_valueContext ) -> TimestampPath: + self._raise_if_query_language_is_not( + query_language_mode=QueryLanguageMode.JSONPath, ctx=ctx + ) path = self._inner_string_of(parse_tree=ctx.keyword_or_string()) return TimestampPath(path=path) + def visitTimestamp_path_decl_var( + self, ctx: ASLParser.Timestamp_path_decl_varContext + ) -> TimestampPathVar: + self._raise_if_query_language_is_not( + query_language_mode=QueryLanguageMode.JSONPath, ctx=ctx + ) + variable_sample: VariableSample = self.visit(ctx.variable_sample()) + return TimestampPathVar(variable_sample=variable_sample) + + def visitTimeout_seconds_path_decl_var( + self, ctx: ASLParser.Timeout_seconds_path_decl_varContext + ) -> TimeoutSecondsPathVar: + self._raise_if_query_language_is_not( + query_language_mode=QueryLanguageMode.JSONPath, ctx=ctx + ) + variable_sample: VariableSample = self.visit(ctx.variable_sample()) + return TimeoutSecondsPathVar(variable_sample=variable_sample) + def visitProcessor_config_decl( self, ctx: ASLParser.Processor_config_declContext ) -> ProcessorConfig: @@ -655,7 +1239,7 @@ def visitItem_processor_decl( cmp = self.visit(child) props.add(cmp) return ItemProcessorDecl( - comment=props.get(typ=Comment), + query_language=props.get(QueryLanguage) or QueryLanguage(), start_at=props.get( typ=StartAt, raise_on_missing=ValueError( @@ -668,6 +1252,7 @@ def visitItem_processor_decl( f"Expected a States declaration at '{ctx.getText()}'." ), ), + comment=props.get(typ=Comment), processor_config=props.get(typ=ProcessorConfig) or ProcessorConfig(), ) @@ -678,6 +1263,7 @@ def visitIterator_decl(self, ctx: ASLParser.Iterator_declContext) -> IteratorDec props.add(cmp) return IteratorDecl( comment=props.get(typ=Comment), + query_language=self._get_current_query_language(), start_at=props.get( typ=StartAt, raise_on_missing=ValueError( @@ -714,7 +1300,7 @@ def visitItem_reader_decl( ) return ItemReader( resource=resource, - parameters=props.get(Parameters), + parargs=props.get(Parargs), reader_config=props.get(ReaderConfig), ) @@ -760,43 +1346,144 @@ def visitCsv_headers_decl( # TODO: check for empty headers behaviour. return CSVHeaders(header_names=csv_headers) - def visitMax_items_path_decl( - self, ctx: ASLParser.Max_items_path_declContext - ) -> MaxItemsPath: + def visitMax_items_path(self, ctx: ASLParser.Max_items_pathContext) -> MaxItemsPath: + self._raise_if_query_language_is_not( + query_language_mode=QueryLanguageMode.JSONPath, ctx=ctx + ) path: str = self._inner_string_of(parse_tree=ctx.STRINGPATH()) return MaxItemsPath(path=path) - def visitMax_items_decl(self, ctx: ASLParser.Max_items_declContext) -> MaxItems: + def visitMax_items_path_var( + self, ctx: ASLParser.Max_items_path_varContext + ) -> MaxItemsPathVar: + self._raise_if_query_language_is_not( + query_language_mode=QueryLanguageMode.JSONPath, ctx=ctx + ) + variable_sample: VariableSample = self.visit(ctx.variable_sample()) + return MaxItemsPathVar(variable_sample=variable_sample) + + def visitMax_items_int(self, ctx: ASLParser.Max_items_intContext) -> MaxItems: return MaxItems(max_items=int(ctx.INT().getText())) - def visitTolerated_failure_count_decl( - self, ctx: ASLParser.Tolerated_failure_count_declContext + def visitMax_items_jsonata( + self, ctx: ASLParser.Max_items_jsonataContext + ) -> MaxItemsJSONata: + expression: str = self._inner_jsonata_expr(ctx=ctx.STRINGJSONATA()) + ja_terminal_expr = JSONataTemplateValueTerminalExpression(expression=expression) + return MaxItemsJSONata( + jsonata_template_value_terminal_expression=ja_terminal_expr + ) + + def visitTolerated_failure_count_int( + self, ctx: ASLParser.Tolerated_failure_count_intContext ) -> ToleratedFailureCount: + LOG.warning( + "ToleratedFailureCount declarations currently have no effect on the program evaluation." + ) count = int(ctx.INT().getText()) return ToleratedFailureCount(tolerated_failure_count=count) - def visitTolerated_failure_count_path_decl( - self, ctx: ASLParser.Tolerated_failure_count_path_declContext + def visitTolerated_failure_count_jsonata( + self, ctx: ASLParser.Tolerated_failure_count_jsonataContext + ) -> ToleratedFailureCountJSONata: + expression: str = self._inner_jsonata_expr(ctx=ctx.STRINGJSONATA()) + ja_terminal_expr = JSONataTemplateValueTerminalExpression(expression=expression) + return ToleratedFailureCountJSONata( + jsonata_template_value_terminal_expression=ja_terminal_expr + ) + + def visitTolerated_failure_count_path( + self, ctx: ASLParser.Tolerated_failure_count_pathContext ) -> ToleratedFailureCountPath: + self._raise_if_query_language_is_not( + query_language_mode=QueryLanguageMode.JSONPath, ctx=ctx + ) + LOG.warning( + "ToleratedFailureCountPath declarations currently have no effect on the program evaluation." + ) path: str = self._inner_string_of(parse_tree=ctx.STRINGPATH()) return ToleratedFailureCountPath(tolerated_failure_count_path=path) - def visitTolerated_failure_percentage_decl( - self, ctx: ASLParser.Tolerated_failure_percentage_declContext + def visitTolerated_failure_count_path_var( + self, ctx: ASLParser.Tolerated_failure_count_path_varContext + ) -> ToleratedFailureCountPathVar: + self._raise_if_query_language_is_not( + query_language_mode=QueryLanguageMode.JSONPath, ctx=ctx + ) + LOG.warning( + "ToleratedFailureCountPath declarations currently have no effect on the program evaluation." + ) + variable_sample: VariableSample = self.visit(ctx.variable_sample()) + return ToleratedFailureCountPathVar(variable_sample=variable_sample) + + def visitTolerated_failure_percentage_number( + self, ctx: ASLParser.Tolerated_failure_percentage_numberContext ) -> ToleratedFailurePercentage: + LOG.warning( + "ToleratedFailurePercentage declarations currently have no effect on the program evaluation." + ) percentage = float(ctx.NUMBER().getText()) return ToleratedFailurePercentage(tolerated_failure_percentage=percentage) - def visitTolerated_failure_percentage_path_decl( - self, ctx: ASLParser.Tolerated_failure_percentage_path_declContext + def visitTolerated_failure_percentage_jsonata( + self, ctx: ASLParser.Tolerated_failure_percentage_jsonataContext + ) -> ToleratedFailurePercentageJSONata: + expression: str = self._inner_jsonata_expr(ctx=ctx.STRINGJSONATA()) + ja_terminal_expr = JSONataTemplateValueTerminalExpression(expression=expression) + return ToleratedFailurePercentageJSONata( + jsonata_template_value_terminal_expression=ja_terminal_expr + ) + + def visitTolerated_failure_percentage_path( + self, ctx: ASLParser.Tolerated_failure_percentage_pathContext ) -> ToleratedFailurePercentagePath: + self._raise_if_query_language_is_not( + query_language_mode=QueryLanguageMode.JSONPath, ctx=ctx + ) + LOG.warning( + "ToleratedFailurePercentagePath declarations currently have no effect on the program evaluation." + ) path: str = self._inner_string_of(parse_tree=ctx.STRINGPATH()) return ToleratedFailurePercentagePath(tolerate_failure_percentage_path=path) + def visitTolerated_failure_percentage_path_var( + self, ctx: ASLParser.Tolerated_failure_percentage_path_varContext + ) -> ToleratedFailurePercentagePathVar: + self._raise_if_query_language_is_not( + query_language_mode=QueryLanguageMode.JSONPath, ctx=ctx + ) + LOG.warning( + "ToleratedFailurePercentagePath declarations currently have no effect on the program evaluation." + ) + variable_sample: VariableSample = self.visit(ctx.variable_sample()) + return ToleratedFailurePercentagePathVar(variable_sample=variable_sample) + def visitLabel_decl(self, ctx: ASLParser.Label_declContext) -> Label: label = self._inner_string_of(parse_tree=ctx.keyword_or_string()) return Label(label=label) + def visitResult_writer_decl( + self, ctx: ASLParser.Result_writer_declContext + ) -> ResultWriter: + props = StateProps() + for child in ctx.children[3:-1]: + cmp = self.visit(child) + props.add(cmp) + resource: Resource = props.get( + typ=Resource, + raise_on_missing=ValueError( + f"Expected a Resource declaration at '{ctx.getText()}'." + ), + ) + # TODO: add tests for arguments in jsonata blocks using result writer + parargs: Parargs = props.get( + typ=Parargs, + raise_on_missing=ValueError( + f"Expected a Parameters/Arguments declaration at '{ctx.getText()}'." + ), + ) + return ResultWriter(resource=resource, parargs=parargs) + def visitRetry_decl(self, ctx: ASLParser.Retry_declContext) -> RetryDecl: retriers: List[RetrierDecl] = list() for child in ctx.children: @@ -890,6 +1577,10 @@ def visitCatcher_decl(self, ctx: ASLParser.Catcher_declContext) -> CatcherDecl: for child in ctx.children: cmp: Optional[Component] = self.visit(child) props.add(cmp) + if self._is_query_language(QueryLanguageMode.JSONPath) and not props.get( + ResultPath + ): + props.add(CatcherDecl.DEFAULT_RESULT_PATH) return CatcherDecl.from_catcher_props(props=props) def visitPayload_value_float( @@ -950,7 +1641,9 @@ def visitPayload_binding_intrinsic_func( self, ctx: ASLParser.Payload_binding_intrinsic_funcContext ) -> PayloadBindingIntrinsicFunc: string_dollar: str = self._inner_string_of(parse_tree=ctx.STRINGDOLLAR()) - intrinsic_func: str = self._inner_string_of(parse_tree=ctx.intrinsic_func()) + intrinsic_func: str = self._inner_string_of( + parse_tree=ctx.STRINGINTRINSICFUNC() + ) return PayloadBindingIntrinsicFunc.from_raw( string_dollar=string_dollar, intrinsic_func=intrinsic_func ) @@ -962,6 +1655,15 @@ def visitPayload_binding_value( value: PayloadValue = self.visit(ctx.payload_value_decl()) return PayloadBindingValue(field=field, value=value) + def visitPayload_binding_var( + self, ctx: ASLParser.Payload_binding_varContext + ) -> PayloadBindingVar: + string_dollar: str = self._inner_string_of(parse_tree=ctx.STRINGDOLLAR()) + variable_sample: VariableSample = self.visit(ctx.variable_sample()) + return PayloadBindingVar.from_raw( + string_dollar=string_dollar, variable_sample=variable_sample + ) + def visitPayload_arr_decl( self, ctx: ASLParser.Payload_arr_declContext ) -> PayloadArr: @@ -989,12 +1691,15 @@ def visitPayload_value_decl( return self.visit(value) def visitProgram_decl(self, ctx: ASLParser.Program_declContext) -> Program: + self._open_query_language_scope(ctx) props = TypedProps() for child in ctx.children: cmp: Optional[Component] = self.visit(child) props.add(cmp) - + if props.get(QueryLanguage) is None: + props.add(self._get_current_query_language()) program = Program( + query_language=props.get(typ=QueryLanguage) or QueryLanguage(), start_at=props.get( typ=StartAt, raise_on_missing=ValueError( @@ -1011,7 +1716,268 @@ def visitProgram_decl(self, ctx: ASLParser.Program_declContext) -> Program: comment=props.get(typ=Comment), version=props.get(typ=Version), ) + self._close_query_language_scope() return program def visitState_machine(self, ctx: ASLParser.State_machineContext) -> Program: return self.visit(ctx.program_decl()) + + def visitQuery_language_decl( + self, ctx: ASLParser.Query_language_declContext + ) -> QueryLanguage: + query_language_mode_int = ctx.children[-1].getSymbol().type + query_language_mode = QueryLanguageMode(value=query_language_mode_int) + return QueryLanguage(query_language_mode=query_language_mode) + + def visitVariable_sample( + self, ctx: ASLParser.Variable_sampleContext + ) -> VariableSample: + query_language_mode: QueryLanguageMode = ( + self._get_current_query_language().query_language_mode + ) + expression: str = self._inner_string_of(parse_tree=ctx.STRINGVAR()) + return VariableSample( + query_language_mode=query_language_mode, expression=expression + ) + + def visitAssign_template_value_terminal_float( + self, ctx: ASLParser.Assign_template_value_terminal_floatContext + ) -> AssignTemplateValueTerminalLit: + float_value = float(ctx.NUMBER().getText()) + return AssignTemplateValueTerminalLit(value=float_value) + + def visitAssign_template_value_terminal_int( + self, ctx: ASLParser.Assign_template_value_terminal_intContext + ) -> AssignTemplateValueTerminalLit: + int_value = int(ctx.INT().getText()) + return AssignTemplateValueTerminalLit(value=int_value) + + def visitAssign_template_value_terminal_bool( + self, ctx: ASLParser.Assign_template_value_terminal_boolContext + ) -> AssignTemplateValueTerminalLit: + bool_term_rule: int = ctx.children[0].getSymbol().type + bool_value: bool = bool_term_rule == ASLLexer.TRUE + return AssignTemplateValueTerminalLit(value=bool_value) + + def visitAssign_template_value_terminal_null( + self, ctx: ASLParser.Assign_template_value_terminal_nullContext + ) -> AssignTemplateValueTerminalLit: + return AssignTemplateValueTerminalLit(value=None) + + def visitAssign_template_value_terminal_expression( + self, ctx: ASLParser.Assign_template_value_terminal_expressionContext + ) -> AssignTemplateValueTerminal: + # Strip the start and end quote from the production literal value. + inner_string_value = self._inner_string_of(parse_tree=ctx.STRINGJSONATA()) + # Return a JSONata expression resolver or a suppressed depending on the current language mode. + current_query_language = self._get_current_query_language() + if current_query_language.query_language_mode == QueryLanguageMode.JSONata: + # Strip the start and end jsonata symbols {%%} + expression_body = inner_string_value[2:-2] + # Often leading and trailing spaces are used around the body: remove. + expression = expression_body.strip() + return AssignTemplateValueTerminalExpression(expression=expression) + else: + return AssignTemplateValueTerminalLit(value=inner_string_value) + + def visitAssign_template_value_terminal_str( + self, ctx: ASLParser.Assign_template_value_terminal_strContext + ) -> AssignTemplateValueTerminalLit: + str_value = self._inner_string_of(parse_tree=ctx.keyword_or_string()) + return AssignTemplateValueTerminalLit(value=str_value) + + def visitAssign_template_value(self, ctx: ASLParser.Assign_template_valueContext): + return self.visit(ctx.children[0]) + + def visitAssign_template_value_array( + self, ctx: ASLParser.Assign_template_value_arrayContext + ) -> AssignTemplateValueArray: + values: List[AssignTemplateValue] = list() + for child in ctx.children: + cmp: Optional[Component] = self.visit(child) + if isinstance(cmp, AssignTemplateValue): + values.append(cmp) + return AssignTemplateValueArray(values=values) + + def visitAssign_template_value_object( + self, ctx: ASLParser.Assign_template_value_objectContext + ) -> AssignTemplateValueObject: + bindings: List[AssignTemplateBinding] = list() + for child in ctx.children: + cmp: Optional[Component] = self.visit(child) + if isinstance(cmp, AssignTemplateBinding): + bindings.append(cmp) + return AssignTemplateValueObject(bindings=bindings) + + def visitAssign_template_binding_assign_value( + self, ctx: ASLParser.Assign_template_binding_assign_valueContext + ) -> AssignTemplateBinding: + identifier: str = self._inner_string_of(ctx.STRING()) + assign_value: AssignTemplateValue = self.visit(ctx.assign_template_value()) + return AssignTemplateBindingValue( + identifier=identifier, assign_value=assign_value + ) + + def visitAssign_template_binding_path( + self, ctx: ASLParser.Assign_template_binding_pathContext + ) -> AssignTemplateBindingPath: + identifier: str = self._inner_string_of(ctx.STRINGDOLLAR()) + identifier = identifier[:-2] + path = self._inner_string_of(parse_tree=ctx.STRINGPATH()) + return AssignTemplateBindingPath(identifier=identifier, path=path) + + def visitAssign_template_binding_path_context( + self, ctx: ASLParser.Assign_template_binding_path_contextContext + ) -> AssignTemplateBindingPathContext: + identifier: str = self._inner_string_of(ctx.STRINGDOLLAR()) + identifier = identifier[:-2] + path = self._inner_string_of(parse_tree=ctx.STRINGPATHCONTEXTOBJ()) + path: str = path[1:] + return AssignTemplateBindingPathContext(identifier=identifier, path=path) + + def visitAssign_template_binding_intrinsic_func( + self, ctx: ASLParser.Assign_template_binding_intrinsic_funcContext + ) -> AssignTemplateBindingIntrinsicFunction: + identifier: str = self._inner_string_of(ctx.STRINGDOLLAR()) + identifier = identifier[:-2] + function_literal: str = self._inner_string_of( + parse_tree=ctx.STRINGINTRINSICFUNC() + ) + return AssignTemplateBindingIntrinsicFunction( + identifier=identifier, function_literal=function_literal + ) + + def visitAssign_template_binding_var( + self, ctx: ASLParser.Assign_template_binding_varContext + ) -> AssignTemplateBindingVar: + identifier: str = self._inner_string_of(ctx.STRINGDOLLAR()) + identifier = identifier[:-2] + variable_sample: VariableSample = self.visit(ctx.variable_sample()) + return AssignTemplateBindingVar( + identifier=identifier, variable_sample=variable_sample + ) + + def visitAssign_decl_binding( + self, ctx: ASLParser.Assign_decl_bindingContext + ) -> AssignDeclBinding: + binding: AssignTemplateBinding = self.visit(ctx.assign_template_binding()) + return AssignDeclBinding(binding=binding) + + def visitAssign_decl_body( + self, ctx: ASLParser.Assign_decl_bodyContext + ) -> List[AssignDeclBinding]: + bindings: List[AssignDeclBinding] = list() + for child in ctx.children: + cmp: Optional[Component] = self.visit(child) + if isinstance(cmp, AssignDeclBinding): + bindings.append(cmp) + return bindings + + def visitAssign_decl(self, ctx: ASLParser.Assign_declContext) -> AssignDecl: + declaration_bindings: List[AssignDeclBinding] = self.visit( + ctx.assign_decl_body() + ) + return AssignDecl(declaration_bindings=declaration_bindings) + + def visitJsonata_template_value_terminal_float( + self, ctx: ASLParser.Jsonata_template_value_terminal_floatContext + ) -> JSONataTemplateValueTerminalLit: + float_value = float(ctx.NUMBER().getText()) + return JSONataTemplateValueTerminalLit(value=float_value) + + def visitJsonata_template_value_terminal_int( + self, ctx: ASLParser.Jsonata_template_value_terminal_intContext + ) -> JSONataTemplateValueTerminalLit: + int_value = int(ctx.INT().getText()) + return JSONataTemplateValueTerminalLit(value=int_value) + + def visitJsonata_template_value_terminal_bool( + self, ctx: ASLParser.Jsonata_template_value_terminal_boolContext + ) -> JSONataTemplateValueTerminalLit: + bool_term_rule: int = ctx.children[0].getSymbol().type + bool_value: bool = bool_term_rule == ASLLexer.TRUE + return JSONataTemplateValueTerminalLit(value=bool_value) + + def visitJsonata_template_value_terminal_null( + self, ctx: ASLParser.Jsonata_template_value_terminal_nullContext + ) -> JSONataTemplateValueTerminalLit: + return JSONataTemplateValueTerminalLit(value=None) + + def visitJsonata_template_value_terminal_expression( + self, ctx: ASLParser.Jsonata_template_value_terminal_expressionContext + ) -> JSONataTemplateValueTerminalExpression: + expression: str = self._inner_jsonata_expr(ctx=ctx.STRINGJSONATA()) + return JSONataTemplateValueTerminalExpression(expression=expression) + + def visitJsonata_template_value_terminal_str( + self, ctx: ASLParser.Jsonata_template_value_terminal_strContext + ) -> JSONataTemplateValueTerminalLit: + str_value = self._inner_string_of(parse_tree=ctx.keyword_or_string()) + return JSONataTemplateValueTerminalLit(value=str_value) + + def visitJsonata_template_value( + self, ctx: ASLParser.Jsonata_template_valueContext + ) -> JSONataTemplateValue: + return self.visit(ctx.children[0]) + + def visitJsonata_template_value_array( + self, ctx: ASLParser.Jsonata_template_value_arrayContext + ) -> JSONataTemplateValueArray: + values: List[JSONataTemplateValue] = list() + for child in ctx.children: + cmp: Optional[Component] = self.visit(child) + if isinstance(cmp, JSONataTemplateValue): + values.append(cmp) + return JSONataTemplateValueArray(values=values) + + def visitJsonata_template_value_object( + self, ctx: ASLParser.Jsonata_template_value_objectContext + ) -> JSONataTemplateValueObject: + bindings: List[JSONataTemplateBinding] = list() + for child in ctx.children: + cmp: Optional[Component] = self.visit(child) + if isinstance(cmp, JSONataTemplateBinding): + bindings.append(cmp) + return JSONataTemplateValueObject(bindings=bindings) + + def visitJsonata_template_binding( + self, ctx: ASLParser.Jsonata_template_bindingContext + ) -> JSONataTemplateBinding: + identifier: str = self._inner_string_of(ctx.keyword_or_string()) + value: JSONataTemplateValue = self.visit(ctx.jsonata_template_value()) + return JSONataTemplateBinding(identifier=identifier, value=value) + + def visitArguments_object( + self, ctx: ASLParser.Arguments_objectContext + ) -> Arguments: + self._raise_if_query_language_is_not( + query_language_mode=QueryLanguageMode.JSONata, ctx=ctx + ) + jsonata_template_value_object: JSONataTemplateValueObject = self.visit( + ctx.jsonata_template_value_object() + ) + return Arguments(jsonata_payload_value=jsonata_template_value_object) + + def visitArguments_expr(self, ctx: ASLParser.Arguments_exprContext) -> Arguments: + expression: str = self._inner_jsonata_expr(ctx=ctx.STRINGJSONATA()) + jsonata_template_value = JSONataTemplateValueTerminalExpression( + expression=expression + ) + return Arguments(jsonata_payload_value=jsonata_template_value) + + def visitOutput_decl(self, ctx: ASLParser.Output_declContext) -> Output: + jsonata_template_value: JSONataTemplateValue = self.visit( + ctx.jsonata_template_value() + ) + return Output(jsonata_template_value=jsonata_template_value) + + def visitItems_array(self, ctx: ASLParser.Items_arrayContext) -> ItemsArray: + jsonata_template_value_array: JSONataTemplateValueArray = self.visit( + ctx.jsonata_template_value_array() + ) + return ItemsArray(jsonata_template_value_array=jsonata_template_value_array) + + def visitItems_jsonata(self, ctx: ASLParser.Items_jsonataContext) -> ItemsJSONata: + expression: str = self._inner_jsonata_expr(ctx=ctx.STRINGJSONATA()) + ja_terminal_expr = JSONataTemplateValueTerminalExpression(expression=expression) + return ItemsJSONata(jsonata_template_value_terminal_expression=ja_terminal_expr) diff --git a/moto/stepfunctions/parser/asl/parse/test_state/__init__.py b/moto/stepfunctions/parser/asl/parse/test_state/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/moto/stepfunctions/parser/asl/parse/test_state/asl_parser.py b/moto/stepfunctions/parser/asl/parse/test_state/asl_parser.py new file mode 100644 index 000000000000..28e1988196a7 --- /dev/null +++ b/moto/stepfunctions/parser/asl/parse/test_state/asl_parser.py @@ -0,0 +1,41 @@ +from typing import Tuple + +from antlr4 import CommonTokenStream, InputStream, ParserRuleContext + +from moto.stepfunctions.parser.asl.antlr.runtime.ASLLexer import ASLLexer +from moto.stepfunctions.parser.asl.antlr.runtime.ASLParser import ASLParser +from moto.stepfunctions.parser.asl.component.eval_component import EvalComponent +from moto.stepfunctions.parser.asl.parse.asl_parser import ( + AmazonStateLanguageParser, + ASLParserException, + SyntaxErrorListener, +) +from moto.stepfunctions.parser.asl.parse.test_state.preprocessor import ( + TestStatePreprocessor, +) + + +class TestStateAmazonStateLanguageParser(AmazonStateLanguageParser): + @staticmethod + def parse(definition: str) -> Tuple[EvalComponent, ParserRuleContext]: + # Attempt to build the AST and look out for syntax errors. + syntax_error_listener = SyntaxErrorListener() + + input_stream = InputStream(definition) + lexer = ASLLexer(input_stream) + stream = CommonTokenStream(lexer) + parser = ASLParser(stream) + parser.removeErrorListeners() + parser.addErrorListener(syntax_error_listener) + # Unlike the main Program parser, TestState parsing occurs at a state declaration level. + tree = parser.state_decl_body() + + errors = syntax_error_listener.errors + if errors: + raise ASLParserException(errors=errors) + + # Attempt to preprocess the AST into evaluation components. + preprocessor = TestStatePreprocessor() + test_state_program = preprocessor.visit(tree) + + return test_state_program, tree diff --git a/moto/stepfunctions/parser/asl/parse/test_state/preprocessor.py b/moto/stepfunctions/parser/asl/parse/test_state/preprocessor.py new file mode 100644 index 000000000000..184e8f7cdf39 --- /dev/null +++ b/moto/stepfunctions/parser/asl/parse/test_state/preprocessor.py @@ -0,0 +1,161 @@ +import enum + +from moto.stepfunctions.parser.asl.antlr.runtime.ASLParser import ASLParser +from moto.stepfunctions.parser.asl.component.common.parargs import Parameters +from moto.stepfunctions.parser.asl.component.common.path.input_path import ( + InputPath, + InputPathContextObject, + InputPathVar, +) +from moto.stepfunctions.parser.asl.component.common.path.result_path import ResultPath +from moto.stepfunctions.parser.asl.component.common.query_language import QueryLanguage +from moto.stepfunctions.parser.asl.component.common.result_selector import ( + ResultSelector, +) +from moto.stepfunctions.parser.asl.component.state.choice.state_choice import ( + StateChoice, +) +from moto.stepfunctions.parser.asl.component.state.exec.execute_state import ( + ExecutionState, +) +from moto.stepfunctions.parser.asl.component.state.state import CommonStateField +from moto.stepfunctions.parser.asl.component.state.state_pass.result import Result +from moto.stepfunctions.parser.asl.component.test_state.program.test_state_program import ( + TestStateProgram, +) +from moto.stepfunctions.parser.asl.component.test_state.state.test_state_state_props import ( + TestStateStateProps, +) +from moto.stepfunctions.parser.asl.eval.test_state.environment import ( + TestStateEnvironment, +) +from moto.stepfunctions.parser.asl.parse.preprocessor import Preprocessor +from moto.stepfunctions.parser.asl.utils.encoding import to_json_str + + +class InspectionDataKey(enum.Enum): + INPUT = "input" + AFTER_INPUT_PATH = "afterInputPath" + AFTER_PARAMETERS = "afterParameters" + RESULT = "result" + AFTER_RESULT_SELECTOR = "afterResultSelector" + AFTER_RESULT_PATH = "afterResultPath" + REQUEST = "request" + RESPONSE = "response" + + +def _decorated_updated_choice_inspection_data(method): + def wrapper(env: TestStateEnvironment, *args, **kwargs): + method(env, *args, **kwargs) + env.set_choice_selected(env.next_state_name) + + return wrapper + + +def _decorated_updates_inspection_data(method, inspection_data_key: InspectionDataKey): + def wrapper(env: TestStateEnvironment, *args, **kwargs): + method(env, *args, **kwargs) + result = to_json_str(env.stack[-1]) + env.inspection_data[inspection_data_key.value] = result # noqa: we know that the here value is a supported inspection data field by design. + + return wrapper + + +def _decorate_state_field(state_field: CommonStateField) -> None: + if isinstance(state_field, ExecutionState): + state_field._eval_execution = _decorated_updates_inspection_data( + method=state_field._eval_execution, # noqa: as part of the decoration we access this protected member. + inspection_data_key=InspectionDataKey.RESULT, + ) + elif isinstance(state_field, StateChoice): + state_field._eval_body = _decorated_updated_choice_inspection_data( + method=state_field._eval_body # noqa: as part of the decoration we access this protected member. + ) + + +class TestStatePreprocessor(Preprocessor): + STATE_NAME: str = "TestState" + + def visitState_decl_body( + self, ctx: ASLParser.State_decl_bodyContext + ) -> TestStateProgram: + self._open_query_language_scope(ctx) + state_props = TestStateStateProps() + state_props.name = self.STATE_NAME + for child in ctx.children: + cmp = self.visit(child) + state_props.add(cmp) + state_field = self._common_state_field_of(state_props=state_props) + if state_props.get(QueryLanguage) is None: + state_props.add(self._get_current_query_language()) + _decorate_state_field(state_field) + self._close_query_language_scope() + return TestStateProgram(state_field) + + def visitInput_path_decl_path( + self, ctx: ASLParser.Input_path_decl_pathContext + ) -> InputPath: + input_path: InputPath = super().visitInput_path_decl_path(ctx=ctx) + input_path._eval_body = _decorated_updates_inspection_data( + method=input_path._eval_body, # noqa + inspection_data_key=InspectionDataKey.AFTER_INPUT_PATH, + ) + return input_path + + def visitInput_path_decl_path_context_object( + self, ctx: ASLParser.Input_path_decl_path_context_objectContext + ) -> InputPathContextObject: + input_path: InputPathContextObject = ( + super().visitInput_path_decl_path_context_object(ctx=ctx) + ) + input_path._eval_body = _decorated_updates_inspection_data( + method=input_path._eval_body, # noqa + inspection_data_key=InspectionDataKey.AFTER_INPUT_PATH, + ) + return input_path + + def visitInput_path_decl_var( + self, ctx: ASLParser.Input_path_decl_varContext + ) -> InputPathVar: + input_path: InputPathVar = super().visitInput_path_decl_var(ctx=ctx) + input_path._eval_body = _decorated_updates_inspection_data( + method=input_path._eval_body, # noqa + inspection_data_key=InspectionDataKey.AFTER_INPUT_PATH, + ) + return input_path + + def visitParameters_decl(self, ctx: ASLParser.Parameters_declContext) -> Parameters: + parameters: Parameters = super().visitParameters_decl(ctx=ctx) + parameters._eval_body = _decorated_updates_inspection_data( + method=parameters._eval_body, # noqa + inspection_data_key=InspectionDataKey.AFTER_PARAMETERS, + ) + return parameters + + def visitResult_selector_decl( + self, ctx: ASLParser.Result_selector_declContext + ) -> ResultSelector: + result_selector: ResultSelector = super().visitResult_selector_decl(ctx=ctx) + result_selector._eval_body = _decorated_updates_inspection_data( + method=result_selector._eval_body, # noqa + inspection_data_key=InspectionDataKey.AFTER_RESULT_SELECTOR, + ) + return result_selector + + def visitResult_path_decl( + self, ctx: ASLParser.Result_path_declContext + ) -> ResultPath: + result_path: ResultPath = super().visitResult_path_decl(ctx=ctx) + result_path._eval_body = _decorated_updates_inspection_data( + method=result_path._eval_body, # noqa + inspection_data_key=InspectionDataKey.AFTER_RESULT_PATH, + ) + return result_path + + def visitResult_decl(self, ctx: ASLParser.Result_declContext) -> Result: + result: Result = super().visitResult_decl(ctx=ctx) + result._eval_body = _decorated_updates_inspection_data( + method=result._eval_body, + inspection_data_key=InspectionDataKey.RESULT, # noqa + ) + return result diff --git a/moto/stepfunctions/parser/asl/static_analyser/__init__.py b/moto/stepfunctions/parser/asl/static_analyser/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/moto/stepfunctions/parser/asl/static_analyser/express_static_analyser.py b/moto/stepfunctions/parser/asl/static_analyser/express_static_analyser.py new file mode 100644 index 000000000000..46184baeee9b --- /dev/null +++ b/moto/stepfunctions/parser/asl/static_analyser/express_static_analyser.py @@ -0,0 +1,34 @@ +from moto.stepfunctions.parser.asl.antlr.runtime.ASLParser import ASLParser +from moto.stepfunctions.parser.asl.component.state.exec.state_task.service.resource import ( + ActivityResource, + Resource, + ResourceCondition, + ServiceResource, +) +from moto.stepfunctions.parser.asl.static_analyser.static_analyser import StaticAnalyser + + +class ExpressStaticAnalyser(StaticAnalyser): + def visitResource_decl(self, ctx: ASLParser.Resource_declContext) -> None: + # TODO add resource path to the error messages. + + resource_str: str = ctx.keyword_or_string().getText()[1:-1] + resource = Resource.from_resource_arn(resource_str) + + if isinstance(resource, ActivityResource): + raise ValueError( + "Invalid State Machine Definition: 'SCHEMA_VALIDATION_FAILED: " + "Express state machine does not support Activity ARN'" + ) + + if isinstance(resource, ServiceResource): + if resource.condition == ResourceCondition.WaitForTaskToken: + raise ValueError( + "Invalid State Machine Definition: 'SCHEMA_VALIDATION_FAILED: " + "Express state machine does not support '.sync' service integration." + ) + if resource.condition is not None: + raise ValueError( + "Invalid State Machine Definition: 'SCHEMA_VALIDATION_FAILED: " + f"Express state machine does not support .'{resource.condition}' service integration." + ) diff --git a/moto/stepfunctions/parser/asl/static_analyser/intrinsic/__init__.py b/moto/stepfunctions/parser/asl/static_analyser/intrinsic/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/moto/stepfunctions/parser/asl/static_analyser/intrinsic/intrinsic_static_analyser.py b/moto/stepfunctions/parser/asl/static_analyser/intrinsic/intrinsic_static_analyser.py new file mode 100644 index 000000000000..b179b71c0967 --- /dev/null +++ b/moto/stepfunctions/parser/asl/static_analyser/intrinsic/intrinsic_static_analyser.py @@ -0,0 +1,14 @@ +import abc + +from moto.stepfunctions.parser.asl.antlr.runtime.ASLIntrinsicParserVisitor import ( + ASLIntrinsicParserVisitor, +) +from moto.stepfunctions.parser.asl.parse.intrinsic.intrinsic_parser import ( + IntrinsicParser, +) + + +class IntrinsicStaticAnalyser(ASLIntrinsicParserVisitor, abc.ABC): + def analyse(self, definition: str) -> None: + _, parser_rule_context = IntrinsicParser.parse(definition) + self.visit(parser_rule_context) diff --git a/moto/stepfunctions/parser/asl/static_analyser/intrinsic/variable_names_intrinsic_static_analyser.py b/moto/stepfunctions/parser/asl/static_analyser/intrinsic/variable_names_intrinsic_static_analyser.py new file mode 100644 index 000000000000..938a8433b0b4 --- /dev/null +++ b/moto/stepfunctions/parser/asl/static_analyser/intrinsic/variable_names_intrinsic_static_analyser.py @@ -0,0 +1,43 @@ +from typing import Set + +from moto.stepfunctions.parser.api import VariableName, VariableNameList +from moto.stepfunctions.parser.asl.antlr.runtime.ASLIntrinsicParser import ( + ASLIntrinsicParser, +) +from moto.stepfunctions.parser.asl.jsonata.jsonata import ( + VariableReference, + extract_jsonata_variable_references, +) +from moto.stepfunctions.parser.asl.static_analyser.intrinsic.intrinsic_static_analyser import ( + IntrinsicStaticAnalyser, +) + + +class VariableNamesIntrinsicStaticAnalyser(IntrinsicStaticAnalyser): + _variable_names: VariableNameList + + def __init__(self): + super().__init__() + self._variable_names = list() + + @staticmethod + def process_and_get(definition: str) -> VariableNameList: + analyser = VariableNamesIntrinsicStaticAnalyser() + analyser.analyse(definition=definition) + return analyser.get_variable_name_list() + + def get_variable_name_list(self) -> VariableNameList: + return self._variable_names + + def visitFunc_arg_list(self, ctx: ASLIntrinsicParser.Func_arg_listContext) -> None: + # TODO: the extraction logic is not always in the same order as AWS's + for child in ctx.children[::-1]: + self.visit(child) + + def visitFunc_arg_var(self, ctx: ASLIntrinsicParser.Func_arg_varContext) -> None: + variable_references: Set[VariableReference] = ( + extract_jsonata_variable_references(ctx.STRING_VARIABLE().getText()) + ) + for variable_reference in variable_references: + variable_name: VariableName = variable_reference[1:] + self._variable_names.append(variable_name) diff --git a/moto/stepfunctions/parser/asl/static_analyser/static_analyser.py b/moto/stepfunctions/parser/asl/static_analyser/static_analyser.py new file mode 100644 index 000000000000..c759fcf8f6e7 --- /dev/null +++ b/moto/stepfunctions/parser/asl/static_analyser/static_analyser.py @@ -0,0 +1,12 @@ +import abc + +from moto.stepfunctions.parser.asl.antlr.runtime.ASLParserVisitor import ( + ASLParserVisitor, +) +from moto.stepfunctions.parser.asl.parse.asl_parser import AmazonStateLanguageParser + + +class StaticAnalyser(ASLParserVisitor, abc.ABC): + def analyse(self, definition: str) -> None: + _, parser_rule_context = AmazonStateLanguageParser.parse(definition) + self.visit(parser_rule_context) diff --git a/moto/stepfunctions/parser/asl/static_analyser/test_state/__init__.py b/moto/stepfunctions/parser/asl/static_analyser/test_state/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/moto/stepfunctions/parser/asl/static_analyser/test_state/test_state_analyser.py b/moto/stepfunctions/parser/asl/static_analyser/test_state/test_state_analyser.py new file mode 100644 index 000000000000..61e3d6af729e --- /dev/null +++ b/moto/stepfunctions/parser/asl/static_analyser/test_state/test_state_analyser.py @@ -0,0 +1,51 @@ +from typing import Set + +from moto.stepfunctions.parser.asl.antlr.runtime.ASLParser import ASLParser +from moto.stepfunctions.parser.asl.component.state.exec.state_task.service.resource import ( + ActivityResource, + Resource, + ServiceResource, +) +from moto.stepfunctions.parser.asl.component.state.state_type import StateType +from moto.stepfunctions.parser.asl.parse.test_state.asl_parser import ( + TestStateAmazonStateLanguageParser, +) +from moto.stepfunctions.parser.asl.static_analyser.static_analyser import StaticAnalyser + + +class TestStateStaticAnalyser(StaticAnalyser): + _SUPPORTED_STATE_TYPES: Set[StateType] = { + StateType.Task, + StateType.Pass, + StateType.Wait, + StateType.Choice, + StateType.Succeed, + StateType.Fail, + } + + def analyse(self, definition) -> None: + _, parser_rule_context = TestStateAmazonStateLanguageParser.parse(definition) + self.visit(parser_rule_context) + + def visitState_type(self, ctx: ASLParser.State_typeContext) -> None: + state_type_value: int = ctx.children[0].symbol.type + state_type = StateType(state_type_value) + if state_type not in self._SUPPORTED_STATE_TYPES: + raise ValueError( + f"Unsupported state type for TestState runs '{state_type}'." + ) + + def visitResource_decl(self, ctx: ASLParser.Resource_declContext) -> None: + resource_str: str = ctx.keyword_or_string().getText()[1:-1] + resource = Resource.from_resource_arn(resource_str) + + if isinstance(resource, ActivityResource): + raise ValueError( + f"ActivityResources are not supported for TestState runs {resource_str}." + ) + + if isinstance(resource, ServiceResource): + if resource.condition is not None: + raise ValueError( + f"Service integration patterns are not supported for TestState runs {resource_str}." + ) diff --git a/moto/stepfunctions/parser/asl/static_analyser/usage_metrics_static_analyser.py b/moto/stepfunctions/parser/asl/static_analyser/usage_metrics_static_analyser.py new file mode 100644 index 000000000000..06303b425b67 --- /dev/null +++ b/moto/stepfunctions/parser/asl/static_analyser/usage_metrics_static_analyser.py @@ -0,0 +1,53 @@ +import logging + +import localstack.services.stepfunctions.usage as UsageMetrics + +from moto.stepfunctions.parser.asl.antlr.runtime.ASLParser import ASLParser +from moto.stepfunctions.parser.asl.component.common.query_language import ( + QueryLanguageMode, +) +from moto.stepfunctions.parser.asl.static_analyser.static_analyser import StaticAnalyser + +LOG = logging.getLogger(__name__) + + +class UsageMetricsStaticAnalyser(StaticAnalyser): + @staticmethod + def process(definition: str) -> "UsageMetricsStaticAnalyser": + analyser = UsageMetricsStaticAnalyser() + try: + analyser.analyse(definition=definition) + + if analyser.has_jsonata: + UsageMetrics.jsonata_create_counter.increment() + else: + UsageMetrics.jsonpath_create_counter.increment() + + if analyser.has_variable_sampling: + UsageMetrics.variables_create_counter.increment() + except Exception as e: + LOG.warning( + "Failed to record Step Functions metrics from static analysis", + exc_info=e, + ) + return analyser + + def __init__(self): + super().__init__() + self.has_jsonata: bool = False + self.has_variable_sampling = False + + def visitQuery_language_decl(self, ctx: ASLParser.Query_language_declContext): + if self.has_jsonata: + return + + query_language_mode_int = ctx.children[-1].getSymbol().type + query_language_mode = QueryLanguageMode(value=query_language_mode_int) + if query_language_mode == QueryLanguageMode.JSONata: + self.has_jsonata = True + + def visitVariable_sample(self, ctx: ASLParser.Variable_sampleContext): + self.has_variable_sampling = True + + def visitAssign_decl(self, ctx: ASLParser.Assign_declContext): + self.has_variable_sampling = True diff --git a/moto/stepfunctions/parser/asl/static_analyser/variable_references_static_analyser.py b/moto/stepfunctions/parser/asl/static_analyser/variable_references_static_analyser.py new file mode 100644 index 000000000000..a7a0e52993a5 --- /dev/null +++ b/moto/stepfunctions/parser/asl/static_analyser/variable_references_static_analyser.py @@ -0,0 +1,110 @@ +from collections import OrderedDict +from typing import List, Set + +from antlr4.tree.Tree import TerminalNodeImpl + +from moto.stepfunctions.parser.api import ( + StateName, + VariableName, + VariableNameList, + VariableReferences, +) +from moto.stepfunctions.parser.asl.antlr.runtime.ASLLexer import ASLLexer +from moto.stepfunctions.parser.asl.antlr.runtime.ASLParser import ASLParser +from moto.stepfunctions.parser.asl.antlt4utils.antlr4utils import Antlr4Utils +from moto.stepfunctions.parser.asl.jsonata.jsonata import ( + VariableReference, + extract_jsonata_variable_references, +) +from moto.stepfunctions.parser.asl.static_analyser.intrinsic.variable_names_intrinsic_static_analyser import ( + VariableNamesIntrinsicStaticAnalyser, +) +from moto.stepfunctions.parser.asl.static_analyser.static_analyser import StaticAnalyser + + +class VariableReferencesStaticAnalyser(StaticAnalyser): + @staticmethod + def process_and_get(definition: str) -> VariableReferences: + analyser = VariableReferencesStaticAnalyser() + analyser.analyse(definition=definition) + return analyser.get_variable_references() + + _fringe_state_names: List[StateName] + _variable_references: VariableReferences + + def __init__(self): + super().__init__() + self._fringe_state_names = list() + self._variable_references = OrderedDict() + + def get_variable_references(self) -> VariableReferences: + return self._variable_references + + def _enter_state(self, state_name: StateName) -> None: + self._fringe_state_names.append(state_name) + + def _exit_state(self) -> None: + self._fringe_state_names.pop() + + def visitState_name(self, ctx: ASLParser.State_nameContext) -> None: + state_name: str = ctx.keyword_or_string().getText()[1:-1] + self._enter_state(state_name) + + def visitState_decl(self, ctx: ASLParser.State_declContext) -> None: + super().visitState_decl(ctx=ctx) + self._exit_state() + + def _put_variable_reference(self, variable_reference: VariableReference) -> None: + variable_name: VariableName = variable_reference[1:] + self._put_variable_name(variable_name) + + def _put_variable_name(self, variable_name: VariableName) -> None: + state_name = self._fringe_state_names[-1] + variable_name_list: VariableNameList = self._variable_references.get( + state_name, list() + ) + if variable_name in variable_name_list: + return + variable_name_list.append(variable_name) + if state_name not in self._variable_references: + self._variable_references[state_name] = variable_name_list + + def _extract_variable_references_from_string_var( + self, terminal_node: TerminalNodeImpl + ) -> None: + reference_body = terminal_node.getText()[1:-1] + variable_references: Set[VariableReference] = ( + extract_jsonata_variable_references(reference_body) + ) + for variable_reference in variable_references: + self._put_variable_reference(variable_reference) + + def _extract_variable_references_from_intrinsic_function( + self, terminal_node: TerminalNodeImpl + ) -> None: + definition_body = terminal_node.getText()[1:-1] + variable_name_list: VariableNameList = ( + VariableNamesIntrinsicStaticAnalyser.process_and_get(definition_body) + ) + for variable_name in variable_name_list: + self._put_variable_name(variable_name) + + def visitTerminal(self, node) -> None: + if Antlr4Utils.is_production(node.parentCtx, ASLParser.RULE_keyword_or_string): + return + + maybe_string_var = Antlr4Utils.is_terminal( + pt=node, token_type=ASLLexer.STRINGVAR + ) + if maybe_string_var is not None: + self._extract_variable_references_from_string_var( + terminal_node=maybe_string_var + ) + + maybe_intrinsic_function = Antlr4Utils.is_terminal( + pt=node, token_type=ASLLexer.STRINGINTRINSICFUNC + ) + if maybe_intrinsic_function is not None: + self._extract_variable_references_from_intrinsic_function( + terminal_node=maybe_intrinsic_function + ) diff --git a/moto/stepfunctions/parser/asl/utils/boto_client.py b/moto/stepfunctions/parser/asl/utils/boto_client.py index 912a835c331a..12272a2a9f3d 100644 --- a/moto/stepfunctions/parser/asl/utils/boto_client.py +++ b/moto/stepfunctions/parser/asl/utils/boto_client.py @@ -1,3 +1,5 @@ +from typing import Any + import boto3 from botocore.client import BaseClient from botocore.config import Config @@ -9,7 +11,9 @@ ) -def boto_client_for(region: str, account: str, service: str) -> BaseClient: +def boto_client_for( + region: str, account: str, service: str, credentials: Any = None +) -> BaseClient: intercepting_boto_calls = botocore_stubber.enabled kwargs = {} if not intercepting_boto_calls: diff --git a/moto/stepfunctions/parser/asl/utils/json_path.py b/moto/stepfunctions/parser/asl/utils/json_path.py index 5263f562643c..2d24d52b4b85 100644 --- a/moto/stepfunctions/parser/asl/utils/json_path.py +++ b/moto/stepfunctions/parser/asl/utils/json_path.py @@ -1,26 +1,40 @@ import json +import re from jsonpath_ng.ext import parse from jsonpath_ng.jsonpath import Index from moto.stepfunctions.parser.asl.utils.encoding import to_json_str +_PATTERN_SINGLETON_ARRAY_ACCESS_OUTPUT: str = r"\[\d+\$" -class JSONPathUtils: - @staticmethod - def extract_json(path: str, data: json) -> json: - input_expr = parse(path) - matches = input_expr.find(data) - if not matches: - raise RuntimeError( - f"The JSONPath {path} could not be found in the input {to_json_str(data)}" - ) - if ( - len(matches) > 1 - or isinstance(matches[0].path, Index) - or (matches[0].context and isinstance(matches[0].context.path, Index)) - ): - value = [match.value for match in matches] - else: - value = matches[0].value - return value + +def _is_singleton_array_access(path: str) -> bool: + # Returns true if the json path terminates with a literal singleton array access. + return bool(re.search(_PATTERN_SINGLETON_ARRAY_ACCESS_OUTPUT, path)) + + +def extract_json(path: str, data: json) -> json: + input_expr = parse(path) + + matches = input_expr.find(data) + if not matches: + raise RuntimeError( + f"The JSONPath {path} could not be found in the input {to_json_str(data)}" + ) + + if ( + len(matches) > 1 + or isinstance(matches[0].path, Index) + or (matches[0].context and isinstance(matches[0].context.path, Index)) + ): + value = [match.value for match in matches] + + # AWS StepFunctions breaks jsonpath specifications and instead + # unpacks literal singleton array accesses. + if _is_singleton_array_access(path=path) and len(value) == 1: + value = value[0] + else: + value = matches[0].value + + return value diff --git a/moto/stepfunctions/parser/backend/activity.py b/moto/stepfunctions/parser/backend/activity.py new file mode 100644 index 000000000000..6701f07cf4a1 --- /dev/null +++ b/moto/stepfunctions/parser/backend/activity.py @@ -0,0 +1,51 @@ +import datetime +from collections import deque +from typing import Deque, Optional + +from moto.stepfunctions.parser.api import ( + ActivityListItem, + Arn, + DescribeActivityOutput, + Name, + Timestamp, +) + + +class ActivityTask: + task_input: str + task_token: str + + def __init__(self, task_token: str, task_input: str): + self.task_token = task_token + self.task_input = task_input + + +class Activity: + arn: Arn + name: Name + creation_date: Timestamp + _tasks: Deque[ActivityTask] + + def __init__(self, arn: Arn, name: Name, creation_date: Optional[Timestamp] = None): + self.arn = arn + self.name = name + self.creation_date = creation_date or datetime.datetime.now( + tz=datetime.timezone.utc + ) + self._tasks = deque() + + def add_task(self, task: ActivityTask): + self._tasks.append(task) + + def get_task(self) -> Optional[ActivityTask]: + return self._tasks.popleft() + + def to_describe_activity_output(self) -> DescribeActivityOutput: + return DescribeActivityOutput( + activityArn=self.arn, name=self.name, creationDate=self.creation_date + ) + + def to_activity_list_item(self) -> ActivityListItem: + return ActivityListItem( + activityArn=self.arn, name=self.name, creationDate=self.creation_date + ) diff --git a/moto/stepfunctions/parser/backend/execution.py b/moto/stepfunctions/parser/backend/execution.py index 5cfe66262081..eeb5d0fe1ca9 100644 --- a/moto/stepfunctions/parser/backend/execution.py +++ b/moto/stepfunctions/parser/backend/execution.py @@ -1,29 +1,38 @@ from __future__ import annotations import datetime +import json import logging -from typing import Optional +from typing import Dict, Optional -from moto.core.utils import iso_8601_datetime_with_milliseconds -from moto.stepfunctions.models import Execution as SimpleExecution -from moto.stepfunctions.models import StateMachine from moto.stepfunctions.parser.api import ( + Arn, CloudWatchEventsExecutionDataDetails, + DescribeExecutionOutput, DescribeStateMachineForExecutionOutput, ExecutionListItem, ExecutionStatus, + GetExecutionHistoryOutput, + HistoryEventList, InvalidName, + SensitiveCause, + SensitiveError, + StartExecutionOutput, + StartSyncExecutionOutput, + StateMachineType, + SyncExecutionStatus, + Timestamp, TraceHeader, + VariableReferences, ) -from moto.stepfunctions.parser.asl.eval.aws_execution_details import AWSExecutionDetails -from moto.stepfunctions.parser.asl.eval.contextobject.contex_object import ( - ContextObjectInitData, +from moto.stepfunctions.parser.asl.eval.evaluation_details import ( + AWSExecutionDetails, + EvaluationDetails, + ExecutionDetails, + StateMachineDetails, ) -from moto.stepfunctions.parser.asl.eval.contextobject.contex_object import ( - Execution as ContextObjectExecution, -) -from moto.stepfunctions.parser.asl.eval.contextobject.contex_object import ( - StateMachine as ContextObjectStateMachine, +from moto.stepfunctions.parser.asl.eval.event.logging import ( + CloudWatchLoggingSession, ) from moto.stepfunctions.parser.asl.eval.program_state import ( ProgramEnded, @@ -32,9 +41,18 @@ ProgramStopped, ProgramTimedOut, ) +from moto.stepfunctions.parser.asl.static_analyser.variable_references_static_analyser import ( + VariableReferencesStaticAnalyser, +) from moto.stepfunctions.parser.asl.utils.encoding import to_json_str -from moto.stepfunctions.parser.backend.execution_worker import ExecutionWorker -from moto.stepfunctions.parser.backend.execution_worker_comm import ExecutionWorkerComm +from moto.stepfunctions.parser.backend.activity import Activity +from moto.stepfunctions.parser.backend.execution_worker import ( + ExecutionWorker, + SyncExecutionWorker, +) +from moto.stepfunctions.parser.backend.execution_worker_comm import ( + ExecutionWorkerCommunication, +) from moto.stepfunctions.parser.backend.state_machine import ( StateMachineInstance, StateMachineVersion, @@ -43,61 +61,136 @@ LOG = logging.getLogger(__name__) -class BaseExecutionWorkerComm(ExecutionWorkerComm): +class BaseExecutionWorkerCommunication(ExecutionWorkerCommunication): + execution: Execution + def __init__(self, execution: Execution): - self.execution: Execution = execution + self.execution = execution - def terminated(self) -> None: + def _reflect_execution_status(self): exit_program_state: ProgramState = ( self.execution.exec_worker.env.program_state() ) - self.execution.stop_date = iso_8601_datetime_with_milliseconds() + self.execution.stop_date = datetime.datetime.now(tz=datetime.timezone.utc) if isinstance(exit_program_state, ProgramEnded): - self.execution.status = ExecutionStatus.SUCCEEDED - self.execution.output = to_json_str( - self.execution.exec_worker.env.inp, separators=(",", ":") - ) + self.execution.exec_status = ExecutionStatus.SUCCEEDED + self.execution.output = self.execution.exec_worker.env.states.get_input() elif isinstance(exit_program_state, ProgramStopped): - self.execution.status = ExecutionStatus.ABORTED + self.execution.exec_status = ExecutionStatus.ABORTED elif isinstance(exit_program_state, ProgramError): - self.execution.status = ExecutionStatus.FAILED + self.execution.exec_status = ExecutionStatus.FAILED self.execution.error = exit_program_state.error.get("error") self.execution.cause = exit_program_state.error.get("cause") elif isinstance(exit_program_state, ProgramTimedOut): - self.execution.status = ExecutionStatus.TIMED_OUT + self.execution.exec_status = ExecutionStatus.TIMED_OUT else: raise RuntimeWarning( f"Execution ended with unsupported ProgramState type '{type(exit_program_state)}'." ) + def terminated(self) -> None: + self._reflect_execution_status() + + +class Execution: + name: str + sm_type: StateMachineType + role_arn: Arn + exec_arn: Arn + + account_id: str + region_name: str + + state_machine: StateMachineInstance + start_date: Timestamp + input_data: Optional[json] + input_details: Optional[CloudWatchEventsExecutionDataDetails] + trace_header: Optional[TraceHeader] + _cloud_watch_logging_session: Optional[CloudWatchLoggingSession] + + exec_status: Optional[ExecutionStatus] + stop_date: Optional[Timestamp] + + output: Optional[json] + output_details: Optional[CloudWatchEventsExecutionDataDetails] + + error: Optional[SensitiveError] + cause: Optional[SensitiveCause] + + exec_worker: Optional[ExecutionWorker] + + _activity_store: Dict[Arn, Activity] -class Execution(SimpleExecution): def __init__( self, name: str, - role_arn: str, + sm_type: StateMachineType, + role_arn: Arn, + exec_arn: Arn, account_id: str, region_name: str, - state_machine: StateMachine, - input_data: Optional[dict] = None, + state_machine: StateMachineInstance, + start_date: Timestamp, + cloud_watch_logging_session: Optional[CloudWatchLoggingSession], + activity_store: Dict[Arn, Activity], + input_data: Optional[json] = None, trace_header: Optional[TraceHeader] = None, ): - super().__init__( - region_name=region_name, - account_id=account_id, - state_machine_name=state_machine.name, - state_machine_arn=state_machine.arn, - execution_name=name, - execution_input=input_data, - ) + self.name = name + self.sm_type = sm_type self.role_arn = role_arn + self.exec_arn = exec_arn + self.execution_arn = exec_arn + self.account_id = account_id + self.region_name = region_name self.state_machine = state_machine + self._cloud_watch_logging_session = cloud_watch_logging_session self.input_data = input_data self.input_details = CloudWatchEventsExecutionDataDetails(included=True) self.trace_header = trace_header - self.status = None + self.exec_status = None + self.stop_date = None + self.output = None self.output_details = CloudWatchEventsExecutionDataDetails(included=True) - self.exec_worker: Optional[ExecutionWorker] = None + self.exec_worker = None + self.error = None + self.cause = None + self._activity_store = activity_store + + # Compatibility with mock SFN + self.state_machine_arn = state_machine.arn + self.start_date = start_date + self.execution_input = input_data + + @property + def status(self): + return self.exec_status.value + + def to_start_output(self) -> StartExecutionOutput: + return StartExecutionOutput( + executionArn=self.exec_arn, startDate=self.start_date + ) + + def to_describe_output(self) -> DescribeExecutionOutput: + describe_output = DescribeExecutionOutput( + executionArn=self.exec_arn, + stateMachineArn=self.state_machine.arn, + name=self.name, + status=self.exec_status, + startDate=self.start_date, + stopDate=self.stop_date, + input=to_json_str(self.input_data, separators=(",", ":")), + inputDetails=self.input_details, + traceHeader=self.trace_header, + ) + if describe_output["status"] == ExecutionStatus.SUCCEEDED: + describe_output["output"] = to_json_str(self.output, separators=(",", ":")) + describe_output["outputDetails"] = self.output_details + if self.error is not None: + describe_output["error"] = self.error + if self.cause is not None: + describe_output["cause"] = self.cause + return describe_output def to_describe_state_machine_for_execution_output( self, @@ -115,10 +208,18 @@ def to_describe_state_machine_for_execution_output( roleArn=self.role_arn, # The date and time the state machine associated with an execution was updated. updateDate=state_machine.create_date, + loggingConfiguration=state_machine.logging_config, ) revision_id = self.state_machine.revision_id if self.state_machine.revision_id: out["revisionId"] = revision_id + variable_references: VariableReferences = ( + VariableReferencesStaticAnalyser.process_and_get( + definition=self.state_machine.definition + ) + ) + if variable_references: + out["variableReferences"] = variable_references return out def to_execution_list_item(self) -> ExecutionListItem: @@ -130,10 +231,10 @@ def to_execution_list_item(self) -> ExecutionListItem: state_machine_version_arn = None item = ExecutionListItem( - executionArn=self.execution_arn, + executionArn=self.exec_arn, stateMachineArn=state_machine_arn, name=self.name, - status=self.status, + status=self.exec_status, startDate=self.start_date, stopDate=self.stop_date, ) @@ -141,46 +242,117 @@ def to_execution_list_item(self) -> ExecutionListItem: item["stateMachineVersionArn"] = state_machine_version_arn return item - def to_history_output(self): - return self.exec_worker.env.event_history.get_event_history() + def to_history_output(self) -> GetExecutionHistoryOutput: + env = self.exec_worker.env + event_history: HistoryEventList = list() + if env is not None: + # The execution has not started yet. + event_history: HistoryEventList = env.event_manager.get_event_history() + return GetExecutionHistoryOutput(events=event_history) - @staticmethod - def _to_serialized_date(timestamp: datetime.datetime) -> str: - """See test in tests.aws.services.stepfunctions.v2.base.test_base.TestSnfBase.test_execution_dateformat""" - return f'{timestamp.astimezone(datetime.timezone.utc).strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3]}Z' + def _get_start_execution_worker_comm(self) -> BaseExecutionWorkerCommunication: + return BaseExecutionWorkerCommunication(self) + + def _get_start_aws_execution_details(self) -> AWSExecutionDetails: + return AWSExecutionDetails( + account=self.account_id, region=self.region_name, role_arn=self.role_arn + ) + + def get_start_execution_details(self) -> ExecutionDetails: + return ExecutionDetails( + arn=self.exec_arn, + name=self.name, + role_arn=self.role_arn, + inpt=self.input_data, + start_time=self.start_date, + ) + + def get_start_state_machine_details(self) -> StateMachineDetails: + return StateMachineDetails( + arn=self.state_machine.arn, + name=self.state_machine.name, + typ=self.state_machine.sm_type, + definition=self.state_machine.definition, + ) + + def _get_start_execution_worker(self) -> ExecutionWorker: + return ExecutionWorker( + evaluation_details=EvaluationDetails( + aws_execution_details=self._get_start_aws_execution_details(), + execution_details=self.get_start_execution_details(), + state_machine_details=self.get_start_state_machine_details(), + ), + exec_comm=self._get_start_execution_worker_comm(), + cloud_watch_logging_session=self._cloud_watch_logging_session, + activity_store=self._activity_store, + ) def start(self) -> None: # TODO: checks exec_worker does not exists already? if self.exec_worker: raise InvalidName() # TODO. - self.exec_worker = ExecutionWorker( - definition=self.state_machine.definition, - input_data=self.input_data, - exec_comm=BaseExecutionWorkerComm(self), - context_object_init=ContextObjectInitData( - Execution=ContextObjectExecution( - Id=self.execution_arn, - Input=self.input_data, - Name=self.name, - RoleArn=self.role_arn, - StartTime=self.start_date, - ), - StateMachine=ContextObjectStateMachine( - Id=self.state_machine.arn, - Name=self.state_machine.name, - ), - ), - aws_execution_details=AWSExecutionDetails( - account=self.account_id, region=self.region_name, role_arn=self.role_arn - ), - ) - self.status = ExecutionStatus.RUNNING + self.exec_worker = self._get_start_execution_worker() + self.exec_status = ExecutionStatus.RUNNING self.exec_worker.start() def stop( self, stop_date: datetime.datetime, error: Optional[str], cause: Optional[str] ): exec_worker: Optional[ExecutionWorker] = self.exec_worker - if not exec_worker: - raise RuntimeError("No running executions.") - exec_worker.stop(stop_date=stop_date, cause=cause, error=error) + if exec_worker: + exec_worker.stop(stop_date=stop_date, cause=cause, error=error) + + +class SyncExecutionWorkerCommunication(BaseExecutionWorkerCommunication): + execution: SyncExecution + + def _reflect_execution_status(self) -> None: + super()._reflect_execution_status() + exit_status: ExecutionStatus = self.execution.exec_status + if exit_status == ExecutionStatus.SUCCEEDED: + self.execution.sync_execution_status = SyncExecutionStatus.SUCCEEDED + elif exit_status == ExecutionStatus.TIMED_OUT: + self.execution.sync_execution_status = SyncExecutionStatus.TIMED_OUT + else: + self.execution.sync_execution_status = SyncExecutionStatus.FAILED + + +class SyncExecution(Execution): + sync_execution_status: Optional[SyncExecutionStatus] = None + + def _get_start_execution_worker(self) -> SyncExecutionWorker: + return SyncExecutionWorker( + evaluation_details=EvaluationDetails( + aws_execution_details=self._get_start_aws_execution_details(), + execution_details=self.get_start_execution_details(), + state_machine_details=self.get_start_state_machine_details(), + ), + exec_comm=self._get_start_execution_worker_comm(), + cloud_watch_logging_session=self._cloud_watch_logging_session, + activity_store=self._activity_store, + ) + + def _get_start_execution_worker_comm(self) -> BaseExecutionWorkerCommunication: + return SyncExecutionWorkerCommunication(self) + + def to_start_sync_execution_output(self) -> StartSyncExecutionOutput: + start_output = StartSyncExecutionOutput( + executionArn=self.exec_arn, + stateMachineArn=self.state_machine.arn, + name=self.name, + status=self.sync_execution_status, + startDate=self.start_date, + stopDate=self.stop_date, + input=to_json_str(self.input_data, separators=(",", ":")), + inputDetails=self.input_details, + traceHeader=self.trace_header, + ) + if self.sync_execution_status == SyncExecutionStatus.SUCCEEDED: + start_output["output"] = to_json_str(self.output, separators=(",", ":")) + if self.output_details: + start_output["outputDetails"] = self.output_details + if self.error is not None: + start_output["error"] = self.error + if self.cause is not None: + start_output["cause"] = self.cause + return start_output diff --git a/moto/stepfunctions/parser/backend/execution_worker.py b/moto/stepfunctions/parser/backend/execution_worker.py index a6ec968e8e78..f098ba2aae61 100644 --- a/moto/stepfunctions/parser/backend/execution_worker.py +++ b/moto/stepfunctions/parser/backend/execution_worker.py @@ -1,71 +1,99 @@ -import copy import datetime from threading import Thread -from typing import Final, Optional +from typing import Dict, Optional from moto.stepfunctions.parser.api import ( - Definition, + Arn, ExecutionStartedEventDetails, HistoryEventExecutionDataDetails, HistoryEventType, ) -from moto.stepfunctions.parser.asl.component.program.program import Program -from moto.stepfunctions.parser.asl.eval.aws_execution_details import AWSExecutionDetails -from moto.stepfunctions.parser.asl.eval.contextobject.contex_object import ( - ContextObjectInitData, -) +from moto.stepfunctions.parser.asl.component.eval_component import EvalComponent from moto.stepfunctions.parser.asl.eval.environment import Environment +from moto.stepfunctions.parser.asl.eval.evaluation_details import EvaluationDetails from moto.stepfunctions.parser.asl.eval.event.event_detail import EventDetails -from moto.stepfunctions.parser.asl.eval.event.event_history import EventHistoryContext +from moto.stepfunctions.parser.asl.eval.event.event_manager import ( + EventHistoryContext, +) +from moto.stepfunctions.parser.asl.eval.event.logging import ( + CloudWatchLoggingSession, +) +from moto.stepfunctions.parser.asl.eval.states import ( + ContextObjectData, + ExecutionData, + StateMachineData, +) from moto.stepfunctions.parser.asl.parse.asl_parser import AmazonStateLanguageParser from moto.stepfunctions.parser.asl.utils.encoding import to_json_str -from moto.stepfunctions.parser.backend.execution_worker_comm import ExecutionWorkerComm +from moto.stepfunctions.parser.backend.activity import Activity +from moto.stepfunctions.parser.backend.execution_worker_comm import ( + ExecutionWorkerCommunication, +) +from moto.stepfunctions.parser.utils import TMP_THREADS class ExecutionWorker: + _evaluation_details: EvaluationDetails + _execution_communication: ExecutionWorkerCommunication + _cloud_watch_logging_session: Optional[CloudWatchLoggingSession] + _activity_store: Dict[Arn, Activity] + env: Optional[Environment] - _definition: Definition - _input_data: Optional[dict] - _exec_comm: Final[ExecutionWorkerComm] - _context_object_init: Final[ContextObjectInitData] - _aws_execution_details: Final[AWSExecutionDetails] def __init__( self, - definition: Definition, - input_data: Optional[dict], - context_object_init: ContextObjectInitData, - aws_execution_details: AWSExecutionDetails, - exec_comm: ExecutionWorkerComm, + evaluation_details: EvaluationDetails, + exec_comm: ExecutionWorkerCommunication, + cloud_watch_logging_session: Optional[CloudWatchLoggingSession], + activity_store: Dict[Arn, Activity], ): - self._definition = definition - self._input_data = input_data - self._exec_comm = exec_comm - self._context_object_init = context_object_init - self._aws_execution_details = aws_execution_details + self._evaluation_details = evaluation_details + self._execution_communication = exec_comm + self._cloud_watch_logging_session = cloud_watch_logging_session + self._activity_store = activity_store self.env = None - def _execution_logic(self) -> None: - program: Program = AmazonStateLanguageParser.parse(self._definition) - self.env = Environment( - aws_execution_details=self._aws_execution_details, - context_object_init=self._context_object_init, + def _get_evaluation_entrypoint(self) -> EvalComponent: + return AmazonStateLanguageParser.parse( + self._evaluation_details.state_machine_details.definition + )[0] + + def _get_evaluation_environment(self) -> Environment: + return Environment( + aws_execution_details=self._evaluation_details.aws_execution_details, + execution_type=self._evaluation_details.state_machine_details.typ, + context=ContextObjectData( + Execution=ExecutionData( + Id=self._evaluation_details.execution_details.arn, + Input=self._evaluation_details.execution_details.inpt, + Name=self._evaluation_details.execution_details.name, + RoleArn=self._evaluation_details.execution_details.role_arn, + StartTime=self._evaluation_details.execution_details.start_time, + ), + StateMachine=StateMachineData( + Id=self._evaluation_details.state_machine_details.arn, + Name=self._evaluation_details.state_machine_details.name, + ), + ), event_history_context=EventHistoryContext.of_program_start(), + cloud_watch_logging_session=self._cloud_watch_logging_session, + activity_store=self._activity_store, ) - self.env.inp = copy.deepcopy( - self._input_data - ) # The program will mutate the input_data, which is otherwise constant in regard to the execution value. - self.env.event_history.add_event( + def _execution_logic(self): + program = self._get_evaluation_entrypoint() + self.env = self._get_evaluation_environment() + + self.env.event_manager.add_event( context=self.env.event_history_context, - hist_type_event=HistoryEventType.ExecutionStarted, - event_detail=EventDetails( + event_type=HistoryEventType.ExecutionStarted, + event_details=EventDetails( executionStartedEventDetails=ExecutionStartedEventDetails( - input=to_json_str(self.env.inp), + input=to_json_str(self._evaluation_details.execution_details.inpt), inputDetails=HistoryEventExecutionDataDetails( truncated=False ), # Always False for api calls. - roleArn=self._aws_execution_details.role_arn, + roleArn=self._evaluation_details.aws_execution_details.role_arn, ) ), update_source_event_id=False, @@ -73,12 +101,20 @@ def _execution_logic(self) -> None: program.eval(self.env) - self._exec_comm.terminated() + self._execution_communication.terminated() - def start(self) -> None: - Thread(target=self._execution_logic).start() + def start(self): + execution_logic_thread = Thread(target=self._execution_logic, daemon=True) + TMP_THREADS.append(execution_logic_thread) + execution_logic_thread.start() def stop( self, stop_date: datetime.datetime, error: Optional[str], cause: Optional[str] - ) -> None: + ): self.env.set_stop(stop_date=stop_date, cause=cause, error=error) + + +class SyncExecutionWorker(ExecutionWorker): + def start(self): + # bypass the native async execution of ASL programs. + self._execution_logic() diff --git a/moto/stepfunctions/parser/backend/execution_worker_comm.py b/moto/stepfunctions/parser/backend/execution_worker_comm.py index cb82687d7bd4..c2e1d74849bb 100644 --- a/moto/stepfunctions/parser/backend/execution_worker_comm.py +++ b/moto/stepfunctions/parser/backend/execution_worker_comm.py @@ -1,7 +1,7 @@ import abc -class ExecutionWorkerComm(abc.ABC): +class ExecutionWorkerCommunication(abc.ABC): """ Defines abstract callbacks for Execution's workers to report their progress, such as termination. Execution instances define custom callbacks routines to update their state according to the latest diff --git a/moto/stepfunctions/parser/backend/state_machine.py b/moto/stepfunctions/parser/backend/state_machine.py index fe6f54865143..26e337708ceb 100644 --- a/moto/stepfunctions/parser/backend/state_machine.py +++ b/moto/stepfunctions/parser/backend/state_machine.py @@ -6,11 +6,9 @@ from collections import OrderedDict from typing import Dict, Final, Optional -from moto.moto_api._internal import mock_random from moto.stepfunctions.parser.api import ( Definition, DescribeStateMachineOutput, - EncryptionConfiguration, LoggingConfiguration, Name, RevisionId, @@ -23,7 +21,15 @@ TagList, TracingConfiguration, ValidationException, + VariableReferences, ) +from moto.stepfunctions.parser.asl.eval.event.logging import ( + CloudWatchLoggingConfiguration, +) +from moto.stepfunctions.parser.asl.static_analyser.variable_references_static_analyser import ( + VariableReferencesStaticAnalyser, +) +from moto.stepfunctions.parser.utils import long_uid class StateMachineInstance: @@ -34,10 +40,10 @@ class StateMachineInstance: role_arn: str create_date: datetime.datetime sm_type: StateMachineType - logging_config: Optional[LoggingConfiguration] + logging_config: LoggingConfiguration + cloud_watch_logging_configuration: Optional[CloudWatchLoggingConfiguration] tags: Optional[TagList] tracing_config: Optional[TracingConfiguration] - encryption_config: Optional[EncryptionConfiguration] def __init__( self, @@ -45,12 +51,14 @@ def __init__( arn: str, definition: Definition, role_arn: str, + logging_config: LoggingConfiguration, + cloud_watch_logging_configuration: Optional[ + CloudWatchLoggingConfiguration + ] = None, create_date: Optional[datetime.datetime] = None, sm_type: Optional[StateMachineType] = None, - logging_config: Optional[LoggingConfiguration] = None, tags: Optional[TagList] = None, tracing_config: Optional[TracingConfiguration] = None, - encryption_config: Optional[EncryptionConfiguration] = None, ): self.name = name self.arn = arn @@ -62,9 +70,9 @@ def __init__( ) self.sm_type = sm_type or StateMachineType.STANDARD self.logging_config = logging_config + self.cloud_watch_logging_configuration = cloud_watch_logging_configuration self.tags = tags self.tracing_config = tracing_config - self.encryption_config = encryption_config def describe(self) -> DescribeStateMachineOutput: describe_output = DescribeStateMachineOutput( @@ -76,16 +84,48 @@ def describe(self) -> DescribeStateMachineOutput: type=self.sm_type, creationDate=self.create_date, loggingConfiguration=self.logging_config, - encryptionConfiguration=self.encryption_config, ) + if self.revision_id: describe_output["revisionId"] = self.revision_id + + variable_references: VariableReferences = ( + VariableReferencesStaticAnalyser.process_and_get(definition=self.definition) + ) + if variable_references: + describe_output["variableReferences"] = variable_references + return describe_output @abc.abstractmethod def itemise(self): ... +class TestStateMachine(StateMachineInstance): + def __init__( + self, + name: Name, + arn: str, + definition: Definition, + role_arn: str, + create_date: Optional[datetime.datetime] = None, + ): + super().__init__( + name, + arn, + definition, + role_arn, + create_date, + StateMachineType.STANDARD, + None, + None, + None, + ) + + def itemise(self): + raise NotImplementedError("TestStateMachine does not support itemise.") + + class TagManager: _tags: Final[Dict[str, Optional[str]]] @@ -133,9 +173,10 @@ def __init__( arn: str, definition: Definition, role_arn: str, + logging_config: LoggingConfiguration, + cloud_watch_logging_configuration: Optional[CloudWatchLoggingConfiguration], create_date: Optional[datetime.datetime] = None, sm_type: Optional[StateMachineType] = None, - logging_config: Optional[LoggingConfiguration] = None, tags: Optional[TagList] = None, tracing_config: Optional[TracingConfiguration] = None, ): @@ -144,18 +185,24 @@ def __init__( arn, definition, role_arn, + logging_config, + cloud_watch_logging_configuration, create_date, sm_type, - logging_config, tags, tracing_config, ) self.versions = dict() self._version_number = 0 self.tag_manager = TagManager() + if tags: + self.tag_manager.add_all(tags) def create_revision( - self, definition: Optional[str], role_arn: Optional[str] + self, + definition: Optional[str], + role_arn: Optional[str], + logging_configuration: Optional[LoggingConfiguration], ) -> Optional[RevisionId]: update_definition = definition and json.loads(definition) != json.loads( self.definition @@ -167,8 +214,20 @@ def create_revision( if update_role_arn: self.role_arn = role_arn - if any([update_definition, update_role_arn]): - self.revision_id = str(mock_random.uuid4()) + update_logging_configuration = ( + logging_configuration and logging_configuration != self.logging_config + ) + if update_logging_configuration: + self.logging_config = logging_configuration + self.cloud_watch_logging_configuration = ( + CloudWatchLoggingConfiguration.from_logging_configuration( + state_machine_arn=self.arn, + logging_configuration=self.logging_config, + ) + ) + + if any([update_definition, update_role_arn, update_logging_configuration]): + self.revision_id = long_uid() return self.revision_id @@ -222,9 +281,9 @@ def __init__( create_date=datetime.datetime.now(tz=datetime.timezone.utc), sm_type=state_machine_revision.sm_type, logging_config=state_machine_revision.logging_config, + cloud_watch_logging_configuration=state_machine_revision.cloud_watch_logging_configuration, tags=state_machine_revision.tags, tracing_config=state_machine_revision.tracing_config, - encryption_config=state_machine_revision.encryption_config, ) self.source_arn = state_machine_revision.arn self.revision_id = state_machine_revision.revision_id diff --git a/moto/stepfunctions/parser/backend/store.py b/moto/stepfunctions/parser/backend/store.py new file mode 100644 index 000000000000..661b38dcf92d --- /dev/null +++ b/moto/stepfunctions/parser/backend/store.py @@ -0,0 +1,22 @@ +from collections import OrderedDict +from typing import Dict + +from localstack.services.stores import AccountRegionBundle, BaseStore, LocalAttribute + +from moto.stepfunctions.parser.api import Arn +from moto.stepfunctions.parser.backend.activity import Activity +from moto.stepfunctions.parser.backend.execution import Execution +from moto.stepfunctions.parser.backend.state_machine import StateMachineInstance + + +class SFNStore(BaseStore): + # Maps ARNs to state machines. + state_machines: Dict[Arn, StateMachineInstance] = LocalAttribute(default=dict) + # Maps Execution-ARNs to state machines. + executions: Dict[Arn, Execution] = LocalAttribute( + default=OrderedDict + ) # TODO: when snapshot to pods stop execution(?) + activities: OrderedDict[Arn, Activity] = LocalAttribute(default=dict) + + +sfn_stores: AccountRegionBundle = AccountRegionBundle("stepfunctions", SFNStore) diff --git a/moto/stepfunctions/parser/backend/test_state/__init__.py b/moto/stepfunctions/parser/backend/test_state/__init__.py new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/moto/stepfunctions/parser/backend/test_state/execution.py b/moto/stepfunctions/parser/backend/test_state/execution.py new file mode 100644 index 000000000000..ad493951646e --- /dev/null +++ b/moto/stepfunctions/parser/backend/test_state/execution.py @@ -0,0 +1,145 @@ +from __future__ import annotations + +import logging +import threading +from typing import Dict, Optional + +from moto.stepfunctions.parser.api import ( + Arn, + ExecutionStatus, + InspectionLevel, + StateMachineType, + TestExecutionStatus, + TestStateOutput, + Timestamp, +) +from moto.stepfunctions.parser.asl.eval.evaluation_details import EvaluationDetails +from moto.stepfunctions.parser.asl.eval.program_state import ( + ProgramEnded, + ProgramError, + ProgramState, +) +from moto.stepfunctions.parser.asl.eval.test_state.program_state import ( + ProgramChoiceSelected, +) +from moto.stepfunctions.parser.asl.utils.encoding import to_json_str +from moto.stepfunctions.parser.backend.activity import Activity +from moto.stepfunctions.parser.backend.execution import ( + BaseExecutionWorkerCommunication, + Execution, +) +from moto.stepfunctions.parser.backend.state_machine import StateMachineInstance +from moto.stepfunctions.parser.backend.test_state.execution_worker import ( + TestStateExecutionWorker, +) + +LOG = logging.getLogger(__name__) + + +class TestStateExecution(Execution): + exec_worker: Optional[TestStateExecutionWorker] + next_state: Optional[str] + + class TestCaseExecutionWorkerCommunication(BaseExecutionWorkerCommunication): + _execution: TestStateExecution + + def terminated(self) -> None: + exit_program_state: ProgramState = ( + self.execution.exec_worker.env.program_state() + ) + if isinstance(exit_program_state, ProgramChoiceSelected): + self.execution.exec_status = ExecutionStatus.SUCCEEDED + self.execution.output = ( + self.execution.exec_worker.env.states.get_input() + ) + self.execution.next_state = exit_program_state.next_state_name + else: + self._reflect_execution_status() + + def __init__( + self, + name: str, + role_arn: Arn, + exec_arn: Arn, + account_id: str, + region_name: str, + state_machine: StateMachineInstance, + start_date: Timestamp, + activity_store: Dict[Arn, Activity], + input_data: Optional[Dict] = None, + ): + super().__init__( + name=name, + sm_type=StateMachineType.STANDARD, + role_arn=role_arn, + exec_arn=exec_arn, + account_id=account_id, + region_name=region_name, + state_machine=state_machine, + start_date=start_date, + activity_store=activity_store, + input_data=input_data, + cloud_watch_logging_session=None, + trace_header=None, + ) + self._execution_terminated_event = threading.Event() + self.next_state = None + + def _get_start_execution_worker_comm(self) -> BaseExecutionWorkerCommunication: + return self.TestCaseExecutionWorkerCommunication(self) + + def _get_start_execution_worker(self) -> TestStateExecutionWorker: + return TestStateExecutionWorker( + evaluation_details=EvaluationDetails( + aws_execution_details=self._get_start_aws_execution_details(), + execution_details=self.get_start_execution_details(), + state_machine_details=self.get_start_state_machine_details(), + ), + exec_comm=self._get_start_execution_worker_comm(), + cloud_watch_logging_session=self._cloud_watch_logging_session, + activity_store=self._activity_store, + ) + + def publish_execution_status_change_event(self): + # Do not publish execution status change events during test state execution. + pass + + def to_test_state_output( + self, inspection_level: InspectionLevel + ) -> TestStateOutput: + exit_program_state: ProgramState = self.exec_worker.env.program_state() + if isinstance(exit_program_state, ProgramEnded): + output_str = to_json_str(self.output) + test_state_output = TestStateOutput( + status=TestExecutionStatus.SUCCEEDED, output=output_str + ) + elif isinstance(exit_program_state, ProgramError): + test_state_output = TestStateOutput( + status=TestExecutionStatus.FAILED, + error=exit_program_state.error["error"], + cause=exit_program_state.error["cause"], + ) + elif isinstance(exit_program_state, ProgramChoiceSelected): + output_str = to_json_str(self.output) + test_state_output = TestStateOutput( + status=TestExecutionStatus.SUCCEEDED, + nextState=self.next_state, + output=output_str, + ) + else: + # TODO: handle other statuses + LOG.warning( + "Unsupported StateMachine exit type for TestState '%s'", + type(exit_program_state), + ) + output_str = to_json_str(self.output) + test_state_output = TestStateOutput( + status=TestExecutionStatus.FAILED, output=output_str + ) + + if inspection_level == InspectionLevel.TRACE: + test_state_output["inspectionData"] = self.exec_worker.env.inspection_data + elif inspection_level == InspectionLevel.DEBUG: + test_state_output["inspectionData"] = self.exec_worker.env.inspection_data + + return test_state_output diff --git a/moto/stepfunctions/parser/backend/test_state/execution_worker.py b/moto/stepfunctions/parser/backend/test_state/execution_worker.py new file mode 100644 index 000000000000..e1122643136c --- /dev/null +++ b/moto/stepfunctions/parser/backend/test_state/execution_worker.py @@ -0,0 +1,50 @@ +from typing import Optional + +from moto.stepfunctions.parser.asl.component.eval_component import EvalComponent +from moto.stepfunctions.parser.asl.eval.environment import Environment +from moto.stepfunctions.parser.asl.eval.event.event_manager import ( + EventHistoryContext, +) +from moto.stepfunctions.parser.asl.eval.states import ( + ContextObjectData, + ExecutionData, + StateMachineData, +) +from moto.stepfunctions.parser.asl.eval.test_state.environment import ( + TestStateEnvironment, +) +from moto.stepfunctions.parser.asl.parse.test_state.asl_parser import ( + TestStateAmazonStateLanguageParser, +) +from moto.stepfunctions.parser.backend.execution_worker import SyncExecutionWorker + + +class TestStateExecutionWorker(SyncExecutionWorker): + env: Optional[TestStateEnvironment] + + def _get_evaluation_entrypoint(self) -> EvalComponent: + return TestStateAmazonStateLanguageParser.parse( + self._evaluation_details.state_machine_details.definition + )[0] + + def _get_evaluation_environment(self) -> Environment: + return TestStateEnvironment( + aws_execution_details=self._evaluation_details.aws_execution_details, + execution_type=self._evaluation_details.state_machine_details.typ, + context=ContextObjectData( + Execution=ExecutionData( + Id=self._evaluation_details.execution_details.arn, + Input=self._evaluation_details.execution_details.inpt, + Name=self._evaluation_details.execution_details.name, + RoleArn=self._evaluation_details.execution_details.role_arn, + StartTime=self._evaluation_details.execution_details.start_time, + ), + StateMachine=StateMachineData( + Id=self._evaluation_details.state_machine_details.arn, + Name=self._evaluation_details.state_machine_details.name, + ), + ), + event_history_context=EventHistoryContext.of_program_start(), + cloud_watch_logging_session=self._cloud_watch_logging_session, + activity_store=self._activity_store, + ) diff --git a/moto/stepfunctions/parser/models.py b/moto/stepfunctions/parser/models.py index cf5fb0951cd5..bebe334c509c 100644 --- a/moto/stepfunctions/parser/models.py +++ b/moto/stepfunctions/parser/models.py @@ -1,4 +1,5 @@ import copy +import datetime import json from typing import Any, Dict, List, Optional @@ -178,14 +179,28 @@ def start_execution( exec_name = name # TODO: validate name format + execution_arn = "arn:{}:states:{}:{}:execution:{}:{}" + execution_arn = execution_arn.format( + self.partition, + self.region_name, + self.account_id, + state_machine.name, + name, + ) + execution = Execution( name=exec_name, + sm_type=state_machine_clone.sm_type, role_arn=state_machine_clone.roleArn, + exec_arn=execution_arn, account_id=self.account_id, region_name=self.region_name, state_machine=state_machine_clone, + start_date=datetime.datetime.now(tz=datetime.timezone.utc), + cloud_watch_logging_session=None, input_data=input_data, trace_header=trace_header, + activity_store={}, ) state_machine.executions.append(execution) @@ -247,7 +262,7 @@ def list_map_runs(self, execution_arn: str) -> Dict[str, Any]: execution.exec_worker.env.map_run_record_pool_manager.get_all() ) return dict( - mapRuns=[map_run_record.to_json() for map_run_record in map_run_records] + mapRuns=[map_run_record.list_item() for map_run_record in map_run_records] ) def update_map_run( diff --git a/moto/stepfunctions/parser/provider.py b/moto/stepfunctions/parser/provider.py new file mode 100644 index 000000000000..ecc84bdf0474 --- /dev/null +++ b/moto/stepfunctions/parser/provider.py @@ -0,0 +1,1401 @@ +import copy +import datetime +import json +import logging +import re +import time +from typing import Optional + +from localstack.aws.api import CommonServiceException, RequestContext +from localstack.services.plugins import ServiceLifecycleHook +from localstack.state import StateVisitor +from localstack.utils.collections import PaginatedList + +from moto.stepfunctions.parser.api import ( + ActivityDoesNotExist, + Arn, + ConflictException, + CreateActivityOutput, + CreateStateMachineInput, + CreateStateMachineOutput, + Definition, + DeleteActivityOutput, + DeleteStateMachineOutput, + DeleteStateMachineVersionOutput, + DescribeActivityOutput, + DescribeExecutionOutput, + DescribeMapRunOutput, + DescribeStateMachineForExecutionOutput, + DescribeStateMachineOutput, + EncryptionConfiguration, + ExecutionDoesNotExist, + ExecutionList, + ExecutionRedriveFilter, + ExecutionStatus, + GetActivityTaskOutput, + GetExecutionHistoryOutput, + IncludedData, + IncludeExecutionDataGetExecutionHistory, + InspectionLevel, + InvalidArn, + InvalidDefinition, + InvalidExecutionInput, + InvalidLoggingConfiguration, + InvalidName, + InvalidToken, + ListActivitiesOutput, + ListExecutionsOutput, + ListExecutionsPageToken, + ListMapRunsOutput, + ListStateMachinesOutput, + ListStateMachineVersionsOutput, + ListTagsForResourceOutput, + LoggingConfiguration, + LogLevel, + LongArn, + MaxConcurrency, + MissingRequiredParameter, + Name, + PageSize, + PageToken, + Publish, + PublishStateMachineVersionOutput, + ResourceNotFound, + RevealSecrets, + ReverseOrder, + RevisionId, + SendTaskFailureOutput, + SendTaskHeartbeatOutput, + SendTaskSuccessOutput, + SensitiveCause, + SensitiveData, + SensitiveError, + StartExecutionOutput, + StartSyncExecutionOutput, + StateMachineAlreadyExists, + StateMachineDoesNotExist, + StateMachineList, + StateMachineType, + StateMachineTypeNotSupported, + StepfunctionsApi, + StopExecutionOutput, + TagKeyList, + TagList, + TagResourceOutput, + TaskDoesNotExist, + TaskTimedOut, + TaskToken, + TestStateOutput, + ToleratedFailureCount, + ToleratedFailurePercentage, + TraceHeader, + TracingConfiguration, + UntagResourceOutput, + UpdateMapRunOutput, + UpdateStateMachineOutput, + ValidateStateMachineDefinitionDiagnostic, + ValidateStateMachineDefinitionDiagnosticList, + ValidateStateMachineDefinitionInput, + ValidateStateMachineDefinitionOutput, + ValidateStateMachineDefinitionResultCode, + ValidateStateMachineDefinitionSeverity, + ValidationException, + VersionDescription, +) +from moto.stepfunctions.parser.asl.component.state.state_execution.state_map.iteration.itemprocessor.map_run_record import ( + MapRunRecord, +) +from moto.stepfunctions.parser.asl.eval.callback.callback import ( + ActivityCallbackEndpoint, + CallbackConsumerTimeout, + CallbackNotifyConsumerError, + CallbackOutcomeFailure, + CallbackOutcomeSuccess, +) +from moto.stepfunctions.parser.asl.eval.event.logging import ( + CloudWatchLoggingConfiguration, + CloudWatchLoggingSession, +) +from moto.stepfunctions.parser.asl.parse.asl_parser import ( + ASLParserException, +) +from moto.stepfunctions.parser.asl.static_analyser.express_static_analyser import ( + ExpressStaticAnalyser, +) +from moto.stepfunctions.parser.asl.static_analyser.static_analyser import ( + StaticAnalyser, +) +from moto.stepfunctions.parser.asl.static_analyser.test_state.test_state_analyser import ( + TestStateStaticAnalyser, +) +from moto.stepfunctions.parser.asl.static_analyser.usage_metrics_static_analyser import ( + UsageMetricsStaticAnalyser, +) +from moto.stepfunctions.parser.backend.activity import Activity, ActivityTask +from moto.stepfunctions.parser.backend.execution import Execution, SyncExecution +from moto.stepfunctions.parser.backend.state_machine import ( + StateMachineInstance, + StateMachineRevision, + StateMachineVersion, + TestStateMachine, +) +from moto.stepfunctions.parser.backend.store import SFNStore, sfn_stores +from moto.stepfunctions.parser.backend.test_state.execution import ( + TestStateExecution, +) +from moto.stepfunctions.parser.stepfunctions_utils import ( + assert_pagination_parameters_valid, + get_next_page_token_from_arn, + normalise_max_results, +) +from moto.stepfunctions.parser.utils import long_uid, short_uid +from moto.utilities.arns import ( + ARN_PARTITION_REGEX, + stepfunctions_activity_arn, + stepfunctions_express_execution_arn, + stepfunctions_standard_execution_arn, + stepfunctions_state_machine_arn, +) + +LOG = logging.getLogger(__name__) + + +class StepFunctionsProvider(StepfunctionsApi, ServiceLifecycleHook): + _TEST_STATE_MAX_TIMEOUT_SECONDS: int = 300 # 5 minutes. + + @staticmethod + def get_store(context: RequestContext) -> SFNStore: + return sfn_stores[context.account_id][context.region] + + def accept_state_visitor(self, visitor: StateVisitor): + visitor.visit(sfn_stores) + + _STATE_MACHINE_ARN_REGEX: re.Pattern = re.compile( + rf"{ARN_PARTITION_REGEX}:states:[a-z0-9-]+:[0-9]{{12}}:stateMachine:[a-zA-Z0-9-_.]+(:\d+)?$" + ) + + _STATE_MACHINE_EXECUTION_ARN_REGEX: re.Pattern = re.compile( + rf"{ARN_PARTITION_REGEX}:states:[a-z0-9-]+:[0-9]{{12}}:(stateMachine|execution|express):[a-zA-Z0-9-_.]+(:\d+)?(:[a-zA-Z0-9-_.]+)*$" + ) + + _ACTIVITY_ARN_REGEX: re.Pattern = re.compile( + rf"{ARN_PARTITION_REGEX}:states:[a-z0-9-]+:[0-9]{{12}}:activity:[a-zA-Z0-9-_\.]{{1,80}}$" + ) + + @staticmethod + def _validate_state_machine_arn(state_machine_arn: str) -> None: + # TODO: InvalidArn exception message do not communicate which part of the ARN is incorrect. + if not StepFunctionsProvider._STATE_MACHINE_ARN_REGEX.match(state_machine_arn): + raise InvalidArn(f"Invalid arn: '{state_machine_arn}'") + + @staticmethod + def _raise_state_machine_does_not_exist(state_machine_arn: str) -> None: + raise StateMachineDoesNotExist( + f"State Machine Does Not Exist: '{state_machine_arn}'" + ) + + @staticmethod + def _validate_state_machine_execution_arn(execution_arn: str) -> None: + # TODO: InvalidArn exception message do not communicate which part of the ARN is incorrect. + if not StepFunctionsProvider._STATE_MACHINE_EXECUTION_ARN_REGEX.match( + execution_arn + ): + raise InvalidArn(f"Invalid arn: '{execution_arn}'") + + @staticmethod + def _validate_activity_arn(activity_arn: str) -> None: + # TODO: InvalidArn exception message do not communicate which part of the ARN is incorrect. + if not StepFunctionsProvider._ACTIVITY_ARN_REGEX.match(activity_arn): + raise InvalidArn(f"Invalid arn: '{activity_arn}'") + + def _raise_state_machine_type_not_supported(self): + raise StateMachineTypeNotSupported( + "This operation is not supported by this type of state machine" + ) + + @staticmethod + def _raise_resource_type_not_in_context(resource_type: str) -> None: + lower_resource_type = resource_type.lower() + raise InvalidArn( + f"Invalid Arn: 'Resource type not valid in this context: {lower_resource_type}'" + ) + + @staticmethod + def _validate_activity_name(name: str) -> None: + # The activity name is validated according to the AWS StepFunctions documentation, the name should not contain: + # - white space + # - brackets < > { } [ ] + # - wildcard characters ? * + # - special characters " # % \ ^ | ~ ` $ & , ; : / + # - control characters (U+0000-001F, U+007F-009F) + # https://docs.aws.amazon.com/step-functions/latest/apireference/API_CreateActivity.html#API_CreateActivity_RequestSyntax + if not (1 <= len(name) <= 80): + raise InvalidName(f"Invalid Name: '{name}'") + invalid_chars = set(' <>{}[]?*"#%\\^|~`$&,;:/') + control_chars = {chr(i) for i in range(32)} | {chr(i) for i in range(127, 160)} + invalid_chars |= control_chars + for char in name: + if char in invalid_chars: + raise InvalidName(f"Invalid Name: '{name}'") + + def _get_execution(self, context: RequestContext, execution_arn: Arn) -> Execution: + execution: Optional[Execution] = self.get_store(context).executions.get( + execution_arn + ) + if not execution: + raise ExecutionDoesNotExist(f"Execution Does Not Exist: '{execution_arn}'") + return execution + + def _get_executions( + self, + context: RequestContext, + execution_status: Optional[ExecutionStatus] = None, + ): + store = self.get_store(context) + execution: list[Execution] = list(store.executions.values()) + if execution_status: + execution = list( + filter( + lambda e: e.exec_status == execution_status, + store.executions.values(), + ) + ) + return execution + + def _get_activity(self, context: RequestContext, activity_arn: Arn) -> Activity: + maybe_activity: Optional[Activity] = self.get_store(context).activities.get( + activity_arn, None + ) + if maybe_activity is None: + raise ActivityDoesNotExist(f"Activity Does Not Exist: '{activity_arn}'") + return maybe_activity + + def _idempotent_revision( + self, + context: RequestContext, + name: str, + definition: Definition, + state_machine_type: StateMachineType, + logging_configuration: LoggingConfiguration, + tracing_configuration: TracingConfiguration, + ) -> Optional[StateMachineRevision]: + # CreateStateMachine's idempotency check is based on the state machine name, definition, type, + # LoggingConfiguration and TracingConfiguration. + # If a following request has a different roleArn or tags, Step Functions will ignore these differences and + # treat it as an idempotent request of the previous. In this case, roleArn and tags will not be updated, even + # if they are different. + state_machines: list[StateMachineInstance] = list( + self.get_store(context).state_machines.values() + ) + revisions = filter( + lambda sm: isinstance(sm, StateMachineRevision), state_machines + ) + for state_machine in revisions: + check = all( + [ + state_machine.name == name, + state_machine.definition == definition, + state_machine.sm_type == state_machine_type, + state_machine.logging_config == logging_configuration, + state_machine.tracing_config == tracing_configuration, + ] + ) + if check: + return state_machine + return None + + def _idempotent_start_execution( + self, + execution: Optional[Execution], + state_machine: StateMachineInstance, + name: Name, + input_data: SensitiveData, + ) -> Optional[Execution]: + # StartExecution is idempotent for STANDARD workflows. For a STANDARD workflow, + # if you call StartExecution with the same name and input as a running execution, + # the call succeeds and return the same response as the original request. + # If the execution is closed or if the input is different, + # it returns a 400 ExecutionAlreadyExists error. You can reuse names after 90 days. + + if not execution: + return None + + if (name, input_data, execution.exec_status, state_machine.sm_type) == ( + execution.name, + execution.input_data, + ExecutionStatus.RUNNING, + StateMachineType.STANDARD, + ): + return execution + + raise CommonServiceException( + code="ExecutionAlreadyExists", + message=f"Execution Already Exists: '{execution.exec_arn}'", + ) + + def _revision_by_name( + self, context: RequestContext, name: str + ) -> Optional[StateMachineInstance]: + state_machines: list[StateMachineInstance] = list( + self.get_store(context).state_machines.values() + ) + for state_machine in state_machines: + if ( + isinstance(state_machine, StateMachineRevision) + and state_machine.name == name + ): + return state_machine + return None + + @staticmethod + def _validate_definition( + definition: str, static_analysers: list[StaticAnalyser] + ) -> None: + try: + for static_analyser in static_analysers: + static_analyser.analyse(definition) + except ASLParserException as asl_parser_exception: + invalid_definition = InvalidDefinition() + invalid_definition.message = repr(asl_parser_exception) + raise invalid_definition + except Exception as exception: + exception_name = exception.__class__.__name__ + exception_args = list(exception.args) + invalid_definition = InvalidDefinition() + invalid_definition.message = f"Error={exception_name} Args={exception_args} in definition '{definition}'." + raise invalid_definition + + @staticmethod + def _sanitise_logging_configuration( + logging_configuration: LoggingConfiguration, + ) -> None: + level = logging_configuration.get("level") + destinations = logging_configuration.get("destinations") + + if destinations is not None and len(destinations) > 1: + raise InvalidLoggingConfiguration( + "Invalid Logging Configuration: Must specify exactly one Log Destination." + ) + + # A LogLevel that is not OFF, should have a destination. + if level is not None and level != LogLevel.OFF and not destinations: + raise InvalidLoggingConfiguration( + "Invalid Logging Configuration: Must specify exactly one Log Destination." + ) + + # Default for level is OFF. + level = level or LogLevel.OFF + + # Default for includeExecutionData is False. + include_flag = logging_configuration.get("includeExecutionData", False) + + # Update configuration object. + logging_configuration["level"] = level + logging_configuration["includeExecutionData"] = include_flag + + def create_state_machine( + self, context: RequestContext, request: CreateStateMachineInput, **kwargs + ) -> CreateStateMachineOutput: + if not request.get("publish", False) and request.get("versionDescription"): + raise ValidationException( + "Version description can only be set when publish is true" + ) + + # Extract parameters and set defaults. + state_machine_name = request["name"] + state_machine_role_arn = request["roleArn"] + state_machine_definition = request["definition"] + state_machine_type = request.get("type") or StateMachineType.STANDARD + state_machine_tracing_configuration = request.get("tracingConfiguration") + state_machine_tags = request.get("tags") + state_machine_logging_configuration = request.get( + "loggingConfiguration", LoggingConfiguration() + ) + self._sanitise_logging_configuration( + logging_configuration=state_machine_logging_configuration + ) + + # CreateStateMachine is an idempotent API. Subsequent requests won’t create a duplicate resource if it was + # already created. + idem_state_machine: Optional[StateMachineRevision] = self._idempotent_revision( + context=context, + name=state_machine_name, + definition=state_machine_definition, + state_machine_type=state_machine_type, + logging_configuration=state_machine_logging_configuration, + tracing_configuration=state_machine_tracing_configuration, + ) + if idem_state_machine is not None: + return CreateStateMachineOutput( + stateMachineArn=idem_state_machine.arn, + creationDate=idem_state_machine.create_date, + ) + + # Assert this state machine name is unique. + state_machine_with_name: Optional[StateMachineRevision] = ( + self._revision_by_name(context=context, name=state_machine_name) + ) + if state_machine_with_name is not None: + raise StateMachineAlreadyExists( + f"State Machine Already Exists: '{state_machine_with_name.arn}'" + ) + + # Compute the state machine's Arn. + state_machine_arn = stepfunctions_state_machine_arn( + name=state_machine_name, + account_id=context.account_id, + region_name=context.region, + ) + state_machines = self.get_store(context).state_machines + + # Reduce the logging configuration to a usable cloud watch representation, and validate the destinations + # if any were given. + cloud_watch_logging_configuration = ( + CloudWatchLoggingConfiguration.from_logging_configuration( + state_machine_arn=state_machine_arn, + logging_configuration=state_machine_logging_configuration, + ) + ) + if cloud_watch_logging_configuration is not None: + cloud_watch_logging_configuration.validate() + + # Run static analysers on the definition given. + if state_machine_type == StateMachineType.EXPRESS: + StepFunctionsProvider._validate_definition( + definition=state_machine_definition, + static_analysers=[ExpressStaticAnalyser()], + ) + else: + StepFunctionsProvider._validate_definition( + definition=state_machine_definition, static_analysers=[StaticAnalyser()] + ) + + # Create the state machine and add it to the store. + state_machine = StateMachineRevision( + name=state_machine_name, + arn=state_machine_arn, + role_arn=state_machine_role_arn, + definition=state_machine_definition, + sm_type=state_machine_type, + logging_config=state_machine_logging_configuration, + cloud_watch_logging_configuration=cloud_watch_logging_configuration, + tracing_config=state_machine_tracing_configuration, + tags=state_machine_tags, + ) + state_machines[state_machine_arn] = state_machine + + create_output = CreateStateMachineOutput( + stateMachineArn=state_machine.arn, creationDate=state_machine.create_date + ) + + # Create the first version if the 'publish' flag is used. + if request.get("publish", False): + version_description = request.get("versionDescription") + state_machine_version = state_machine.create_version( + description=version_description + ) + if state_machine_version is not None: + state_machine_version_arn = state_machine_version.arn + state_machines[state_machine_version_arn] = state_machine_version + create_output["stateMachineVersionArn"] = state_machine_version_arn + + # Run static analyser on definition and collect usage metrics + UsageMetricsStaticAnalyser.process(state_machine_definition) + + return create_output + + def describe_state_machine( + self, + context: RequestContext, + state_machine_arn: Arn, + included_data: IncludedData = None, + **kwargs, + ) -> DescribeStateMachineOutput: + self._validate_state_machine_arn(state_machine_arn) + state_machine = self.get_store(context).state_machines.get(state_machine_arn) + if state_machine is None: + self._raise_state_machine_does_not_exist(state_machine_arn) + return state_machine.describe() + + def describe_state_machine_for_execution( + self, + context: RequestContext, + execution_arn: Arn, + included_data: IncludedData = None, + **kwargs, + ) -> DescribeStateMachineForExecutionOutput: + self._validate_state_machine_execution_arn(execution_arn) + execution: Execution = self._get_execution( + context=context, execution_arn=execution_arn + ) + return execution.to_describe_state_machine_for_execution_output() + + def send_task_heartbeat( + self, context: RequestContext, task_token: TaskToken, **kwargs + ) -> SendTaskHeartbeatOutput: + running_executions: list[Execution] = self._get_executions( + context, ExecutionStatus.RUNNING + ) + for execution in running_executions: + try: + if execution.exec_worker.env.callback_pool_manager.heartbeat( + callback_id=task_token + ): + return SendTaskHeartbeatOutput() + except CallbackNotifyConsumerError as consumer_error: + if isinstance(consumer_error, CallbackConsumerTimeout): + raise TaskTimedOut() + else: + raise TaskDoesNotExist() + raise InvalidToken() + + def send_task_success( + self, + context: RequestContext, + task_token: TaskToken, + output: SensitiveData, + **kwargs, + ) -> SendTaskSuccessOutput: + outcome = CallbackOutcomeSuccess(callback_id=task_token, output=output) + running_executions: list[Execution] = self._get_executions( + context, ExecutionStatus.RUNNING + ) + for execution in running_executions: + try: + if execution.exec_worker.env.callback_pool_manager.notify( + callback_id=task_token, outcome=outcome + ): + return SendTaskSuccessOutput() + except CallbackNotifyConsumerError as consumer_error: + if isinstance(consumer_error, CallbackConsumerTimeout): + raise TaskTimedOut() + else: + raise TaskDoesNotExist() + raise InvalidToken("Invalid token") + + def send_task_failure( + self, + context: RequestContext, + task_token: TaskToken, + error: SensitiveError = None, + cause: SensitiveCause = None, + **kwargs, + ) -> SendTaskFailureOutput: + outcome = CallbackOutcomeFailure( + callback_id=task_token, error=error, cause=cause + ) + store = self.get_store(context) + for execution in store.executions.values(): + try: + if execution.exec_worker.env.callback_pool_manager.notify( + callback_id=task_token, outcome=outcome + ): + return SendTaskFailureOutput() + except CallbackNotifyConsumerError as consumer_error: + if isinstance(consumer_error, CallbackConsumerTimeout): + raise TaskTimedOut() + else: + raise TaskDoesNotExist() + raise InvalidToken("Invalid token") + + def start_execution( + self, + context: RequestContext, + state_machine_arn: Arn, + name: Name = None, + input: SensitiveData = None, + trace_header: TraceHeader = None, + **kwargs, + ) -> StartExecutionOutput: + self._validate_state_machine_arn(state_machine_arn) + unsafe_state_machine: Optional[StateMachineInstance] = self.get_store( + context + ).state_machines.get(state_machine_arn) + if not unsafe_state_machine: + self._raise_state_machine_does_not_exist(state_machine_arn) + + # Update event change parameters about the state machine and should not affect those about this execution. + state_machine_clone = copy.deepcopy(unsafe_state_machine) + + if input is None: + input_data = dict() + else: + try: + input_data = json.loads(input) + except Exception as ex: + raise InvalidExecutionInput( + str(ex) + ) # TODO: report parsing error like AWS. + + normalised_state_machine_arn = ( + state_machine_clone.source_arn + if isinstance(state_machine_clone, StateMachineVersion) + else state_machine_clone.arn + ) + exec_name = name or long_uid() # TODO: validate name format + if state_machine_clone.sm_type == StateMachineType.STANDARD: + exec_arn = stepfunctions_standard_execution_arn( + normalised_state_machine_arn, exec_name + ) + else: + # Exhaustive check on STANDARD and EXPRESS type, validated on creation. + exec_arn = stepfunctions_express_execution_arn( + normalised_state_machine_arn, exec_name + ) + + if execution := self.get_store(context).executions.get(exec_arn): + # Return already running execution if name and input match + existing_execution = self._idempotent_start_execution( + execution=execution, + state_machine=state_machine_clone, + name=name, + input_data=input_data, + ) + + if existing_execution: + return existing_execution.to_start_output() + + # Create the execution logging session, if logging is configured. + cloud_watch_logging_session = None + if state_machine_clone.cloud_watch_logging_configuration is not None: + cloud_watch_logging_session = CloudWatchLoggingSession( + execution_arn=exec_arn, + configuration=state_machine_clone.cloud_watch_logging_configuration, + ) + + execution = Execution( + name=exec_name, + sm_type=state_machine_clone.sm_type, + role_arn=state_machine_clone.role_arn, + exec_arn=exec_arn, + account_id=context.account_id, + region_name=context.region, + state_machine=state_machine_clone, + start_date=datetime.datetime.now(tz=datetime.timezone.utc), + cloud_watch_logging_session=cloud_watch_logging_session, + input_data=input_data, + trace_header=trace_header, + activity_store=self.get_store(context).activities, + ) + + self.get_store(context).executions[exec_arn] = execution + + execution.start() + return execution.to_start_output() + + def start_sync_execution( + self, + context: RequestContext, + state_machine_arn: Arn, + name: Name = None, + input: SensitiveData = None, + trace_header: TraceHeader = None, + included_data: IncludedData = None, + **kwargs, + ) -> StartSyncExecutionOutput: + self._validate_state_machine_arn(state_machine_arn) + unsafe_state_machine: Optional[StateMachineInstance] = self.get_store( + context + ).state_machines.get(state_machine_arn) + if not unsafe_state_machine: + self._raise_state_machine_does_not_exist(state_machine_arn) + + if unsafe_state_machine.sm_type == StateMachineType.STANDARD: + self._raise_state_machine_type_not_supported() + + # Update event change parameters about the state machine and should not affect those about this execution. + state_machine_clone = copy.deepcopy(unsafe_state_machine) + + if input is None: + input_data = dict() + else: + try: + input_data = json.loads(input) + except Exception as ex: + raise InvalidExecutionInput( + str(ex) + ) # TODO: report parsing error like AWS. + + normalised_state_machine_arn = ( + state_machine_clone.source_arn + if isinstance(state_machine_clone, StateMachineVersion) + else state_machine_clone.arn + ) + exec_name = name or long_uid() # TODO: validate name format + exec_arn = stepfunctions_express_execution_arn( + normalised_state_machine_arn, exec_name + ) + + if exec_arn in self.get_store(context).executions: + raise InvalidName() # TODO + + # Create the execution logging session, if logging is configured. + cloud_watch_logging_session = None + if state_machine_clone.cloud_watch_logging_configuration is not None: + cloud_watch_logging_session = CloudWatchLoggingSession( + execution_arn=exec_arn, + configuration=state_machine_clone.cloud_watch_logging_configuration, + ) + + execution = SyncExecution( + name=exec_name, + sm_type=state_machine_clone.sm_type, + role_arn=state_machine_clone.role_arn, + exec_arn=exec_arn, + account_id=context.account_id, + region_name=context.region, + state_machine=state_machine_clone, + start_date=datetime.datetime.now(tz=datetime.timezone.utc), + cloud_watch_logging_session=cloud_watch_logging_session, + input_data=input_data, + trace_header=trace_header, + activity_store=self.get_store(context).activities, + ) + self.get_store(context).executions[exec_arn] = execution + + execution.start() + return execution.to_start_sync_execution_output() + + def describe_execution( + self, + context: RequestContext, + execution_arn: Arn, + included_data: IncludedData = None, + **kwargs, + ) -> DescribeExecutionOutput: + self._validate_state_machine_execution_arn(execution_arn) + execution: Execution = self._get_execution( + context=context, execution_arn=execution_arn + ) + + # Action only compatible with STANDARD workflows. + if execution.sm_type != StateMachineType.STANDARD: + self._raise_resource_type_not_in_context(resource_type=execution.sm_type) + + return execution.to_describe_output() + + @staticmethod + def _list_execution_filter( + ex: Execution, state_machine_arn: Optional[str], status_filter: Optional[str] + ) -> bool: + if state_machine_arn and ex.state_machine.arn != state_machine_arn: + return False + + if not status_filter: + return True + return ex.exec_status == status_filter + + def list_executions( + self, + context: RequestContext, + state_machine_arn: Arn = None, + status_filter: ExecutionStatus = None, + max_results: PageSize = None, + next_token: ListExecutionsPageToken = None, + map_run_arn: LongArn = None, + redrive_filter: ExecutionRedriveFilter = None, + **kwargs, + ) -> ListExecutionsOutput: + self._validate_state_machine_arn(state_machine_arn) + assert_pagination_parameters_valid( + max_results=max_results, + next_token=next_token, + next_token_length_limit=3096, + ) + max_results = normalise_max_results(max_results) + + state_machine = self.get_store(context).state_machines.get(state_machine_arn) + if state_machine is None: + self._raise_state_machine_does_not_exist(state_machine_arn) + + if state_machine.sm_type != StateMachineType.STANDARD: + self._raise_state_machine_type_not_supported() + + # TODO: add support for paging + + allowed_execution_status = [ + ExecutionStatus.SUCCEEDED, + ExecutionStatus.TIMED_OUT, + ExecutionStatus.PENDING_REDRIVE, + ExecutionStatus.ABORTED, + ExecutionStatus.FAILED, + ExecutionStatus.RUNNING, + ] + + validation_errors = [] + + if status_filter and status_filter not in allowed_execution_status: + validation_errors.append( + f"Value '{status_filter}' at 'statusFilter' failed to satisfy constraint: Member must satisfy enum value set: [{', '.join(allowed_execution_status)}]" + ) + + if not state_machine_arn and not map_run_arn: + validation_errors.append("Must provide a StateMachine ARN or MapRun ARN") + + if validation_errors: + errors_message = "; ".join(validation_errors) + message = f"{len(validation_errors)} validation {'errors' if len(validation_errors) > 1 else 'error'} detected: {errors_message}" + raise CommonServiceException(message=message, code="ValidationException") + + executions: ExecutionList = [ + execution.to_execution_list_item() + for execution in self.get_store(context).executions.values() + if self._list_execution_filter( + execution, + state_machine_arn=state_machine_arn, + status_filter=status_filter, + ) + ] + + executions.sort(key=lambda item: item["startDate"], reverse=True) + + paginated_executions = PaginatedList(executions) + page, token_for_next_page = paginated_executions.get_page( + token_generator=lambda item: get_next_page_token_from_arn( + item.get("executionArn") + ), + page_size=max_results, + next_token=next_token, + ) + + return ListExecutionsOutput(executions=page, nextToken=token_for_next_page) + + def list_state_machines( + self, + context: RequestContext, + max_results: PageSize = None, + next_token: PageToken = None, + **kwargs, + ) -> ListStateMachinesOutput: + assert_pagination_parameters_valid(max_results, next_token) + max_results = normalise_max_results(max_results) + + state_machines: StateMachineList = [ + sm.itemise() + for sm in self.get_store(context).state_machines.values() + if isinstance(sm, StateMachineRevision) + ] + state_machines.sort(key=lambda item: item["name"]) + + paginated_state_machines = PaginatedList(state_machines) + page, token_for_next_page = paginated_state_machines.get_page( + token_generator=lambda item: get_next_page_token_from_arn( + item.get("stateMachineArn") + ), + page_size=max_results, + next_token=next_token, + ) + + return ListStateMachinesOutput( + stateMachines=page, nextToken=token_for_next_page + ) + + def list_state_machine_versions( + self, + context: RequestContext, + state_machine_arn: Arn, + next_token: PageToken = None, + max_results: PageSize = None, + **kwargs, + ) -> ListStateMachineVersionsOutput: + self._validate_state_machine_arn(state_machine_arn) + assert_pagination_parameters_valid(max_results, next_token) + max_results = normalise_max_results(max_results) + + state_machines = self.get_store(context).state_machines + state_machine_revision = state_machines.get(state_machine_arn) + if not isinstance(state_machine_revision, StateMachineRevision): + raise InvalidArn(f"Invalid arn: {state_machine_arn}") + + state_machine_version_items = list() + for version_arn in state_machine_revision.versions.values(): + state_machine_version = state_machines[version_arn] + if isinstance(state_machine_version, StateMachineVersion): + state_machine_version_items.append(state_machine_version.itemise()) + else: + raise RuntimeError( + f"Expected {version_arn} to be a StateMachine Version, but got '{type(state_machine_version)}'." + ) + + state_machine_version_items.sort( + key=lambda item: item["creationDate"], reverse=True + ) + + paginated_state_machine_versions = PaginatedList(state_machine_version_items) + page, token_for_next_page = paginated_state_machine_versions.get_page( + token_generator=lambda item: get_next_page_token_from_arn( + item.get("stateMachineVersionArn") + ), + page_size=max_results, + next_token=next_token, + ) + + return ListStateMachineVersionsOutput( + stateMachineVersions=page, nextToken=token_for_next_page + ) + + def get_execution_history( + self, + context: RequestContext, + execution_arn: Arn, + max_results: PageSize = None, + reverse_order: ReverseOrder = None, + next_token: PageToken = None, + include_execution_data: IncludeExecutionDataGetExecutionHistory = None, + **kwargs, + ) -> GetExecutionHistoryOutput: + # TODO: add support for paging, ordering, and other manipulations. + self._validate_state_machine_execution_arn(execution_arn) + execution: Execution = self._get_execution( + context=context, execution_arn=execution_arn + ) + + # Action only compatible with STANDARD workflows. + if execution.sm_type != StateMachineType.STANDARD: + self._raise_resource_type_not_in_context(resource_type=execution.sm_type) + + history: GetExecutionHistoryOutput = execution.to_history_output() + if reverse_order: + history["events"].reverse() + return history + + def delete_state_machine( + self, context: RequestContext, state_machine_arn: Arn, **kwargs + ) -> DeleteStateMachineOutput: + # TODO: halt executions? + self._validate_state_machine_arn(state_machine_arn) + state_machines = self.get_store(context).state_machines + state_machine = state_machines.get(state_machine_arn) + if isinstance(state_machine, StateMachineRevision): + state_machines.pop(state_machine_arn) + for version_arn in state_machine.versions.values(): + state_machines.pop(version_arn, None) + return DeleteStateMachineOutput() + + def delete_state_machine_version( + self, context: RequestContext, state_machine_version_arn: LongArn, **kwargs + ) -> DeleteStateMachineVersionOutput: + self._validate_state_machine_arn(state_machine_version_arn) + state_machines = self.get_store(context).state_machines + state_machine_version = state_machines.get(state_machine_version_arn) + if isinstance(state_machine_version, StateMachineVersion): + state_machines.pop(state_machine_version.arn) + state_machine_revision = state_machines.get( + state_machine_version.source_arn + ) + if isinstance(state_machine_revision, StateMachineRevision): + state_machine_revision.delete_version(state_machine_version_arn) + + return DeleteStateMachineVersionOutput() + + def stop_execution( + self, + context: RequestContext, + execution_arn: Arn, + error: SensitiveError = None, + cause: SensitiveCause = None, + **kwargs, + ) -> StopExecutionOutput: + self._validate_state_machine_execution_arn(execution_arn) + execution: Execution = self._get_execution( + context=context, execution_arn=execution_arn + ) + + # Action only compatible with STANDARD workflows. + if execution.sm_type != StateMachineType.STANDARD: + self._raise_resource_type_not_in_context(resource_type=execution.sm_type) + + stop_date = datetime.datetime.now(tz=datetime.timezone.utc) + execution.stop(stop_date=stop_date, cause=cause, error=error) + return StopExecutionOutput(stopDate=stop_date) + + def update_state_machine( + self, + context: RequestContext, + state_machine_arn: Arn, + definition: Definition = None, + role_arn: Arn = None, + logging_configuration: LoggingConfiguration = None, + tracing_configuration: TracingConfiguration = None, + publish: Publish = None, + version_description: VersionDescription = None, + encryption_configuration: EncryptionConfiguration = None, + **kwargs, + ) -> UpdateStateMachineOutput: + self._validate_state_machine_arn(state_machine_arn) + state_machines = self.get_store(context).state_machines + + state_machine = state_machines.get(state_machine_arn) + if not isinstance(state_machine, StateMachineRevision): + self._raise_state_machine_does_not_exist(state_machine_arn) + + # TODO: Add logic to handle metrics for when SFN definitions update + if not any([definition, role_arn, logging_configuration]): + raise MissingRequiredParameter( + "Either the definition, the role ARN, the LoggingConfiguration, " + "or the TracingConfiguration must be specified" + ) + + if definition is not None: + self._validate_definition( + definition=definition, static_analysers=[StaticAnalyser()] + ) + + if logging_configuration is not None: + self._sanitise_logging_configuration( + logging_configuration=logging_configuration + ) + + revision_id = state_machine.create_revision( + definition=definition, + role_arn=role_arn, + logging_configuration=logging_configuration, + ) + + version_arn = None + if publish: + version = state_machine.create_version(description=version_description) + if version is not None: + version_arn = version.arn + state_machines[version_arn] = version + else: + target_revision_id = revision_id or state_machine.revision_id + version_arn = state_machine.versions[target_revision_id] + + update_output = UpdateStateMachineOutput( + updateDate=datetime.datetime.now(tz=datetime.timezone.utc) + ) + if revision_id is not None: + update_output["revisionId"] = revision_id + if version_arn is not None: + update_output["stateMachineVersionArn"] = version_arn + return update_output + + def publish_state_machine_version( + self, + context: RequestContext, + state_machine_arn: Arn, + revision_id: RevisionId = None, + description: VersionDescription = None, + **kwargs, + ) -> PublishStateMachineVersionOutput: + self._validate_state_machine_arn(state_machine_arn) + state_machines = self.get_store(context).state_machines + + state_machine_revision = state_machines.get(state_machine_arn) + if not isinstance(state_machine_revision, StateMachineRevision): + self._raise_state_machine_does_not_exist(state_machine_arn) + + if ( + revision_id is not None + and state_machine_revision.revision_id != revision_id + ): + raise ConflictException( + f"Failed to publish the State Machine version for revision {revision_id}. " + f"The current State Machine revision is {state_machine_revision.revision_id}." + ) + + state_machine_version = state_machine_revision.create_version( + description=description + ) + if state_machine_version is not None: + state_machines[state_machine_version.arn] = state_machine_version + else: + target_revision_id = revision_id or state_machine_revision.revision_id + state_machine_version_arn = state_machine_revision.versions.get( + target_revision_id + ) + state_machine_version = state_machines[state_machine_version_arn] + + return PublishStateMachineVersionOutput( + creationDate=state_machine_version.create_date, + stateMachineVersionArn=state_machine_version.arn, + ) + + def tag_resource( + self, context: RequestContext, resource_arn: Arn, tags: TagList, **kwargs + ) -> TagResourceOutput: + # TODO: add tagging for activities. + state_machines = self.get_store(context).state_machines + state_machine = state_machines.get(resource_arn) + if not isinstance(state_machine, StateMachineRevision): + raise ResourceNotFound(f"Resource not found: '{resource_arn}'") + + state_machine.tag_manager.add_all(tags) + return TagResourceOutput() + + def untag_resource( + self, context: RequestContext, resource_arn: Arn, tag_keys: TagKeyList, **kwargs + ) -> UntagResourceOutput: + # TODO: add untagging for activities. + state_machines = self.get_store(context).state_machines + state_machine = state_machines.get(resource_arn) + if not isinstance(state_machine, StateMachineRevision): + raise ResourceNotFound(f"Resource not found: '{resource_arn}'") + + state_machine.tag_manager.remove_all(tag_keys) + return UntagResourceOutput() + + def list_tags_for_resource( + self, context: RequestContext, resource_arn: Arn, **kwargs + ) -> ListTagsForResourceOutput: + # TODO: add untagging for activities. + state_machines = self.get_store(context).state_machines + state_machine = state_machines.get(resource_arn) + if not isinstance(state_machine, StateMachineRevision): + raise ResourceNotFound(f"Resource not found: '{resource_arn}'") + + tags: TagList = state_machine.tag_manager.to_tag_list() + return ListTagsForResourceOutput(tags=tags) + + def describe_map_run( + self, context: RequestContext, map_run_arn: LongArn, **kwargs + ) -> DescribeMapRunOutput: + store = self.get_store(context) + for execution in store.executions.values(): + map_run_record: Optional[MapRunRecord] = ( + execution.exec_worker.env.map_run_record_pool_manager.get(map_run_arn) + ) + if map_run_record is not None: + return map_run_record.describe() + raise ResourceNotFound() + + def list_map_runs( + self, + context: RequestContext, + execution_arn: Arn, + max_results: PageSize = None, + next_token: PageToken = None, + **kwargs, + ) -> ListMapRunsOutput: + # TODO: add support for paging. + execution = self._get_execution(context=context, execution_arn=execution_arn) + map_run_records: list[MapRunRecord] = ( + execution.exec_worker.env.map_run_record_pool_manager.get_all() + ) + return ListMapRunsOutput( + mapRuns=[map_run_record.list_item() for map_run_record in map_run_records] + ) + + def update_map_run( + self, + context: RequestContext, + map_run_arn: LongArn, + max_concurrency: MaxConcurrency = None, + tolerated_failure_percentage: ToleratedFailurePercentage = None, + tolerated_failure_count: ToleratedFailureCount = None, + **kwargs, + ) -> UpdateMapRunOutput: + if ( + tolerated_failure_percentage is not None + or tolerated_failure_count is not None + ): + raise NotImplementedError( + "Updating of ToleratedFailureCount and ToleratedFailurePercentage is currently unsupported." + ) + # TODO: investigate behaviour of empty requests. + store = self.get_store(context) + for execution in store.executions.values(): + map_run_record: Optional[MapRunRecord] = ( + execution.exec_worker.env.map_run_record_pool_manager.get(map_run_arn) + ) + if map_run_record is not None: + map_run_record.update( + max_concurrency=max_concurrency, + tolerated_failure_count=tolerated_failure_count, + tolerated_failure_percentage=tolerated_failure_percentage, + ) + LOG.warning( + "StepFunctions UpdateMapRun changes are currently not being reflected in the MapRun instances." + ) + return UpdateMapRunOutput() + raise ResourceNotFound() + + def test_state( + self, + context: RequestContext, + definition: Definition, + role_arn: Arn = None, + input: SensitiveData = None, + inspection_level: InspectionLevel = None, + reveal_secrets: RevealSecrets = None, + variables: SensitiveData = None, + **kwargs, + ) -> TestStateOutput: + StepFunctionsProvider._validate_definition( + definition=definition, static_analysers=[TestStateStaticAnalyser()] + ) + + name: Optional[Name] = f"TestState-{short_uid()}" + arn = stepfunctions_state_machine_arn( + name=name, account_id=context.account_id, region_name=context.region + ) + state_machine = TestStateMachine( + name=name, + arn=arn, + role_arn=role_arn, + definition=definition, + ) + exec_arn = stepfunctions_standard_execution_arn(state_machine.arn, name) + + input_json = json.loads(input) + execution = TestStateExecution( + name=name, + role_arn=role_arn, + exec_arn=exec_arn, + account_id=context.account_id, + region_name=context.region, + state_machine=state_machine, + start_date=datetime.datetime.now(tz=datetime.timezone.utc), + input_data=input_json, + activity_store=self.get_store(context).activities, + ) + execution.start() + + test_state_output = execution.to_test_state_output( + inspection_level=inspection_level or InspectionLevel.INFO + ) + + return test_state_output + + def create_activity( + self, + context: RequestContext, + name: Name, + tags: TagList = None, + encryption_configuration: EncryptionConfiguration = None, + **kwargs, + ) -> CreateActivityOutput: + self._validate_activity_name(name=name) + + activity_arn = stepfunctions_activity_arn( + name=name, account_id=context.account_id, region_name=context.region + ) + activities = self.get_store(context).activities + if activity_arn not in activities: + activity = Activity(arn=activity_arn, name=name) + activities[activity_arn] = activity + else: + activity = activities[activity_arn] + + return CreateActivityOutput( + activityArn=activity.arn, creationDate=activity.creation_date + ) + + def delete_activity( + self, context: RequestContext, activity_arn: Arn, **kwargs + ) -> DeleteActivityOutput: + self._validate_activity_arn(activity_arn) + self.get_store(context).activities.pop(activity_arn, None) + return DeleteActivityOutput() + + def describe_activity( + self, context: RequestContext, activity_arn: Arn, **kwargs + ) -> DescribeActivityOutput: + self._validate_activity_arn(activity_arn) + activity = self._get_activity(context=context, activity_arn=activity_arn) + return activity.to_describe_activity_output() + + def list_activities( + self, + context: RequestContext, + max_results: PageSize = None, + next_token: PageToken = None, + **kwargs, + ) -> ListActivitiesOutput: + activities: list[Activity] = list(self.get_store(context).activities.values()) + return ListActivitiesOutput( + activities=[activity.to_activity_list_item() for activity in activities] + ) + + def _send_activity_task_started( + self, + context: RequestContext, + task_token: TaskToken, + worker_name: Optional[Name], + ) -> None: + executions: list[Execution] = self._get_executions(context) + for execution in executions: + callback_endpoint = execution.exec_worker.env.callback_pool_manager.get( + callback_id=task_token + ) + if isinstance(callback_endpoint, ActivityCallbackEndpoint): + callback_endpoint.notify_activity_task_start(worker_name=worker_name) + return + raise InvalidToken() + + @staticmethod + def _pull_activity_task(activity: Activity) -> Optional[ActivityTask]: + seconds_left = 60 + while seconds_left > 0: + try: + return activity.get_task() + except IndexError: + time.sleep(1) + seconds_left -= 1 + return None + + def get_activity_task( + self, + context: RequestContext, + activity_arn: Arn, + worker_name: Name = None, + **kwargs, + ) -> GetActivityTaskOutput: + self._validate_activity_arn(activity_arn) + + activity = self._get_activity(context=context, activity_arn=activity_arn) + maybe_task: Optional[ActivityTask] = self._pull_activity_task(activity=activity) + if maybe_task is not None: + self._send_activity_task_started( + context, maybe_task.task_token, worker_name=worker_name + ) + return GetActivityTaskOutput( + taskToken=maybe_task.task_token, input=maybe_task.task_input + ) + + return GetActivityTaskOutput(taskToken=None, input=None) + + def validate_state_machine_definition( + self, + context: RequestContext, + request: ValidateStateMachineDefinitionInput, + **kwargs, + ) -> ValidateStateMachineDefinitionOutput: + # TODO: increase parity of static analysers, current implementation is an unblocker for this API action. + # TODO: add support for ValidateStateMachineDefinitionSeverity + # TODO: add support for ValidateStateMachineDefinitionMaxResult + + state_machine_type: StateMachineType = request.get( + "type", StateMachineType.STANDARD + ) + definition: str = request["definition"] + + static_analysers = list() + if state_machine_type == StateMachineType.STANDARD: + static_analysers.append(StaticAnalyser()) + else: + static_analysers.append(ExpressStaticAnalyser()) + + diagnostics: ValidateStateMachineDefinitionDiagnosticList = list() + try: + StepFunctionsProvider._validate_definition( + definition=definition, static_analysers=static_analysers + ) + validation_result = ValidateStateMachineDefinitionResultCode.OK + except InvalidDefinition as invalid_definition: + validation_result = ValidateStateMachineDefinitionResultCode.FAIL + diagnostics.append( + ValidateStateMachineDefinitionDiagnostic( + severity=ValidateStateMachineDefinitionSeverity.ERROR, + code="SCHEMA_VALIDATION_FAILED", + message=invalid_definition.message, + ) + ) + except Exception as ex: + validation_result = ValidateStateMachineDefinitionResultCode.FAIL + LOG.error("Unknown error during validation %s", ex) + + return ValidateStateMachineDefinitionOutput( + result=validation_result, diagnostics=diagnostics, truncated=False + ) diff --git a/moto/stepfunctions/parser/quotas.py b/moto/stepfunctions/parser/quotas.py new file mode 100644 index 000000000000..dccc28e99493 --- /dev/null +++ b/moto/stepfunctions/parser/quotas.py @@ -0,0 +1,12 @@ +from typing import Any + +from moto.stepfunctions.parser.asl.utils.encoding import to_json_str + +MAX_STATE_SIZE_UTF8_BYTES: int = 256 * 1024 # 256 KB of data as a UTF-8 encoded string. + + +def is_within_size_quota(value: Any) -> bool: + item_str = value if isinstance(value, str) else to_json_str(value) + item_bytes = item_str.encode("utf-8") + len_item_bytes = len(item_bytes) + return len_item_bytes < MAX_STATE_SIZE_UTF8_BYTES diff --git a/moto/stepfunctions/parser/resource_providers/aws_stepfunctions_statemachine.schema.json b/moto/stepfunctions/parser/resource_providers/aws_stepfunctions_statemachine.schema.json index ecc15e42f672..c09f0187b1b6 100644 --- a/moto/stepfunctions/parser/resource_providers/aws_stepfunctions_statemachine.schema.json +++ b/moto/stepfunctions/parser/resource_providers/aws_stepfunctions_statemachine.schema.json @@ -264,4 +264,4 @@ ] } } -} +} \ No newline at end of file diff --git a/moto/stepfunctions/parser/stepfunctions_utils.py b/moto/stepfunctions/parser/stepfunctions_utils.py new file mode 100644 index 000000000000..fda3e30a11e1 --- /dev/null +++ b/moto/stepfunctions/parser/stepfunctions_utils.py @@ -0,0 +1,47 @@ +import base64 +import logging +from typing import Tuple + +from moto.stepfunctions.parser.api import ValidationException +from moto.stepfunctions.parser.utils import to_bytes, to_str + +LOG = logging.getLogger(__name__) + + +def get_next_page_token_from_arn(resource_arn: str) -> str: + return to_str(base64.b64encode(to_bytes(resource_arn))) + + +_DEFAULT_SFN_MAX_RESULTS: int = 100 + + +def normalise_max_results(max_results: int = 100) -> int: + if not max_results: + return _DEFAULT_SFN_MAX_RESULTS + return max_results + + +def assert_pagination_parameters_valid( + max_results: int, + next_token: str, + next_token_length_limit: int = 1024, + max_results_upper_limit: int = 1000, +) -> Tuple[int, str]: + validation_errors = [] + + if isinstance(max_results, int) and max_results > max_results_upper_limit: + validation_errors.append( + f"Value '{max_results}' at 'maxResults' failed to satisfy constraint: " + f"Member must have value less than or equal to {max_results_upper_limit}" + ) + + if isinstance(next_token, str) and len(next_token) > next_token_length_limit: + validation_errors.append( + f"Value '{next_token}' at 'nextToken' failed to satisfy constraint: " + f"Member must have length less than or equal to {next_token_length_limit}" + ) + + if validation_errors: + errors_message = "; ".join(validation_errors) + message = f"{len(validation_errors)} validation {'errors' if len(validation_errors) > 1 else 'error'} detected: {errors_message}" + raise ValidationException(message) diff --git a/moto/stepfunctions/parser/usage.py b/moto/stepfunctions/parser/usage.py new file mode 100644 index 000000000000..8d5e9391f314 --- /dev/null +++ b/moto/stepfunctions/parser/usage.py @@ -0,0 +1,20 @@ +""" +Usage reporting for StepFunctions service +""" + +from localstack.utils.analytics.usage import UsageCounter + +# Count of StepFunctions being created with JSONata QueryLanguage +jsonata_create_counter = UsageCounter("stepfunctions:jsonata:create") + +# Count of StepFunctions being created with JSONPath QueryLanguage +jsonpath_create_counter = UsageCounter("stepfunctions:jsonpath:create") + +# Count of StepFunctions being created that use Variable Sampling or the Assign block +variables_create_counter = UsageCounter("stepfunctions:variables:create") + +# Successful invocations (also including expected error cases in line with AWS behaviour) +invocation_counter = UsageCounter("stepfunctions:invocation") + +# Unexpected errors that we do not account for +error_counter = UsageCounter("stepfunctions:error") diff --git a/moto/stepfunctions/parser/utils.py b/moto/stepfunctions/parser/utils.py index c5181118be76..91f088a94bfd 100644 --- a/moto/stepfunctions/parser/utils.py +++ b/moto/stepfunctions/parser/utils.py @@ -1,5 +1,6 @@ import re -from typing import Dict, List, Set, Type +from typing import Dict, List, Set, Type, Union +from uuid import uuid4 TMP_THREADS = [] @@ -21,7 +22,7 @@ class SubtypesInstanceManager: _instances: Dict[str, "SubtypesInstanceManager"] @classmethod - def get(cls, subtype_name: str): + def get(cls, subtype_name: str, raise_if_missing: bool = False): instances = cls.instances() base_type = cls.get_base_type() instance = instances.get(subtype_name) @@ -58,6 +59,12 @@ def to_str(obj, encoding: str = "utf-8", errors="strict") -> str: return obj.decode(encoding, errors) if isinstance(obj, bytes) else obj +def to_bytes(obj: Union[str, bytes], encoding: str = "utf-8", errors="strict") -> bytes: + """If ``obj`` is an instance of ``text_type``, return + ``obj.encode(encoding, errors)``, otherwise return ``obj``""" + return obj.encode(encoding, errors) if isinstance(obj, str) else obj + + _re_camel_to_snake_case = re.compile("((?<=[a-z0-9])[A-Z]|(?!^)[A-Z](?=[a-z]))") @@ -80,3 +87,7 @@ def get_all_subclasses(clazz: Type) -> Set[Type]: result.add(sub) result.update(get_all_subclasses(sub)) return result + + +def long_uid() -> str: + return str(uuid4()) diff --git a/moto/stepfunctions/responses.py b/moto/stepfunctions/responses.py index 3191bd9998ca..1b26327e4fed 100644 --- a/moto/stepfunctions/responses.py +++ b/moto/stepfunctions/responses.py @@ -3,6 +3,7 @@ from moto.core.common_types import TYPE_RESPONSE from moto.core.config import default_user_config from moto.core.responses import BaseResponse +from moto.core.utils import iso_8601_datetime_with_milliseconds from .models import StepFunctionBackend, stepfunctions_backends from .parser.api import ExecutionStatus @@ -151,7 +152,7 @@ def start_execution(self) -> TYPE_RESPONSE: ) response = { "executionArn": execution.execution_arn, - "startDate": execution.start_date, + "startDate": iso_8601_datetime_with_milliseconds(execution.start_date), } return 200, {}, json.dumps(response) @@ -167,17 +168,24 @@ def list_executions(self) -> TYPE_RESPONSE: max_results=max_results, next_token=next_token, ) - executions = [ - { + executions = [] + for execution in results: + result = { "executionArn": execution.execution_arn, "name": execution.name, - "startDate": execution.start_date, - "stopDate": execution.stop_date, + "startDate": iso_8601_datetime_with_milliseconds(execution.start_date), "stateMachineArn": state_machine.arn, "status": execution.status, } - for execution in results - ] + if execution.status in [ + ExecutionStatus.SUCCEEDED, + ExecutionStatus.FAILED, + ExecutionStatus.ABORTED, + ]: + result["stopDate"] = iso_8601_datetime_with_milliseconds( + execution.stop_date + ) + executions.append(result) response = {"executions": executions} if next_token: response["nextToken"] = next_token @@ -190,13 +198,26 @@ def describe_execution(self) -> TYPE_RESPONSE: "executionArn": arn, "input": json.dumps(execution.execution_input), "name": execution.name, - "startDate": execution.start_date, + "startDate": iso_8601_datetime_with_milliseconds(execution.start_date), "stateMachineArn": execution.state_machine_arn, "status": execution.status, - "stopDate": execution.stop_date, } - if execution.status == ExecutionStatus.SUCCEEDED: - response["output"] = execution.output + if execution.status in [ + ExecutionStatus.SUCCEEDED, + ExecutionStatus.ABORTED, + ExecutionStatus.FAILED, + ]: + response["stopDate"] = iso_8601_datetime_with_milliseconds( + execution.stop_date + ) + if execution.status in [ + ExecutionStatus.SUCCEEDED, + ExecutionStatus.SUCCEEDED.value, + ]: + if isinstance(execution.output, str): + response["output"] = execution.output + elif execution.output is not None: + response["output"] = json.dumps(execution.output) response["outputDetails"] = execution.output_details if execution.error is not None: response["error"] = execution.error @@ -212,7 +233,9 @@ def describe_state_machine_for_execution(self) -> TYPE_RESPONSE: def stop_execution(self) -> TYPE_RESPONSE: arn = self._get_param("executionArn") execution = self.stepfunction_backend.stop_execution(arn) - response = {"stopDate": execution.stop_date} + response = { + "stopDate": iso_8601_datetime_with_milliseconds(execution.stop_date) + } return 200, {}, json.dumps(response) def get_execution_history(self) -> TYPE_RESPONSE: @@ -220,8 +243,7 @@ def get_execution_history(self) -> TYPE_RESPONSE: execution_history = self.stepfunction_backend.get_execution_history( execution_arn ) - response = {"events": execution_history} - return 200, {}, json.dumps(response) + return 200, {}, json.dumps(execution_history) def send_task_failure(self) -> TYPE_RESPONSE: task_token = self._get_param("taskToken") diff --git a/moto/utilities/collections.py b/moto/utilities/collections.py new file mode 100644 index 000000000000..b54cef9b6926 --- /dev/null +++ b/moto/utilities/collections.py @@ -0,0 +1,28 @@ +from typing import Any, List + +from moto.core.versions import PYTHON_39 + + +def select_attributes(obj: Any, attributes: List[str]) -> Any: + """Select a subset of attributes from the given dict (returns a copy)""" + attributes = attributes if isinstance(attributes, (list, tuple)) else [attributes] # type: ignore + return {k: v for k, v in obj.items() if k in attributes} + + +def select_from_typed_dict(typed_dict: Any, obj: Any, filter: bool = False) -> Any: + """ + Select a subset of attributes from a dictionary based on the keys of a given `TypedDict`. + :param typed_dict: the `TypedDict` blueprint + :param obj: the object to filter + :param filter: if True, remove all keys with an empty (e.g., empty string or dictionary) or `None` value + :return: the resulting dictionary (it returns a copy) + """ + if not PYTHON_39: + # Python 3.8 does not have __required_keys__, __optional_keys__ + return dict(obj) + selection = select_attributes( + obj, [*typed_dict.__required_keys__, *typed_dict.__optional_keys__] + ) + if filter: + selection = {k: v for k, v in selection.items() if v} + return selection diff --git a/scripts/import_sfn_parser.sh b/scripts/import_sfn_parser.sh new file mode 100755 index 000000000000..45d1605143a3 --- /dev/null +++ b/scripts/import_sfn_parser.sh @@ -0,0 +1,110 @@ +#!/bin/bash + +# Keep Moto-specific parts +mkdir tmp +mv moto/stepfunctions/parser/README.md tmp +mv moto/stepfunctions/parser/api.py tmp +mv moto/stepfunctions/parser/models.py tmp +mv moto/stepfunctions/parser/utils.py tmp +mv moto/stepfunctions/parser/asl/utils/boto_client.py tmp +mv moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service_api_gateway.py tmp +mv moto/stepfunctions/parser/asl/component/state/exec/state_task/service/state_task_service_aws_sdk.py tmp +mv moto/stepfunctions/parser/asl/component/state/exec/state_task/lambda_eval_utils.py tmp +mv moto/stepfunctions/parser/backend/execution.py tmp + +# Remove old implementation +rm -rf moto/stepfunctions/parser + +# Copy implementation as is +cp -r ../../localstack/localstack/localstack-core/localstack/services/stepfunctions moto/stepfunctions/parser + +# Remove parser/spec files that we don't need +rm -r moto/stepfunctions/parser/asl/antlr/.gitignore +rm -r moto/stepfunctions/parser/asl/antlr/Makefile + +# Shorten paths, as they are too long for Windows implementations +mv moto/stepfunctions/parser/asl/component/state/state_choice moto/stepfunctions/parser/asl/component/state/choice +mv moto/stepfunctions/parser/asl/component/state/state_execution moto/stepfunctions/parser/asl/component/state/exec +mv moto/stepfunctions/parser/asl/component/state/state_fail moto/stepfunctions/parser/asl/component/state/fail +mv moto/stepfunctions/parser/asl/component/state/state_wait moto/stepfunctions/parser/asl/component/state/wait +mv moto/stepfunctions/parser/asl/component/state/exec/state_map/item_reader/resource_eval moto/stepfunctions/parser/asl/component/state/exec/state_map/item_reader/eval +mv moto/stepfunctions/parser/asl/component/state/exec/state_map/item_reader/eval/resource_output_transformer/resource_output_transformer.py moto/stepfunctions/parser/asl/component/state/exec/state_map/item_reader/eval/resource_output_transformer/transformer.py +mv moto/stepfunctions/parser/asl/component/state/exec/state_map/item_reader/eval/resource_output_transformer/resource_output_transformer_csv.py moto/stepfunctions/parser/asl/component/state/exec/state_map/item_reader/eval/resource_output_transformer/transformer_csv.py +mv moto/stepfunctions/parser/asl/component/state/exec/state_map/item_reader/eval/resource_output_transformer/resource_output_transformer_factory.py moto/stepfunctions/parser/asl/component/state/exec/state_map/item_reader/eval/resource_output_transformer/transformer_factory.py +mv moto/stepfunctions/parser/asl/component/state/exec/state_map/item_reader/eval/resource_output_transformer/resource_output_transformer_json.py moto/stepfunctions/parser/asl/component/state/exec/state_map/item_reader/eval/resource_output_transformer/transformer_json.py + +# Alter imports with shorter paths +find moto/stepfunctions/parser/asl -type f | xargs sed -i 's/state.state_execution/state.exec/' +find moto/stepfunctions/parser/asl -type f | xargs sed -i 's/state.state_choice/state.choice/' +find moto/stepfunctions/parser/asl -type f | xargs sed -i 's/state.state_fail/state.fail/' +find moto/stepfunctions/parser/asl -type f | xargs sed -i 's/state.state_wait/state.wait/' +find moto/stepfunctions/parser/asl -type f | xargs sed -i 's/item_reader.resource_eval.resource_eval/item_reader.eval.resource_eval/' +find moto/stepfunctions/parser/asl -type f | xargs sed -i 's/item_reader.resource_eval.resource_output_transformer/item_reader.eval.resource_output_transformer/' +find moto/stepfunctions/parser/asl -type f | xargs sed -i 's/eval.resource_output_transformer.resource_output_transformer/eval.resource_output_transformer.transformer/' + +# Allow for Python 3.8 +find moto/stepfunctions/parser/asl -type f -name "*.py" | xargs sed -i 's/NotRequired/Optional/' +find moto/stepfunctions/parser -type f -name "*.py" | xargs sed -i 's/Union\[str, json\]/Any/' +find moto/stepfunctions/parser -type f -name "*.py" | xargs sed -i '1s/^/from typing import Any, List\n/' +find moto/stepfunctions/parser/asl -type f -name "*.py" | xargs sed -i 's/: list\[/: List\[/' +find moto/stepfunctions/parser/asl -type f -name "*.py" | xargs sed -i 's/\[list\[/\[List\[/' + +# Remove custom LS logic +find moto/stepfunctions/parser/ -type f -name "*.py" | xargs sed -i 's/from localstack.utils.aws.arns/from moto.utilities.arns/' +find moto/stepfunctions/parser/ -type f -name "*.py" | xargs sed -i 's/from localstack.utils.objects/from moto.stepfunctions.parser.utils/' +find moto/stepfunctions/parser/ -type f -name "*.py" | xargs sed -i 's/from localstack.utils.strings/from moto.stepfunctions.parser.utils/' +find moto/stepfunctions/parser/ -type f -name "*.py" | xargs sed -i 's/from localstack.utils.common/from moto.stepfunctions.parser.utils/' +find moto/stepfunctions/parser/ -type f -name "*.py" | xargs sed -i 's/from localstack.utils.threads/from moto.stepfunctions.parser.utils/' +find moto/stepfunctions/parser/asl -type f -name "*.py" | xargs sed -i 's/ArnData,//' +find moto/stepfunctions/parser/asl -type f -name "*.py" | xargs sed -i 's/: ArnData//' +find moto/stepfunctions/parser/asl -type f -name "*.py" | xargs sed -i 's/arn_data["region"]/arn_data.region/' +find moto/stepfunctions/parser/asl -type f -name "*.py" | xargs sed -i 's/arn_data["region"]/arn_data.region/' +find moto/stepfunctions/parser/asl -type f -name "*.py" | xargs sed -i 's/arn_data.get("region")/arn_data.region/' +find moto/stepfunctions/parser/asl -type f -name "*.py" | xargs sed -i 's/arn_data.get("account")/arn_data.account/' +find moto/stepfunctions/parser/asl -type f -name "*.py" | xargs sed -i 's/arn_data.get("resource")/arn_data.resource_id/' +find moto/stepfunctions/parser/asl -type f -name "*.py" | xargs sed -i 's/except InvalidArnException/except IndexError/' +find moto/stepfunctions/parser/asl -type f -name "*.py" | xargs sed -i 's/List\[InputLogEvent\]/List\[Any\]/' +find moto/stepfunctions/parser/asl -type f -name "*.py" | xargs sed -i 's/from localstack.aws.api.logs import InputLogEvent//' +find moto/stepfunctions/parser/asl -type f -name "*.py" | xargs sed -i 's/from localstack.aws.connect import connect_to//' + +find moto/stepfunctions/parser/asl/component/state/exec/state_task -type f -name "*.py" | xargs sed -i 's/InvocationType.RequestResponse/"RequestResponse"/' +find moto/stepfunctions/parser/asl/component/state/exec/state_task -type f -name "*.py" | xargs sed -i '/InvocationType/d' +find moto/stepfunctions/parser/asl/component/state/exec/state_task -type f -name "*.py" | xargs sed -i 's/InvocationRequest/dict/' + +rm moto/stepfunctions/parser/asl/jsonata/packages.py +find moto/stepfunctions/parser/asl -type f -name "*.py" | xargs sed -i '/jsonata_package/d' +find moto/stepfunctions/parser/asl -type f -name "*.py" | xargs sed -i '/singleton_factory/d' +find moto/stepfunctions/parser/asl -type f -name "*.py" | xargs sed -i 's/_JSONataJVMBridge.get().eval\_jsonata/None/' + +find moto/stepfunctions/parser/asl -type f -name "*.py" | xargs sed -i 's/localstack.utils.collections/moto.utilities.collections/' + +# Fix wildcard imports +find moto/stepfunctions/parser/asl/antlr -type f -name "*.py" | xargs sed -i 's/from antlr4 import \*/from antlr4 import DFA,ATNDeserializer,NoViableAltException,Parser,ParserATNSimulator,ParserRuleContext,ParseTreeListener,ParseTreeVisitor,PredictionContextCache,RecognitionException,Token,TokenStream,Lexer,LexerATNSimulator/' +find moto/stepfunctions/parser/asl/antlr -type f -name "*.py" | xargs sed -i 's/if sys.version_info[1] > 5://' +find moto/stepfunctions/parser/asl/antlr -type f -name "*.py" | xargs sed -i 's/from typing import TextIO\nelse://' + +# Alter import paths as appropriate +find moto/stepfunctions/parser -type f | xargs sed -i 's/from localstack.services.stepfunctions/from moto.stepfunctions.parser/' +find moto/stepfunctions/parser -type f | xargs sed -i 's/from localstack.aws.api.stepfunctions import/from moto.stepfunctions.parser.api import/' +find moto/stepfunctions/parser/asl -type f | xargs sed -i 's/from localstack.utils.strings import long_uid/from uuid import uuid4 as long_uid/' + +# Fix some typo's +mv moto/stepfunctions/parser/asl/component/intrinsic/functionname/state_fuinction_name_types.py moto/stepfunctions/parser/asl/component/intrinsic/functionname/state_function_name_types.py +find moto/stepfunctions/parser -type f -name "*.py" | xargs sed -i 's/from moto.stepfunctions.parser.asl.component.intrinsic.functionname.state_fuinction_name_types/from moto.stepfunctions.parser.asl.component.intrinsic.functionname.state_function_name_types/' + +mv tmp/README.md moto/stepfunctions/parser/ +mv tmp/api.py moto/stepfunctions/parser/ +mv tmp/models.py moto/stepfunctions/parser/ +mv tmp/utils.py moto/stepfunctions/parser/ +mv tmp/boto_client.py moto/stepfunctions/parser/asl/utils/ +mv tmp/state_task_service_api_gateway.py moto/stepfunctions/parser/asl/component/state/exec/state_task/service/ +mv tmp/state_task_service_aws_sdk.py moto/stepfunctions/parser/asl/component/state/exec/state_task/service/ +mv tmp/lambda_eval_utils.py moto/stepfunctions/parser/asl/component/state/exec/state_task/ +mv tmp/execution.py moto/stepfunctions/parser/backend/ +cp api.py moto/stepfunctions/parser/ + +rmdir tmp + +# Format files as appropriate +ruff check --fix moto/stepfunctions/parser +ruff format moto/stepfunctions/parser diff --git a/tests/test_stepfunctions/parser/templates/credentials.json b/tests/test_stepfunctions/parser/templates/credentials.json new file mode 100644 index 000000000000..9fe8349a8d9f --- /dev/null +++ b/tests/test_stepfunctions/parser/templates/credentials.json @@ -0,0 +1,14 @@ +{ + "StartAt": "ListTables", + "States": { + "ListTables": { + "Type": "Task", + "Parameters": {}, + "Resource": "arn:aws:states:::aws-sdk:dynamodb:listTables", + "End": true, + "Credentials": { + "RoleArn": "arn:aws:iam::123456789012:role/role/role" + } + } + } + } \ No newline at end of file diff --git a/tests/test_stepfunctions/parser/test_parallel_states.py b/tests/test_stepfunctions/parser/test_parallel_states.py index 6b99450dfaad..da9f16cca335 100644 --- a/tests/test_stepfunctions/parser/test_parallel_states.py +++ b/tests/test_stepfunctions/parser/test_parallel_states.py @@ -14,7 +14,11 @@ def test_state_machine_with_parallel_states(): def _verify_result(client, execution, execution_arn): assert "stopDate" in execution - assert execution["output"] == "[[1,2,3,4],[1,2,3,4],[1,2,3,4]]" + assert json.loads(execution["output"]) == [ + [1, 2, 3, 4], + [1, 2, 3, 4], + [1, 2, 3, 4], + ] history = client.get_execution_history(executionArn=execution_arn) assert len(history["events"]) == 20 diff --git a/tests/test_stepfunctions/parser/test_stepfunctions.py b/tests/test_stepfunctions/parser/test_stepfunctions.py index c8af68d88b72..20b8be0ea63c 100644 --- a/tests/test_stepfunctions/parser/test_stepfunctions.py +++ b/tests/test_stepfunctions/parser/test_stepfunctions.py @@ -6,7 +6,7 @@ import boto3 import pytest -from moto import settings +from moto import mock_aws, settings from . import ( allow_aws_request, @@ -165,3 +165,15 @@ def test_version_is_only_available_when_published(): iam.delete_role_policy(RoleName=role_name, PolicyName="allowLambdaInvoke") iam.delete_role(RoleName=role_name) kms.schedule_key_deletion(KeyId=kms_key_id, PendingWindowInDays=7) + + +@mock_aws(config={"stepfunctions": {"execute_state_machine": True}}) +def test_verify_template_with_credentials(): + if settings.TEST_SERVER_MODE: + raise SkipTest("Don't need to test this in ServerMode") + + def _verify_result(client, execution, execution_arn): + output = json.loads(execution["output"]) + assert output["TableNames"] == [] + + verify_execution_result(_verify_result, "SUCCEEDED", "credentials")