Beispiel #1
0
def generate_msg_text_from_spec(package, interface_name, indent=0):
    """
    Generate a dictionary with the compact message.

    Compact message contains:
        - Constants
        - messge fields. If the message contains other composed interfaces
          a link will be added to this interfaces.

    :param package: name of the package
    :type package: str:
    :param interface_name: name of the message
    :type interface_name: str
    :param indent: number of indentations to add to the generated text (default = 0)
    :type indent: int, optional
    :returns: dictionary with the compact definition (constanst and message with links)
    :rtype: dict
    """
    interface_location = IdlLocator(
        pathlib.Path(get_package_share_directory(package)),
        pathlib.Path('action') / (interface_name + '.idl'))
    message = parse_idl_file(interface_location).content.get_elements_of_type(
        Action)

    compact_srv = {}

    for attribute in ['goal', 'result', 'feedback']:
        definition = utils.generate_compact_definition(
            getattr(message[0], attribute), indent)
        utils.copy_dict_with_suffix(compact_srv, definition, attribute)

    return compact_srv
def generate_msg_text_from_spec(package, interface_name, indent=0):
    """
    Generate a dictionary with the compact message.

    Compact message contains:
        - Constants
        - messge fields. If the message contains other composed interfaces
          a link will be added to this interfaces.

    :param package: name of the package
    :type package: str:
    :param interface_name: name of the message
    :type interface_name: str
    :param indent: number of indentations to add to the generated text (default = 0)
    :type indent: int, optional
    :returns: dictionary with the compact definition (constanst and message with links)
    :rtype: dict
    """
    interface_location = IdlLocator(
        pathlib.Path(get_package_share_directory(package)),
        pathlib.Path('srv') / (interface_name + '.idl'))
    message = parse_idl_file(interface_location).content.get_elements_of_type(
        Service)

    compact_srv = {}

    compact_request = utils.generate_compact_definition(
        message[0].request_message, indent)
    utils.copy_dict_with_suffix(compact_srv, compact_request, 'request')

    compact_response = utils.generate_compact_definition(
        message[0].response_message, indent)
    utils.copy_dict_with_suffix(compact_srv, compact_response, 'response')

    return compact_srv
Beispiel #3
0
def generate_files(generator_arguments_file,
                   mapping,
                   additional_context=None,
                   keep_case=False,
                   post_process_callback=None):
    args = read_generator_arguments(generator_arguments_file)

    template_basepath = pathlib.Path(args['template_dir'])
    for template_filename in mapping.keys():
        assert (template_basepath / template_filename).exists(), \
            'Could not find template: ' + template_filename

    latest_target_timestamp = get_newest_modification_time(
        args['target_dependencies'])
    generated_files = []

    for idl_tuple in args.get('idl_tuples', []):
        idl_parts = idl_tuple.rsplit(':', 1)
        assert len(idl_parts) == 2
        locator = IdlLocator(*idl_parts)
        idl_rel_path = pathlib.Path(idl_parts[1])
        idl_stem = idl_rel_path.stem
        if not keep_case:
            idl_stem = convert_camel_case_to_lower_case_underscore(idl_stem)
        try:
            idl_file = parse_idl_file(locator)
            for template_file, generated_filename in mapping.items():
                generated_file = os.path.join(args['output_dir'],
                                              str(idl_rel_path.parent),
                                              generated_filename % idl_stem)
                generated_files.append(generated_file)
                data = {
                    'package_name': args['package_name'],
                    'interface_path': idl_rel_path,
                    'content': idl_file.content,
                }
                if additional_context is not None:
                    data.update(additional_context)
                expand_template(os.path.basename(template_file),
                                data,
                                generated_file,
                                minimum_timestamp=latest_target_timestamp,
                                template_basepath=template_basepath,
                                post_process_callback=post_process_callback)
        except Exception as e:
            print('Error processing idl file: ' +
                  str(locator.get_absolute_path()),
                  file=sys.stderr)
            raise (e)

    return generated_files
Beispiel #4
0
def generate_files(generator_arguments_file, mapping, additional_context=None, keep_case=False):
    args = read_generator_arguments(generator_arguments_file)

    template_basepath = pathlib.Path(args['template_dir'])
    for template_filename in mapping.keys():
        assert (template_basepath / template_filename).exists(), \
            'Could not find template: ' + template_filename

    latest_target_timestamp = get_newest_modification_time(args['target_dependencies'])

    for idl_tuple in args.get('idl_tuples', []):
        idl_parts = idl_tuple.rsplit(':', 1)
        assert len(idl_parts) == 2
        locator = IdlLocator(*idl_parts)
        idl_rel_path = pathlib.Path(idl_parts[1])
        idl_stem = idl_rel_path.stem
        if not keep_case:
            idl_stem = convert_camel_case_to_lower_case_underscore(idl_stem)
        try:
            idl_file = parse_idl_file(locator)
            for template_file, generated_filename in mapping.items():
                generated_file = os.path.join(
                    args['output_dir'], str(idl_rel_path.parent),
                    generated_filename % idl_stem)
                data = {
                    'package_name': args['package_name'],
                    'interface_path': idl_rel_path,
                    'content': idl_file.content,
                }
                if additional_context is not None:
                    data.update(additional_context)
                expand_template(
                    os.path.basename(template_file), data,
                    generated_file, minimum_timestamp=latest_target_timestamp,
                    template_basepath=template_basepath)
        except Exception as e:
            print(
                'Error processing idl file: ' +
                str(locator.get_absolute_path()), file=sys.stderr)
            raise(e)

    return 0
Beispiel #5
0
def generate(generator_arguments_file: str) -> List[str]:
    mapping = {
        "_idl.pyi.em": "_%s.pyi",
    }
    generated_files: List[str] = generate_files(generator_arguments_file,
                                                mapping)

    args = read_generator_arguments(generator_arguments_file)
    package_name = args["package_name"]

    # For __init__.pyi, it is required to output the exact same contents as
    # rosidl_python does.
    modules: Dict[str, Set[str]] = {}
    idl_content = IdlContent()
    for idl_tuple in args.get("idl_tuples", []):
        idl_parts = idl_tuple.rsplit(":", 1)
        assert len(idl_parts) == 2

        idl_rel_path = pathlib.Path(idl_parts[1])
        idl_stems = modules.setdefault(str(idl_rel_path.parent), set())
        idl_stems.add(idl_rel_path.stem)

        locator = IdlLocator(*idl_parts)
        idl_file = parse_idl_file(locator)
        idl_content.elements += idl_file.content.elements

    for subfolder in modules.keys():
        with open(os.path.join(args["output_dir"], subfolder, "__init__.pyi"),
                  "w") as f:
            for idl_stem in sorted(modules[subfolder]):
                module_name = "_{}".format(
                    convert_camel_case_to_lower_case_underscore(idl_stem))
                f.write(
                    f"from {package_name}.{subfolder}.{module_name} import "
                    f"{idl_stem} as {idl_stem}  # noqa: F401\n")

    return generated_files
Beispiel #6
0
def generate_rs(generator_arguments_file, typesupport_impls):
    args = read_generator_arguments(generator_arguments_file)
    package_name = args['package_name']

    # expand init modules for each directory
    modules = {}
    idl_content = IdlContent()
    for idl_tuple in args.get('idl_tuples', []):
        idl_parts = idl_tuple.rsplit(':', 1)
        assert len(idl_parts) == 2

        idl_rel_path = pathlib.Path(idl_parts[1])
        idl_stems = modules.setdefault(str(idl_rel_path.parent), set())
        idl_stems.add(idl_rel_path.stem)

        locator = IdlLocator(*idl_parts)
        idl_file = parse_idl_file(locator)
        idl_content.elements += idl_file.content.elements

    typesupport_impls = typesupport_impls.split(';')

    template_dir = args['template_dir']
    type_support_impl_by_filename = {
        '%s_rs.ep.{0}.c'.format(impl): impl
        for impl in typesupport_impls
    }

    mapping_msgs = {
        os.path.join(template_dir, 'msg.rs.em'): ['rust/src/%s.rs'],
        os.path.join(template_dir, 'msg.c.em'): type_support_impl_by_filename.keys(),
    }

    mapping_srvs = {
        os.path.join(template_dir, 'srv.rs.em'): ['rust/src/%s.rs'],
        os.path.join(template_dir, 'srv.c.em'): type_support_impl_by_filename.keys(),
    }

    # Ensure the required templates exist
    for template_file in mapping_msgs.keys():
        assert os.path.exists(template_file), \
            'Messages template file %s not found' % template_file
    for template_file in mapping_srvs.keys():
        assert os.path.exists(template_file), \
            'Services template file %s not found' % template_file

    data = {
        'get_c_type': get_c_type,
        'get_rs_type': get_rs_type,
        'constant_value_to_rs': constant_value_to_rs,
        'value_to_rs': value_to_rs,
        'convert_camel_case_to_lower_case_underscore':
        convert_camel_case_to_lower_case_underscore,
        'convert_lower_case_underscore_to_camel_case':
        convert_lower_case_underscore_to_camel_case,
        'get_builtin_rs_type': get_builtin_rs_type,
        'msg_specs': [],
        'srv_specs': [],
        'package_name': args['package_name'],
        'typesupport_impls': typesupport_impls,
    }
    latest_target_timestamp = get_newest_modification_time(
        args['target_dependencies'])

    for message in idl_content.get_elements_of_type(Message):
        data['msg_specs'].append(('msg', message))

    for service in idl_content.get_elements_of_type(Service):
        data['srv_specs'].append(('srv', service))

    if data['msg_specs']:
        for template_file, generated_filenames in mapping_msgs.items():
            for generated_filename in generated_filenames:
                generated_file = os.path.join(args['output_dir'],
                                              generated_filename % 'msg')
                expand_template(
                    os.path.join(template_dir, template_file),
                    data.copy(),
                    generated_file,
                    minimum_timestamp=latest_target_timestamp)

    if data['srv_specs']:
        for template_file, generated_filenames in mapping_srvs.items():
            for generated_filename in generated_filenames:
                generated_file = os.path.join(args['output_dir'],
                                              generated_filename % 'srv')
                expand_template(
                    os.path.join(template_dir, template_file),
                    data.copy(),
                    generated_file,
                    minimum_timestamp=latest_target_timestamp)

    expand_template(
        os.path.join(template_dir, 'lib.rs.em'),
        data.copy(),
        os.path.join(args['output_dir'], 'rust/src/lib.rs'),
        minimum_timestamp=latest_target_timestamp)

    return 0
def generate_py(generator_arguments_file, typesupport_impls):
    mapping = {
        '_idl.py.em': '_%s.py',
        '_idl_support.c.em': '_%s_s.c',
    }
    generate_files(generator_arguments_file, mapping)

    args = read_generator_arguments(generator_arguments_file)
    package_name = args['package_name']

    # expand init modules for each directory
    modules = {}
    idl_content = IdlContent()
    for idl_tuple in args.get('idl_tuples', []):
        idl_parts = idl_tuple.rsplit(':', 1)
        assert len(idl_parts) == 2

        idl_rel_path = pathlib.Path(idl_parts[1])
        idl_stems = modules.setdefault(str(idl_rel_path.parent), set())
        idl_stems.add(idl_rel_path.stem)

        locator = IdlLocator(*idl_parts)
        idl_file = parse_idl_file(locator)
        idl_content.elements += idl_file.content.elements

    # NOTE(sam): remove when a language specific name mangling is implemented

    def print_warning_if_reserved_keyword(member_name, interface_type,
                                          interface_name):
        if (keyword.iskeyword(member.name)):
            print("Member name '{}' in the {} '{}' is a "
                  'reserved keyword in Python and is not supported '
                  'at the moment. Please use a different name.'.format(
                      member_name, interface_type, interface_name),
                  file=sys.stderr)

    for message in idl_content.get_elements_of_type(Message):
        for member in message.structure.members:
            print_warning_if_reserved_keyword(
                member.name, 'message', message.structure.namespaced_type.name)

    for service in idl_content.get_elements_of_type(Service):
        for member in service.request_message.structure.members:
            print_warning_if_reserved_keyword(member.name, 'service request',
                                              service.namespaced_type.name)
        for member in service.response_message.structure.members:
            print_warning_if_reserved_keyword(member.name, 'service response',
                                              service.namespaced_type.name)

    for action in idl_content.get_elements_of_type(Action):
        for member in action.goal.structure.members:
            print_warning_if_reserved_keyword(member.name, 'action goal',
                                              action.namespaced_type.name)
        for member in action.feedback.structure.members:
            print_warning_if_reserved_keyword(member.name, 'action feedback',
                                              action.namespaced_type.name)
        for member in action.result.structure.members:
            print_warning_if_reserved_keyword(member.name, 'action result',
                                              action.namespaced_type.name)

    for subfolder in modules.keys():
        with open(os.path.join(args['output_dir'], subfolder, '__init__.py'),
                  'w') as f:
            for idl_stem in sorted(modules[subfolder]):
                module_name = '_' + \
                    convert_camel_case_to_lower_case_underscore(idl_stem)
                f.write(
                    f'from {package_name}.{subfolder}.{module_name} import '
                    f'{idl_stem}  # noqa: F401\n')

    # expand templates per available typesupport implementation
    template_dir = args['template_dir']
    type_support_impl_by_filename = {
        '_%s_s.ep.{0}.c'.format(impl): impl
        for impl in typesupport_impls
    }
    mapping_msg_pkg_extension = {
        os.path.join(template_dir, '_idl_pkg_typesupport_entry_point.c.em'):
        type_support_impl_by_filename.keys(),
    }

    for template_file in mapping_msg_pkg_extension.keys():
        assert os.path.exists(
            template_file), 'Could not find template: ' + template_file

    latest_target_timestamp = get_newest_modification_time(
        args['target_dependencies'])

    for template_file, generated_filenames in mapping_msg_pkg_extension.items(
    ):
        for generated_filename in generated_filenames:
            package_name = args['package_name']
            data = {
                'package_name':
                args['package_name'],
                'content':
                idl_content,
                'typesupport_impl':
                type_support_impl_by_filename.get(generated_filename, ''),
            }
            generated_file = os.path.join(args['output_dir'],
                                          generated_filename % package_name)
            expand_template(template_file,
                            data,
                            generated_file,
                            minimum_timestamp=latest_target_timestamp)

    return 0
Beispiel #8
0
def message_idl_file():
    return parse_idl_file(MESSAGE_IDL_LOCATOR)
Beispiel #9
0
def action_idl_file():
    return parse_idl_file(ACTION_IDL_LOCATOR)
Beispiel #10
0
def service_idl_file():
    return parse_idl_file(SERVICE_IDL_LOCATOR)
Beispiel #11
0
def generate_rs(generator_arguments_file, typesupport_impls):
    args = read_generator_arguments(generator_arguments_file)
    package_name = args['package_name']

    # expand init modules for each directory
    modules = {}
    idl_content = IdlContent()
    dependency_packages = set()

    (Path(args['output_dir']) / 'rust/src').mkdir(parents=True, exist_ok=True)

    for dep_tuple in args.get('ros_interface_dependencies', []):
        dep_parts = dep_tuple.rsplit(':', 1)
        assert len(dep_parts) == 2
        if dep_parts[0] != package_name:
            dependency_packages.add(dep_parts[0])

    for idl_tuple in args.get('idl_tuples', []):
        idl_parts = idl_tuple.rsplit(':', 1)
        assert len(idl_parts) == 2

        idl_rel_path = pathlib.Path(idl_parts[1])
        idl_stems = modules.setdefault(str(idl_rel_path.parent), set())
        idl_stems.add(idl_rel_path.stem)

        locator = IdlLocator(*idl_parts)
        idl_file = parse_idl_file(locator)
        idl_content.elements += idl_file.content.elements

    typesupport_impls = typesupport_impls.split(';')

    template_dir = args['template_dir']

    mapping_msgs = {
        os.path.join(template_dir, 'msg.rs.em'): ['rust/src/%s.rs'],
    }

    mapping_srvs = {
        os.path.join(template_dir, 'srv.rs.em'): ['rust/src/%s.rs'],
    }

    # Ensure the required templates exist
    for template_file in mapping_msgs.keys():
        assert os.path.exists(template_file), \
            'Messages template file %s not found' % template_file
    for template_file in mapping_srvs.keys():
        assert os.path.exists(template_file), \
            'Services template file %s not found' % template_file

    data = {
        'get_rmw_rs_type': make_get_rmw_rs_type(args['package_name']),
        'get_rs_name': get_rs_name,
        'get_idiomatic_rs_type':
        make_get_idiomatic_rs_type(args['package_name']),
        'constant_value_to_rs': constant_value_to_rs,
        'value_to_rs': value_to_rs,
        'convert_camel_case_to_lower_case_underscore':
        convert_camel_case_to_lower_case_underscore,
        'convert_lower_case_underscore_to_camel_case':
        convert_lower_case_underscore_to_camel_case,
        'msg_specs': [],
        'srv_specs': [],
        'package_name': args['package_name'],
        'typesupport_impls': typesupport_impls,
    }

    latest_target_timestamp = get_newest_modification_time(
        args['target_dependencies'])

    for message in idl_content.get_elements_of_type(Message):
        data['msg_specs'].append(('msg', message))

    for service in idl_content.get_elements_of_type(Service):
        data['srv_specs'].append(('srv', service))

    if data['msg_specs']:
        for template_file, generated_filenames in mapping_msgs.items():
            for generated_filename in generated_filenames:
                generated_file = os.path.join(args['output_dir'],
                                              generated_filename % 'msg')
                expand_template(os.path.join(template_dir, template_file),
                                data.copy(),
                                generated_file,
                                minimum_timestamp=latest_target_timestamp)

    if data['srv_specs']:
        for template_file, generated_filenames in mapping_srvs.items():
            for generated_filename in generated_filenames:
                generated_file = os.path.join(args['output_dir'],
                                              generated_filename % 'srv')
                expand_template(os.path.join(template_dir, template_file),
                                data.copy(),
                                generated_file,
                                minimum_timestamp=latest_target_timestamp)

    expand_template(os.path.join(template_dir, 'lib.rs.em'),
                    data.copy(),
                    os.path.join(args['output_dir'], 'rust/src/lib.rs'),
                    minimum_timestamp=latest_target_timestamp)

    cargo_toml_data = {
        'dependency_packages': dependency_packages,
        'package_name': args['package_name'],
        'package_version': args['package_version'],
    }
    expand_template(os.path.join(template_dir, 'Cargo.toml.em'),
                    cargo_toml_data,
                    os.path.join(args['output_dir'], 'rust/Cargo.toml'),
                    minimum_timestamp=latest_target_timestamp)

    expand_template(os.path.join(template_dir, 'build.rs.em'), {},
                    os.path.join(args['output_dir'], 'rust/build.rs'),
                    minimum_timestamp=latest_target_timestamp)

    return 0
Beispiel #12
0
def generate_py(generator_arguments_file, typesupport_impls):
    mapping = {
        '_idl.py.em': '_%s.py',
        '_idl_support.c.em': '_%s_s.c',
    }
    generate_files(generator_arguments_file, mapping)

    args = read_generator_arguments(generator_arguments_file)
    package_name = args['package_name']

    # expand init modules for each directory
    modules = {}
    idl_content = IdlContent()
    for idl_tuple in args.get('idl_tuples', []):
        idl_parts = idl_tuple.rsplit(':', 1)
        assert len(idl_parts) == 2

        idl_rel_path = pathlib.Path(idl_parts[1])
        idl_stems = modules.setdefault(str(idl_rel_path.parent), set())
        idl_stems.add(idl_rel_path.stem)

        locator = IdlLocator(*idl_parts)
        idl_file = parse_idl_file(locator)
        idl_content.elements += idl_file.content.elements

    for subfolder in modules.keys():
        with open(os.path.join(args['output_dir'], subfolder, '__init__.py'),
                  'w') as f:
            for idl_stem in sorted(modules[subfolder]):
                module_name = '_' + \
                    convert_camel_case_to_lower_case_underscore(idl_stem)
                f.write('from {package_name}.{subfolder}.{module_name} import '
                        '{idl_stem}  # noqa: F401\n'.format_map(locals()))

    # expand templates per available typesupport implementation
    template_dir = args['template_dir']
    type_support_impl_by_filename = {
        '_%s_s.ep.{0}.c'.format(impl): impl
        for impl in typesupport_impls
    }
    mapping_msg_pkg_extension = {
        os.path.join(template_dir, '_idl_pkg_typesupport_entry_point.c.em'):
        type_support_impl_by_filename.keys(),
    }

    for template_file in mapping_msg_pkg_extension.keys():
        assert os.path.exists(
            template_file), 'Could not find template: ' + template_file

    latest_target_timestamp = get_newest_modification_time(
        args['target_dependencies'])

    for template_file, generated_filenames in mapping_msg_pkg_extension.items(
    ):
        for generated_filename in generated_filenames:
            package_name = args['package_name']
            data = {
                'package_name':
                args['package_name'],
                'content':
                idl_content,
                'typesupport_impl':
                type_support_impl_by_filename.get(generated_filename, ''),
            }
            generated_file = os.path.join(args['output_dir'],
                                          generated_filename % package_name)
            expand_template(template_file,
                            data,
                            generated_file,
                            minimum_timestamp=latest_target_timestamp)

    return 0