Skip to content

[22893] Add modules support to idl_serialize #5691

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 20 commits into from
Mar 21, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
165 changes: 135 additions & 30 deletions src/cpp/fastdds/xtypes/serializers/idl/dynamic_type_idl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,10 @@ namespace dds {

using namespace eprosima::utilities::collections;

constexpr auto TYPE_OPENING = "\n{\n";
constexpr auto TYPE_OPENING = "{\n";
constexpr auto TYPE_CLOSURE = "};\n";
constexpr auto TAB_SEPARATOR = " ";
constexpr auto MODULE_SEPARATOR = "::";

//////////////////////////
// DYNAMIC TYPE TO TREE //
Expand Down Expand Up @@ -667,6 +668,10 @@ ReturnCode_t alias_to_idl(
return ret;
}

// Open modules definition (if any) and get type name
std::string type_name = node.info.type_kind_name;
unsigned int n_modules = open_modules_definition(type_name, idl);

idl << "typedef ";

// Find the base type of the alias
Expand All @@ -678,7 +683,10 @@ ReturnCode_t alias_to_idl(
return ret;
}

idl << " " << node.info.type_kind_name << ";\n";
idl << " " << type_name << ";\n";

// Close modules definition (if any)
close_modules_definition(n_modules, idl);

return ret;
}
Expand Down Expand Up @@ -706,6 +714,10 @@ ReturnCode_t bitmask_to_idl(
return RETCODE_BAD_PARAMETER;
}

// Open modules definition (if any) and get type name
std::string type_name = node.info.type_kind_name;
unsigned int n_modules = open_modules_definition(type_name, idl);

// Annotation with the bitmask size
static constexpr std::uint32_t DEFAULT_BITMASK_SIZE = 32;
const auto bitmask_size = bounds[0];
Expand All @@ -715,7 +727,9 @@ ReturnCode_t bitmask_to_idl(
idl << "@bit_bound(" << std::to_string(bitmask_size) << ")\n";
}

idl << "bitmask " << node.info.type_kind_name << TYPE_OPENING;
idl << tabulate_n(n_modules) << "bitmask " << type_name << "\n";

idl << tabulate_n(n_modules) << TYPE_OPENING;

const auto member_count = node.info.dynamic_type->get_member_count();

Expand All @@ -732,7 +746,7 @@ ReturnCode_t bitmask_to_idl(
return ret;
}

idl << TAB_SEPARATOR;
idl << TAB_SEPARATOR << tabulate_n(n_modules);

// Annotation with the position
const auto id = member->get_id();
Expand All @@ -756,8 +770,11 @@ ReturnCode_t bitmask_to_idl(
pos = id + 1;
}

// Close definition
idl << TYPE_CLOSURE;
// Close type definition
idl << tabulate_n(n_modules) << TYPE_CLOSURE;

// Close modules definition (if any)
close_modules_definition(n_modules, idl);

return ret;
}
Expand All @@ -770,7 +787,13 @@ ReturnCode_t bitset_to_idl(

ReturnCode_t ret = RETCODE_OK;

idl << "bitset " << node.info.type_kind_name << TYPE_OPENING;
// Open modules definition (if any) and get type name
std::string type_name = node.info.type_kind_name;
unsigned int n_modules = open_modules_definition(type_name, idl);

idl << "bitset " << type_name << "\n";

idl << tabulate_n(n_modules) << TYPE_OPENING;

// Find the bits that each bitfield occupies
BoundSeq bounds;
Expand Down Expand Up @@ -814,10 +837,10 @@ ReturnCode_t bitset_to_idl(
const auto gap = id - bits_set;
bits_set += gap;

idl << TAB_SEPARATOR << "bitfield<" << std::to_string(gap) << ">;\n";
idl << tabulate_n(n_modules) << TAB_SEPARATOR << "bitfield<" << std::to_string(gap) << ">;\n";
}

idl << TAB_SEPARATOR << "bitfield<" << std::to_string(bounds[index]);
idl << tabulate_n(n_modules) << TAB_SEPARATOR << "bitfield<" << std::to_string(bounds[index]);

MemberDescriptor::_ref_type member_descriptor {traits<MemberDescriptor>::make_shared()};
ret = member->get_descriptor(member_descriptor);
Expand Down Expand Up @@ -852,8 +875,11 @@ ReturnCode_t bitset_to_idl(
bits_set += bounds[index];
}

// Close definition
idl << TYPE_CLOSURE;
// Close type definition
idl << tabulate_n(n_modules) << TYPE_CLOSURE;

// Close modules definition (if any)
close_modules_definition(n_modules, idl);

return ret;
}
Expand All @@ -866,7 +892,13 @@ ReturnCode_t enum_to_idl(

ReturnCode_t ret = RETCODE_OK;

idl << "enum " << node.info.type_kind_name << TYPE_OPENING << TAB_SEPARATOR;
// Open modules definition (if any) and get type name
std::string type_name = node.info.type_kind_name;
unsigned int n_modules = open_modules_definition(type_name, idl);

idl << "enum " << type_name << "\n";

idl << tabulate_n(n_modules) << TYPE_OPENING << TAB_SEPARATOR;

for (std::uint32_t index = 0; index < node.info.dynamic_type->get_member_count(); index++)
{
Expand All @@ -879,16 +911,23 @@ ReturnCode_t enum_to_idl(
return ret;
}

if (0 != index)
idl << tabulate_n(n_modules) << member->get_name().to_string();

if (node.info.dynamic_type->get_member_count() - 1 != index)
{
idl << ",\n" << TAB_SEPARATOR;
}

idl << member->get_name().to_string();
else
{
idl << "\n";
}
}

// Close definition
idl << "\n" << TYPE_CLOSURE;
// Close type definition
idl << tabulate_n(n_modules) << TYPE_CLOSURE;

// Close modules definition (if any)
close_modules_definition(n_modules, idl);

return ret;
}
Expand All @@ -911,6 +950,10 @@ ReturnCode_t struct_to_idl(
return ret;
}

// Open modules definition (if any) and get type name
std::string type_name = node.info.type_kind_name;
unsigned int n_modules = open_modules_definition(type_name, idl);

switch (type_descriptor->extensibility_kind())
{
case ExtensibilityKind::FINAL:
Expand All @@ -925,7 +968,7 @@ ReturnCode_t struct_to_idl(
}
case ExtensibilityKind::APPENDABLE:
{
// Appendable is the default extensibility kind
idl << "@extensibility(APPENDABLE)\n";
break;
}
default:
Expand All @@ -935,8 +978,8 @@ ReturnCode_t struct_to_idl(
}
}

// Add types name
idl << "struct " << node.info.type_kind_name;
// Add type name
idl << tabulate_n(n_modules) << "struct " << type_name;

const auto base_type = type_descriptor->base_type();

Expand All @@ -955,11 +998,13 @@ ReturnCode_t struct_to_idl(
}
}

idl << TYPE_OPENING;
idl << "\n" << tabulate_n(n_modules) << TYPE_OPENING;

// Add struct attributes
for (auto const& child : node.branches())
{
idl << tabulate_n(n_modules);

if (child.info.is_base)
{
continue;
Expand All @@ -970,8 +1015,11 @@ ReturnCode_t struct_to_idl(
idl << ";\n";
}

// Close definition
idl << TYPE_CLOSURE;
// Close type definition
idl << tabulate_n(n_modules) << TYPE_CLOSURE;

// Close modules definition (if any)
close_modules_definition(n_modules, idl);

return ret;
}
Expand All @@ -993,7 +1041,11 @@ ReturnCode_t union_to_idl(
return ret;
}

idl << "union " << node.info.type_kind_name << " switch (";
// Open modules definition (if any) and get type name
std::string type_name = node.info.type_kind_name;
unsigned int n_modules = open_modules_definition(type_name, idl);

idl << "union " << type_name << " switch (";

ret = type_kind_to_idl(type_descriptor->discriminator_type(), idl);

Expand All @@ -1002,7 +1054,7 @@ ReturnCode_t union_to_idl(
return ret;
}

idl << ")" << TYPE_OPENING;
idl << ")\n" << tabulate_n(n_modules) << TYPE_OPENING;

for (std::uint32_t index = 1; index < node.info.dynamic_type->get_member_count(); index++)
{
Expand All @@ -1022,15 +1074,15 @@ ReturnCode_t union_to_idl(

for (const auto& label : labels)
{
idl << TAB_SEPARATOR << "case " << std::to_string(label) << ":\n";
idl << tabulate_n(n_modules) << TAB_SEPARATOR << "case " << std::to_string(label) << ":\n";
}

if (member_descriptor->is_default_label())
{
idl << TAB_SEPARATOR << "default:\n";
idl << tabulate_n(n_modules) << TAB_SEPARATOR << "default:\n";
}

idl << TAB_SEPARATOR << TAB_SEPARATOR;
idl << TAB_SEPARATOR << TAB_SEPARATOR << tabulate_n(n_modules);

ret = type_kind_to_idl(member_descriptor->type(), idl);

Expand All @@ -1042,8 +1094,11 @@ ReturnCode_t union_to_idl(
idl << " " << member->get_name().to_string() << ";\n";
}

// Close definition
idl << TYPE_CLOSURE;
// Close type definition
idl << tabulate_n(n_modules) << TYPE_CLOSURE;

// Close modules definition (if any)
close_modules_definition(n_modules, idl);

return ret;
}
Expand Down Expand Up @@ -1082,6 +1137,56 @@ ReturnCode_t node_to_idl(
return RETCODE_OK;
}

unsigned int open_modules_definition(
std::string& type_name,
std::ostream& idl) noexcept
{
unsigned int n_modules = 0;

while (type_name.find(MODULE_SEPARATOR) != std::string::npos)
{
size_t pos_start = 0;
size_t pos_end = type_name.find(MODULE_SEPARATOR);

std::string module_name = type_name.substr(0, pos_end);
type_name.erase(pos_start, pos_end - pos_start + std::strlen(MODULE_SEPARATOR));

idl << tabulate_n(n_modules) << "module " << module_name << "\n";

idl << tabulate_n(n_modules) << TYPE_OPENING;

n_modules++;
}

idl << tabulate_n(n_modules);

return n_modules;
}

void close_modules_definition(
unsigned int& n_modules,
std::ostream& idl) noexcept
{
while (n_modules > 0)
{
idl << tabulate_n(--n_modules) << TYPE_CLOSURE;
}
}

std::string tabulate_n(
const unsigned int& n_tabs) noexcept
{
std::string tabs;

tabs.reserve(std::strlen(TAB_SEPARATOR) * n_tabs);
for (unsigned int i = 0; i < n_tabs; i++)
{
tabs += TAB_SEPARATOR;
}

return tabs;
}

///////////////////////
// AUXILIARY METHODS //
///////////////////////
Expand Down
32 changes: 32 additions & 0 deletions src/cpp/fastdds/xtypes/serializers/idl/dynamic_type_idl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,38 @@ ReturnCode_t node_to_idl(
const utilities::collections::TreeNode<TreeNodeType>& node,
std::ostream& idl) noexcept;

/**
* @brief Resolves and inserts the opening modules definition of a type (if any), and removes them from \c type_name .
*
* @param type_name The full name of the type, including modules (if defined).
* @param idl The idl representation of the tree.
*
* @return The number of modules resolved.
*/
unsigned int open_modules_definition(
std::string& type_name,
std::ostream& idl) noexcept;

/**
* @brief Closes the modules definition for the processed type.
*
* @param n_modules The number of modules that need to be closed.
* @param idl The idl representation of the tree.
*/
void close_modules_definition(
unsigned int& n_modules,
std::ostream& idl) noexcept;

/**
* @brief Returns a string with \c n_tabs concatenated tabs.
*
* @param n_tabs The number of tabs to return.
*
* @return A string with \c n_tabs concatenated tabs.
*/
std::string tabulate_n(
const unsigned int& n_tabs) noexcept;

///////////////////////
// AUXILIARY METHODS //
///////////////////////
Expand Down
4 changes: 2 additions & 2 deletions test/unittest/dds/xtypes/serializers/idl/DynTypeIDLTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ class DynTypeIDLTests : public ::testing::TestWithParam<std::string>
{
// Find TypeObjects for the type
xtypes::TypeObjectPair type_objs;
ASSERT_EQ(DomainParticipantFactory::get_instance()->type_object_registry().get_type_objects(
type_name, type_objs),
ASSERT_EQ(DomainParticipantFactory::get_instance()->type_object_registry().get_type_objects(type_name,
type_objs),
fastdds::dds::RETCODE_OK);

// Create DynamicType from TypeObject
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ typedef boolean MyBoolean;

typedef MyBoolean MyRecursiveBoolean;

@extensibility(APPENDABLE)
struct AliasStruct
{
MyLong my_long;
Expand Down
Loading
Loading