"""The AaC Constraint Assignment Arguments plugin implementation module."""
# NOTE: It is safe to edit this file.
# This file is only initially generated by aac gen-plugin, and it won't be overwritten if the file already exists.
# There may be some unused imports depending on the definition of the plugin...but that's ok
from aac.execute.aac_execution_result import (
ExecutionResult,
ExecutionStatus,
ExecutionMessage,
MessageLevel,
)
from aac.context.language_context import LanguageContext
from aac.context.definition import Definition
from typing import Any
plugin_name = "Constraint Assignment Arguments"
[docs]
def check_arguments_against_constraint_definition( # noqa: C901
instance: Any, definition: Definition, defining_schema
) -> ExecutionResult:
"""Business logic for the Check arguments against constraint definition constraint."""
context = LanguageContext()
if not context.is_aac_instance(
instance, "aac.lang.SchemaConstraintAssignment"
) and not context.is_aac_instance(
instance, "aac.lang.PrimitiveConstraintAssignment"
):
# the constraint failed
error_msg = ExecutionMessage(
f"The Check arguments against constraint definition constraint for {instance.name} failed. You may only use this constraint on SchemaConstraintAssignment or PrimitiveConstraintAssignment definitions. Received {type(instance)}.)",
MessageLevel.ERROR,
("No file to reference" if not definition.source or definition.source.uri == "<string>" else definition.source.uri),
None,
)
return ExecutionResult(
plugin_name,
"Check arguments against constraint definition",
ExecutionStatus.GENERAL_FAILURE,
[error_msg],
)
constraint_name = instance.name
constraint_args: dict = {}
if instance.arguments is None:
constraint_args = {}
elif not isinstance(instance.arguments, list):
error_msg = ExecutionMessage(
f"The Check arguments against constraint definition constraint for {instance.name} failed because the assigned arguments were not parsed as a list of entries and cannot be evaluated. Received {instance.arguments}",
MessageLevel.ERROR,
"No file to reference" if not definition.source or definition.source.uri == "<string>" else definition.source.uri,
None,
)
return ExecutionResult(
plugin_name,
"Check arguments against constraint definition",
ExecutionStatus.GENERAL_FAILURE,
[error_msg],
)
else:
for arg in instance.arguments:
if not isinstance(arg, dict):
error_msg = ExecutionMessage(
f"The Check arguments against constraint definition constraint for {instance.name} failed because the assigned arguments were not parsed as a list of PluginInputValue entries and cannot be evaluated. Received {instance.arguments}",
MessageLevel.ERROR,
"No file to reference" if not definition.source or definition.source.uri == "<string>" else definition.source.uri,
None,
)
return ExecutionResult(
plugin_name,
"Check arguments against constraint definition",
ExecutionStatus.GENERAL_FAILURE,
[error_msg],
)
constraint_args[arg["name"]] = arg["value"]
constraint_definition = None
for plugin in context.get_definitions_by_root("plugin"):
for schema_constraint in plugin.instance.schema_constraints:
if schema_constraint.name == constraint_name:
constraint_definition = schema_constraint
break
for primitive_constraint in plugin.instance.primitive_constraints:
if primitive_constraint.name == constraint_name:
constraint_definition = primitive_constraint
break
# Make sure we found the constraint definition
if constraint_definition is None:
# the constraint failed
error_msg = ExecutionMessage(
f"The Check arguments against constraint definition constraint for {instance.name} failed because the constraint definition could not be found.",
MessageLevel.ERROR,
"No file to reference" if not definition.source or definition.source.uri == "<string>" else definition.source.uri,
None,
)
return ExecutionResult(
plugin_name,
"Check arguments against constraint definition",
ExecutionStatus.GENERAL_FAILURE,
[error_msg],
)
# Make sure there are no arguments if the constraint definition has no arguments
if (
constraint_definition.arguments is None
or len(constraint_definition.arguments) == 0
):
if constraint_args is not None and constraint_args != {}:
# the constraint failed
error_msg = ExecutionMessage(
f"The Check arguments against constraint definition constraint for {instance.name} failed because the constraint definition does not have arguments, but the constraint assignment does. Assigned arguments are {constraint_args}.",
MessageLevel.ERROR,
"No file to reference" if not definition.source or definition.source.uri == "<string>" else definition.source.uri,
None,
)
return ExecutionResult(
plugin_name,
"Check arguments against constraint definition",
ExecutionStatus.GENERAL_FAILURE,
[error_msg],
)
else: # If there are arguments, then make sure they match the constraint definition
defined_argument_names = []
for field in constraint_definition.arguments:
# make sure required arguments are present
defined_argument_names.append(field.name)
if field.is_required and (
not constraint_args or field.name not in constraint_args
):
# the constraint failed
error_msg = ExecutionMessage(
f"The Check arguments against constraint definition constraint for {instance.name} failed because the constraint definition has a required argument named {field.name} that was not found in the constraint assignment.",
MessageLevel.ERROR,
"No file to reference" if not definition.source or definition.source.uri == "<string>" else definition.source.uri,
None,
)
return ExecutionResult(
plugin_name,
"Check arguments against constraint definition",
ExecutionStatus.GENERAL_FAILURE,
[error_msg],
)
# make sure the arguments provided are defined in the constraint definition
for arg_name in constraint_args:
if arg_name not in defined_argument_names:
# the constraint failed
error_msg = ExecutionMessage(
f"The Check arguments against constraint definition constraint for {instance.name} failed because the constraint definition does not have an argument named {arg_name}, but the constraint assignment does. Argument {arg_name} is not in defined argument names {defined_argument_names}.",
MessageLevel.ERROR,
"No file to reference" if not definition.source or definition.source.uri == "<string>" else definition.source.uri,
None,
)
return ExecutionResult(
plugin_name,
"Check arguments against constraint definition",
ExecutionStatus.GENERAL_FAILURE,
[error_msg],
)
return ExecutionResult(
plugin_name,
"Check arguments against constraint definition",
ExecutionStatus.SUCCESS,
[],
)