/**
 * 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 "airavata_errors_types.h"

#include <algorithm>
#include <ostream>

#include <thrift/TToString.h>

namespace apache { namespace airavata { namespace api { namespace error {

int _kAiravataErrorTypeValues[] = {
  AiravataErrorType::UNKNOWN,
  AiravataErrorType::PERMISSION_DENIED,
  AiravataErrorType::INTERNAL_ERROR,
  AiravataErrorType::AUTHENTICATION_FAILURE,
  AiravataErrorType::INVALID_AUTHORIZATION,
  AiravataErrorType::AUTHORIZATION_EXPIRED,
  AiravataErrorType::UNKNOWN_GATEWAY_ID,
  AiravataErrorType::UNSUPPORTED_OPERATION
};
const char* _kAiravataErrorTypeNames[] = {
  "UNKNOWN",
  "PERMISSION_DENIED",
  "INTERNAL_ERROR",
  "AUTHENTICATION_FAILURE",
  "INVALID_AUTHORIZATION",
  "AUTHORIZATION_EXPIRED",
  "UNKNOWN_GATEWAY_ID",
  "UNSUPPORTED_OPERATION"
};
const std::map<int, const char*> _AiravataErrorType_VALUES_TO_NAMES(::apache::thrift::TEnumIterator(8, _kAiravataErrorTypeValues, _kAiravataErrorTypeNames), ::apache::thrift::TEnumIterator(-1, NULL, NULL));


ExperimentNotFoundException::~ExperimentNotFoundException() throw() {
}


void ExperimentNotFoundException::__set_message(const std::string& val) {
  this->message = val;
}

uint32_t ExperimentNotFoundException::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;

  bool isset_message = false;

  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->message);
          isset_message = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  if (!isset_message)
    throw TProtocolException(TProtocolException::INVALID_DATA);
  return xfer;
}

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

  xfer += oprot->writeFieldBegin("message", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->message);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}

void swap(ExperimentNotFoundException &a, ExperimentNotFoundException &b) {
  using ::std::swap;
  swap(a.message, b.message);
}

ExperimentNotFoundException::ExperimentNotFoundException(const ExperimentNotFoundException& other0) : TException() {
  message = other0.message;
}
ExperimentNotFoundException& ExperimentNotFoundException::operator=(const ExperimentNotFoundException& other1) {
  message = other1.message;
  return *this;
}
void ExperimentNotFoundException::printTo(std::ostream& out) const {
  using ::apache::thrift::to_string;
  out << "ExperimentNotFoundException(";
  out << "message=" << to_string(message);
  out << ")";
}

const char* ExperimentNotFoundException::what() const throw() {
  try {
    std::stringstream ss;
    ss << "TException - service has thrown: " << *this;
    this->thriftTExceptionMessageHolder_ = ss.str();
    return this->thriftTExceptionMessageHolder_.c_str();
  } catch (const std::exception&) {
    return "TException - service has thrown: ExperimentNotFoundException";
  }
}


ProjectNotFoundException::~ProjectNotFoundException() throw() {
}


void ProjectNotFoundException::__set_message(const std::string& val) {
  this->message = val;
}

uint32_t ProjectNotFoundException::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;

  bool isset_message = false;

  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->message);
          isset_message = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  if (!isset_message)
    throw TProtocolException(TProtocolException::INVALID_DATA);
  return xfer;
}

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

  xfer += oprot->writeFieldBegin("message", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->message);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}

void swap(ProjectNotFoundException &a, ProjectNotFoundException &b) {
  using ::std::swap;
  swap(a.message, b.message);
}

ProjectNotFoundException::ProjectNotFoundException(const ProjectNotFoundException& other2) : TException() {
  message = other2.message;
}
ProjectNotFoundException& ProjectNotFoundException::operator=(const ProjectNotFoundException& other3) {
  message = other3.message;
  return *this;
}
void ProjectNotFoundException::printTo(std::ostream& out) const {
  using ::apache::thrift::to_string;
  out << "ProjectNotFoundException(";
  out << "message=" << to_string(message);
  out << ")";
}

const char* ProjectNotFoundException::what() const throw() {
  try {
    std::stringstream ss;
    ss << "TException - service has thrown: " << *this;
    this->thriftTExceptionMessageHolder_ = ss.str();
    return this->thriftTExceptionMessageHolder_.c_str();
  } catch (const std::exception&) {
    return "TException - service has thrown: ProjectNotFoundException";
  }
}


InvalidRequestException::~InvalidRequestException() throw() {
}


void InvalidRequestException::__set_message(const std::string& val) {
  this->message = val;
}

uint32_t InvalidRequestException::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;

  bool isset_message = false;

  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->message);
          isset_message = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  if (!isset_message)
    throw TProtocolException(TProtocolException::INVALID_DATA);
  return xfer;
}

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

  xfer += oprot->writeFieldBegin("message", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->message);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}

void swap(InvalidRequestException &a, InvalidRequestException &b) {
  using ::std::swap;
  swap(a.message, b.message);
}

InvalidRequestException::InvalidRequestException(const InvalidRequestException& other4) : TException() {
  message = other4.message;
}
InvalidRequestException& InvalidRequestException::operator=(const InvalidRequestException& other5) {
  message = other5.message;
  return *this;
}
void InvalidRequestException::printTo(std::ostream& out) const {
  using ::apache::thrift::to_string;
  out << "InvalidRequestException(";
  out << "message=" << to_string(message);
  out << ")";
}

const char* InvalidRequestException::what() const throw() {
  try {
    std::stringstream ss;
    ss << "TException - service has thrown: " << *this;
    this->thriftTExceptionMessageHolder_ = ss.str();
    return this->thriftTExceptionMessageHolder_.c_str();
  } catch (const std::exception&) {
    return "TException - service has thrown: InvalidRequestException";
  }
}


TimedOutException::~TimedOutException() throw() {
}


uint32_t TimedOutException::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;
    }
    xfer += iprot->skip(ftype);
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  return xfer;
}

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

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}

void swap(TimedOutException &a, TimedOutException &b) {
  using ::std::swap;
  (void) a;
  (void) b;
}

TimedOutException::TimedOutException(const TimedOutException& other6) : TException() {
  (void) other6;
}
TimedOutException& TimedOutException::operator=(const TimedOutException& other7) {
  (void) other7;
  return *this;
}
void TimedOutException::printTo(std::ostream& out) const {
  using ::apache::thrift::to_string;
  out << "TimedOutException(";
  out << ")";
}

const char* TimedOutException::what() const throw() {
  try {
    std::stringstream ss;
    ss << "TException - service has thrown: " << *this;
    this->thriftTExceptionMessageHolder_ = ss.str();
    return this->thriftTExceptionMessageHolder_.c_str();
  } catch (const std::exception&) {
    return "TException - service has thrown: TimedOutException";
  }
}


AuthenticationException::~AuthenticationException() throw() {
}


void AuthenticationException::__set_message(const std::string& val) {
  this->message = val;
}

uint32_t AuthenticationException::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;

  bool isset_message = false;

  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->message);
          isset_message = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  if (!isset_message)
    throw TProtocolException(TProtocolException::INVALID_DATA);
  return xfer;
}

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

  xfer += oprot->writeFieldBegin("message", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->message);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}

void swap(AuthenticationException &a, AuthenticationException &b) {
  using ::std::swap;
  swap(a.message, b.message);
}

AuthenticationException::AuthenticationException(const AuthenticationException& other8) : TException() {
  message = other8.message;
}
AuthenticationException& AuthenticationException::operator=(const AuthenticationException& other9) {
  message = other9.message;
  return *this;
}
void AuthenticationException::printTo(std::ostream& out) const {
  using ::apache::thrift::to_string;
  out << "AuthenticationException(";
  out << "message=" << to_string(message);
  out << ")";
}

const char* AuthenticationException::what() const throw() {
  try {
    std::stringstream ss;
    ss << "TException - service has thrown: " << *this;
    this->thriftTExceptionMessageHolder_ = ss.str();
    return this->thriftTExceptionMessageHolder_.c_str();
  } catch (const std::exception&) {
    return "TException - service has thrown: AuthenticationException";
  }
}


AuthorizationException::~AuthorizationException() throw() {
}


void AuthorizationException::__set_message(const std::string& val) {
  this->message = val;
}

uint32_t AuthorizationException::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;

  bool isset_message = false;

  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->message);
          isset_message = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  if (!isset_message)
    throw TProtocolException(TProtocolException::INVALID_DATA);
  return xfer;
}

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

  xfer += oprot->writeFieldBegin("message", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->message);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}

void swap(AuthorizationException &a, AuthorizationException &b) {
  using ::std::swap;
  swap(a.message, b.message);
}

AuthorizationException::AuthorizationException(const AuthorizationException& other10) : TException() {
  message = other10.message;
}
AuthorizationException& AuthorizationException::operator=(const AuthorizationException& other11) {
  message = other11.message;
  return *this;
}
void AuthorizationException::printTo(std::ostream& out) const {
  using ::apache::thrift::to_string;
  out << "AuthorizationException(";
  out << "message=" << to_string(message);
  out << ")";
}

const char* AuthorizationException::what() const throw() {
  try {
    std::stringstream ss;
    ss << "TException - service has thrown: " << *this;
    this->thriftTExceptionMessageHolder_ = ss.str();
    return this->thriftTExceptionMessageHolder_.c_str();
  } catch (const std::exception&) {
    return "TException - service has thrown: AuthorizationException";
  }
}


AiravataClientException::~AiravataClientException() throw() {
}


void AiravataClientException::__set_airavataErrorType(const AiravataErrorType::type val) {
  this->airavataErrorType = val;
}

void AiravataClientException::__set_parameter(const std::string& val) {
  this->parameter = val;
__isset.parameter = true;
}

uint32_t AiravataClientException::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;

  bool isset_airavataErrorType = false;

  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_I32) {
          int32_t ecast12;
          xfer += iprot->readI32(ecast12);
          this->airavataErrorType = (AiravataErrorType::type)ecast12;
          isset_airavataErrorType = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->parameter);
          this->__isset.parameter = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  if (!isset_airavataErrorType)
    throw TProtocolException(TProtocolException::INVALID_DATA);
  return xfer;
}

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

  xfer += oprot->writeFieldBegin("airavataErrorType", ::apache::thrift::protocol::T_I32, 1);
  xfer += oprot->writeI32((int32_t)this->airavataErrorType);
  xfer += oprot->writeFieldEnd();

  if (this->__isset.parameter) {
    xfer += oprot->writeFieldBegin("parameter", ::apache::thrift::protocol::T_STRING, 2);
    xfer += oprot->writeString(this->parameter);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}

void swap(AiravataClientException &a, AiravataClientException &b) {
  using ::std::swap;
  swap(a.airavataErrorType, b.airavataErrorType);
  swap(a.parameter, b.parameter);
  swap(a.__isset, b.__isset);
}

AiravataClientException::AiravataClientException(const AiravataClientException& other13) : TException() {
  airavataErrorType = other13.airavataErrorType;
  parameter = other13.parameter;
  __isset = other13.__isset;
}
AiravataClientException& AiravataClientException::operator=(const AiravataClientException& other14) {
  airavataErrorType = other14.airavataErrorType;
  parameter = other14.parameter;
  __isset = other14.__isset;
  return *this;
}
void AiravataClientException::printTo(std::ostream& out) const {
  using ::apache::thrift::to_string;
  out << "AiravataClientException(";
  out << "airavataErrorType=" << to_string(airavataErrorType);
  out << ", " << "parameter="; (__isset.parameter ? (out << to_string(parameter)) : (out << "<null>"));
  out << ")";
}

const char* AiravataClientException::what() const throw() {
  try {
    std::stringstream ss;
    ss << "TException - service has thrown: " << *this;
    this->thriftTExceptionMessageHolder_ = ss.str();
    return this->thriftTExceptionMessageHolder_.c_str();
  } catch (const std::exception&) {
    return "TException - service has thrown: AiravataClientException";
  }
}


ValidatorResult::~ValidatorResult() throw() {
}


void ValidatorResult::__set_result(const bool val) {
  this->result = val;
}

void ValidatorResult::__set_errorDetails(const std::string& val) {
  this->errorDetails = val;
__isset.errorDetails = true;
}

uint32_t ValidatorResult::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;

  bool isset_result = false;

  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_BOOL) {
          xfer += iprot->readBool(this->result);
          isset_result = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->errorDetails);
          this->__isset.errorDetails = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  if (!isset_result)
    throw TProtocolException(TProtocolException::INVALID_DATA);
  return xfer;
}

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

  xfer += oprot->writeFieldBegin("result", ::apache::thrift::protocol::T_BOOL, 1);
  xfer += oprot->writeBool(this->result);
  xfer += oprot->writeFieldEnd();

  if (this->__isset.errorDetails) {
    xfer += oprot->writeFieldBegin("errorDetails", ::apache::thrift::protocol::T_STRING, 2);
    xfer += oprot->writeString(this->errorDetails);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}

void swap(ValidatorResult &a, ValidatorResult &b) {
  using ::std::swap;
  swap(a.result, b.result);
  swap(a.errorDetails, b.errorDetails);
  swap(a.__isset, b.__isset);
}

ValidatorResult::ValidatorResult(const ValidatorResult& other15) {
  result = other15.result;
  errorDetails = other15.errorDetails;
  __isset = other15.__isset;
}
ValidatorResult& ValidatorResult::operator=(const ValidatorResult& other16) {
  result = other16.result;
  errorDetails = other16.errorDetails;
  __isset = other16.__isset;
  return *this;
}
void ValidatorResult::printTo(std::ostream& out) const {
  using ::apache::thrift::to_string;
  out << "ValidatorResult(";
  out << "result=" << to_string(result);
  out << ", " << "errorDetails="; (__isset.errorDetails ? (out << to_string(errorDetails)) : (out << "<null>"));
  out << ")";
}


ValidationResults::~ValidationResults() throw() {
}


void ValidationResults::__set_validationState(const bool val) {
  this->validationState = val;
}

void ValidationResults::__set_validationResultList(const std::vector<ValidatorResult> & val) {
  this->validationResultList = val;
}

uint32_t ValidationResults::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;

  bool isset_validationState = false;
  bool isset_validationResultList = false;

  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_BOOL) {
          xfer += iprot->readBool(this->validationState);
          isset_validationState = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_LIST) {
          {
            this->validationResultList.clear();
            uint32_t _size17;
            ::apache::thrift::protocol::TType _etype20;
            xfer += iprot->readListBegin(_etype20, _size17);
            this->validationResultList.resize(_size17);
            uint32_t _i21;
            for (_i21 = 0; _i21 < _size17; ++_i21)
            {
              xfer += this->validationResultList[_i21].read(iprot);
            }
            xfer += iprot->readListEnd();
          }
          isset_validationResultList = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  if (!isset_validationState)
    throw TProtocolException(TProtocolException::INVALID_DATA);
  if (!isset_validationResultList)
    throw TProtocolException(TProtocolException::INVALID_DATA);
  return xfer;
}

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

  xfer += oprot->writeFieldBegin("validationState", ::apache::thrift::protocol::T_BOOL, 1);
  xfer += oprot->writeBool(this->validationState);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldBegin("validationResultList", ::apache::thrift::protocol::T_LIST, 2);
  {
    xfer += oprot->writeListBegin(::apache::thrift::protocol::T_STRUCT, static_cast<uint32_t>(this->validationResultList.size()));
    std::vector<ValidatorResult> ::const_iterator _iter22;
    for (_iter22 = this->validationResultList.begin(); _iter22 != this->validationResultList.end(); ++_iter22)
    {
      xfer += (*_iter22).write(oprot);
    }
    xfer += oprot->writeListEnd();
  }
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}

void swap(ValidationResults &a, ValidationResults &b) {
  using ::std::swap;
  swap(a.validationState, b.validationState);
  swap(a.validationResultList, b.validationResultList);
}

ValidationResults::ValidationResults(const ValidationResults& other23) {
  validationState = other23.validationState;
  validationResultList = other23.validationResultList;
}
ValidationResults& ValidationResults::operator=(const ValidationResults& other24) {
  validationState = other24.validationState;
  validationResultList = other24.validationResultList;
  return *this;
}
void ValidationResults::printTo(std::ostream& out) const {
  using ::apache::thrift::to_string;
  out << "ValidationResults(";
  out << "validationState=" << to_string(validationState);
  out << ", " << "validationResultList=" << to_string(validationResultList);
  out << ")";
}


LaunchValidationException::~LaunchValidationException() throw() {
}


void LaunchValidationException::__set_validationResult(const ValidationResults& val) {
  this->validationResult = val;
}

void LaunchValidationException::__set_errorMessage(const std::string& val) {
  this->errorMessage = val;
__isset.errorMessage = true;
}

uint32_t LaunchValidationException::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;

  bool isset_validationResult = false;

  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_STRUCT) {
          xfer += this->validationResult.read(iprot);
          isset_validationResult = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->errorMessage);
          this->__isset.errorMessage = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  if (!isset_validationResult)
    throw TProtocolException(TProtocolException::INVALID_DATA);
  return xfer;
}

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

  xfer += oprot->writeFieldBegin("validationResult", ::apache::thrift::protocol::T_STRUCT, 1);
  xfer += this->validationResult.write(oprot);
  xfer += oprot->writeFieldEnd();

  if (this->__isset.errorMessage) {
    xfer += oprot->writeFieldBegin("errorMessage", ::apache::thrift::protocol::T_STRING, 2);
    xfer += oprot->writeString(this->errorMessage);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}

void swap(LaunchValidationException &a, LaunchValidationException &b) {
  using ::std::swap;
  swap(a.validationResult, b.validationResult);
  swap(a.errorMessage, b.errorMessage);
  swap(a.__isset, b.__isset);
}

LaunchValidationException::LaunchValidationException(const LaunchValidationException& other25) : TException() {
  validationResult = other25.validationResult;
  errorMessage = other25.errorMessage;
  __isset = other25.__isset;
}
LaunchValidationException& LaunchValidationException::operator=(const LaunchValidationException& other26) {
  validationResult = other26.validationResult;
  errorMessage = other26.errorMessage;
  __isset = other26.__isset;
  return *this;
}
void LaunchValidationException::printTo(std::ostream& out) const {
  using ::apache::thrift::to_string;
  out << "LaunchValidationException(";
  out << "validationResult=" << to_string(validationResult);
  out << ", " << "errorMessage="; (__isset.errorMessage ? (out << to_string(errorMessage)) : (out << "<null>"));
  out << ")";
}

const char* LaunchValidationException::what() const throw() {
  try {
    std::stringstream ss;
    ss << "TException - service has thrown: " << *this;
    this->thriftTExceptionMessageHolder_ = ss.str();
    return this->thriftTExceptionMessageHolder_.c_str();
  } catch (const std::exception&) {
    return "TException - service has thrown: LaunchValidationException";
  }
}


AiravataSystemException::~AiravataSystemException() throw() {
}


void AiravataSystemException::__set_airavataErrorType(const AiravataErrorType::type val) {
  this->airavataErrorType = val;
}

void AiravataSystemException::__set_message(const std::string& val) {
  this->message = val;
__isset.message = true;
}

uint32_t AiravataSystemException::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;

  bool isset_airavataErrorType = false;

  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_I32) {
          int32_t ecast27;
          xfer += iprot->readI32(ecast27);
          this->airavataErrorType = (AiravataErrorType::type)ecast27;
          isset_airavataErrorType = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      case 2:
        if (ftype == ::apache::thrift::protocol::T_STRING) {
          xfer += iprot->readString(this->message);
          this->__isset.message = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  if (!isset_airavataErrorType)
    throw TProtocolException(TProtocolException::INVALID_DATA);
  return xfer;
}

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

  xfer += oprot->writeFieldBegin("airavataErrorType", ::apache::thrift::protocol::T_I32, 1);
  xfer += oprot->writeI32((int32_t)this->airavataErrorType);
  xfer += oprot->writeFieldEnd();

  if (this->__isset.message) {
    xfer += oprot->writeFieldBegin("message", ::apache::thrift::protocol::T_STRING, 2);
    xfer += oprot->writeString(this->message);
    xfer += oprot->writeFieldEnd();
  }
  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}

void swap(AiravataSystemException &a, AiravataSystemException &b) {
  using ::std::swap;
  swap(a.airavataErrorType, b.airavataErrorType);
  swap(a.message, b.message);
  swap(a.__isset, b.__isset);
}

AiravataSystemException::AiravataSystemException(const AiravataSystemException& other28) : TException() {
  airavataErrorType = other28.airavataErrorType;
  message = other28.message;
  __isset = other28.__isset;
}
AiravataSystemException& AiravataSystemException::operator=(const AiravataSystemException& other29) {
  airavataErrorType = other29.airavataErrorType;
  message = other29.message;
  __isset = other29.__isset;
  return *this;
}
void AiravataSystemException::printTo(std::ostream& out) const {
  using ::apache::thrift::to_string;
  out << "AiravataSystemException(";
  out << "airavataErrorType=" << to_string(airavataErrorType);
  out << ", " << "message="; (__isset.message ? (out << to_string(message)) : (out << "<null>"));
  out << ")";
}

const char* AiravataSystemException::what() const throw() {
  try {
    std::stringstream ss;
    ss << "TException - service has thrown: " << *this;
    this->thriftTExceptionMessageHolder_ = ss.str();
    return this->thriftTExceptionMessageHolder_.c_str();
  } catch (const std::exception&) {
    return "TException - service has thrown: AiravataSystemException";
  }
}


DataManagerServiceException::~DataManagerServiceException() throw() {
}


void DataManagerServiceException::__set_message(const std::string& val) {
  this->message = val;
}

uint32_t DataManagerServiceException::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;

  bool isset_message = false;

  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->message);
          isset_message = true;
        } else {
          xfer += iprot->skip(ftype);
        }
        break;
      default:
        xfer += iprot->skip(ftype);
        break;
    }
    xfer += iprot->readFieldEnd();
  }

  xfer += iprot->readStructEnd();

  if (!isset_message)
    throw TProtocolException(TProtocolException::INVALID_DATA);
  return xfer;
}

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

  xfer += oprot->writeFieldBegin("message", ::apache::thrift::protocol::T_STRING, 1);
  xfer += oprot->writeString(this->message);
  xfer += oprot->writeFieldEnd();

  xfer += oprot->writeFieldStop();
  xfer += oprot->writeStructEnd();
  return xfer;
}

void swap(DataManagerServiceException &a, DataManagerServiceException &b) {
  using ::std::swap;
  swap(a.message, b.message);
}

DataManagerServiceException::DataManagerServiceException(const DataManagerServiceException& other30) : TException() {
  message = other30.message;
}
DataManagerServiceException& DataManagerServiceException::operator=(const DataManagerServiceException& other31) {
  message = other31.message;
  return *this;
}
void DataManagerServiceException::printTo(std::ostream& out) const {
  using ::apache::thrift::to_string;
  out << "DataManagerServiceException(";
  out << "message=" << to_string(message);
  out << ")";
}

const char* DataManagerServiceException::what() const throw() {
  try {
    std::stringstream ss;
    ss << "TException - service has thrown: " << *this;
    this->thriftTExceptionMessageHolder_ = ss.str();
    return this->thriftTExceptionMessageHolder_.c_str();
  } catch (const std::exception&) {
    return "TException - service has thrown: DataManagerServiceException";
  }
}

}}}} // namespace
