/*
 * 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.utils.builtindatatype.YangDataTypes;
import org.onosproject.yangutils.translator.exception.TranslatorException;
import org.onosproject.yangutils.translator.tojava.javamodel.YangJavaTypeTranslator;
import org.onosproject.yangutils.utils.io.YangPluginConfig;

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(JavaFileInfoTranslator 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)));

            // In case if data type is binary, MoreObjects is not required and should be removed.
            if (curNode instanceof YangTypeHolder) {
                YangType yangType = ((YangTypeHolder) curNode).getTypeList().get(0);
                if (yangType.getDataType() == YangDataTypes.BINARY) {
                    imports.remove(getJavaImportData().getImportForToString());
                }
            }
            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;
    }
}
