/**
 * 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.
 */

/**
 * Autogenerated by Thrift Compiler (0.18.1)
 *
 * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 *  @generated
 */
package org.apache.airavata.model.dbevent;

@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
@javax.annotation.Generated(value = "Autogenerated by Thrift Compiler (0.18.1)")
public class DBEventPublisherContext implements org.apache.thrift.TBase<DBEventPublisherContext, DBEventPublisherContext._Fields>, java.io.Serializable, Cloneable, Comparable<DBEventPublisherContext> {
  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("DBEventPublisherContext");

  private static final org.apache.thrift.protocol.TField CRUD_TYPE_FIELD_DESC = new org.apache.thrift.protocol.TField("crudType", org.apache.thrift.protocol.TType.I32, (short)1);
  private static final org.apache.thrift.protocol.TField ENTITY_TYPE_FIELD_DESC = new org.apache.thrift.protocol.TField("entityType", org.apache.thrift.protocol.TType.I32, (short)2);
  private static final org.apache.thrift.protocol.TField ENTITY_DATA_MODEL_FIELD_DESC = new org.apache.thrift.protocol.TField("entityDataModel", org.apache.thrift.protocol.TType.STRING, (short)3);

  private static final org.apache.thrift.scheme.SchemeFactory STANDARD_SCHEME_FACTORY = new DBEventPublisherContextStandardSchemeFactory();
  private static final org.apache.thrift.scheme.SchemeFactory TUPLE_SCHEME_FACTORY = new DBEventPublisherContextTupleSchemeFactory();

  private @org.apache.thrift.annotation.Nullable CrudType crudType; // required
  private @org.apache.thrift.annotation.Nullable EntityType entityType; // required
  private @org.apache.thrift.annotation.Nullable java.nio.ByteBuffer entityDataModel; // 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 {
    /**
     * 
     * @see CrudType
     */
    CRUD_TYPE((short)1, "crudType"),
    /**
     * 
     * @see EntityType
     */
    ENTITY_TYPE((short)2, "entityType"),
    ENTITY_DATA_MODEL((short)3, "entityDataModel");

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

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

    /**
     * Find the _Fields constant that matches fieldId, or null if its not found.
     */
    @org.apache.thrift.annotation.Nullable
    public static _Fields findByThriftId(int fieldId) {
      switch(fieldId) {
        case 1: // CRUD_TYPE
          return CRUD_TYPE;
        case 2: // ENTITY_TYPE
          return ENTITY_TYPE;
        case 3: // ENTITY_DATA_MODEL
          return ENTITY_DATA_MODEL;
        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 java.lang.IllegalArgumentException("Field " + fieldId + " doesn't exist!");
      return fields;
    }

    /**
     * Find the _Fields constant that matches name, or null if its not found.
     */
    @org.apache.thrift.annotation.Nullable
    public static _Fields findByName(java.lang.String name) {
      return byName.get(name);
    }

    private final short _thriftId;
    private final java.lang.String _fieldName;

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

    @Override
    public short getThriftFieldId() {
      return _thriftId;
    }

    @Override
    public java.lang.String getFieldName() {
      return _fieldName;
    }
  }

  // isset id assignments
  public static final java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
  static {
    java.util.Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new java.util.EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
    tmpMap.put(_Fields.CRUD_TYPE, new org.apache.thrift.meta_data.FieldMetaData("crudType", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, CrudType.class)));
    tmpMap.put(_Fields.ENTITY_TYPE, new org.apache.thrift.meta_data.FieldMetaData("entityType", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, EntityType.class)));
    tmpMap.put(_Fields.ENTITY_DATA_MODEL, new org.apache.thrift.meta_data.FieldMetaData("entityDataModel", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING        , true)));
    metaDataMap = java.util.Collections.unmodifiableMap(tmpMap);
    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(DBEventPublisherContext.class, metaDataMap);
  }

  public DBEventPublisherContext() {
  }

  public DBEventPublisherContext(
    CrudType crudType,
    EntityType entityType,
    java.nio.ByteBuffer entityDataModel)
  {
    this();
    this.crudType = crudType;
    this.entityType = entityType;
    this.entityDataModel = org.apache.thrift.TBaseHelper.copyBinary(entityDataModel);
  }

  /**
   * Performs a deep copy on <i>other</i>.
   */
  public DBEventPublisherContext(DBEventPublisherContext other) {
    if (other.isSetCrudType()) {
      this.crudType = other.crudType;
    }
    if (other.isSetEntityType()) {
      this.entityType = other.entityType;
    }
    if (other.isSetEntityDataModel()) {
      this.entityDataModel = org.apache.thrift.TBaseHelper.copyBinary(other.entityDataModel);
    }
  }

  @Override
  public DBEventPublisherContext deepCopy() {
    return new DBEventPublisherContext(this);
  }

  @Override
  public void clear() {
    this.crudType = null;
    this.entityType = null;
    this.entityDataModel = null;
  }

  /**
   * 
   * @see CrudType
   */
  @org.apache.thrift.annotation.Nullable
  public CrudType getCrudType() {
    return this.crudType;
  }

  /**
   * 
   * @see CrudType
   */
  public void setCrudType(@org.apache.thrift.annotation.Nullable CrudType crudType) {
    this.crudType = crudType;
  }

  public void unsetCrudType() {
    this.crudType = null;
  }

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

  public void setCrudTypeIsSet(boolean value) {
    if (!value) {
      this.crudType = null;
    }
  }

  /**
   * 
   * @see EntityType
   */
  @org.apache.thrift.annotation.Nullable
  public EntityType getEntityType() {
    return this.entityType;
  }

  /**
   * 
   * @see EntityType
   */
  public void setEntityType(@org.apache.thrift.annotation.Nullable EntityType entityType) {
    this.entityType = entityType;
  }

  public void unsetEntityType() {
    this.entityType = null;
  }

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

  public void setEntityTypeIsSet(boolean value) {
    if (!value) {
      this.entityType = null;
    }
  }

  public byte[] getEntityDataModel() {
    setEntityDataModel(org.apache.thrift.TBaseHelper.rightSize(entityDataModel));
    return entityDataModel == null ? null : entityDataModel.array();
  }

  public java.nio.ByteBuffer bufferForEntityDataModel() {
    return org.apache.thrift.TBaseHelper.copyBinary(entityDataModel);
  }

  public void setEntityDataModel(byte[] entityDataModel) {
    this.entityDataModel = entityDataModel == null ? (java.nio.ByteBuffer)null   : java.nio.ByteBuffer.wrap(entityDataModel.clone());
  }

  public void setEntityDataModel(@org.apache.thrift.annotation.Nullable java.nio.ByteBuffer entityDataModel) {
    this.entityDataModel = org.apache.thrift.TBaseHelper.copyBinary(entityDataModel);
  }

  public void unsetEntityDataModel() {
    this.entityDataModel = null;
  }

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

  public void setEntityDataModelIsSet(boolean value) {
    if (!value) {
      this.entityDataModel = null;
    }
  }

  @Override
  public void setFieldValue(_Fields field, @org.apache.thrift.annotation.Nullable java.lang.Object value) {
    switch (field) {
    case CRUD_TYPE:
      if (value == null) {
        unsetCrudType();
      } else {
        setCrudType((CrudType)value);
      }
      break;

    case ENTITY_TYPE:
      if (value == null) {
        unsetEntityType();
      } else {
        setEntityType((EntityType)value);
      }
      break;

    case ENTITY_DATA_MODEL:
      if (value == null) {
        unsetEntityDataModel();
      } else {
        if (value instanceof byte[]) {
          setEntityDataModel((byte[])value);
        } else {
          setEntityDataModel((java.nio.ByteBuffer)value);
        }
      }
      break;

    }
  }

  @org.apache.thrift.annotation.Nullable
  @Override
  public java.lang.Object getFieldValue(_Fields field) {
    switch (field) {
    case CRUD_TYPE:
      return getCrudType();

    case ENTITY_TYPE:
      return getEntityType();

    case ENTITY_DATA_MODEL:
      return getEntityDataModel();

    }
    throw new java.lang.IllegalStateException();
  }

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

    switch (field) {
    case CRUD_TYPE:
      return isSetCrudType();
    case ENTITY_TYPE:
      return isSetEntityType();
    case ENTITY_DATA_MODEL:
      return isSetEntityDataModel();
    }
    throw new java.lang.IllegalStateException();
  }

  @Override
  public boolean equals(java.lang.Object that) {
    if (that instanceof DBEventPublisherContext)
      return this.equals((DBEventPublisherContext)that);
    return false;
  }

  public boolean equals(DBEventPublisherContext that) {
    if (that == null)
      return false;
    if (this == that)
      return true;

    boolean this_present_crudType = true && this.isSetCrudType();
    boolean that_present_crudType = true && that.isSetCrudType();
    if (this_present_crudType || that_present_crudType) {
      if (!(this_present_crudType && that_present_crudType))
        return false;
      if (!this.crudType.equals(that.crudType))
        return false;
    }

    boolean this_present_entityType = true && this.isSetEntityType();
    boolean that_present_entityType = true && that.isSetEntityType();
    if (this_present_entityType || that_present_entityType) {
      if (!(this_present_entityType && that_present_entityType))
        return false;
      if (!this.entityType.equals(that.entityType))
        return false;
    }

    boolean this_present_entityDataModel = true && this.isSetEntityDataModel();
    boolean that_present_entityDataModel = true && that.isSetEntityDataModel();
    if (this_present_entityDataModel || that_present_entityDataModel) {
      if (!(this_present_entityDataModel && that_present_entityDataModel))
        return false;
      if (!this.entityDataModel.equals(that.entityDataModel))
        return false;
    }

    return true;
  }

  @Override
  public int hashCode() {
    int hashCode = 1;

    hashCode = hashCode * 8191 + ((isSetCrudType()) ? 131071 : 524287);
    if (isSetCrudType())
      hashCode = hashCode * 8191 + crudType.getValue();

    hashCode = hashCode * 8191 + ((isSetEntityType()) ? 131071 : 524287);
    if (isSetEntityType())
      hashCode = hashCode * 8191 + entityType.getValue();

    hashCode = hashCode * 8191 + ((isSetEntityDataModel()) ? 131071 : 524287);
    if (isSetEntityDataModel())
      hashCode = hashCode * 8191 + entityDataModel.hashCode();

    return hashCode;
  }

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

    int lastComparison = 0;

    lastComparison = java.lang.Boolean.compare(isSetCrudType(), other.isSetCrudType());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetCrudType()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.crudType, other.crudType);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetEntityType(), other.isSetEntityType());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetEntityType()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.entityType, other.entityType);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = java.lang.Boolean.compare(isSetEntityDataModel(), other.isSetEntityDataModel());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetEntityDataModel()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.entityDataModel, other.entityDataModel);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    return 0;
  }

  @org.apache.thrift.annotation.Nullable
  @Override
  public _Fields fieldForId(int fieldId) {
    return _Fields.findByThriftId(fieldId);
  }

  @Override
  public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
    scheme(iprot).read(iprot, this);
  }

  @Override
  public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
    scheme(oprot).write(oprot, this);
  }

  @Override
  public java.lang.String toString() {
    java.lang.StringBuilder sb = new java.lang.StringBuilder("DBEventPublisherContext(");
    boolean first = true;

    sb.append("crudType:");
    if (this.crudType == null) {
      sb.append("null");
    } else {
      sb.append(this.crudType);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("entityType:");
    if (this.entityType == null) {
      sb.append("null");
    } else {
      sb.append(this.entityType);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("entityDataModel:");
    if (this.entityDataModel == null) {
      sb.append("null");
    } else {
      org.apache.thrift.TBaseHelper.toString(this.entityDataModel, sb);
    }
    first = false;
    sb.append(")");
    return sb.toString();
  }

  public void validate() throws org.apache.thrift.TException {
    // check for required fields
    if (!isSetCrudType()) {
      throw new org.apache.thrift.protocol.TProtocolException("Required field 'crudType' is unset! Struct:" + toString());
    }

    if (!isSetEntityType()) {
      throw new org.apache.thrift.protocol.TProtocolException("Required field 'entityType' is unset! Struct:" + toString());
    }

    if (!isSetEntityDataModel()) {
      throw new org.apache.thrift.protocol.TProtocolException("Required field 'entityDataModel' is unset! 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, java.lang.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 DBEventPublisherContextStandardSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
    @Override
    public DBEventPublisherContextStandardScheme getScheme() {
      return new DBEventPublisherContextStandardScheme();
    }
  }

  private static class DBEventPublisherContextStandardScheme extends org.apache.thrift.scheme.StandardScheme<DBEventPublisherContext> {

    @Override
    public void read(org.apache.thrift.protocol.TProtocol iprot, DBEventPublisherContext 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: // CRUD_TYPE
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.crudType = org.apache.airavata.model.dbevent.CrudType.findByValue(iprot.readI32());
              struct.setCrudTypeIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 2: // ENTITY_TYPE
            if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
              struct.entityType = org.apache.airavata.model.dbevent.EntityType.findByValue(iprot.readI32());
              struct.setEntityTypeIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 3: // ENTITY_DATA_MODEL
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.entityDataModel = iprot.readBinary();
              struct.setEntityDataModelIsSet(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();
      struct.validate();
    }

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

      oprot.writeStructBegin(STRUCT_DESC);
      if (struct.crudType != null) {
        oprot.writeFieldBegin(CRUD_TYPE_FIELD_DESC);
        oprot.writeI32(struct.crudType.getValue());
        oprot.writeFieldEnd();
      }
      if (struct.entityType != null) {
        oprot.writeFieldBegin(ENTITY_TYPE_FIELD_DESC);
        oprot.writeI32(struct.entityType.getValue());
        oprot.writeFieldEnd();
      }
      if (struct.entityDataModel != null) {
        oprot.writeFieldBegin(ENTITY_DATA_MODEL_FIELD_DESC);
        oprot.writeBinary(struct.entityDataModel);
        oprot.writeFieldEnd();
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

  }

  private static class DBEventPublisherContextTupleSchemeFactory implements org.apache.thrift.scheme.SchemeFactory {
    @Override
    public DBEventPublisherContextTupleScheme getScheme() {
      return new DBEventPublisherContextTupleScheme();
    }
  }

  private static class DBEventPublisherContextTupleScheme extends org.apache.thrift.scheme.TupleScheme<DBEventPublisherContext> {

    @Override
    public void write(org.apache.thrift.protocol.TProtocol prot, DBEventPublisherContext struct) throws org.apache.thrift.TException {
      org.apache.thrift.protocol.TTupleProtocol oprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
      oprot.writeI32(struct.crudType.getValue());
      oprot.writeI32(struct.entityType.getValue());
      oprot.writeBinary(struct.entityDataModel);
    }

    @Override
    public void read(org.apache.thrift.protocol.TProtocol prot, DBEventPublisherContext struct) throws org.apache.thrift.TException {
      org.apache.thrift.protocol.TTupleProtocol iprot = (org.apache.thrift.protocol.TTupleProtocol) prot;
      struct.crudType = org.apache.airavata.model.dbevent.CrudType.findByValue(iprot.readI32());
      struct.setCrudTypeIsSet(true);
      struct.entityType = org.apache.airavata.model.dbevent.EntityType.findByValue(iprot.readI32());
      struct.setEntityTypeIsSet(true);
      struct.entityDataModel = iprot.readBinary();
      struct.setEntityDataModelIsSet(true);
    }
  }

  private static <S extends org.apache.thrift.scheme.IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
    return (org.apache.thrift.scheme.StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
  }
}

