def _specification_type_to_python_type(specification_type: str) -> str: """ Convert a data type in protocol specification into its Python equivalent. :param specification_type: a protocol specification data type :return: The equivalent data type in Python """ if specification_type.startswith("pt:optional"): python_type = _optional_specification_type_to_python_type( specification_type) elif specification_type.startswith("pt:union"): python_type = _mt_specification_type_to_python_type(specification_type) elif specification_type.startswith("ct:"): python_type = _ct_specification_type_to_python_type(specification_type) elif specification_type in SPECIFICATION_PRIMITIVE_TYPES: python_type = _pt_specification_type_to_python_type(specification_type) elif specification_type.startswith("pt:set"): python_type = _pct_specification_type_to_python_type( specification_type) elif specification_type.startswith("pt:list"): python_type = _pct_specification_type_to_python_type( specification_type) elif specification_type.startswith("pt:dict"): python_type = _pmt_specification_type_to_python_type( specification_type) else: raise ProtocolSpecificationParseError( "Unsupported type: '{}'".format(specification_type)) return python_type
def extract( protocol_specification: ProtocolSpecification, ) -> PythonicProtocolSpecification: """ Converts a protocol specification into a Pythonic protocol specification. :param protocol_specification: a protocol specification :return: a Pythonic protocol specification """ # check the specification is valid result_bool, result_msg = validate(protocol_specification) if not result_bool: raise ProtocolSpecificationParseError(result_msg) spec = PythonicProtocolSpecification() all_performatives_set = set() all_custom_types_set = set() for ( performative, speech_act_content_config, ) in protocol_specification.speech_acts.read_all(): all_performatives_set.add(performative) spec.speech_acts[performative] = {} for content_name, content_type in speech_act_content_config.args.items( ): # determine necessary imports from typing if len(re.findall("pt:set\\[", content_type)) >= 1: spec.typing_imports["FrozenSet"] = True if len(re.findall("pt:dict\\[", content_type)) >= 1: spec.typing_imports["Dict"] = True if len(re.findall("pt:union\\[", content_type)) >= 1: spec.typing_imports["Union"] = True if len(re.findall("pt:optional\\[", content_type)) >= 1: spec.typing_imports["Optional"] = True # specification type --> python type pythonic_content_type = _specification_type_to_python_type( content_type) spec.all_unique_contents[content_name] = pythonic_content_type spec.speech_acts[performative][ content_name] = pythonic_content_type if content_type.startswith("ct:"): all_custom_types_set.add(pythonic_content_type) # sort the sets spec.all_performatives = sorted(all_performatives_set) spec.all_custom_types = sorted(all_custom_types_set) # "XXX" custom type --> "CustomXXX" spec.custom_custom_types = { pure_custom_type: "Custom" + pure_custom_type for pure_custom_type in spec.all_custom_types } # Dialogue attributes if (protocol_specification.dialogue_config != {} and protocol_specification.dialogue_config is not None): spec.initial_performatives = [ initial_performative.upper() for initial_performative in cast( List[str], protocol_specification.dialogue_config["initiation"]) ] spec.reply = cast( Dict[str, List[str]], protocol_specification.dialogue_config["reply"], ) spec.terminal_performatives = [ terminal_performative.upper() for terminal_performative in cast( List[str], protocol_specification.dialogue_config["termination"], ) ] roles_set = cast(Dict[str, None], protocol_specification.dialogue_config["roles"]) spec.roles = sorted(roles_set) spec.end_states = cast( List[str], protocol_specification.dialogue_config["end_states"]) return spec
def _raise_psperror(*args, **kwargs): raise ProtocolSpecificationParseError()