Search in sources :

Example 1 with Indicator_Type

use of org.eclipse.titan.designer.AST.TTCN3.attributes.ErroneousAttributeSpecification.Indicator_Type in project titan.EclipsePlug-ins by eclipse.

the class ErroneousAttributes method buildErroneousDescriptorTree.

private ErroneousDescriptor buildErroneousDescriptorTree(final CompilationTimeStamp timestamp, final List<FieldErr_Type> fldArray, final int level) {
    final ErroneousDescriptor erroneousDescr = new ErroneousDescriptor();
    Qualifier omitBeforeQualifier = null;
    Qualifier omitAfterQualifier = null;
    final Map<Integer, List<FieldErr_Type>> embeddedFieldArrayMap = new HashMap<Integer, List<FieldErr_Type>>();
    for (FieldErr_Type actualFieldErr : fldArray) {
        if (actualFieldErr.subrefsArray.size() <= level) {
            ErrorReporter.INTERNAL_ERROR();
            return erroneousDescr;
        }
        final int fieldIndex = actualFieldErr.subrefsArray.get(level);
        final IType fieldType = actualFieldErr.typeArray.get(level);
        if (omitBeforeQualifier != null && erroneousDescr.omitBefore != -1 && erroneousDescr.omitBefore > fieldIndex) {
            final String message = MessageFormat.format("Field `{0}'' cannot be referenced because all fields before field `{1}'' have been omitted", actualFieldErr.qualifier.getDisplayName(), omitBeforeQualifier.getDisplayName());
            actualFieldErr.qualifier.getLocation().reportSemanticError(message);
            continue;
        }
        if (omitAfterQualifier != null && erroneousDescr.omitAfter != -1 && erroneousDescr.omitAfter < fieldIndex) {
            final String message = MessageFormat.format("Field `{0}'' cannot be referenced because all fields after field `{1}'' have been omitted", actualFieldErr.qualifier.getDisplayName(), omitAfterQualifier.getDisplayName());
            actualFieldErr.qualifier.getLocation().reportSemanticError(message);
            continue;
        }
        final Indicator_Type actIndicator = actualFieldErr.errAttrSpec.getIndicator();
        final boolean isOmit = actualFieldErr.errAttrSpec.isOmit();
        if (actualFieldErr.subrefsArray.size() == level + 1) {
            // erroneous value
            if (actualFieldErr.typeArray.size() != level + 1) {
                ErrorReporter.INTERNAL_ERROR();
                return erroneousDescr;
            }
            if (fieldType.getTypetype() == Type_type.TYPE_ASN1_SET && isOmit && actIndicator != Indicator_Type.Value_Indicator) {
                final String message = MessageFormat.format("Cannot omit all fields {0} `{1}'' which is a field of an ASN.1 SET type. " + "The order of fields in ASN.1 SET types changes depending on tagging (see X.690 9.3). " + "Fields can be omitted individually, independently of the field order which depends on tagging", actIndicator.getDisplayName(), actualFieldErr.qualifier.getDisplayName());
                actualFieldErr.qualifier.getLocation().reportSemanticError(message);
                continue;
            }
            switch(fieldType.getTypetypeTtcn3()) {
                case TYPE_TTCN3_CHOICE:
                    if (actIndicator != Indicator_Type.Value_Indicator) {
                        final String message = MessageFormat.format("Indicator `{0}'' cannot be used with reference `{1}'' which points to a field of a union type", actIndicator.getDisplayName(), actualFieldErr.qualifier.getDisplayName());
                        actualFieldErr.qualifier.getLocation().reportSemanticError(message);
                        continue;
                    }
                    break;
                case TYPE_TTCN3_SEQUENCE:
                case TYPE_TTCN3_SET:
                    if (isOmit && actIndicator == Indicator_Type.After_Indicator) {
                        int lastFieldIndex;
                        switch(fieldType.getTypetype()) {
                            case TYPE_ASN1_SEQUENCE:
                                lastFieldIndex = ((ASN1_Sequence_Type) fieldType).getNofComponents(timestamp) - 1;
                                break;
                            case TYPE_ASN1_SET:
                                lastFieldIndex = ((ASN1_Set_Type) fieldType).getNofComponents(timestamp) - 1;
                                break;
                            default:
                                lastFieldIndex = ((TTCN3_Set_Seq_Choice_BaseType) fieldType).getNofComponents() - 1;
                        }
                        if (fieldIndex == lastFieldIndex) {
                            final String message = MessageFormat.format("There is nothing to omit after the last field ({0}) of a record/set type", actualFieldErr.qualifier.getDisplayName());
                            actualFieldErr.qualifier.getLocation().reportSemanticError(message);
                            continue;
                        }
                    }
                // $FALL-THROUGH$
                case TYPE_SEQUENCE_OF:
                case TYPE_SET_OF:
                    if (isOmit && actIndicator == Indicator_Type.Before_Indicator && fieldIndex == 0) {
                        actualFieldErr.qualifier.getLocation().reportSemanticError(MessageFormat.format("There is nothing to omit before the first field ({0})", actualFieldErr.qualifier.getDisplayName()));
                        continue;
                    }
                    break;
                default:
                    break;
            }
            // check for duplicate value+indicator
            if (erroneousDescr.valuesMap.containsKey(fieldIndex)) {
                final ErroneousValues evs = erroneousDescr.valuesMap.get(fieldIndex);
                if ((evs.before != null && actIndicator == Indicator_Type.Before_Indicator) || (evs.value != null && actIndicator == Indicator_Type.Value_Indicator) || (evs.after != null && actIndicator == Indicator_Type.After_Indicator)) {
                    actualFieldErr.qualifier.getLocation().reportSemanticError(MessageFormat.format("Duplicate reference to field `{0}'' with indicator `{1}''", actualFieldErr.qualifier.getDisplayName(), actIndicator.getDisplayName()));
                    continue;
                }
            }
            // values were used
            if (actIndicator == Indicator_Type.Value_Indicator && embeddedFieldArrayMap.containsKey(fieldIndex)) {
                final String message = MessageFormat.format("Reference to field `{0}'' with indicator `value'' would invalidate previously specified erroneous data", actualFieldErr.qualifier.getDisplayName());
                actualFieldErr.qualifier.getLocation().reportSemanticError(message);
                continue;
            }
            // duplication of omit before/after rule
            if (actIndicator == Indicator_Type.Before_Indicator && isOmit) {
                if (omitBeforeQualifier != null && erroneousDescr.omitBefore != -1) {
                    final String message = MessageFormat.format("Duplicate rule for omitting all fields before the specified field. " + "Used on field `{0}'' but previously already used on field `{1}''", actualFieldErr.qualifier.getDisplayName(), omitBeforeQualifier.getDisplayName());
                    actualFieldErr.qualifier.getLocation().reportSemanticError(message);
                    continue;
                }
                boolean isInvalid = false;
                for (Integer idx : erroneousDescr.valuesMap.keySet()) {
                    if (idx < fieldIndex) {
                        isInvalid = true;
                        break;
                    }
                }
                if (!isInvalid) {
                    for (Integer idx : embeddedFieldArrayMap.keySet()) {
                        if (idx < fieldIndex) {
                            isInvalid = true;
                            break;
                        }
                    }
                }
                if (isInvalid) {
                    final String message = MessageFormat.format("Omitting fields before field `{0}'' would invalidate previously specified erroneous data", actualFieldErr.qualifier.getDisplayName());
                    actualFieldErr.qualifier.getLocation().reportSemanticError(message);
                    continue;
                }
                // save valid omit before data
                omitBeforeQualifier = actualFieldErr.qualifier;
                erroneousDescr.omitBefore = fieldIndex;
                erroneousDescr.omitBeforeName = omitBeforeQualifier.getDisplayName();
                continue;
            }
            if (actIndicator == Indicator_Type.After_Indicator && isOmit) {
                if (omitAfterQualifier != null && erroneousDescr.omitAfter != -1) {
                    final String message = MessageFormat.format("Duplicate rule for omitting all fields after the specified field. " + "Used on field `{0}'' but previously already used on field `{1}''", actualFieldErr.qualifier.getDisplayName(), omitAfterQualifier.getDisplayName());
                    actualFieldErr.qualifier.getLocation().reportSemanticError(message);
                    continue;
                }
                boolean isInvalid = false;
                for (Integer idx : erroneousDescr.valuesMap.keySet()) {
                    if (idx > fieldIndex) {
                        isInvalid = true;
                        break;
                    }
                }
                if (!isInvalid) {
                    for (Integer idx : embeddedFieldArrayMap.keySet()) {
                        if (idx > fieldIndex) {
                            isInvalid = true;
                            break;
                        }
                    }
                }
                if (isInvalid) {
                    final String message = MessageFormat.format("Omitting fields after field `{0}'' would invalidate previously specified erroneous data", actualFieldErr.qualifier.getDisplayName());
                    actualFieldErr.qualifier.getLocation().reportSemanticError(message);
                    continue;
                }
                // save valid omit after data
                omitAfterQualifier = actualFieldErr.qualifier;
                erroneousDescr.omitAfter = fieldIndex;
                erroneousDescr.omitAfterName = omitAfterQualifier.getDisplayName();
                continue;
            }
            // if not before/after omit then save this into
            // values_m
            final boolean hasKey = erroneousDescr.valuesMap.containsKey(fieldIndex);
            final ErroneousValues evs = hasKey ? erroneousDescr.valuesMap.get(fieldIndex) : new ErroneousValues(actualFieldErr.qualifier.getDisplayName());
            switch(actIndicator) {
                case Before_Indicator:
                    evs.before = actualFieldErr.errAttrSpec;
                    break;
                case Value_Indicator:
                    evs.value = actualFieldErr.errAttrSpec;
                    break;
                case After_Indicator:
                    evs.after = actualFieldErr.errAttrSpec;
                    break;
                default:
                    ErrorReporter.INTERNAL_ERROR();
            }
            if (!hasKey) {
                erroneousDescr.valuesMap.put(fieldIndex, evs);
            }
        } else {
            // embedded err.value
            if (erroneousDescr.valuesMap.containsKey(fieldIndex) && erroneousDescr.valuesMap.get(fieldIndex).value != null) {
                final String message = MessageFormat.format("Field `{0}'' is embedded into a field which was previously overwritten or omitted", actualFieldErr.qualifier.getDisplayName());
                actualFieldErr.qualifier.getLocation().reportSemanticError(message);
                continue;
            }
            // add the embedded field to the map
            final boolean hasIndex = embeddedFieldArrayMap.containsKey(fieldIndex);
            final List<FieldErr_Type> embeddedFieldArray = hasIndex ? embeddedFieldArrayMap.get(fieldIndex) : new ArrayList<FieldErr_Type>(1);
            embeddedFieldArray.add(actualFieldErr);
            if (!hasIndex) {
                embeddedFieldArrayMap.put(fieldIndex, embeddedFieldArray);
            }
        }
    }
    // recursive calls to create embedded descriptors
    for (Integer idx : embeddedFieldArrayMap.keySet()) {
        erroneousDescr.descriptorMap.put(idx, buildErroneousDescriptorTree(timestamp, embeddedFieldArrayMap.get(idx), level + 1));
    }
    return erroneousDescr;
}
Also used : HashMap(java.util.HashMap) ASN1_Set_Type(org.eclipse.titan.designer.AST.ASN1.types.ASN1_Set_Type) IType(org.eclipse.titan.designer.AST.IType) Indicator_Type(org.eclipse.titan.designer.AST.TTCN3.attributes.ErroneousAttributeSpecification.Indicator_Type) ASN1_Sequence_Type(org.eclipse.titan.designer.AST.ASN1.types.ASN1_Sequence_Type) ArrayList(java.util.ArrayList) List(java.util.List) TTCN3_Set_Seq_Choice_BaseType(org.eclipse.titan.designer.AST.TTCN3.types.TTCN3_Set_Seq_Choice_BaseType)

Aggregations

ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 List (java.util.List)1 ASN1_Sequence_Type (org.eclipse.titan.designer.AST.ASN1.types.ASN1_Sequence_Type)1 ASN1_Set_Type (org.eclipse.titan.designer.AST.ASN1.types.ASN1_Set_Type)1 IType (org.eclipse.titan.designer.AST.IType)1 Indicator_Type (org.eclipse.titan.designer.AST.TTCN3.attributes.ErroneousAttributeSpecification.Indicator_Type)1 TTCN3_Set_Seq_Choice_BaseType (org.eclipse.titan.designer.AST.TTCN3.types.TTCN3_Set_Seq_Choice_BaseType)1