/**
 * 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.9.3)
 *
 * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 *  @generated
 */
#include "metadata_models_types.h"

#include <algorithm>
#include <ostream>

#include <thrift/TToString.h>

namespace apache { namespace airavata { namespace model { namespace data { namespace metadata {

int _kMetadataTypeValues[] = {
  MetadataType::FILE,
  MetadataType::COLLECTION
};
const char* _kMetadataTypeNames[] = {
  "FILE",
  "COLLECTION"
};
const std::map<int, const char*> _MetadataType_VALUES_TO_NAMES(::apache::thrift::TEnumIterator(2, _kMetadataTypeValues, _kMetadataTypeNames), ::apache::thrift::TEnumIterator(-1, NULL, NULL));


MetadataModel::~MetadataModel() throw() {
}


void MetadataModel::__set_metadataId(const std::string& val) {
  this->metadataId = val;
__isset.metadataId = true;
}

void MetadataModel::__set_gatewayId(const std::string& val) {
  this->gatewayId = val;
__isset.gatewayId = true;
}

void MetadataModel::__set_username(const std::string& val) {
  this->username = val;
__isset.username = true;
}

void MetadataModel::__set_size(const double val) {
  this->size = val;
__isset.size = true;
}

void MetadataModel::__set_sharedUsers(const std::vector<std::string> & val) {
  this->sharedUsers = val;
__isset.sharedUsers = true;
}

void MetadataModel::__set_sharedPublic(const bool val) {
  this->sharedPublic = val;
__isset.sharedPublic = true;
}

void MetadataModel::__set_userFriendlyName(const std::string& val) {
  this->userFriendlyName = val;
__isset.userFriendlyName = true;
}

void MetadataModel::__set_userFriendlyDescription(const std::string& val) {
  this->userFriendlyDescription = val;
__isset.userFriendlyDescription = true;
}

void MetadataModel::__set_metadataType(const MetadataType::type val) {
  this->metadataType = val;
__isset.metadataType = true;
}

void MetadataModel::__set_associatedEntityId(const std::string& val) {
  this->associatedEntityId = val;
__isset.associatedEntityId = true;
}

void MetadataModel::__set_customInformation(const std::map<std::string, std::string> & val) {
  this->customInformation = val;
__isset.customInformation = true;
}

void MetadataModel::__set_creationTime(const int64_t val) {
  this->creationTime = val;
__isset.creationTime = true;
}

void MetadataModel::__set_lastModifiedTime(const int64_t val) {
  this->lastModifiedTime = val;
__isset.lastModifiedTime = true;
}

uint32_t MetadataModel::read(::apache::thrift::protocol::TProtocol* iprot) {

  apache::thrift::protocol::TInputRecursionTracker tracker(*iprot);
  uint32_t xfer = 0;
  std::string fname;
  ::apache::thrift::protocol::TType ftype;
  int16_t fid;

  xfer += iprot->readStructBegin(fname);

  using ::apache::thrift::protocol::TProtocolException;


  while (true)
  {
    xfer += iprot->readFieldBegin(fname, ftype, fid);
    if (ftype == ::apache::thrift::protocol::T_STOP) {
      break;
    }
    switch (fid)
    {
      case 1:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->metadataId);
          this->__isset.metadataId = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->gatewayId);
          this->__isset.gatewayId = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 3:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->username);
          this->__isset.username = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 4:
        if (ftype == ::apache::thrift::protocol::T_DOUBLE) {
          xfer += iprot->readDouble(this->size);
          this->__isset.size = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 5:
        if (ftype == ::apache::thrift::protocol::T_LIST) {
          {
            this->sharedUsers.clear();
            uint32_t _size0;
            ::apache::thrift::protocol::TType _etype3;
            xfer += iprot->readListBegin(_etype3, _size0);
            this->sharedUsers.resize(_size0);
            uint32_t _i4;
            for (_i4 = 0; _i4 < _size0; ++_i4)
            {
              xfer += iprot->readString(this->sharedUsers[_i4]);
            }
            xfer += iprot->readListEnd();
          }
          this->__isset.sharedUsers = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 6:
        if (ftype == ::apache::thrift::protocol::T_BOOL) {
          xfer += iprot->readBool(this->sharedPublic);
          this->__isset.sharedPublic = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 7:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->userFriendlyName);
          this->__isset.userFriendlyName = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 8:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->userFriendlyDescription);
          this->__isset.userFriendlyDescription = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 9:
        if (ftype == ::apache::thrift::protocol::T_I32) {
          int32_t ecast5;
          xfer += iprot->readI32(ecast5);
          this->metadataType = (MetadataType::type)ecast5;
          this->__isset.metadataType = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 10:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->associatedEntityId);
          this->__isset.associatedEntityId = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 11:
        if (ftype == ::apache::thrift::protocol::T_MAP) {
          {
            this->customInformation.clear();
            uint32_t _size6;
            ::apache::thrift::protocol::TType _ktype7;
            ::apache::thrift::protocol::TType _vtype8;
            xfer += iprot->readMapBegin(_ktype7, _vtype8, _size6);
            uint32_t _i10;
            for (_i10 = 0; _i10 < _size6; ++_i10)
            {
              std::string _key11;
              xfer += iprot->readString(_key11);
              std::string& _val12 = this->customInformation[_key11];
              xfer += iprot->readString(_val12);
            }
            xfer += iprot->readMapEnd();
          }
          this->__isset.customInformation = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 12:
        if (ftype == ::apache::thrift::protocol::T_I64) {
          xfer += iprot->readI64(this->creationTime);
          this->__isset.creationTime = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 13:
        if (ftype == ::apache::thrift::protocol::T_I64) {
          xfer += iprot->readI64(this->lastModifiedTime);
          this->__isset.lastModifiedTime = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

uint32_t MetadataModel::write(::apache::thrift::protocol::TProtocol* oprot) const {
  uint32_t xfer = 0;
  apache::thrift::protocol::TOutputRecursionTracker tracker(*oprot);
  xfer += oprot->writeStructBegin("MetadataModel");

  if (this->__isset.metadataId) {
    xfer += oprot->writeFieldBegin("metadataId", ::apache::thrift::protocol::T_STRING, 1);
    xfer += oprot->writeString(this->metadataId);
    xfer += oprot->writeFieldEnd();
  }
  if (this->__isset.gatewayId) {
    xfer += oprot->writeFieldBegin("gatewayId", ::apache::thrift::protocol::T_STRING, 2);
    xfer += oprot->writeString(this->gatewayId);
    xfer += oprot->writeFieldEnd();
  }
  if (this->__isset.username) {
    xfer += oprot->writeFieldBegin("username", ::apache::thrift::protocol::T_STRING, 3);
    xfer += oprot->writeString(this->username);
    xfer += oprot->writeFieldEnd();
  }
  if (this->__isset.size) {
    xfer += oprot->writeFieldBegin("size", ::apache::thrift::protocol::T_DOUBLE, 4);
    xfer += oprot->writeDouble(this->size);
    xfer += oprot->writeFieldEnd();
  }
  if (this->__isset.sharedUsers) {
    xfer += oprot->writeFieldBegin("sharedUsers", ::apache::thrift::protocol::T_LIST, 5);
    {
      xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(this->sharedUsers.size()));
      std::vector<std::string> ::const_iterator _iter13;
      for (_iter13 = this->sharedUsers.begin(); _iter13 != this->sharedUsers.end(); ++_iter13)
      {
        xfer += oprot->writeString((*_iter13));
      }
      xfer += oprot->writeListEnd();
    }
    xfer += oprot->writeFieldEnd();
  }
  if (this->__isset.sharedPublic) {
    xfer += oprot->writeFieldBegin("sharedPublic", ::apache::thrift::protocol::T_BOOL, 6);
    xfer += oprot->writeBool(this->sharedPublic);
    xfer += oprot->writeFieldEnd();
  }
  if (this->__isset.userFriendlyName) {
    xfer += oprot->writeFieldBegin("userFriendlyName", ::apache::thrift::protocol::T_STRING, 7);
    xfer += oprot->writeString(this->userFriendlyName);
    xfer += oprot->writeFieldEnd();
  }
  if (this->__isset.userFriendlyDescription) {
    xfer += oprot->writeFieldBegin("userFriendlyDescription", ::apache::thrift::protocol::T_STRING, 8);
    xfer += oprot->writeString(this->userFriendlyDescription);
    xfer += oprot->writeFieldEnd();
  }
  if (this->__isset.metadataType) {
    xfer += oprot->writeFieldBegin("metadataType", ::apache::thrift::protocol::T_I32, 9);
    xfer += oprot->writeI32((int32_t)this->metadataType);
    xfer += oprot->writeFieldEnd();
  }
  if (this->__isset.associatedEntityId) {
    xfer += oprot->writeFieldBegin("associatedEntityId", ::apache::thrift::protocol::T_STRING, 10);
    xfer += oprot->writeString(this->associatedEntityId);
    xfer += oprot->writeFieldEnd();
  }
  if (this->__isset.customInformation) {
    xfer += oprot->writeFieldBegin("customInformation", ::apache::thrift::protocol::T_MAP, 11);
    {
      xfer += oprot->writeMapBegin(::apache::thrift::protocol::T_STRING, ::apache::thrift::protocol::T_STRING, static_cast<uint32_t>(this->customInformation.size()));
      std::map<std::string, std::string> ::const_iterator _iter14;
      for (_iter14 = this->customInformation.begin(); _iter14 != this->customInformation.end(); ++_iter14)
      {
        xfer += oprot->writeString(_iter14->first);
        xfer += oprot->writeString(_iter14->second);
      }
      xfer += oprot->writeMapEnd();
    }
    xfer += oprot->writeFieldEnd();
  }
  if (this->__isset.creationTime) {
    xfer += oprot->writeFieldBegin("creationTime", ::apache::thrift::protocol::T_I64, 12);
    xfer += oprot->writeI64(this->creationTime);
    xfer += oprot->writeFieldEnd();
  }
  if (this->__isset.lastModifiedTime) {
    xfer += oprot->writeFieldBegin("lastModifiedTime", ::apache::thrift::protocol::T_I64, 13);
    xfer += oprot->writeI64(this->lastModifiedTime);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}

void swap(MetadataModel &a, MetadataModel &b) {
  using ::std::swap;
  swap(a.metadataId, b.metadataId);
  swap(a.gatewayId, b.gatewayId);
  swap(a.username, b.username);
  swap(a.size, b.size);
  swap(a.sharedUsers, b.sharedUsers);
  swap(a.sharedPublic, b.sharedPublic);
  swap(a.userFriendlyName, b.userFriendlyName);
  swap(a.userFriendlyDescription, b.userFriendlyDescription);
  swap(a.metadataType, b.metadataType);
  swap(a.associatedEntityId, b.associatedEntityId);
  swap(a.customInformation, b.customInformation);
  swap(a.creationTime, b.creationTime);
  swap(a.lastModifiedTime, b.lastModifiedTime);
  swap(a.__isset, b.__isset);
}

MetadataModel::MetadataModel(const MetadataModel& other15) {
  metadataId = other15.metadataId;
  gatewayId = other15.gatewayId;
  username = other15.username;
  size = other15.size;
  sharedUsers = other15.sharedUsers;
  sharedPublic = other15.sharedPublic;
  userFriendlyName = other15.userFriendlyName;
  userFriendlyDescription = other15.userFriendlyDescription;
  metadataType = other15.metadataType;
  associatedEntityId = other15.associatedEntityId;
  customInformation = other15.customInformation;
  creationTime = other15.creationTime;
  lastModifiedTime = other15.lastModifiedTime;
  __isset = other15.__isset;
}
MetadataModel& MetadataModel::operator=(const MetadataModel& other16) {
  metadataId = other16.metadataId;
  gatewayId = other16.gatewayId;
  username = other16.username;
  size = other16.size;
  sharedUsers = other16.sharedUsers;
  sharedPublic = other16.sharedPublic;
  userFriendlyName = other16.userFriendlyName;
  userFriendlyDescription = other16.userFriendlyDescription;
  metadataType = other16.metadataType;
  associatedEntityId = other16.associatedEntityId;
  customInformation = other16.customInformation;
  creationTime = other16.creationTime;
  lastModifiedTime = other16.lastModifiedTime;
  __isset = other16.__isset;
  return *this;
}
void MetadataModel::printTo(std::ostream& out) const {
  using ::apache::thrift::to_string;
  out << "MetadataModel(";
  out << "metadataId="; (__isset.metadataId ? (out << to_string(metadataId)) : (out << "<null>"));
  out << ", " << "gatewayId="; (__isset.gatewayId ? (out << to_string(gatewayId)) : (out << "<null>"));
  out << ", " << "username="; (__isset.username ? (out << to_string(username)) : (out << "<null>"));
  out << ", " << "size="; (__isset.size ? (out << to_string(size)) : (out << "<null>"));
  out << ", " << "sharedUsers="; (__isset.sharedUsers ? (out << to_string(sharedUsers)) : (out << "<null>"));
  out << ", " << "sharedPublic="; (__isset.sharedPublic ? (out << to_string(sharedPublic)) : (out << "<null>"));
  out << ", " << "userFriendlyName="; (__isset.userFriendlyName ? (out << to_string(userFriendlyName)) : (out << "<null>"));
  out << ", " << "userFriendlyDescription="; (__isset.userFriendlyDescription ? (out << to_string(userFriendlyDescription)) : (out << "<null>"));
  out << ", " << "metadataType="; (__isset.metadataType ? (out << to_string(metadataType)) : (out << "<null>"));
  out << ", " << "associatedEntityId="; (__isset.associatedEntityId ? (out << to_string(associatedEntityId)) : (out << "<null>"));
  out << ", " << "customInformation="; (__isset.customInformation ? (out << to_string(customInformation)) : (out << "<null>"));
  out << ", " << "creationTime="; (__isset.creationTime ? (out << to_string(creationTime)) : (out << "<null>"));
  out << ", " << "lastModifiedTime="; (__isset.lastModifiedTime ? (out << to_string(lastModifiedTime)) : (out << "<null>"));
  out << ")";
}

}}}}} // namespace
