/**
 * Autogenerated by Thrift Compiler (0.9.3)
 *
 * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 *  @generated
 */
package org.apache.sentry.api.service.thrift;

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 javax.annotation.Generated;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked"})
/**
 * API that returns either all users or roles privileges found on the Sentry server.
 * 
 * The response returns a mapping object that maps the role or user name to the privileges
 * they have in the server. An empty set of privileges may be returned to each role or user
 * name. Null values are not returned.
 * 
 */
@Generated(value = "Autogenerated by Thrift Compiler (0.9.3)")
public class TSentryPrivilegesResponse implements org.apache.thrift.TBase<TSentryPrivilegesResponse, TSentryPrivilegesResponse._Fields>, java.io.Serializable, Cloneable, Comparable<TSentryPrivilegesResponse> {
  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("TSentryPrivilegesResponse");

  private static final org.apache.thrift.protocol.TField STATUS_FIELD_DESC = new org.apache.thrift.protocol.TField("status", org.apache.thrift.protocol.TType.STRUCT, (short)1);
  private static final org.apache.thrift.protocol.TField PRIVILEGES_MAP_FIELD_DESC = new org.apache.thrift.protocol.TField("privilegesMap", org.apache.thrift.protocol.TType.MAP, (short)2);

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

  private org.apache.sentry.service.thrift.TSentryResponseStatus status; // required
  private Map<String,Set<TSentryPrivilege>> privilegesMap; // 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 {
    STATUS((short)1, "status"),
    PRIVILEGES_MAP((short)2, "privilegesMap");

    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: // STATUS
          return STATUS;
        case 2: // PRIVILEGES_MAP
          return PRIVILEGES_MAP;
        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.STATUS, new org.apache.thrift.meta_data.FieldMetaData("status", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, org.apache.sentry.service.thrift.TSentryResponseStatus.class)));
    tmpMap.put(_Fields.PRIVILEGES_MAP, new org.apache.thrift.meta_data.FieldMetaData("privilegesMap", org.apache.thrift.TFieldRequirementType.REQUIRED, 
        new org.apache.thrift.meta_data.MapMetaData(org.apache.thrift.protocol.TType.MAP, 
            new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING), 
            new org.apache.thrift.meta_data.SetMetaData(org.apache.thrift.protocol.TType.SET, 
                new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, TSentryPrivilege.class)))));
    metaDataMap = Collections.unmodifiableMap(tmpMap);
    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(TSentryPrivilegesResponse.class, metaDataMap);
  }

  public TSentryPrivilegesResponse() {
  }

  public TSentryPrivilegesResponse(
    org.apache.sentry.service.thrift.TSentryResponseStatus status,
    Map<String,Set<TSentryPrivilege>> privilegesMap)
  {
    this();
    this.status = status;
    this.privilegesMap = privilegesMap;
  }

  /**
   * Performs a deep copy on <i>other</i>.
   */
  public TSentryPrivilegesResponse(TSentryPrivilegesResponse other) {
    if (other.isSetStatus()) {
      this.status = new org.apache.sentry.service.thrift.TSentryResponseStatus(other.status);
    }
    if (other.isSetPrivilegesMap()) {
      Map<String,Set<TSentryPrivilege>> __this__privilegesMap = new HashMap<String,Set<TSentryPrivilege>>(other.privilegesMap.size());
      for (Map.Entry<String, Set<TSentryPrivilege>> other_element : other.privilegesMap.entrySet()) {

        String other_element_key = other_element.getKey();
        Set<TSentryPrivilege> other_element_value = other_element.getValue();

        String __this__privilegesMap_copy_key = other_element_key;

        Set<TSentryPrivilege> __this__privilegesMap_copy_value = new HashSet<TSentryPrivilege>(other_element_value.size());
        for (TSentryPrivilege other_element_value_element : other_element_value) {
          __this__privilegesMap_copy_value.add(new TSentryPrivilege(other_element_value_element));
        }

        __this__privilegesMap.put(__this__privilegesMap_copy_key, __this__privilegesMap_copy_value);
      }
      this.privilegesMap = __this__privilegesMap;
    }
  }

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

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

  public org.apache.sentry.service.thrift.TSentryResponseStatus getStatus() {
    return this.status;
  }

  public void setStatus(org.apache.sentry.service.thrift.TSentryResponseStatus status) {
    this.status = status;
  }

  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 int getPrivilegesMapSize() {
    return (this.privilegesMap == null) ? 0 : this.privilegesMap.size();
  }

  public void putToPrivilegesMap(String key, Set<TSentryPrivilege> val) {
    if (this.privilegesMap == null) {
      this.privilegesMap = new HashMap<String,Set<TSentryPrivilege>>();
    }
    this.privilegesMap.put(key, val);
  }

  public Map<String,Set<TSentryPrivilege>> getPrivilegesMap() {
    return this.privilegesMap;
  }

  public void setPrivilegesMap(Map<String,Set<TSentryPrivilege>> privilegesMap) {
    this.privilegesMap = privilegesMap;
  }

  public void unsetPrivilegesMap() {
    this.privilegesMap = null;
  }

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

  public void setPrivilegesMapIsSet(boolean value) {
    if (!value) {
      this.privilegesMap = null;
    }
  }

  public void setFieldValue(_Fields field, Object value) {
    switch (field) {
    case STATUS:
      if (value == null) {
        unsetStatus();
      } else {
        setStatus((org.apache.sentry.service.thrift.TSentryResponseStatus)value);
      }
      break;

    case PRIVILEGES_MAP:
      if (value == null) {
        unsetPrivilegesMap();
      } else {
        setPrivilegesMap((Map<String,Set<TSentryPrivilege>>)value);
      }
      break;

    }
  }

  public Object getFieldValue(_Fields field) {
    switch (field) {
    case STATUS:
      return getStatus();

    case PRIVILEGES_MAP:
      return getPrivilegesMap();

    }
    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 STATUS:
      return isSetStatus();
    case PRIVILEGES_MAP:
      return isSetPrivilegesMap();
    }
    throw new IllegalStateException();
  }

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

  public boolean equals(TSentryPrivilegesResponse that) {
    if (that == null)
      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;
    }

    boolean this_present_privilegesMap = true && this.isSetPrivilegesMap();
    boolean that_present_privilegesMap = true && that.isSetPrivilegesMap();
    if (this_present_privilegesMap || that_present_privilegesMap) {
      if (!(this_present_privilegesMap && that_present_privilegesMap))
        return false;
      if (!this.privilegesMap.equals(that.privilegesMap))
        return false;
    }

    return true;
  }

  @Override
  public int hashCode() {
    List<Object> list = new ArrayList<Object>();

    boolean present_status = true && (isSetStatus());
    list.add(present_status);
    if (present_status)
      list.add(status);

    boolean present_privilegesMap = true && (isSetPrivilegesMap());
    list.add(present_privilegesMap);
    if (present_privilegesMap)
      list.add(privilegesMap);

    return list.hashCode();
  }

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

    int lastComparison = 0;

    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;
      }
    }
    lastComparison = Boolean.valueOf(isSetPrivilegesMap()).compareTo(other.isSetPrivilegesMap());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetPrivilegesMap()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.privilegesMap, other.privilegesMap);
      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("TSentryPrivilegesResponse(");
    boolean first = true;

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

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

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

    // check for sub-struct validity
    if (status != null) {
      status.validate();
    }
  }

  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 TSentryPrivilegesResponseStandardSchemeFactory implements SchemeFactory {
    public TSentryPrivilegesResponseStandardScheme getScheme() {
      return new TSentryPrivilegesResponseStandardScheme();
    }
  }

  private static class TSentryPrivilegesResponseStandardScheme extends StandardScheme<TSentryPrivilegesResponse> {

    public void read(org.apache.thrift.protocol.TProtocol iprot, TSentryPrivilegesResponse 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: // STATUS
            if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
              struct.status = new org.apache.sentry.service.thrift.TSentryResponseStatus();
              struct.status.read(iprot);
              struct.setStatusIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 2: // PRIVILEGES_MAP
            if (schemeField.type == org.apache.thrift.protocol.TType.MAP) {
              {
                org.apache.thrift.protocol.TMap _map236 = iprot.readMapBegin();
                struct.privilegesMap = new HashMap<String,Set<TSentryPrivilege>>(2*_map236.size);
                String _key237;
                Set<TSentryPrivilege> _val238;
                for (int _i239 = 0; _i239 < _map236.size; ++_i239)
                {
                  _key237 = iprot.readString();
                  {
                    org.apache.thrift.protocol.TSet _set240 = iprot.readSetBegin();
                    _val238 = new HashSet<TSentryPrivilege>(2*_set240.size);
                    TSentryPrivilege _elem241;
                    for (int _i242 = 0; _i242 < _set240.size; ++_i242)
                    {
                      _elem241 = new TSentryPrivilege();
                      _elem241.read(iprot);
                      _val238.add(_elem241);
                    }
                    iprot.readSetEnd();
                  }
                  struct.privilegesMap.put(_key237, _val238);
                }
                iprot.readMapEnd();
              }
              struct.setPrivilegesMapIsSet(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();
    }

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

      oprot.writeStructBegin(STRUCT_DESC);
      if (struct.status != null) {
        oprot.writeFieldBegin(STATUS_FIELD_DESC);
        struct.status.write(oprot);
        oprot.writeFieldEnd();
      }
      if (struct.privilegesMap != null) {
        oprot.writeFieldBegin(PRIVILEGES_MAP_FIELD_DESC);
        {
          oprot.writeMapBegin(new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.SET, struct.privilegesMap.size()));
          for (Map.Entry<String, Set<TSentryPrivilege>> _iter243 : struct.privilegesMap.entrySet())
          {
            oprot.writeString(_iter243.getKey());
            {
              oprot.writeSetBegin(new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRUCT, _iter243.getValue().size()));
              for (TSentryPrivilege _iter244 : _iter243.getValue())
              {
                _iter244.write(oprot);
              }
              oprot.writeSetEnd();
            }
          }
          oprot.writeMapEnd();
        }
        oprot.writeFieldEnd();
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

  }

  private static class TSentryPrivilegesResponseTupleSchemeFactory implements SchemeFactory {
    public TSentryPrivilegesResponseTupleScheme getScheme() {
      return new TSentryPrivilegesResponseTupleScheme();
    }
  }

  private static class TSentryPrivilegesResponseTupleScheme extends TupleScheme<TSentryPrivilegesResponse> {

    @Override
    public void write(org.apache.thrift.protocol.TProtocol prot, TSentryPrivilegesResponse struct) throws org.apache.thrift.TException {
      TTupleProtocol oprot = (TTupleProtocol) prot;
      struct.status.write(oprot);
      {
        oprot.writeI32(struct.privilegesMap.size());
        for (Map.Entry<String, Set<TSentryPrivilege>> _iter245 : struct.privilegesMap.entrySet())
        {
          oprot.writeString(_iter245.getKey());
          {
            oprot.writeI32(_iter245.getValue().size());
            for (TSentryPrivilege _iter246 : _iter245.getValue())
            {
              _iter246.write(oprot);
            }
          }
        }
      }
    }

    @Override
    public void read(org.apache.thrift.protocol.TProtocol prot, TSentryPrivilegesResponse struct) throws org.apache.thrift.TException {
      TTupleProtocol iprot = (TTupleProtocol) prot;
      struct.status = new org.apache.sentry.service.thrift.TSentryResponseStatus();
      struct.status.read(iprot);
      struct.setStatusIsSet(true);
      {
        org.apache.thrift.protocol.TMap _map247 = new org.apache.thrift.protocol.TMap(org.apache.thrift.protocol.TType.STRING, org.apache.thrift.protocol.TType.SET, iprot.readI32());
        struct.privilegesMap = new HashMap<String,Set<TSentryPrivilege>>(2*_map247.size);
        String _key248;
        Set<TSentryPrivilege> _val249;
        for (int _i250 = 0; _i250 < _map247.size; ++_i250)
        {
          _key248 = iprot.readString();
          {
            org.apache.thrift.protocol.TSet _set251 = new org.apache.thrift.protocol.TSet(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
            _val249 = new HashSet<TSentryPrivilege>(2*_set251.size);
            TSentryPrivilege _elem252;
            for (int _i253 = 0; _i253 < _set251.size; ++_i253)
            {
              _elem252 = new TSentryPrivilege();
              _elem252.read(iprot);
              _val249.add(_elem252);
            }
          }
          struct.privilegesMap.put(_key248, _val249);
        }
      }
      struct.setPrivilegesMapIsSet(true);
    }
  }

}

