/*
 * Copyright 2016-present Open Networking Laboratory
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.onosproject.yangutils.datamodel;

import java.io.Serializable;

import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
import org.onosproject.yangutils.datamodel.utils.ResolvableStatus;
import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes;

import com.google.common.base.Strings;

import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.INTRA_FILE_RESOLVED;
import static org.onosproject.yangutils.datamodel.utils.ResolvableStatus.RESOLVED;
import static org.onosproject.yangutils.datamodel.utils.RestrictionResolver.processLengthRestriction;
import static org.onosproject.yangutils.datamodel.utils.RestrictionResolver.processRangeRestriction;
import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypeUtils.isOfRangeRestrictedType;
import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.BINARY;
import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.BITS;
import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.BOOLEAN;
import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.DECIMAL64;
import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.DERIVED;
import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.EMPTY;
import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.ENUMERATION;
import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.IDENTITYREF;
import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.LEAFREF;
import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.STRING;
import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.UNION;

/**
 * Represents the derived information.
 *
 * @param <T> extended information.
 */
public class YangDerivedInfo<T>
        implements LocationInfo, Cloneable, Serializable {

    private static final long serialVersionUID = 806201641L;

    /**
     * YANG typedef reference.
     */
    private YangTypeDef referredTypeDef;

    /**
     * Resolved additional information about data type after linking, example
     * restriction info, named values, etc. The extra information is based
     * on the data type. Based on the data type, the extended info can vary.
     */
    private T resolvedExtendedInfo;

    /**
     * Line number of pattern restriction in YANG file.
     */
    private int lineNumber;

    /**
     * Position of pattern restriction in line.
     */
    private int charPositionInLine;

    /**
     * Effective built-in type, requried in case type of typedef is again a
     * derived type. This information is to be added during linking.
     */
    private YangDataTypes effectiveBuiltInType;

    /**
     * Length restriction string to temporary store the length restriction when the type
     * is derived.
     */
    private String lengthRestrictionString;

    /**
     * Range restriction string to temporary store the range restriction when the type
     * is derived.
     */
    private String rangeRestrictionString;

    /**
     * Pattern restriction string to  temporary store the pattern restriction when the type
     * is derived.
     */
    private YangPatternRestriction patternRestriction;

    /**
     * Returns the referred typedef reference.
     *
     * @return referred typedef reference
     */
    public YangTypeDef getReferredTypeDef() {
        return referredTypeDef;
    }

    /**
     * Sets the referred typedef reference.
     *
     * @param referredTypeDef referred typedef reference
     */
    public void setReferredTypeDef(YangTypeDef referredTypeDef) {
        this.referredTypeDef = referredTypeDef;
    }

    /**
     * Returns resolved extended information after successful linking.
     *
     * @return resolved extended information
     */
    public T getResolvedExtendedInfo() {
        return resolvedExtendedInfo;
    }

    /**
     * Sets resolved extended information after successful linking.
     *
     * @param resolvedExtendedInfo resolved extended information
     */
    public void setResolvedExtendedInfo(T resolvedExtendedInfo) {
        this.resolvedExtendedInfo = resolvedExtendedInfo;
    }

    @Override
    public int getLineNumber() {
        return lineNumber;
    }

    @Override
    public int getCharPosition() {
        return charPositionInLine;
    }

    @Override
    public void setLineNumber(int lineNumber) {
        this.lineNumber = lineNumber;
    }

    @Override
    public void setCharPosition(int charPositionInLine) {
        this.charPositionInLine = charPositionInLine;
    }

    /**
     * Returns the length restriction string.
     *
     * @return the length restriction string
     */
    public String getLengthRestrictionString() {
        return lengthRestrictionString;
    }

    /**
     * Sets the length restriction string.
     *
     * @param lengthRestrictionString the length restriction string
     */
    public void setLengthRestrictionString(String lengthRestrictionString) {
        this.lengthRestrictionString = lengthRestrictionString;
    }

    /**
     * Returns the range restriction string.
     *
     * @return the range restriction string
     */
    public String getRangeRestrictionString() {
        return rangeRestrictionString;
    }

    /**
     * Sets the range restriction string.
     *
     * @param rangeRestrictionString the range restriction string
     */
    public void setRangeRestrictionString(String rangeRestrictionString) {
        this.rangeRestrictionString = rangeRestrictionString;
    }

    /**
     * Returns the pattern restriction.
     *
     * @return the pattern restriction
     */
    public YangPatternRestriction getPatternRestriction() {
        return patternRestriction;
    }

    /**
     * Sets the pattern restriction.
     *
     * @param patternRestriction the pattern restriction
     */
    public void setPatternRestriction(YangPatternRestriction patternRestriction) {
        this.patternRestriction = patternRestriction;
    }

    /**
     * Returns effective built-in type.
     *
     * @return effective built-in type
     */
    public YangDataTypes getEffectiveBuiltInType() {
        return effectiveBuiltInType;
    }

    /**
     * Sets effective built-in type.
     *
     * @param effectiveBuiltInType effective built-in type
     */
    public void setEffectiveBuiltInType(YangDataTypes effectiveBuiltInType) {
        this.effectiveBuiltInType = effectiveBuiltInType;
    }

    /**
     * Resolves the type derived info, by obtaining the effective built-in type
     * and resolving the restrictions.
     *
     * @return resolution status
     * @throws DataModelException a violation in data mode rule
     */
    public ResolvableStatus resolve()
            throws DataModelException {

        YangType<?> baseType = getReferredTypeDef().getTypeDefBaseType();

        /*
         * Checks the data type of the referred typedef, if it's derived, obtain
         * effective built-in type and restrictions from it's derived info,
         * otherwise take from the base type of type itself.
         */
        if (baseType.getDataType() == DERIVED) {
            ResolvableStatus resolvableStatus = resolveTypeDerivedInfo(baseType);
            if (resolvableStatus != null) {
                return resolvableStatus;
            }
        } else if ((baseType.getDataType() == LEAFREF) || (baseType.getDataType() == IDENTITYREF)) {
            setEffectiveBuiltInType(baseType.getDataType());
            return RESOLVED;
        } else {
            setEffectiveBuiltInType(baseType.getDataType());
            /*
             * Check whether the effective built-in type can have range
             * restrictions, if yes call resolution of range.
             */
            if (isOfRangeRestrictedType(getEffectiveBuiltInType())) {
                if (baseType.getDataTypeExtendedInfo() == null) {
                    resolveRangeRestriction(null);
                    /*
                     * Return the resolution status as resolved, if it's not
                     * resolve range/string restriction will throw exception in
                     * previous function.
                     */
                    return RESOLVED;
                } else {
                    if (!(baseType.getDataTypeExtendedInfo() instanceof YangRangeRestriction)) {
                        throw new DataModelException("Linker error: Referred typedef restriction info is of invalid " +
                                "type.");
                    }
                    resolveRangeRestriction((YangRangeRestriction) baseType.getDataTypeExtendedInfo());
                    /*
                     * Return the resolution status as resolved, if it's not
                     * resolve range/string restriction will throw exception in
                     * previous function.
                     */
                    return RESOLVED;
                }
                /*
                 * If the effective built-in type is of type string calls for
                 * string resolution.
                 */
            } else if (getEffectiveBuiltInType() == STRING) {
                if (baseType.getDataTypeExtendedInfo() == null) {
                    resolveStringRestriction(null);
                    /*
                     * Return the resolution status as resolved, if it's not
                     * resolve range/string restriction will throw exception in
                     * previous function.
                     */
                    return RESOLVED;
                } else {
                    if (!(baseType.getDataTypeExtendedInfo() instanceof YangStringRestriction)) {
                        throw new DataModelException("Linker error: Referred typedef restriction info is of invalid " +
                                "type.");
                    }
                    resolveStringRestriction((YangStringRestriction) baseType.getDataTypeExtendedInfo());
                    /*
                     * Return the resolution status as resolved, if it's not
                     * resolve range/string restriction will throw exception in
                     * previous function.
                     */
                    return RESOLVED;
                }
            } else if (getEffectiveBuiltInType() == BINARY) {
                if (baseType.getDataTypeExtendedInfo() == null) {
                    resolveBinaryRestriction(null);
                    /*
                     * Return the resolution status as resolved, if it's not
                     * resolve length restriction will throw exception in
                     * previous function.
                     */
                    return RESOLVED;
                } else {
                    if (!(baseType.getDataTypeExtendedInfo() instanceof YangRangeRestriction)) {
                        throw new DataModelException("Linker error: Referred typedef restriction info is of invalid " +
                                "type.");
                    }
                    resolveBinaryRestriction((YangRangeRestriction) baseType.getDataTypeExtendedInfo());
                    /*
                     * Return the resolution status as resolved, if it's not
                     * resolve length restriction will throw exception in
                     * previous function.
                     */
                    return RESOLVED;
                }
            }  else if (getEffectiveBuiltInType() == DECIMAL64) {
                if (baseType.getDataTypeExtendedInfo() != null) {
                    if (((YangDecimal64) baseType.getDataTypeExtendedInfo()).getRangeRestrictedExtendedInfo() == null) {
                        resolveRangeRestriction(null);
                        /*
                         * Return the resolution status as resolved, if it's not;
                         * resolve range restriction will throw exception in
                         * previous function.
                         */
                        return RESOLVED;
                    } else {
                        if (!(((YangDecimal64) baseType.getDataTypeExtendedInfo())
                                .getRangeRestrictedExtendedInfo() instanceof YangRangeRestriction)) {
                            throw new DataModelException("Linker error: Referred typedef restriction info is" +
                                                                 " of invalid type.");
                        }
                        resolveRangeRestriction((YangRangeRestriction) ((YangDecimal64) baseType
                                .getDataTypeExtendedInfo()).getRangeRestrictedExtendedInfo());
                        /*
                         * Return the resolution status as resolved, if it's not
                         * resolve range/string restriction will throw exception in
                         * previous function.
                         */
                        return RESOLVED;
                    }

                } else {
                    throw new DataModelException("Linker error: Unable to find type extended info for decimal64.");
                }
            }
        }

        /*
         * Check if the data type is the one which can't be restricted, in this
         * case check whether no self restrictions should be present.
         */
        if (isOfValidNonRestrictedType(getEffectiveBuiltInType())) {
            if (Strings.isNullOrEmpty(getLengthRestrictionString())
                    && Strings.isNullOrEmpty(getRangeRestrictionString())
                    && getPatternRestriction() == null) {
                return RESOLVED;
            } else {
                throw new DataModelException("YANG file error: Restrictions can't be applied to a given type");
            }
        }

        // Throw exception for unsupported types
        throw new DataModelException("Linker error: Unable to process the derived type.");
    }

    /**
     * Resolves the type derived info, by obtaining the effective built-in type
     * and resolving the restrictions.
     *
     * @param baseType base type of typedef
     * @return resolution status
     * @throws DataModelException a violation in data mode rule
     */
    public ResolvableStatus resolveTypeDerivedInfo(YangType<?> baseType)
            throws DataModelException {
        /*
         * Check whether the referred typedef is resolved.
         */
        if (baseType.getResolvableStatus() != INTRA_FILE_RESOLVED && baseType.getResolvableStatus() != RESOLVED) {
            throw new DataModelException("Linker Error: Referred typedef is not resolved for type.");
        }

        /*
         * Check if the referred typedef is intra file resolved, if yes sets
         * current status also to intra file resolved .
         */
        if (getReferredTypeDef().getTypeDefBaseType().getResolvableStatus() == INTRA_FILE_RESOLVED) {
            return INTRA_FILE_RESOLVED;
        }
        setEffectiveBuiltInType(((YangDerivedInfo<?>) baseType.getDataTypeExtendedInfo())
                                        .getEffectiveBuiltInType());
        YangDerivedInfo refDerivedInfo = (YangDerivedInfo<?>) baseType.getDataTypeExtendedInfo();
        /*
         * Check whether the effective built-in type can have range
         * restrictions, if yes call resolution of range.
         */
        if (isOfRangeRestrictedType(getEffectiveBuiltInType())) {
            if (refDerivedInfo.getResolvedExtendedInfo() == null) {
                resolveRangeRestriction(null);
                /*
                 * Return the resolution status as resolved, if it's not
                 * resolve range/string restriction will throw exception in
                 * previous function.
                 */
                return RESOLVED;
            } else {
                if (!(refDerivedInfo.getResolvedExtendedInfo() instanceof YangRangeRestriction)) {
                    throw new DataModelException("Linker error: Referred typedef restriction info is of invalid " +
                                                         "type.");
                }
                resolveRangeRestriction((YangRangeRestriction) refDerivedInfo.getResolvedExtendedInfo());
                /*
                 * Return the resolution status as resolved, if it's not
                 * resolve range/string restriction will throw exception in
                 * previous function.
                 */
                return RESOLVED;
            }
            /*
             * If the effective built-in type is of type string calls for
             * string resolution.
             */
        } else if (getEffectiveBuiltInType() == STRING) {
            if (refDerivedInfo.getResolvedExtendedInfo() == null) {
                resolveStringRestriction(null);
                /*
                 * Return the resolution status as resolved, if it's not
                 * resolve range/string restriction will throw exception in
                 * previous function.
                 */
                return RESOLVED;
            } else {
                if (!(refDerivedInfo.getResolvedExtendedInfo() instanceof YangStringRestriction)) {
                    throw new DataModelException("Linker error: Referred typedef restriction info is of invalid " +
                                                         "type.");
                }
                resolveStringRestriction((YangStringRestriction) refDerivedInfo.getResolvedExtendedInfo());
                /*
                 * Return the resolution status as resolved, if it's not
                 * resolve range/string restriction will throw exception in
                 * previous function.
                 */
                return RESOLVED;
            }
        } else if (getEffectiveBuiltInType() == BINARY) {
            if (refDerivedInfo.getResolvedExtendedInfo() == null) {
                resolveBinaryRestriction(null);
                /*
                 * Return the resolution status as resolved, if it's not
                 * resolve length restriction will throw exception in
                 * previous function.
                 */
                return RESOLVED;
            } else {
                if (!(refDerivedInfo.getResolvedExtendedInfo() instanceof YangRangeRestriction)) {
                    throw new DataModelException("Linker error: Referred typedef restriction info is of invalid " +
                                                         "type.");
                }
                resolveBinaryRestriction((YangRangeRestriction) refDerivedInfo.getResolvedExtendedInfo());
                /*
                 * Return the resolution status as resolved, if it's not
                 * resolve length restriction will throw exception in
                 * previous function.
                 */
                return RESOLVED;
            }
        } else if (getEffectiveBuiltInType() == DECIMAL64) {
            if (refDerivedInfo.getResolvedExtendedInfo() == null) {
                resolveRangeRestriction(null);
                 /*
                  * Return the resolution status as resolved, if it's not;
                  * resolve range restriction will throw exception in
                  * previous function.
                  */
                return RESOLVED;
            } else {
                if (!(refDerivedInfo.getResolvedExtendedInfo() instanceof YangRangeRestriction)) {
                    throw new DataModelException("Linker error: Referred typedef restriction info is of invalid " +
                                                         "type.");
                }
                resolveRangeRestriction((YangRangeRestriction) refDerivedInfo
                        .getResolvedExtendedInfo());
                /*
                 * Return the resolution status as resolved, if it's not
                 * resolve range/string restriction will throw exception in
                 * previous function.
                 */
                return RESOLVED;
            }
        }

        return null;
    }

    /**
     * Resolves the string restrictions.
     *
     * @param refStringRestriction referred string restriction of typedef
     * @throws DataModelException a violation in data model rule
     */
    private void resolveStringRestriction(YangStringRestriction refStringRestriction)
            throws DataModelException {
        YangStringRestriction curStringRestriction = null;
        YangRangeRestriction refRangeRestriction = null;
        YangPatternRestriction refPatternRestriction = null;

        /*
         * Check that range restriction should be null when built-in type is
         * string.
         */
        if (!Strings.isNullOrEmpty(getRangeRestrictionString())) {
            DataModelException dataModelException = new DataModelException("YANG file error: Range restriction " +
                    "should't be present for string data type.");
            dataModelException.setLine(lineNumber);
            dataModelException.setCharPosition(charPositionInLine);
            throw dataModelException;
        }

        /*
         * If referred restriction and self restriction both are null, no
         * resolution is required.
         */
        if (refStringRestriction == null && Strings.isNullOrEmpty(getLengthRestrictionString())
                && getPatternRestriction() == null) {
            return;
        }

        /*
         * If referred string restriction is not null, take value of length and
         * pattern restriction and assign.
         */
        if (refStringRestriction != null) {
            refRangeRestriction = refStringRestriction.getLengthRestriction();
            refPatternRestriction = refStringRestriction.getPatternRestriction();
        }

        YangRangeRestriction lengthRestriction = resolveLengthRestriction(refRangeRestriction);
        YangPatternRestriction patternRestriction = resolvePatternRestriction(refPatternRestriction);

        /*
         * Check if either of length or pattern restriction is present, if yes
         * create string restriction and assign value.
         */
        if (lengthRestriction != null || patternRestriction != null) {
            curStringRestriction = new YangStringRestriction();
            curStringRestriction.setLengthRestriction(lengthRestriction);
            curStringRestriction.setPatternRestriction(patternRestriction);
        }
        setResolvedExtendedInfo((T) curStringRestriction);
    }

    /**
     * Resolves the binary restrictions.
     *
     * @param refLengthRestriction referred length restriction of typedef
     * @throws DataModelException a violation in data model rule
     */
    private void resolveBinaryRestriction(YangRangeRestriction refLengthRestriction)
            throws DataModelException {

        if (rangeRestrictionString != null || patternRestriction != null) {
            DataModelException dataModelException =
                    new DataModelException("YANG file error: for binary " +
                                                   "range restriction or pattern restriction is not allowed.");
            dataModelException.setLine(lineNumber);
            dataModelException.setCharPosition(charPositionInLine);
            throw dataModelException;
        }

        // Get the final resolved length restriction
        YangRangeRestriction lengthRestriction = resolveLengthRestriction(refLengthRestriction);
        // Set the lenght restriction.
        setResolvedExtendedInfo((T) lengthRestriction);
    }

    /**
     * Resolves pattern restriction.
     *
     * @param refPatternRestriction referred pattern restriction of typedef
     * @return resolved pattern restriction
     */
    private YangPatternRestriction resolvePatternRestriction(YangPatternRestriction refPatternRestriction) {
        /*
         * If referred restriction and self restriction both are null, no
         * resolution is required.
         */
        if (refPatternRestriction == null && getPatternRestriction() == null) {
            return null;
        }

        /*
         * If self restriction is null, and referred restriction is present
         * shallow copy the referred to self.
         */
        if (getPatternRestriction() == null) {
            return refPatternRestriction;
        }

        /*
         * If referred restriction is null, and self restriction is present
         * carry out self resolution.
         */
        if (refPatternRestriction == null) {
            return getPatternRestriction();
        }

        /*
         * Get patterns of referred type and add it to current pattern
         * restrictions.
         */
        for (String pattern : refPatternRestriction.getPatternList()) {
            getPatternRestriction().addPattern(pattern);
        }
        return getPatternRestriction();
    }

    /**
     * Resolves the length restrictions.
     *
     * @param refLengthRestriction referred length restriction of typedef
     * @return resolved length restriction
     * @throws DataModelException a violation in data model rule
     */
    private YangRangeRestriction resolveLengthRestriction(YangRangeRestriction refLengthRestriction)
            throws DataModelException {

        /*
         * If referred restriction and self restriction both are null, no
         * resolution is required.
         */
        if (refLengthRestriction == null && Strings.isNullOrEmpty(getLengthRestrictionString())) {
            return null;
        }

        /*
         * If self restriction is null, and referred restriction is present
         * shallow copy the referred to self.
         */
        if (Strings.isNullOrEmpty(getLengthRestrictionString())) {
            return refLengthRestriction;
        }

        /*
         * If referred restriction is null, and self restriction is present
         * carry out self resolution.
         */
        if (refLengthRestriction == null) {
            YangRangeRestriction curLengthRestriction = processLengthRestriction(null, lineNumber,
                    charPositionInLine, false, getLengthRestrictionString());
            return curLengthRestriction;
        }

        /*
         * Carry out self resolution based with obtained effective built-in type
         * and MIN/MAX values as per the referred typedef's values.
         */
        YangRangeRestriction curLengthRestriction = processLengthRestriction(refLengthRestriction, lineNumber,
                charPositionInLine, true, getLengthRestrictionString());

        // Resolve the range with referred typedef's restriction.
        resolveLengthAndRangeRestriction(refLengthRestriction, curLengthRestriction);
        return curLengthRestriction;
    }

    /**
     * Resolves the length/range self and referred restriction, to check whether
     * the all the range interval in self restriction is stricter than the
     * referred typedef's restriction.
     *
     * @param refRestriction referred restriction
     * @param curRestriction self restriction
     */
    private void resolveLengthAndRangeRestriction(YangRangeRestriction refRestriction,
            YangRangeRestriction curRestriction)
            throws DataModelException {
        for (Object curInterval : curRestriction.getAscendingRangeIntervals()) {
            if (!(curInterval instanceof YangRangeInterval)) {
                throw new DataModelException("Linker error: Current range intervals not processed correctly.");
            }
            try {
                refRestriction.isValidInterval((YangRangeInterval) curInterval);
            } catch (DataModelException e) {
                DataModelException dataModelException = new DataModelException(e);
                dataModelException.setLine(lineNumber);
                dataModelException.setCharPosition(charPositionInLine);
                throw dataModelException;
            }
        }
    }

    /**
     * Resolves the range restrictions.
     *
     * @param refRangeRestriction referred range restriction of typedef
     * @throws DataModelException a violation in data model rule
     */
    private void resolveRangeRestriction(YangRangeRestriction refRangeRestriction)
            throws DataModelException {

        /*
         * Check that string restriction should be null when built-in type is of
         * range type.
         */
        if (!Strings.isNullOrEmpty(getLengthRestrictionString()) || getPatternRestriction() != null) {
            DataModelException dataModelException = new DataModelException("YANG file error: Length/Pattern " +
                    "restriction should't be present for int/uint/decimal data type.");
            dataModelException.setLine(lineNumber);
            dataModelException.setCharPosition(charPositionInLine);
            throw dataModelException;
        }

        /*
         * If referred restriction and self restriction both are null, no
         * resolution is required.
         */
        if (refRangeRestriction == null && Strings.isNullOrEmpty(getRangeRestrictionString())) {
            return;
        }

        /*
         * If self restriction is null, and referred restriction is present
         * shallow copy the referred to self.
         */
        if (Strings.isNullOrEmpty(getRangeRestrictionString())) {
            setResolvedExtendedInfo((T) refRangeRestriction);
            return;
        }

        /*
         * If referred restriction is null, and self restriction is present
         * carry out self resolution.
         */
        if (refRangeRestriction == null) {
            YangRangeRestriction curRangeRestriction = processRangeRestriction(null, lineNumber,
                    charPositionInLine, false, getRangeRestrictionString(), getEffectiveBuiltInType());
            setResolvedExtendedInfo((T) curRangeRestriction);
            return;
        }

        /*
         * Carry out self resolution based with obtained effective built-in type
         * and MIN/MAX values as per the referred typedef's values.
         */
        YangRangeRestriction curRangeRestriction = processRangeRestriction(refRangeRestriction, lineNumber,
                charPositionInLine, true, getRangeRestrictionString(), getEffectiveBuiltInType());

        // Resolve the range with referred typedef's restriction.
        resolveLengthAndRangeRestriction(refRangeRestriction, curRangeRestriction);
        setResolvedExtendedInfo((T) curRangeRestriction);
    }

    /**
     * Returns whether the data type is of non restricted type.
     *
     * @param dataType data type to be checked
     * @return true, if data type can't be restricted, false otherwise
     */
    private boolean isOfValidNonRestrictedType(YangDataTypes dataType) {
        return dataType == BOOLEAN
                || dataType == ENUMERATION
                || dataType == BITS
                || dataType == EMPTY
                || dataType == UNION
                || dataType == IDENTITYREF
                || dataType == LEAFREF;
    }
}
