/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 */
/**
 * This class is used to store the revision and timestamp of a column family
 * in a transaction.
 *
 */
/**
 * Autogenerated by Thrift Compiler (0.7.0)
 *
 * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 */
package org.apache.hcatalog.hbase.snapshot.transaction.thrift;

import java.util.Map;
import java.util.HashMap;
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.Collections;
import java.util.BitSet;

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

    private static final org.apache.thrift.protocol.TField REVISION_FIELD_DESC = new org.apache.thrift.protocol.TField("revision", org.apache.thrift.protocol.TType.I64, (short) 1);
    private static final org.apache.thrift.protocol.TField TIMESTAMP_FIELD_DESC = new org.apache.thrift.protocol.TField("timestamp", org.apache.thrift.protocol.TType.I64, (short) 2);

    public long revision; // required
    public long timestamp; // 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 {
        REVISION((short) 1, "revision"),
        TIMESTAMP((short) 2, "timestamp");

        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: // REVISION
                return REVISION;
            case 2: // TIMESTAMP
                return TIMESTAMP;
            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
    private static final int __REVISION_ISSET_ID = 0;
    private static final int __TIMESTAMP_ISSET_ID = 1;
    private BitSet __isset_bit_vector = new BitSet(2);

    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.REVISION, new org.apache.thrift.meta_data.FieldMetaData("revision", org.apache.thrift.TFieldRequirementType.DEFAULT,
            new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64)));
        tmpMap.put(_Fields.TIMESTAMP, new org.apache.thrift.meta_data.FieldMetaData("timestamp", org.apache.thrift.TFieldRequirementType.DEFAULT,
            new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64)));
        metaDataMap = Collections.unmodifiableMap(tmpMap);
        org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(StoreFamilyRevision.class, metaDataMap);
    }

    public StoreFamilyRevision() {
    }

    public StoreFamilyRevision(
        long revision,
        long timestamp) {
        this();
        this.revision = revision;
        setRevisionIsSet(true);
        this.timestamp = timestamp;
        setTimestampIsSet(true);
    }

    /**
     * Performs a deep copy on <i>other</i>.
     */
    public StoreFamilyRevision(StoreFamilyRevision other) {
        __isset_bit_vector.clear();
        __isset_bit_vector.or(other.__isset_bit_vector);
        this.revision = other.revision;
        this.timestamp = other.timestamp;
    }

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

    @Override
    public void clear() {
        setRevisionIsSet(false);
        this.revision = 0;
        setTimestampIsSet(false);
        this.timestamp = 0;
    }

    public long getRevision() {
        return this.revision;
    }

    public StoreFamilyRevision setRevision(long revision) {
        this.revision = revision;
        setRevisionIsSet(true);
        return this;
    }

    public void unsetRevision() {
        __isset_bit_vector.clear(__REVISION_ISSET_ID);
    }

    /** Returns true if field revision is set (has been assigned a value) and false otherwise */
    public boolean isSetRevision() {
        return __isset_bit_vector.get(__REVISION_ISSET_ID);
    }

    public void setRevisionIsSet(boolean value) {
        __isset_bit_vector.set(__REVISION_ISSET_ID, value);
    }

    public long getTimestamp() {
        return this.timestamp;
    }

    public StoreFamilyRevision setTimestamp(long timestamp) {
        this.timestamp = timestamp;
        setTimestampIsSet(true);
        return this;
    }

    public void unsetTimestamp() {
        __isset_bit_vector.clear(__TIMESTAMP_ISSET_ID);
    }

    /** Returns true if field timestamp is set (has been assigned a value) and false otherwise */
    public boolean isSetTimestamp() {
        return __isset_bit_vector.get(__TIMESTAMP_ISSET_ID);
    }

    public void setTimestampIsSet(boolean value) {
        __isset_bit_vector.set(__TIMESTAMP_ISSET_ID, value);
    }

    public void setFieldValue(_Fields field, Object value) {
        switch (field) {
        case REVISION:
            if (value == null) {
                unsetRevision();
            } else {
                setRevision((Long) value);
            }
            break;

        case TIMESTAMP:
            if (value == null) {
                unsetTimestamp();
            } else {
                setTimestamp((Long) value);
            }
            break;

        }
    }

    public Object getFieldValue(_Fields field) {
        switch (field) {
        case REVISION:
            return Long.valueOf(getRevision());

        case TIMESTAMP:
            return Long.valueOf(getTimestamp());

        }
        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 REVISION:
            return isSetRevision();
        case TIMESTAMP:
            return isSetTimestamp();
        }
        throw new IllegalStateException();
    }

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

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

        boolean this_present_revision = true;
        boolean that_present_revision = true;
        if (this_present_revision || that_present_revision) {
            if (!(this_present_revision && that_present_revision))
                return false;
            if (this.revision != that.revision)
                return false;
        }

        boolean this_present_timestamp = true;
        boolean that_present_timestamp = true;
        if (this_present_timestamp || that_present_timestamp) {
            if (!(this_present_timestamp && that_present_timestamp))
                return false;
            if (this.timestamp != that.timestamp)
                return false;
        }

        return true;
    }

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

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

        int lastComparison = 0;
        StoreFamilyRevision typedOther = (StoreFamilyRevision) other;

        lastComparison = Boolean.valueOf(isSetRevision()).compareTo(typedOther.isSetRevision());
        if (lastComparison != 0) {
            return lastComparison;
        }
        if (isSetRevision()) {
            lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.revision, typedOther.revision);
            if (lastComparison != 0) {
                return lastComparison;
            }
        }
        lastComparison = Boolean.valueOf(isSetTimestamp()).compareTo(typedOther.isSetTimestamp());
        if (lastComparison != 0) {
            return lastComparison;
        }
        if (isSetTimestamp()) {
            lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.timestamp, typedOther.timestamp);
            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 {
        org.apache.thrift.protocol.TField field;
        iprot.readStructBegin();
        while (true) {
            field = iprot.readFieldBegin();
            if (field.type == org.apache.thrift.protocol.TType.STOP) {
                break;
            }
            switch (field.id) {
            case 1: // REVISION
                if (field.type == org.apache.thrift.protocol.TType.I64) {
                    this.revision = iprot.readI64();
                    setRevisionIsSet(true);
                } else {
                    org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
                }
                break;
            case 2: // TIMESTAMP
                if (field.type == org.apache.thrift.protocol.TType.I64) {
                    this.timestamp = iprot.readI64();
                    setTimestampIsSet(true);
                } else {
                    org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
                }
                break;
            default:
                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, field.type);
            }
            iprot.readFieldEnd();
        }
        iprot.readStructEnd();

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

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

        oprot.writeStructBegin(STRUCT_DESC);
        oprot.writeFieldBegin(REVISION_FIELD_DESC);
        oprot.writeI64(this.revision);
        oprot.writeFieldEnd();
        oprot.writeFieldBegin(TIMESTAMP_FIELD_DESC);
        oprot.writeI64(this.timestamp);
        oprot.writeFieldEnd();
        oprot.writeFieldStop();
        oprot.writeStructEnd();
    }

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

        sb.append("revision:");
        sb.append(this.revision);
        first = false;
        if (!first) sb.append(", ");
        sb.append("timestamp:");
        sb.append(this.timestamp);
        first = false;
        sb.append(")");
        return sb.toString();
    }

    public void validate() throws org.apache.thrift.TException {
        // check for required fields
    }

    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 {
            // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
            __isset_bit_vector = new BitSet(1);
            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);
        }
    }

}

