/*
 * 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) ||
                    (((YangDecimal64) refDerivedInfo.getResolvedExtendedInfo())
                            .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) refDerivedInfo.getResolvedExtendedInfo())
                        .getRangeRestrictedExtendedInfo() instanceof YangRangeRestriction)) {
                    throw new DataModelException("Linker error: Referred typedef restriction info is of invalid " +
                                                         "type.");
                }
                resolveRangeRestriction((YangRangeRestriction) ((YangDecimal64) refDerivedInfo
                        .getResolvedExtendedInfo()).getRangeRestrictedExtendedInfo());
                /*
                 * 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;
    }
}
