/*
 * 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.translator.tojava;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.onosproject.yangutils.datamodel.YangNode;
import org.onosproject.yangutils.datamodel.YangType;
import org.onosproject.yangutils.datamodel.YangTypeHolder;
import org.onosproject.yangutils.datamodel.javadatamodel.JavaFileInfo;
import org.onosproject.yangutils.datamodel.javadatamodel.YangPluginConfig;
import org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes;
import org.onosproject.yangutils.translator.exception.TranslatorException;
import org.onosproject.yangutils.translator.tojava.javamodel.YangJavaTypeTranslator;

import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.INT32;
import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.INT64;
import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.UINT16;
import static org.onosproject.yangutils.datamodel.utils.builtindatatype.YangDataTypes.UINT32;
import static org.onosproject.yangutils.translator.tojava.GeneratedJavaFileType.GENERATE_TYPEDEF_CLASS;
import static org.onosproject.yangutils.translator.tojava.GeneratedJavaFileType.GENERATE_UNION_CLASS;
import static org.onosproject.yangutils.translator.tojava.GeneratedTempFileType.CONSTRUCTOR_FOR_TYPE_MASK;
import static org.onosproject.yangutils.translator.tojava.GeneratedTempFileType.FROM_STRING_IMPL_MASK;
import static org.onosproject.yangutils.translator.tojava.GeneratedTempFileType.OF_STRING_IMPL_MASK;
import static org.onosproject.yangutils.translator.tojava.JavaAttributeInfo.getAttributeInfoForTheData;
import static org.onosproject.yangutils.translator.tojava.JavaQualifiedTypeInfoTranslator.getQualifiedInfoOfFromString;
import static org.onosproject.yangutils.translator.tojava.utils.JavaFileGenerator.generateTypeDefClassFile;
import static org.onosproject.yangutils.translator.tojava.utils.JavaFileGenerator.generateUnionClassFile;
import static org.onosproject.yangutils.translator.tojava.utils.JavaIdentifierSyntax.createPackage;
import static org.onosproject.yangutils.translator.tojava.utils.MethodsGenerator.getOfMethodStringAndJavaDoc;
import static org.onosproject.yangutils.translator.tojava.utils.MethodsGenerator.getTypeConstructorStringAndJavaDoc;
import static org.onosproject.yangutils.translator.tojava.utils.ValidatorTypeForUnionTypes.INT_TYPE_CONFLICT;
import static org.onosproject.yangutils.translator.tojava.utils.ValidatorTypeForUnionTypes.LONG_TYPE_CONFLICT;
import static org.onosproject.yangutils.utils.UtilConstants.EMPTY_STRING;
import static org.onosproject.yangutils.utils.UtilConstants.NEW_LINE;
import static org.onosproject.yangutils.utils.io.impl.FileSystemUtil.closeFile;
import static org.onosproject.yangutils.utils.io.impl.YangIoUtils.getCamelCase;

/**
 * Represents implementation of java data type code fragments temporary implementations. Maintains the temp files
 * required specific for user defined data type java snippet generation.
 */
public class TempJavaTypeFragmentFiles
        extends TempJavaFragmentFiles {

    /**
     * File name for of string method.
     */
    private static final String OF_STRING_METHOD_FILE_NAME = "OfString";

    /**
     * File name for construction for special type like union, typedef.
     */
    private static final String CONSTRUCTOR_FOR_TYPE_FILE_NAME = "ConstructorForType";

    /**
     * File name for typedef class file name suffix.
     */
    private static final String TYPEDEF_CLASS_FILE_NAME_SUFFIX = EMPTY_STRING;

    /**
     * File name for generated class file for special type like union, typedef suffix.
     */
    private static final String UNION_TYPE_CLASS_FILE_NAME_SUFFIX = EMPTY_STRING;

    /**
     * Integer index in type list.
     */
    private int intIndex = 0;

    /**
     * UInt index in type list.
     */
    private int uIntIndex = 0;

    /**
     * long index in type list.
     */
    private int longIndex = 0;

    /**
     * ULong index in type list.
     */
    private int uLongIndex = 0;

    /**
     * Temporary file handle for of string method of class.
     */
    private File ofStringImplTempFileHandle;

    /**
     * Temporary file handle for constructor for type class.
     */
    private File constructorForTypeTempFileHandle;

    /**
     * Java file handle for typedef class file.
     */
    private File typedefClassJavaFileHandle;

    /**
     * Java file handle for type class like union, typedef file.
     */
    private File typeClassJavaFileHandle;

    /**
     * Java attribute for int.
     */
    private JavaAttributeInfo intAttribute;

    /**
     * Java attribute for long.
     */
    private JavaAttributeInfo longAttribute;

    /**
     * Java attribute for uInt.
     */
    private JavaAttributeInfo uIntAttribute;

    /**
     * Java attribute for uLong.
     */
    private JavaAttributeInfo uLongAttribute;

    /**
     * Creates an instance of temporary java code fragment.
     *
     * @param javaFileInfo generated java file info
     * @throws IOException when fails to create new file handle
     */
    TempJavaTypeFragmentFiles(JavaFileInfo javaFileInfo)
            throws IOException {

        super(javaFileInfo);

        /*
         * Initialize getterImpl, attributes, hash code, equals and to strings
         * when generation file type matches to typeDef class mask.
         */
        addGeneratedTempFile(OF_STRING_IMPL_MASK);
        addGeneratedTempFile(CONSTRUCTOR_FOR_TYPE_MASK);
        addGeneratedTempFile(FROM_STRING_IMPL_MASK);

        setOfStringImplTempFileHandle(getTemporaryFileHandle(OF_STRING_METHOD_FILE_NAME));
        setConstructorForTypeTempFileHandle(getTemporaryFileHandle(CONSTRUCTOR_FOR_TYPE_FILE_NAME));

    }

    /**
     * Returns type class constructor method's temporary file handle.
     *
     * @return type class constructor method's temporary file handle
     */

    public File getConstructorForTypeTempFileHandle() {
        return constructorForTypeTempFileHandle;
    }

    /**
     * Sets type class constructor method's temporary file handle.
     *
     * @param constructorForTypeTempFileHandle type class constructor method's temporary file handle
     */
    private void setConstructorForTypeTempFileHandle(File constructorForTypeTempFileHandle) {
        this.constructorForTypeTempFileHandle = constructorForTypeTempFileHandle;
    }

    /**
     * Returns java file handle for typedef class file.
     *
     * @return java file handle for typedef class file
     */
    private File getTypedefClassJavaFileHandle() {
        return typedefClassJavaFileHandle;
    }

    /**
     * Sets the java file handle for typedef class file.
     *
     * @param typedefClassJavaFileHandle java file handle
     */
    private void setTypedefClassJavaFileHandle(File typedefClassJavaFileHandle) {
        this.typedefClassJavaFileHandle = typedefClassJavaFileHandle;
    }

    /**
     * Returns java file handle for type class file.
     *
     * @return java file handle for type class file
     */
    private File getTypeClassJavaFileHandle() {
        return typeClassJavaFileHandle;
    }

    /**
     * Sets the java file handle for type class file.
     *
     * @param typeClassJavaFileHandle type file handle
     */
    private void setTypeClassJavaFileHandle(File typeClassJavaFileHandle) {
        this.typeClassJavaFileHandle = typeClassJavaFileHandle;
    }

    /**
     * Returns of string method's temporary file handle.
     *
     * @return of string method's temporary file handle
     */

    public File getOfStringImplTempFileHandle() {
        return ofStringImplTempFileHandle;
    }

    /**
     * Set of string method's temporary file handle.
     *
     * @param ofStringImplTempFileHandle of string method's temporary file handle
     */
    private void setOfStringImplTempFileHandle(File ofStringImplTempFileHandle) {
        this.ofStringImplTempFileHandle = ofStringImplTempFileHandle;
    }

    /**
     * Adds all the type in the current data model node as part of the generated temporary file.
     *
     * @param yangTypeHolder YANG java data model node which has type info, eg union / typedef
     * @param pluginConfig   plugin configurations for naming conventions
     * @throws IOException IO operation fail
     */
    void addTypeInfoToTempFiles(YangTypeHolder yangTypeHolder, YangPluginConfig pluginConfig)
            throws IOException {

        List<YangType<?>> typeList = yangTypeHolder.getTypeList();
        if (typeList != null) {
            for (YangType<?> yangType : typeList) {
                if (!(yangType instanceof YangJavaTypeTranslator)) {
                    throw new TranslatorException("Type does not have Java info");
                }
                JavaAttributeInfo javaAttributeInfo = getAttributeForType(yangType, pluginConfig);
                addJavaSnippetInfoToApplicableTempFiles(javaAttributeInfo,
                        pluginConfig, typeList);
            }
            addTypeConstructor(pluginConfig);
            addMethodsInConflictCase(pluginConfig);
        }
    }

    /**
     * Returns java attribute.
     *
     * @param yangType     YANG type
     * @param pluginConfig plugin configurations
     * @return java attribute
     */
    private JavaAttributeInfo getAttributeForType(YangType yangType, YangPluginConfig pluginConfig) {
        YangJavaTypeTranslator<?> javaType = (YangJavaTypeTranslator<?>) yangType;
        javaType.updateJavaQualifiedInfo(pluginConfig.getConflictResolver());
        String typeName = javaType.getDataTypeName();
        typeName = getCamelCase(typeName, pluginConfig.getConflictResolver());
        return getAttributeInfoForTheData(
                javaType.getJavaQualifiedInfo(),
                typeName, javaType,
                getIsQualifiedAccessOrAddToImportList(javaType.getJavaQualifiedInfo()),
                false);
    }

    /**
     * Adds the new attribute info to the target generated temporary files for union class.
     *
     * @param javaAttributeInfo the attribute info that needs to be added to temporary files
     * @param pluginConfig      plugin configurations
     * @param typeList          type list
     * @throws IOException IO operation fail
     */
    private void addJavaSnippetInfoToApplicableTempFiles(JavaAttributeInfo javaAttributeInfo,
                                                         YangPluginConfig pluginConfig, List<YangType<?>> typeList)
            throws IOException {

        YangDataTypes attrType = javaAttributeInfo.getAttributeType().getDataType();

        if (attrType == INT32 || attrType == UINT16) {
            boolean isIntConflict = validateForConflictingIntTypes(typeList);
            javaAttributeInfo.setIntConflict(isIntConflict);
            updateAttributeCondition(javaAttributeInfo);
            if (!isIntConflict) {
                addMethodsWhenNoConflictingTypes(javaAttributeInfo, pluginConfig);
            }
        } else if (attrType == INT64 || attrType == UINT32) {
            boolean isLongConflict = validateForConflictingLongTypes(typeList);
            javaAttributeInfo.setLongConflict(isLongConflict);
            updateAttributeCondition(javaAttributeInfo);
            if (!isLongConflict) {
                addMethodsWhenNoConflictingTypes(javaAttributeInfo, pluginConfig);
            }
        } else {
            addMethodsWhenNoConflictingTypes(javaAttributeInfo, pluginConfig);
        }
        super.addJavaSnippetInfoToApplicableTempFiles(javaAttributeInfo, pluginConfig);

    }

    /**
     * Adds of method and constructor when there is no conflicting types.
     *
     * @param javaAttributeInfo java attribute info
     * @param pluginConfig      plugin configurations
     * @throws IOException when fails to do IO operations
     */
    private void addMethodsWhenNoConflictingTypes(JavaAttributeInfo javaAttributeInfo,
                                                  YangPluginConfig pluginConfig) throws IOException {
        if ((getGeneratedTempFiles() & OF_STRING_IMPL_MASK) != 0) {
            addOfStringMethod(javaAttributeInfo, pluginConfig);
        }

        if ((getGeneratedTempFiles() & CONSTRUCTOR_FOR_TYPE_MASK) != 0) {
            addTypeConstructor(javaAttributeInfo, pluginConfig);
        }
    }

    /**
     * Adds of, getter and from string method in conflict cases.
     *
     * @param pluginConfig plugin configurations
     * @throws IOException when fails to do IO operations
     */
    private void addMethodsInConflictCase(YangPluginConfig pluginConfig) throws IOException {
        JavaAttributeInfo attr = getIntAttribute();
        if (attr != null) {
            attr = getUIntAttribute();
        }
        if (attr != null) {
            if (attr.isIntConflict()) {
                if (getIntIndex() < getUIntIndex()) {
                    appendToFile(getOfStringImplTempFileHandle(), getOfMethodStringAndJavaDoc(getIntAttribute(),
                            getGeneratedJavaClassName(), pluginConfig)
                            + NEW_LINE);
                    addGetterImpl(getIntAttribute(), pluginConfig);
                    addFromStringMethod(getIntAttribute(), pluginConfig);
                } else {
                    appendToFile(getOfStringImplTempFileHandle(), getOfMethodStringAndJavaDoc(getUIntAttribute(),
                            getGeneratedJavaClassName(), pluginConfig)
                            + NEW_LINE);
                    addGetterImpl(getUIntAttribute(), pluginConfig);
                    addFromStringMethod(getUIntAttribute(), pluginConfig);
                }
            }
        }
        attr = getLongAttribute();
        if (attr != null) {
            attr = getULongAttribute();
        }
        if (attr != null) {
            if (attr.isLongConflict()) {
                if (getLongIndex() < getULongIndex()) {
                    appendToFile(getOfStringImplTempFileHandle(), getOfMethodStringAndJavaDoc(getLongAttribute(),
                            getGeneratedJavaClassName(), pluginConfig)
                            + NEW_LINE);
                    addGetterImpl(getLongAttribute(), pluginConfig);
                    addFromStringMethod(getLongAttribute(), pluginConfig);
                } else {
                    appendToFile(getOfStringImplTempFileHandle(), getOfMethodStringAndJavaDoc(getULongAttribute(),
                            getGeneratedJavaClassName(), pluginConfig)
                            + NEW_LINE);
                    addGetterImpl(getULongAttribute(), pluginConfig);
                    addFromStringMethod(getULongAttribute(), pluginConfig);
                }
            }
        }
    }

    /**
     * Adds from string method for conflict case.
     *
     * @param newAttrInfo  new attribute
     * @param pluginConfig plugin configurations
     * @throws IOException when fails to do IO operations
     */
    private void addFromStringMethod(JavaAttributeInfo newAttrInfo, YangPluginConfig pluginConfig) throws IOException {

        JavaQualifiedTypeInfoTranslator qualifiedInfoOfFromString = getQualifiedInfoOfFromString(newAttrInfo,
                pluginConfig.getConflictResolver());
            /*
             * Create a new java attribute info with qualified information of
             * wrapper classes.
             */
        JavaAttributeInfo fromStringAttributeInfo = getAttributeInfoForTheData(qualifiedInfoOfFromString,
                newAttrInfo.getAttributeName(),
                newAttrInfo.getAttributeType(),
                getIsQualifiedAccessOrAddToImportList(qualifiedInfoOfFromString), false);

        addFromStringMethod(newAttrInfo, fromStringAttributeInfo);
    }

    /**
     * Adds type constructor.
     *
     * @param attr         attribute info
     * @param pluginConfig plugin configurations
     * @throws IOException when fails to append to temporary file
     */
    private void addTypeConstructor(JavaAttributeInfo attr, YangPluginConfig pluginConfig)
            throws IOException {
        appendToFile(getConstructorForTypeTempFileHandle(), getTypeConstructorStringAndJavaDoc(attr,
                getGeneratedJavaClassName(), pluginConfig) + NEW_LINE);
    }

    /**
     * Adds type constructor.
     *
     * @param pluginConfig plugin configurations
     * @throws IOException when fails to append to temporary file
     */
    private void addTypeConstructor(YangPluginConfig pluginConfig)
            throws IOException {
        JavaAttributeInfo attr = getIntAttribute();
        if (attr != null) {
            attr = getUIntAttribute();
        }
        if (attr != null) {
            if (attr.isIntConflict()) {
                appendToFile(getConstructorForTypeTempFileHandle(), getTypeConstructorStringAndJavaDoc(
                        getIntAttribute(),
                        getUIntAttribute(), getGeneratedJavaClassName(), pluginConfig, INT_TYPE_CONFLICT,
                        getIntIndex()
                                < getUIntIndex()) + NEW_LINE);
            }
        }
        attr = getLongAttribute();
        if (attr != null) {
            attr = getULongAttribute();
        }
        if (attr != null) {
            if (attr.isLongConflict()) {
                appendToFile(getConstructorForTypeTempFileHandle(), getTypeConstructorStringAndJavaDoc(
                        getLongAttribute(),
                        getULongAttribute(), getGeneratedJavaClassName(), pluginConfig, LONG_TYPE_CONFLICT,
                        getLongIndex()
                                < getULongIndex()) + NEW_LINE);
            }
        }
    }

    /**
     * Adds of string for type.
     *
     * @param attr         attribute info
     * @param pluginConfig plugin configurations
     * @throws IOException when fails to append to temporary file
     */
    private void addOfStringMethod(JavaAttributeInfo attr, YangPluginConfig pluginConfig)
            throws IOException {
        appendToFile(getOfStringImplTempFileHandle(), getOfMethodStringAndJavaDoc(attr,
                getGeneratedJavaClassName(), pluginConfig)
                + NEW_LINE);
    }

    /**
     * Removes all temporary file handles.
     *
     * @param isErrorOccurred flag to tell translator that error has occurred while file generation
     * @throws IOException when failed to delete the temporary files
     */
    @Override
    public void freeTemporaryResources(boolean isErrorOccurred)
            throws IOException {

        if ((getGeneratedJavaFiles() & GENERATE_TYPEDEF_CLASS) != 0) {
            closeFile(getTypedefClassJavaFileHandle(), isErrorOccurred);
        }

        if ((getGeneratedJavaFiles() & GENERATE_UNION_CLASS) != 0) {
            closeFile(getTypeClassJavaFileHandle(), isErrorOccurred);
        }

        if ((getGeneratedTempFiles() & CONSTRUCTOR_FOR_TYPE_MASK) != 0) {
            closeFile(getConstructorForTypeTempFileHandle(), true);
        }
        if ((getGeneratedTempFiles() & OF_STRING_IMPL_MASK) != 0) {
            closeFile(getOfStringImplTempFileHandle(), true);
        }
        if ((getGeneratedTempFiles() & FROM_STRING_IMPL_MASK) != 0) {
            closeFile(getFromStringImplTempFileHandle(), true);
        }

        super.freeTemporaryResources(isErrorOccurred);

    }

    /**
     * Constructs java code exit.
     *
     * @param fileType generated file type
     * @param curNode  current YANG node
     * @throws IOException when fails to generate java files
     */
    @Override
    public void generateJavaFile(int fileType, YangNode curNode)
            throws IOException {
        List<String> imports = new ArrayList<>();
        if (isAttributePresent()) {
            imports = getJavaImportData().getImports();
        }

        createPackage(curNode);

        /*
         * Creates type def class file.
         */
        if ((fileType & GENERATE_TYPEDEF_CLASS) != 0) {
            addImportsToStringAndHasCodeMethods(imports, true);
            setTypedefClassJavaFileHandle(getJavaFileHandle(getJavaClassName(TYPEDEF_CLASS_FILE_NAME_SUFFIX)));
            generateTypeDefClassFile(getTypedefClassJavaFileHandle(), curNode, imports);
        }
        /*
         * Creates type class file.
         */
        if ((fileType & GENERATE_UNION_CLASS) != 0) {
            addImportsToStringAndHasCodeMethods(imports, true);
            setTypeClassJavaFileHandle(getJavaFileHandle(getJavaClassName(UNION_TYPE_CLASS_FILE_NAME_SUFFIX)));
            generateUnionClassFile(getTypeClassJavaFileHandle(), curNode, imports);
        }

        /*
         * Close all the file handles.
         */
        freeTemporaryResources(false);
    }

    /**
     * Returns int type index from type list.
     *
     * @return int type index from type list
     */
    public int getIntIndex() {
        return intIndex;
    }

    /**
     * Sets int type index from type list.
     *
     * @param intIndex int type index from type list.
     */
    private void setIntIndex(int intIndex) {
        this.intIndex = intIndex;
    }

    /**
     * Returns uInt type index from type list.
     *
     * @return uInt type index from type list
     */
    public int getUIntIndex() {
        return uIntIndex;
    }

    /**
     * Sets uInt type index from type list.
     *
     * @param uIntIndex uInt type index from type list.
     */
    private void setUIntIndex(int uIntIndex) {
        this.uIntIndex = uIntIndex;
    }

    /**
     * Returns long type index from type list.
     *
     * @return long type index from type list
     */
    public int getLongIndex() {
        return longIndex;
    }

    /**
     * Sets long type index from type list.
     *
     * @param longIndex long type index from type list.
     */
    private void setLongIndex(int longIndex) {
        this.longIndex = longIndex;
    }

    /**
     * Returns uLong type index from type list.
     *
     * @return uLong type index from type list
     */
    public int getULongIndex() {
        return uLongIndex;
    }

    /**
     * Sets uLong type index from type list.
     *
     * @param uLongIndex uLong type index from type list.
     */
    private void setULongIndex(int uLongIndex) {
        this.uLongIndex = uLongIndex;
    }

    /**
     * Validates conflict for int and uInt.
     *
     * @param typeList type list
     * @return true if conflict is there
     */
    private boolean validateForConflictingIntTypes(List<YangType<?>> typeList) {
        boolean isIntPresent = false;
        boolean isUIntPresent = false;
        for (YangType type : typeList) {
            if (type.getDataType().equals(INT32)) {
                setIntIndex(typeList.indexOf(type));
                isIntPresent = true;
            }
            if (type.getDataType().equals(UINT16)) {
                setUIntIndex(typeList.indexOf(type));
                isUIntPresent = true;
            }
        }

        return isIntPresent && isUIntPresent;
    }

    /**
     * Validates conflict for long and uLong.
     *
     * @param typeList type list
     * @return true if conflict is there
     */
    private boolean validateForConflictingLongTypes(List<YangType<?>> typeList) {
        boolean isLongPresent = false;
        boolean isULongPresent = false;
        for (YangType type : typeList) {
            if (type.getDataType().equals(INT64)) {
                setLongIndex(typeList.indexOf(type));
                isLongPresent = true;
            }
            if (type.getDataType().equals(UINT32)) {
                setULongIndex(typeList.indexOf(type));
                isULongPresent = true;
            }
        }

        return isLongPresent && isULongPresent;
    }

    /**
     * Updates attribute info in case of conflicts.
     *
     * @param javaAttributeInfo java attribute info
     */
    private void updateAttributeCondition(JavaAttributeInfo javaAttributeInfo) {

        if (javaAttributeInfo.isIntConflict()) {
            if (javaAttributeInfo.getAttributeType().getDataType() == UINT16) {
                setUIntAttribute(javaAttributeInfo);
            } else if (javaAttributeInfo.getAttributeType().getDataType() == INT32) {
                setIntAttribute(javaAttributeInfo);
            }

        }
        if (javaAttributeInfo.isLongConflict()) {
            if (javaAttributeInfo.getAttributeType().getDataType() == UINT32) {
                setULongAttribute(javaAttributeInfo);
            } else if (javaAttributeInfo.getAttributeType().getDataType() == INT64) {
                setLongAttribute(javaAttributeInfo);
            }

        }
    }

    /**
     * Returns attribute for int.
     *
     * @return attribute for int
     */
    public JavaAttributeInfo getIntAttribute() {
        return intAttribute;
    }

    /**
     * Sets attribute for int.
     *
     * @param intAttribute attribute for int
     */
    private void setIntAttribute(JavaAttributeInfo intAttribute) {
        this.intAttribute = intAttribute;
    }

    /**
     * Returns attribute for long.
     *
     * @return attribute for long
     */
    public JavaAttributeInfo getLongAttribute() {
        return longAttribute;
    }

    /**
     * Sets attribute for long.
     *
     * @param longAttribute attribute for long
     */
    private void setLongAttribute(JavaAttributeInfo longAttribute) {
        this.longAttribute = longAttribute;
    }

    /**
     * Returns attribute for uInt.
     *
     * @return attribute for uInt
     */
    public JavaAttributeInfo getUIntAttribute() {
        return uIntAttribute;
    }

    /**
     * Sets attribute for uInt.
     *
     * @param uIntAttribute attribute for uInt
     */
    private void setUIntAttribute(JavaAttributeInfo uIntAttribute) {
        this.uIntAttribute = uIntAttribute;
    }

    /**
     * Returns attribute for uLong.
     *
     * @return attribute for uLong
     */
    public JavaAttributeInfo getULongAttribute() {
        return uLongAttribute;
    }

    /**
     * Sets attribute for uLong.
     *
     * @param uLongAttribute attribute for uLong
     */
    private void setULongAttribute(JavaAttributeInfo uLongAttribute) {
        this.uLongAttribute = uLongAttribute;
    }
}
