/**
 * Autogenerated by Thrift Compiler (0.14.1)
 *
 * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 *  @generated
 */
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using Thrift;
using Thrift.Collections;

using Thrift.Protocol;
using Thrift.Protocol.Entities;
using Thrift.Protocol.Utilities;
using Thrift.Transport;
using Thrift.Transport.Client;
using Thrift.Transport.Server;
using Thrift.Processor;


#pragma warning disable IDE0079  // remove unnecessary pragmas
#pragma warning disable IDE1006  // parts of the code use IDL spelling


public partial class TDataNodeLocation : TBase
{

  public int DataNodeId { get; set; }

  public TEndPoint ClientRpcEndPoint { get; set; }

  public TEndPoint InternalEndPoint { get; set; }

  public TEndPoint MPPDataExchangeEndPoint { get; set; }

  public TEndPoint DataRegionConsensusEndPoint { get; set; }

  public TEndPoint SchemaRegionConsensusEndPoint { get; set; }

  public TDataNodeLocation()
  {
  }

  public TDataNodeLocation(int dataNodeId, TEndPoint clientRpcEndPoint, TEndPoint internalEndPoint, TEndPoint mPPDataExchangeEndPoint, TEndPoint dataRegionConsensusEndPoint, TEndPoint schemaRegionConsensusEndPoint) : this()
  {
    this.DataNodeId = dataNodeId;
    this.ClientRpcEndPoint = clientRpcEndPoint;
    this.InternalEndPoint = internalEndPoint;
    this.MPPDataExchangeEndPoint = mPPDataExchangeEndPoint;
    this.DataRegionConsensusEndPoint = dataRegionConsensusEndPoint;
    this.SchemaRegionConsensusEndPoint = schemaRegionConsensusEndPoint;
  }

  public TDataNodeLocation DeepCopy()
  {
    var tmp24 = new TDataNodeLocation();
    tmp24.DataNodeId = this.DataNodeId;
    if((ClientRpcEndPoint != null))
    {
      tmp24.ClientRpcEndPoint = (TEndPoint)this.ClientRpcEndPoint.DeepCopy();
    }
    if((InternalEndPoint != null))
    {
      tmp24.InternalEndPoint = (TEndPoint)this.InternalEndPoint.DeepCopy();
    }
    if((MPPDataExchangeEndPoint != null))
    {
      tmp24.MPPDataExchangeEndPoint = (TEndPoint)this.MPPDataExchangeEndPoint.DeepCopy();
    }
    if((DataRegionConsensusEndPoint != null))
    {
      tmp24.DataRegionConsensusEndPoint = (TEndPoint)this.DataRegionConsensusEndPoint.DeepCopy();
    }
    if((SchemaRegionConsensusEndPoint != null))
    {
      tmp24.SchemaRegionConsensusEndPoint = (TEndPoint)this.SchemaRegionConsensusEndPoint.DeepCopy();
    }
    return tmp24;
  }

  public async global::System.Threading.Tasks.Task ReadAsync(TProtocol iprot, CancellationToken cancellationToken)
  {
    iprot.IncrementRecursionDepth();
    try
    {
      bool isset_dataNodeId = false;
      bool isset_clientRpcEndPoint = false;
      bool isset_internalEndPoint = false;
      bool isset_mPPDataExchangeEndPoint = false;
      bool isset_dataRegionConsensusEndPoint = false;
      bool isset_schemaRegionConsensusEndPoint = false;
      TField field;
      await iprot.ReadStructBeginAsync(cancellationToken);
      while (true)
      {
        field = await iprot.ReadFieldBeginAsync(cancellationToken);
        if (field.Type == TType.Stop)
        {
          break;
        }

        switch (field.ID)
        {
          case 1:
            if (field.Type == TType.I32)
            {
              DataNodeId = await iprot.ReadI32Async(cancellationToken);
              isset_dataNodeId = true;
            }
            else
            {
              await TProtocolUtil.SkipAsync(iprot, field.Type, cancellationToken);
            }
            break;
          case 2:
            if (field.Type == TType.Struct)
            {
              ClientRpcEndPoint = new TEndPoint();
              await ClientRpcEndPoint.ReadAsync(iprot, cancellationToken);
              isset_clientRpcEndPoint = true;
            }
            else
            {
              await TProtocolUtil.SkipAsync(iprot, field.Type, cancellationToken);
            }
            break;
          case 3:
            if (field.Type == TType.Struct)
            {
              InternalEndPoint = new TEndPoint();
              await InternalEndPoint.ReadAsync(iprot, cancellationToken);
              isset_internalEndPoint = true;
            }
            else
            {
              await TProtocolUtil.SkipAsync(iprot, field.Type, cancellationToken);
            }
            break;
          case 4:
            if (field.Type == TType.Struct)
            {
              MPPDataExchangeEndPoint = new TEndPoint();
              await MPPDataExchangeEndPoint.ReadAsync(iprot, cancellationToken);
              isset_mPPDataExchangeEndPoint = true;
            }
            else
            {
              await TProtocolUtil.SkipAsync(iprot, field.Type, cancellationToken);
            }
            break;
          case 5:
            if (field.Type == TType.Struct)
            {
              DataRegionConsensusEndPoint = new TEndPoint();
              await DataRegionConsensusEndPoint.ReadAsync(iprot, cancellationToken);
              isset_dataRegionConsensusEndPoint = true;
            }
            else
            {
              await TProtocolUtil.SkipAsync(iprot, field.Type, cancellationToken);
            }
            break;
          case 6:
            if (field.Type == TType.Struct)
            {
              SchemaRegionConsensusEndPoint = new TEndPoint();
              await SchemaRegionConsensusEndPoint.ReadAsync(iprot, cancellationToken);
              isset_schemaRegionConsensusEndPoint = true;
            }
            else
            {
              await TProtocolUtil.SkipAsync(iprot, field.Type, cancellationToken);
            }
            break;
          default: 
            await TProtocolUtil.SkipAsync(iprot, field.Type, cancellationToken);
            break;
        }

        await iprot.ReadFieldEndAsync(cancellationToken);
      }

      await iprot.ReadStructEndAsync(cancellationToken);
      if (!isset_dataNodeId)
      {
        throw new TProtocolException(TProtocolException.INVALID_DATA);
      }
      if (!isset_clientRpcEndPoint)
      {
        throw new TProtocolException(TProtocolException.INVALID_DATA);
      }
      if (!isset_internalEndPoint)
      {
        throw new TProtocolException(TProtocolException.INVALID_DATA);
      }
      if (!isset_mPPDataExchangeEndPoint)
      {
        throw new TProtocolException(TProtocolException.INVALID_DATA);
      }
      if (!isset_dataRegionConsensusEndPoint)
      {
        throw new TProtocolException(TProtocolException.INVALID_DATA);
      }
      if (!isset_schemaRegionConsensusEndPoint)
      {
        throw new TProtocolException(TProtocolException.INVALID_DATA);
      }
    }
    finally
    {
      iprot.DecrementRecursionDepth();
    }
  }

  public async global::System.Threading.Tasks.Task WriteAsync(TProtocol oprot, CancellationToken cancellationToken)
  {
    oprot.IncrementRecursionDepth();
    try
    {
      var struc = new TStruct("TDataNodeLocation");
      await oprot.WriteStructBeginAsync(struc, cancellationToken);
      var field = new TField();
      field.Name = "dataNodeId";
      field.Type = TType.I32;
      field.ID = 1;
      await oprot.WriteFieldBeginAsync(field, cancellationToken);
      await oprot.WriteI32Async(DataNodeId, cancellationToken);
      await oprot.WriteFieldEndAsync(cancellationToken);
      if((ClientRpcEndPoint != null))
      {
        field.Name = "clientRpcEndPoint";
        field.Type = TType.Struct;
        field.ID = 2;
        await oprot.WriteFieldBeginAsync(field, cancellationToken);
        await ClientRpcEndPoint.WriteAsync(oprot, cancellationToken);
        await oprot.WriteFieldEndAsync(cancellationToken);
      }
      if((InternalEndPoint != null))
      {
        field.Name = "internalEndPoint";
        field.Type = TType.Struct;
        field.ID = 3;
        await oprot.WriteFieldBeginAsync(field, cancellationToken);
        await InternalEndPoint.WriteAsync(oprot, cancellationToken);
        await oprot.WriteFieldEndAsync(cancellationToken);
      }
      if((MPPDataExchangeEndPoint != null))
      {
        field.Name = "mPPDataExchangeEndPoint";
        field.Type = TType.Struct;
        field.ID = 4;
        await oprot.WriteFieldBeginAsync(field, cancellationToken);
        await MPPDataExchangeEndPoint.WriteAsync(oprot, cancellationToken);
        await oprot.WriteFieldEndAsync(cancellationToken);
      }
      if((DataRegionConsensusEndPoint != null))
      {
        field.Name = "dataRegionConsensusEndPoint";
        field.Type = TType.Struct;
        field.ID = 5;
        await oprot.WriteFieldBeginAsync(field, cancellationToken);
        await DataRegionConsensusEndPoint.WriteAsync(oprot, cancellationToken);
        await oprot.WriteFieldEndAsync(cancellationToken);
      }
      if((SchemaRegionConsensusEndPoint != null))
      {
        field.Name = "schemaRegionConsensusEndPoint";
        field.Type = TType.Struct;
        field.ID = 6;
        await oprot.WriteFieldBeginAsync(field, cancellationToken);
        await SchemaRegionConsensusEndPoint.WriteAsync(oprot, cancellationToken);
        await oprot.WriteFieldEndAsync(cancellationToken);
      }
      await oprot.WriteFieldStopAsync(cancellationToken);
      await oprot.WriteStructEndAsync(cancellationToken);
    }
    finally
    {
      oprot.DecrementRecursionDepth();
    }
  }

  public override bool Equals(object that)
  {
    if (!(that is TDataNodeLocation other)) return false;
    if (ReferenceEquals(this, other)) return true;
    return System.Object.Equals(DataNodeId, other.DataNodeId)
      && System.Object.Equals(ClientRpcEndPoint, other.ClientRpcEndPoint)
      && System.Object.Equals(InternalEndPoint, other.InternalEndPoint)
      && System.Object.Equals(MPPDataExchangeEndPoint, other.MPPDataExchangeEndPoint)
      && System.Object.Equals(DataRegionConsensusEndPoint, other.DataRegionConsensusEndPoint)
      && System.Object.Equals(SchemaRegionConsensusEndPoint, other.SchemaRegionConsensusEndPoint);
  }

  public override int GetHashCode() {
    int hashcode = 157;
    unchecked {
      hashcode = (hashcode * 397) + DataNodeId.GetHashCode();
      if((ClientRpcEndPoint != null))
      {
        hashcode = (hashcode * 397) + ClientRpcEndPoint.GetHashCode();
      }
      if((InternalEndPoint != null))
      {
        hashcode = (hashcode * 397) + InternalEndPoint.GetHashCode();
      }
      if((MPPDataExchangeEndPoint != null))
      {
        hashcode = (hashcode * 397) + MPPDataExchangeEndPoint.GetHashCode();
      }
      if((DataRegionConsensusEndPoint != null))
      {
        hashcode = (hashcode * 397) + DataRegionConsensusEndPoint.GetHashCode();
      }
      if((SchemaRegionConsensusEndPoint != null))
      {
        hashcode = (hashcode * 397) + SchemaRegionConsensusEndPoint.GetHashCode();
      }
    }
    return hashcode;
  }

  public override string ToString()
  {
    var sb = new StringBuilder("TDataNodeLocation(");
    sb.Append(", DataNodeId: ");
    DataNodeId.ToString(sb);
    if((ClientRpcEndPoint != null))
    {
      sb.Append(", ClientRpcEndPoint: ");
      ClientRpcEndPoint.ToString(sb);
    }
    if((InternalEndPoint != null))
    {
      sb.Append(", InternalEndPoint: ");
      InternalEndPoint.ToString(sb);
    }
    if((MPPDataExchangeEndPoint != null))
    {
      sb.Append(", MPPDataExchangeEndPoint: ");
      MPPDataExchangeEndPoint.ToString(sb);
    }
    if((DataRegionConsensusEndPoint != null))
    {
      sb.Append(", DataRegionConsensusEndPoint: ");
      DataRegionConsensusEndPoint.ToString(sb);
    }
    if((SchemaRegionConsensusEndPoint != null))
    {
      sb.Append(", SchemaRegionConsensusEndPoint: ");
      SchemaRegionConsensusEndPoint.ToString(sb);
    }
    sb.Append(')');
    return sb.ToString();
  }
}

