/**
 * Autogenerated by Thrift Compiler (0.9.1)
 *
 * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 *  @generated
 */
package org.apache.airavata.datacat.models.Messaging;

import org.apache.thrift.scheme.IScheme;
import org.apache.thrift.scheme.SchemeFactory;
import org.apache.thrift.scheme.StandardScheme;

import org.apache.thrift.scheme.TupleScheme;
import org.apache.thrift.protocol.TTupleProtocol;
import org.apache.thrift.protocol.TProtocolException;
import org.apache.thrift.EncodingUtils;
import org.apache.thrift.TException;
import org.apache.thrift.async.AsyncMethodCallback;
import org.apache.thrift.server.AbstractNonblockingServer.*;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
import java.util.EnumMap;
import java.util.Set;
import java.util.HashSet;
import java.util.EnumSet;
import java.util.Collections;
import java.util.BitSet;
import java.nio.ByteBuffer;
import java.util.Arrays;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ExperimentOutputParsedEvent implements org.apache.thrift.TBase<ExperimentOutputParsedEvent, ExperimentOutputParsedEvent._Fields>, java.io.Serializable, Cloneable, Comparable<ExperimentOutputParsedEvent> {
    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("ExperimentOutputParsedEvent");

    private static final org.apache.thrift.protocol.TField EXPERIMENT_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("experimentId", org.apache.thrift.protocol.TType.STRING, (short)1);
    private static final org.apache.thrift.protocol.TField DOCUMENT_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("documentID", org.apache.thrift.protocol.TType.STRING, (short)2);
    private static final org.apache.thrift.protocol.TField STATUS_FIELD_DESC = new org.apache.thrift.protocol.TField("status", org.apache.thrift.protocol.TType.STRING, (short)3);

    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
    static {
        schemes.put(StandardScheme.class, new ExperimentOutputParsedEventStandardSchemeFactory());
        schemes.put(TupleScheme.class, new ExperimentOutputParsedEventTupleSchemeFactory());
    }

    public String experimentId; // required
    public String documentID; // required
    public String status; // required

    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
        EXPERIMENT_ID((short)1, "experimentId"),
        DOCUMENT_ID((short)2, "documentID"),
        STATUS((short)3, "status");

        private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

        static {
            for (_Fields field : EnumSet.allOf(_Fields.class)) {
                byName.put(field.getFieldName(), field);
            }
        }

        /**
         * Find the _Fields constant that matches fieldId, or null if its not found.
         */
        public static _Fields findByThriftId(int fieldId) {
            switch(fieldId) {
                case 1: // EXPERIMENT_ID
                    return EXPERIMENT_ID;
                case 2: // DOCUMENT_ID
                    return DOCUMENT_ID;
                case 3: // STATUS
                    return STATUS;
                default:
                    return null;
            }
        }

        /**
         * Find the _Fields constant that matches fieldId, throwing an exception
         * if it is not found.
         */
        public static _Fields findByThriftIdOrThrow(int fieldId) {
            _Fields fields = findByThriftId(fieldId);
            if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
            return fields;
        }

        /**
         * Find the _Fields constant that matches name, or null if its not found.
         */
        public static _Fields findByName(String name) {
            return byName.get(name);
        }

        private final short _thriftId;
        private final String _fieldName;

        _Fields(short thriftId, String fieldName) {
            _thriftId = thriftId;
            _fieldName = fieldName;
        }

        public short getThriftFieldId() {
            return _thriftId;
        }

        public String getFieldName() {
            return _fieldName;
        }
    }

    // isset id assignments
    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
    static {
        Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
        tmpMap.put(_Fields.EXPERIMENT_ID, new org.apache.thrift.meta_data.FieldMetaData("experimentId", org.apache.thrift.TFieldRequirementType.REQUIRED,
                new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
        tmpMap.put(_Fields.DOCUMENT_ID, new org.apache.thrift.meta_data.FieldMetaData("documentID", org.apache.thrift.TFieldRequirementType.REQUIRED,
                new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
        tmpMap.put(_Fields.STATUS, new org.apache.thrift.meta_data.FieldMetaData("status", org.apache.thrift.TFieldRequirementType.REQUIRED,
                new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
        metaDataMap = Collections.unmodifiableMap(tmpMap);
        org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(ExperimentOutputParsedEvent.class, metaDataMap);
    }

    public ExperimentOutputParsedEvent() {
    }

    public ExperimentOutputParsedEvent(
            String experimentId,
            String documentID,
            String status)
    {
        this();
        this.experimentId = experimentId;
        this.documentID = documentID;
        this.status = status;
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public ExperimentOutputParsedEvent(ExperimentOutputParsedEvent other) {
        if (other.isSetExperimentId()) {
            this.experimentId = other.experimentId;
        }
        if (other.isSetDocumentID()) {
            this.documentID = other.documentID;
        }
        if (other.isSetStatus()) {
            this.status = other.status;
        }
    }

    public ExperimentOutputParsedEvent deepCopy() {
        return new ExperimentOutputParsedEvent(this);
    }

    @Override
    public void clear() {
        this.experimentId = null;
        this.documentID = null;
        this.status = null;
    }

    public String getExperimentId() {
        return this.experimentId;
    }

    public ExperimentOutputParsedEvent setExperimentId(String experimentId) {
        this.experimentId = experimentId;
        return this;
    }

    public void unsetExperimentId() {
        this.experimentId = null;
    }

    /** Returns true if field experimentId is set (has been assigned a value) and false otherwise */
    public boolean isSetExperimentId() {
        return this.experimentId != null;
    }

    public void setExperimentIdIsSet(boolean value) {
        if (!value) {
            this.experimentId = null;
        }
    }

    public String getDocumentID() {
        return this.documentID;
    }

    public ExperimentOutputParsedEvent setDocumentID(String documentID) {
        this.documentID = documentID;
        return this;
    }

    public void unsetDocumentID() {
        this.documentID = null;
    }

    /** Returns true if field documentID is set (has been assigned a value) and false otherwise */
    public boolean isSetDocumentID() {
        return this.documentID != null;
    }

    public void setDocumentIDIsSet(boolean value) {
        if (!value) {
            this.documentID = null;
        }
    }

    public String getStatus() {
        return this.status;
    }

    public ExperimentOutputParsedEvent setStatus(String status) {
        this.status = status;
        return this;
    }

    public void unsetStatus() {
        this.status = null;
    }

    /** Returns true if field status is set (has been assigned a value) and false otherwise */
    public boolean isSetStatus() {
        return this.status != null;
    }

    public void setStatusIsSet(boolean value) {
        if (!value) {
            this.status = null;
        }
    }

    public void setFieldValue(_Fields field, Object value) {
        switch (field) {
            case EXPERIMENT_ID:
                if (value == null) {
                    unsetExperimentId();
                } else {
                    setExperimentId((String)value);
                }
                break;

            case DOCUMENT_ID:
                if (value == null) {
                    unsetDocumentID();
                } else {
                    setDocumentID((String)value);
                }
                break;

            case STATUS:
                if (value == null) {
                    unsetStatus();
                } else {
                    setStatus((String)value);
                }
                break;

        }
    }

    public Object getFieldValue(_Fields field) {
        switch (field) {
            case EXPERIMENT_ID:
                return getExperimentId();

            case DOCUMENT_ID:
                return getDocumentID();

            case STATUS:
                return getStatus();

        }
        throw new IllegalStateException();
    }

    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
    public boolean isSet(_Fields field) {
        if (field == null) {
            throw new IllegalArgumentException();
        }

        switch (field) {
            case EXPERIMENT_ID:
                return isSetExperimentId();
            case DOCUMENT_ID:
                return isSetDocumentID();
            case STATUS:
                return isSetStatus();
        }
        throw new IllegalStateException();
    }

    @Override
    public boolean equals(Object that) {
        if (that == null)
            return false;
        if (that instanceof ExperimentOutputParsedEvent)
            return this.equals((ExperimentOutputParsedEvent)that);
        return false;
    }

    public boolean equals(ExperimentOutputParsedEvent that) {
        if (that == null)
            return false;

        boolean this_present_experimentId = true && this.isSetExperimentId();
        boolean that_present_experimentId = true && that.isSetExperimentId();
        if (this_present_experimentId || that_present_experimentId) {
            if (!(this_present_experimentId && that_present_experimentId))
                return false;
            if (!this.experimentId.equals(that.experimentId))
                return false;
        }

        boolean this_present_documentID = true && this.isSetDocumentID();
        boolean that_present_documentID = true && that.isSetDocumentID();
        if (this_present_documentID || that_present_documentID) {
            if (!(this_present_documentID && that_present_documentID))
                return false;
            if (!this.documentID.equals(that.documentID))
                return false;
        }

        boolean this_present_status = true && this.isSetStatus();
        boolean that_present_status = true && that.isSetStatus();
        if (this_present_status || that_present_status) {
            if (!(this_present_status && that_present_status))
                return false;
            if (!this.status.equals(that.status))
                return false;
        }

        return true;
    }

    @Override
    public int hashCode() {
        return 0;
    }

    @Override
    public int compareTo(ExperimentOutputParsedEvent other) {
        if (!getClass().equals(other.getClass())) {
            return getClass().getName().compareTo(other.getClass().getName());
        }

        int lastComparison = 0;

        lastComparison = Boolean.valueOf(isSetExperimentId()).compareTo(other.isSetExperimentId());
        if (lastComparison != 0) {
            return lastComparison;
        }
        if (isSetExperimentId()) {
            lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.experimentId, other.experimentId);
            if (lastComparison != 0) {
                return lastComparison;
            }
        }
        lastComparison = Boolean.valueOf(isSetDocumentID()).compareTo(other.isSetDocumentID());
        if (lastComparison != 0) {
            return lastComparison;
        }
        if (isSetDocumentID()) {
            lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.documentID, other.documentID);
            if (lastComparison != 0) {
                return lastComparison;
            }
        }
        lastComparison = Boolean.valueOf(isSetStatus()).compareTo(other.isSetStatus());
        if (lastComparison != 0) {
            return lastComparison;
        }
        if (isSetStatus()) {
            lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.status, other.status);
            if (lastComparison != 0) {
                return lastComparison;
            }
        }
        return 0;
    }

    public _Fields fieldForId(int fieldId) {
        return _Fields.findByThriftId(fieldId);
    }

    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
        schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
        schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder("ExperimentOutputParsedEvent(");
        boolean first = true;

        sb.append("experimentId:");
        if (this.experimentId == null) {
            sb.append("null");
        } else {
            sb.append(this.experimentId);
        }
        first = false;
        if (!first) sb.append(", ");
        sb.append("documentID:");
        if (this.documentID == null) {
            sb.append("null");
        } else {
            sb.append(this.documentID);
        }
        first = false;
        if (!first) sb.append(", ");
        sb.append("status:");
        if (this.status == null) {
            sb.append("null");
        } else {
            sb.append(this.status);
        }
        first = false;
        sb.append(")");
        return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
        // check for required fields
        if (experimentId == null) {
            throw new org.apache.thrift.protocol.TProtocolException("Required field 'experimentId' was not present! Struct: " + toString());
        }
        if (documentID == null) {
            throw new org.apache.thrift.protocol.TProtocolException("Required field 'documentID' was not present! Struct: " + toString());
        }
        if (status == null) {
            throw new org.apache.thrift.protocol.TProtocolException("Required field 'status' was not present! Struct: " + toString());
        }
        // check for sub-struct validity
    }

    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
        try {
            write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
        } catch (org.apache.thrift.TException te) {
            throw new java.io.IOException(te);
        }
    }

    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
        try {
            read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
        } catch (org.apache.thrift.TException te) {
            throw new java.io.IOException(te);
        }
    }

    private static class ExperimentOutputParsedEventStandardSchemeFactory implements SchemeFactory {
        public ExperimentOutputParsedEventStandardScheme getScheme() {
            return new ExperimentOutputParsedEventStandardScheme();
        }
    }

    private static class ExperimentOutputParsedEventStandardScheme extends StandardScheme<ExperimentOutputParsedEvent> {

        public void read(org.apache.thrift.protocol.TProtocol iprot, ExperimentOutputParsedEvent struct) throws org.apache.thrift.TException {
            org.apache.thrift.protocol.TField schemeField;
            iprot.readStructBegin();
            while (true)
            {
                schemeField = iprot.readFieldBegin();
                if (schemeField.type == org.apache.thrift.protocol.TType.STOP) {
                    break;
                }
                switch (schemeField.id) {
                    case 1: // EXPERIMENT_ID
                        if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                            struct.experimentId = iprot.readString();
                            struct.setExperimentIdIsSet(true);
                        } else {
                            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
                        }
                        break;
                    case 2: // DOCUMENT_ID
                        if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                            struct.documentID = iprot.readString();
                            struct.setDocumentIDIsSet(true);
                        } else {
                            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
                        }
                        break;
                    case 3: // STATUS
                        if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
                            struct.status = iprot.readString();
                            struct.setStatusIsSet(true);
                        } else {
                            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
                        }
                        break;
                    default:
                        org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
                }
                iprot.readFieldEnd();
            }
            iprot.readStructEnd();

            // check for required fields of primitive type, which can't be checked in the validate method
            struct.validate();
        }

        public void write(org.apache.thrift.protocol.TProtocol oprot, ExperimentOutputParsedEvent struct) throws org.apache.thrift.TException {
            struct.validate();

            oprot.writeStructBegin(STRUCT_DESC);
            if (struct.experimentId != null) {
                oprot.writeFieldBegin(EXPERIMENT_ID_FIELD_DESC);
                oprot.writeString(struct.experimentId);
                oprot.writeFieldEnd();
            }
            if (struct.documentID != null) {
                oprot.writeFieldBegin(DOCUMENT_ID_FIELD_DESC);
                oprot.writeString(struct.documentID);
                oprot.writeFieldEnd();
            }
            if (struct.status != null) {
                oprot.writeFieldBegin(STATUS_FIELD_DESC);
                oprot.writeString(struct.status);
                oprot.writeFieldEnd();
            }
            oprot.writeFieldStop();
            oprot.writeStructEnd();
        }

    }

    private static class ExperimentOutputParsedEventTupleSchemeFactory implements SchemeFactory {
        public ExperimentOutputParsedEventTupleScheme getScheme() {
            return new ExperimentOutputParsedEventTupleScheme();
        }
    }

    private static class ExperimentOutputParsedEventTupleScheme extends TupleScheme<ExperimentOutputParsedEvent> {

        @Override
        public void write(org.apache.thrift.protocol.TProtocol prot, ExperimentOutputParsedEvent struct) throws org.apache.thrift.TException {
            TTupleProtocol oprot = (TTupleProtocol) prot;
            oprot.writeString(struct.experimentId);
            oprot.writeString(struct.documentID);
            oprot.writeString(struct.status);
        }

        @Override
        public void read(org.apache.thrift.protocol.TProtocol prot, ExperimentOutputParsedEvent struct) throws org.apache.thrift.TException {
            TTupleProtocol iprot = (TTupleProtocol) prot;
            struct.experimentId = iprot.readString();
            struct.setExperimentIdIsSet(true);
            struct.documentID = iprot.readString();
            struct.setDocumentIDIsSet(true);
            struct.status = iprot.readString();
            struct.setStatusIsSet(true);
        }
    }

}

