Skip to content

[23128] Support builtin annotations in IDL Parser #5908

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

Open
wants to merge 27 commits into
base: master
Choose a base branch
from

Conversation

Carlosespicur
Copy link
Contributor

@Carlosespicur Carlosespicur commented Jun 30, 2025

Description

This PR add support for builtin annotations in IDL Parser:

  • Adds Annotation class, which provides an interface to simplify the annotations parsing.
  • Adds a method AnnotationsList::from_builtin(), that defines each supported builtin annotation
  • Fixes Cleanup guards for error handling
  • Adds a IDLParserUtils file, for generic std::string transformations
  • Add a IDLParserTags file to avoid hardcoding annotations values and names

@Mergifyio backport 3.3.x

Contributor Checklist

  • Commit messages follow the project guidelines.
  • The code follows the style guidelines of this project.
  • Tests that thoroughly check the new feature have been added/Regression tests checking the bug and its fix have been added; the added tests pass locally
  • Any new/modified methods have been properly documented using Doxygen.
  • N/A Any new configuration API has an equivalent XML API (with the corresponding XSD extension)
  • N/A Changes are backport compatible: they do NOT break ABI nor change library core behavior.
  • Changes are API compatible.
  • New feature has been added to the versions.md file (if applicable).
  • New feature has been documented/Current behavior is correctly described in the documentation.
    Related documentation PR:
  • N/A Applicable backports have been included in the description.

Reviewer Checklist

  • The PR has a milestone assigned.
  • The title and description correctly express the PR's purpose.
  • Check contributor checklist is correct.
  • If this is a critical bug fix, backports to the critical-only supported branches have been requested.
  • Check CI results: changes do not issue any warning.
  • Check CI results: failing tests are unrelated with the changes.

@Carlosespicur Carlosespicur added this to the v3.3.0 milestone Jun 30, 2025
@Carlosespicur Carlosespicur force-pushed the feature/idl-parser-builtin-annotations branch 7 times, most recently from 71ea547 to 7c8a32c Compare July 4, 2025 07:10
@Carlosespicur Carlosespicur marked this pull request as ready for review July 4, 2025 07:39
Comment on lines 115 to 118
using TypeDescriptorAnnotationHandler = std::function<bool (TypeDescriptor::_ref_type& /* descriptor */,
const std::map<std::string, std::string>&) /* annotation's member values */>;
using MemberDescriptorAnnotationHandler = std::function<bool (MemberDescriptor::_ref_type& /* descriptor */,
const std::map<std::string, std::string>& /* annotation's member values */)>;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please refactor these into two virtual methods, and create a class for each built-in annotation:

Suggested change
using TypeDescriptorAnnotationHandler = std::function<bool (TypeDescriptor::_ref_type& /* descriptor */,
const std::map<std::string, std::string>&) /* annotation's member values */>;
using MemberDescriptorAnnotationHandler = std::function<bool (MemberDescriptor::_ref_type& /* descriptor */,
const std::map<std::string, std::string>& /* annotation's member values */)>;
virtual bool apply_to_type(
TypeDescriptor::_ref_type& /* descriptor */,
const std::map<std::string, std::string>& /* annotation_member_values */)
{
return true;
}
virtual bool apply_to_member(
MemberDescriptor::_ref_type& /* descriptor */,
const std::map<std::string, std::string>& /* annotation_member_values */)
{
return true;
}

/**
* @brief Check if the annotation is a builtin annotation
*/
bool is_builtin() const
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can also be converted into a virtual method, that returns false by default.
We can then have a BuiltinAnnotation class that just overloads this method, and then make the builtin annotations inherit from that one to customize the apply_to_xxx methods.

@Carlosespicur Carlosespicur force-pushed the feature/idl-parser-builtin-annotations branch 3 times, most recently from c99f9a2 to 7effe6a Compare July 14, 2025 06:17
Signed-off-by: Carlosespicur <carlosespicur@proton.me>
…ions

Signed-off-by: Carlosespicur <carlosespicur@proton.me>
Signed-off-by: Carlosespicur <carlosespicur@proton.me>
Signed-off-by: Carlosespicur <carlosespicur@proton.me>
Signed-off-by: Carlosespicur <carlosespicur@proton.me>
Signed-off-by: Carlosespicur <carlosespicur@proton.me>
Signed-off-by: Carlosespicur <carlosespicur@proton.me>
Signed-off-by: Carlosespicur <carlosespicur@proton.me>
Signed-off-by: Carlosespicur <carlosespicur@proton.me>
Signed-off-by: Carlosespicur <carlosespicur@proton.me>
…p as AnnotationsList's container

Signed-off-by: Carlosespicur <carlosespicur@proton.me>
Signed-off-by: Carlosespicur <carlosespicur@proton.me>
Signed-off-by: Carlosespicur <carlosespicur@proton.me>
Signed-off-by: Carlosespicur <carlosespicur@proton.me>
Signed-off-by: Carlosespicur <carlosespicur@proton.me>
@Carlosespicur Carlosespicur force-pushed the feature/idl-parser-builtin-annotations branch from 94991d9 to b787c9f Compare July 14, 2025 06:19
@github-actions github-actions bot added the ci-pending PR which CI is running label Jul 14, 2025
Signed-off-by: Carlosespicur <carlosespicur@proton.me>
@Carlosespicur Carlosespicur requested review from MiguelCompany and removed request for MiguelCompany July 14, 2025 09:51
Signed-off-by: Carlosespicur <carlosespicur@proton.me>
@Carlosespicur Carlosespicur requested review from MiguelCompany and removed request for MiguelCompany July 15, 2025 07:11
Signed-off-by: Carlosespicur <carlosespicur@proton.me>
@Carlosespicur Carlosespicur requested review from MiguelCompany and removed request for MiguelCompany July 15, 2025 08:00
} // namespace dds
} // namespace fastdds
} // namespace eprosima
/* Built-in annotations related tags */
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/* Built-in annotations related tags */

Comment on lines +33 to +39
struct id_ann_duplicated_ids
{
@id(0) long first;
@id(0) string second;
@id(1) float third;
};

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
struct id_ann_duplicated_ids
{
@id(0) long first;
@id(0) string second;
@id(1) float third;
};
struct id_ann_duplicated_ids
{
@id(0) long first;
@id(0) string second;
@id(1) float third;
};
struct id_ann_implicit_duplicated_ids
{
@id(3) long first;
string second;
@id(4) float third;
};

Comment on lines +51 to +52

@id(1) union id_ann_on_union switch(long)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
@id(1) union id_ann_on_union switch(long)
union id_ann_on_union_discriminator switch(@id(1) long)
{
case 0:
long first;
default:
string second;
};
@id(1) union id_ann_on_union switch(long)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As we discussed, for now modifying discriminator's descriptor properties using annotations will be kept as unsupported. I will update the documentation with this case.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be nice if we can also make the parser fail with an error log when applying annotations to a discriminator.

@key(value = FALSE) string second;
@key(FALSE) float third;
};

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
union key_ann_valid_union switch(@key long)
{
case 0:
long first;
default:
string second;
};

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here

@optional(value = FALSE) string second;
@optional(FALSE) float third;
};

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
union optional_ann_invalid_union switch(long)
{
case 0:
@optional long first;
default:
string second;
};

@@ -0,0 +1,20 @@
struct value_ann_valid_struct
{
@value("foo") string first;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Annotation @value is only valid for enumeration members.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This case is difficult to treat, due to both @default and @value annotations can be used to configure MemberDescriptor::default_value property, and IDL/XTypes specifications impose restrictions over the parent kind of a @value annotated member, but not in the @default case, i.e:

struct valid_struct
{
    @default(1) long valid_member;
};

should be valid, but:

struct invalid_struct
{
    @value(1) long invalid_member;
};

not. Both cases should be handled when adding the member to the constructed type (before adding it, we don't know the member's parent kind), but I think there is not a way to address the problem calling MemberDescriptor::is_consistent() method. There are two possibilities:

  1. Modify is_consistent() logic to allow configuring MemberDescriptor::default_value() if and only if MemberDescriptorImpl::parent_kind_ == TK_ENUM, making both described cases to fail, but restricting @value to enumerations.
  2. Keep is_consistent() logic, which makes both described cases to be parsed as the same.

Is there a better approach for this? @MiguelCompany @richiware

@value(8) struct value_ann_on_struct
{
long first;
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing files for:

  • non_serialized
  • hashid
  • default_literal

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New is_default_literal member added in MemberDescriptor/DynamicTypeBuilder/DynamicType related classes and DefaultLiteralAnnotation updated to modify it.

TODO: non_serialized, hashid, autoid implementations in DynTypes API

@@ -160,7 +261,7 @@ class Context
std::map<std::string, std::string>& state,
const std::string& type);

std::vector<std::string> split_string(
static std::vector<std::string> split_string(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shall we move this to IdlParserUtils.hpp?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I think it's unrelated to the context

@@ -174,19 +275,38 @@ class Context
return tokens;
}

static std::string join_strings(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shall we move this to IdlParserUtils.hpp?

#include "../TypeValueConverter.hpp"
#include "IdlParserTags.hpp"
#include "IdlParserUtils.hpp"

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Improve readability and maintainability by having each declared type in a separate file.
Then include all files here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will wait for this refactor to take place before reviewing this

Signed-off-by: Carlosespicur <carlosespicur@proton.me>
@Carlosespicur Carlosespicur modified the milestones: v3.3.1, v3.4.0 Jul 18, 2025
Signed-off-by: Carlosespicur <carlosespicur@proton.me>
Signed-off-by: Carlosespicur <carlosespicur@proton.me>
Signed-off-by: Carlosespicur <carlosespicur@proton.me>
…otated without parameters

Signed-off-by: Carlosespicur <carlosespicur@proton.me>
…nd tests

Signed-off-by: Carlosespicur <carlosespicur@proton.me>
…eral type in type descriptor

Signed-off-by: Carlosespicur <carlosespicur@proton.me>
@Carlosespicur Carlosespicur force-pushed the feature/idl-parser-builtin-annotations branch from e6f0c92 to 00e9f3d Compare July 22, 2025 09:35
…e member in MemberDescriptor

Signed-off-by: Carlosespicur <carlosespicur@proton.me>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ci-pending PR which CI is running
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants