From 03fbf21d24ba42a70e558cb3ab2caa77fccf9fbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ricardo=20Gonz=C3=A1lez?= Date: Mon, 8 Jul 2024 08:21:17 +0200 Subject: [PATCH] Annotations for union's discriminators (#148) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Refs #21222. Add default annotation to union's discriminator Signed-off-by: Ricardo González Moreno * Refs #21222. Get default integer discriminator value from max Signed-off-by: Ricardo González Moreno * Refs #21222. Documentation Signed-off-by: Ricardo González Moreno * Refs #21222. Apply suggestions Signed-off-by: Ricardo González Moreno * Refs #21222. Apply suggestion Signed-off-by: Ricardo González Moreno --------- Signed-off-by: Ricardo González Moreno --- .../com/eprosima/idl/parser/grammar/IDL.g4 | 9 +- .../idl/generator/manager/TemplateUtil.java | 53 +++++++++-- .../idl/parser/typecode/UnionTypeCode.java | 88 ++++++++++++++++++- 3 files changed, 139 insertions(+), 11 deletions(-) diff --git a/src/main/antlr/com/eprosima/idl/parser/grammar/IDL.g4 b/src/main/antlr/com/eprosima/idl/parser/grammar/IDL.g4 index 423326f0..f5fda1b0 100644 --- a/src/main/antlr/com/eprosima/idl/parser/grammar/IDL.g4 +++ b/src/main/antlr/com/eprosima/idl/parser/grammar/IDL.g4 @@ -1694,6 +1694,7 @@ union_type [Vector annotations, ArrayList defs] returns UnionTypeCode unionTP = null; TemplateGroup unionTemplates = null; Boolean fw_decl = false; + ArrayList discriminator_annotations = new ArrayList(); } : KW_UNION identifier @@ -1732,7 +1733,7 @@ union_type [Vector annotations, ArrayList defs] returns } } } - KW_SWITCH LEFT_BRACKET switch_type_spec { dist_type=$switch_type_spec.typecode; } RIGHT_BRACKET + KW_SWITCH LEFT_BRACKET (annotation_appl { discriminator_annotations.add($annotation_appl.annotation); })? switch_type_spec { dist_type=$switch_type_spec.typecode; } RIGHT_BRACKET { // TODO Check supported types for discriminator: long, enumeration, etc... if (fw_decl) @@ -1753,6 +1754,12 @@ union_type [Vector annotations, ArrayList defs] returns } unionTP.setDefined(); + // Set discriminator annotations. + for(Annotation annotation : discriminator_annotations) + { + unionTP.getDiscriminator().addAnnotation(ctx, annotation); + } + // Apply annotations to the TypeCode if (null != annotations) { diff --git a/src/main/java/com/eprosima/idl/generator/manager/TemplateUtil.java b/src/main/java/com/eprosima/idl/generator/manager/TemplateUtil.java index 7cdb34f6..7948efad 100644 --- a/src/main/java/com/eprosima/idl/generator/manager/TemplateUtil.java +++ b/src/main/java/com/eprosima/idl/generator/manager/TemplateUtil.java @@ -68,13 +68,41 @@ public static void find_and_set_default_discriminator_value(ArrayList list = new ArrayList(members); do { - ++dvalue; found = false; for(Member member : list) @@ -109,7 +137,7 @@ public static void find_and_set_default_discriminator_value(ArrayList= minimum_valid_value); + + if (found) + { + // All values were used. Using value 0 as default implicit value. + default_discriminator_value = 0; + } - union_type.setDefaultvalue(Long.toString(dvalue)); - union_type.setJavaDefaultvalue(Long.toString(dvalue)); + union_type.setDefaultvalue(Long.toString(default_discriminator_value)); + union_type.setJavaDefaultvalue(Long.toString(default_discriminator_value)); } else if(disc_type.getKind() == Kind.KIND_BOOLEAN) { diff --git a/src/main/java/com/eprosima/idl/parser/typecode/UnionTypeCode.java b/src/main/java/com/eprosima/idl/parser/typecode/UnionTypeCode.java index a41c7fc2..9f7bb82a 100644 --- a/src/main/java/com/eprosima/idl/parser/typecode/UnionTypeCode.java +++ b/src/main/java/com/eprosima/idl/parser/typecode/UnionTypeCode.java @@ -101,10 +101,12 @@ public int addMember( List labels = null; List javalabels = null; - if (Kind.KIND_ENUM == discriminator_.getTypecode().getKind() || - Kind.KIND_BITMASK == discriminator_.getTypecode().getKind()) + TypeCode discriminator_typecode = discriminator_.getTypecode(); + + if (Kind.KIND_ENUM == discriminator_typecode.getKind() || + Kind.KIND_BITMASK == discriminator_typecode.getKind()) { - MemberedTypeCode enum_type = (MemberedTypeCode)discriminator_.getTypecode(); + MemberedTypeCode enum_type = (MemberedTypeCode)discriminator_typecode; labels = new ArrayList(); javalabels = new ArrayList(); @@ -121,6 +123,37 @@ public int addMember( javalabels = internal_labels; } + // Checks the discriminator has the @default annotation. In that case check the union's member has a label with + // the @default annotation value and if they match store the union's member index. + try + { + if (discriminator_.isAnnotationDefault()) + { + String default_value = discriminator_.getAnnotationDefaultValue(); + + for (String label : labels) + { + if (label.equals(default_value)) + { + if (m_defaultannotated_index == -1) + { + m_defaultannotated_index = getMembers().size(); + } + else + { + // Default value matches with more than one member. + return -2; + } + } + } + } + } + catch(RuntimeGenerationException ex) + { + // Never enter here because we check previously using isAnnotationDefault(). + } + + member.setLabels(labels); member.setJavaLabels(javalabels); @@ -133,6 +166,26 @@ public int addMember( return 0; } + /*! + * @ingroup api_for_stg + * @brief This function returns the union's member which contains a label that matches with discriminator's + * @default annotation. If no one then return \b null. + * @return The union's member that passes the conditions or \b null value. + */ + public Member getDefaultAnnotatedMember() throws RuntimeGenerationException + { + if (m_defaultannotated_index != -1) + { + return getMembers().get(m_defaultannotated_index); + } + else if (discriminator_.isAnnotationDefault()) + { + throw new RuntimeGenerationException("UnionTypeCode::getDefaultAnnotatedMember(): Discriminator has a default value but that value was not found in label cases"); + } + + return null; + } + public Member getDefaultMember() { if (m_defaultindex != -1) @@ -217,6 +270,29 @@ public void setJavaDefaultvalue( m_javaDefaultValue = value; } + /*! + * @ingroup api_for_stg + * @brief This function returns the discriminator's @default annotation value as string. If annotation was not + * defined, returns \b null. + * @return The discriminator's @default annotation value or \b null if annotation was not defined + */ + public String getDefaultAnnotatedValue() + { + try + { + if (discriminator_.isAnnotationDefault()) + { + return discriminator_.getAnnotationDefaultValue(); + } + } + catch(RuntimeGenerationException ex) + { + // Never enter here because we check previously using isAnnotationDefault(). + } + + return null; + } + // Used in stringtemplates public String getDefaultvalue() { @@ -278,6 +354,12 @@ public void addAnnotation( private int m_defaultindex = -1; + /*! + * Stores the index of the union's member which contains a label that matches with the discriminator's @default + * annotation. + */ + private int m_defaultannotated_index = -1; + private String m_defaultValue = null; private String m_javaDefaultValue = null;