/**
 * Autogenerated by Thrift Compiler (0.14.0)
 *
 * 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 System.ServiceModel;
using System.Runtime.Serialization;

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

namespace OptReqDefTest
{
  public abstract partial class jack : TUnionBase
  {
    public abstract global::System.Threading.Tasks.Task WriteAsync(TProtocol tProtocol, CancellationToken cancellationToken);
    public readonly int Isset;
    public abstract object Data { get; }
    protected jack(int isset)
    {
      Isset = isset;
    }

    public override bool Equals(object that)
    {
      if (!(that is jack other)) return false;
      if (ReferenceEquals(this, other)) return true;

      if(this.Isset != other.Isset) return false;

      switch (Isset)
      {
        case 1:
          return Equals(As_stars, other.As_stars);
        case 2:
          return Equals(As_stripes, other.As_stripes);
        case 310:
          return Equals(As_far_set_list, other.As_far_set_list);
        case 311:
          return Equals(As_far_list_map_set, other.As_far_list_map_set);
        case 312:
          return Equals(As_far_map_dist_to_rds, other.As_far_map_dist_to_rds);
        case 320:
          return Equals(As_nested_union, other.As_nested_union);
        case 321:
          return Equals(As_nested_struct, other.As_nested_struct);
        case 401:
          return Equals(As_opt_one, other.As_opt_one);
        case 402:
          return Equals(As_opt_two, other.As_opt_two);
        case 403:
          return Equals(As_opt_three, other.As_opt_three);
        case 404:
          return Equals(As_opt_four, other.As_opt_four);
        case 405:
          return Equals(As_opt_five, other.As_opt_five);
        case 406:
          return Equals(As_opt_six, other.As_opt_six);
        case 407:
          return Equals(As_opt_seven, other.As_opt_seven);
        case 408:
          return Equals(As_opt_eight, other.As_opt_eight);
        default:
          return true;
    }
  }

  public override int GetHashCode()
  {
    switch (Isset)
    {
      case 1:
        return As_stars.GetHashCode();
      case 2:
        return As_stripes.GetHashCode();
      case 310:
        return As_far_set_list.GetHashCode();
      case 311:
        return As_far_list_map_set.GetHashCode();
      case 312:
        return As_far_map_dist_to_rds.GetHashCode();
      case 320:
        return As_nested_union.GetHashCode();
      case 321:
        return As_nested_struct.GetHashCode();
      case 401:
        return As_opt_one.GetHashCode();
      case 402:
        return As_opt_two.GetHashCode();
      case 403:
        return As_opt_three.GetHashCode();
      case 404:
        return As_opt_four.GetHashCode();
      case 405:
        return As_opt_five.GetHashCode();
      case 406:
        return As_opt_six.GetHashCode();
      case 407:
        return As_opt_seven.GetHashCode();
      case 408:
        return As_opt_eight.GetHashCode();
      default:
        return (new ___undefined()).GetHashCode();
    }
  }

  public jack DeepCopy()
  {
    switch (Isset)
    {
      case 1:
        return new stars(As_stars.DeepCopy());
      case 2:
        return new stripes(As_stripes.DeepCopy());
      case 310:
        return new far_set_list(As_far_set_list.DeepCopy());
      case 311:
        return new far_list_map_set(As_far_list_map_set.DeepCopy());
      case 312:
        return new far_map_dist_to_rds(As_far_map_dist_to_rds.DeepCopy());
      case 320:
        return new nested_union(As_nested_union.DeepCopy());
      case 321:
        return new nested_struct(As_nested_struct.DeepCopy());
      case 401:
        return new opt_one(As_opt_one);
      case 402:
        return new opt_two(As_opt_two);
      case 403:
        return new opt_three(As_opt_three);
      case 404:
        return new opt_four(As_opt_four);
      case 405:
        return new opt_five(As_opt_five.ToArray());
      case 406:
        return new opt_six(As_opt_six.DeepCopy());
      case 407:
        return new opt_seven(As_opt_seven.DeepCopy());
      case 408:
        return new opt_eight(As_opt_eight.DeepCopy());
      default:
        return new ___undefined();
    }
  }

  public class ___undefined : jack
  {
    public override object Data { get { return null; } }
    public ___undefined() : base(0) {}

    public new ___undefined DeepCopy()
    {
      return new ___undefined();
    }

    public override bool Equals(object that)
    {
      if (!(that is ___undefined other)) return false;
      if (ReferenceEquals(this, other)) return true;
      return true;
    }

    public override int GetHashCode() {
      int hashcode = 157;
      unchecked {
      }
      return hashcode;
    }

    public override global::System.Threading.Tasks.Task WriteAsync(TProtocol oprot, CancellationToken cancellationToken)
    {
      throw new TProtocolException( TProtocolException.INVALID_DATA, "Cannot persist an union type which is not set.");
    }

  }

  public List<global::OptReqDefTest.RaceDetails> As_stars
  {
    get
    {
      return (1 == Isset) ? (List<global::OptReqDefTest.RaceDetails>)Data : default(List<global::OptReqDefTest.RaceDetails>);
    }
  }

  public class stars : jack
  {
    private List<global::OptReqDefTest.RaceDetails> _data;
    public override object Data { get { return _data; } }
    public stars(List<global::OptReqDefTest.RaceDetails> data) : base(1)
    {
      this._data = data;
    }
    public new stars DeepCopy()
    {
      return new stars(_data.DeepCopy());
    }

    public override bool Equals(object that)
    {
      if (!(that is jack other)) return false;
      if (ReferenceEquals(this, other)) return true;

      return Equals( _data, other.As_stars);
    }

    public override int GetHashCode()
    {
      return _data.GetHashCode();
    }

    public override async global::System.Threading.Tasks.Task WriteAsync(TProtocol oprot, CancellationToken cancellationToken) {
      oprot.IncrementRecursionDepth();
      try
      {
        var struc = new TStruct("jack");
        await oprot.WriteStructBeginAsync(struc, cancellationToken);
        var field = new TField();
        field.Name = "stars";
        field.Type = TType.List;
        field.ID = 1;
        await oprot.WriteFieldBeginAsync(field, cancellationToken);
        {
          await oprot.WriteListBeginAsync(new TList(TType.Struct, _data.Count), cancellationToken);
          foreach (global::OptReqDefTest.RaceDetails _iter123 in _data)
          {
            await _iter123.WriteAsync(oprot, cancellationToken);
          }
          await oprot.WriteListEndAsync(cancellationToken);
        }
        await oprot.WriteFieldEndAsync(cancellationToken);
        await oprot.WriteFieldStopAsync(cancellationToken);
        await oprot.WriteStructEndAsync(cancellationToken);
      }
      finally
      {
        oprot.DecrementRecursionDepth();
      }
    }
  }

  public List<List<global::OptReqDefTest.RaceDetails>> As_stripes
  {
    get
    {
      return (2 == Isset) ? (List<List<global::OptReqDefTest.RaceDetails>>)Data : default(List<List<global::OptReqDefTest.RaceDetails>>);
    }
  }

  public class stripes : jack
  {
    private List<List<global::OptReqDefTest.RaceDetails>> _data;
    public override object Data { get { return _data; } }
    public stripes(List<List<global::OptReqDefTest.RaceDetails>> data) : base(2)
    {
      this._data = data;
    }
    public new stripes DeepCopy()
    {
      return new stripes(_data.DeepCopy());
    }

    public override bool Equals(object that)
    {
      if (!(that is jack other)) return false;
      if (ReferenceEquals(this, other)) return true;

      return Equals( _data, other.As_stripes);
    }

    public override int GetHashCode()
    {
      return _data.GetHashCode();
    }

    public override async global::System.Threading.Tasks.Task WriteAsync(TProtocol oprot, CancellationToken cancellationToken) {
      oprot.IncrementRecursionDepth();
      try
      {
        var struc = new TStruct("jack");
        await oprot.WriteStructBeginAsync(struc, cancellationToken);
        var field = new TField();
        field.Name = "stripes";
        field.Type = TType.List;
        field.ID = 2;
        await oprot.WriteFieldBeginAsync(field, cancellationToken);
        {
          await oprot.WriteListBeginAsync(new TList(TType.List, _data.Count), cancellationToken);
          foreach (List<global::OptReqDefTest.RaceDetails> _iter124 in _data)
          {
            {
              await oprot.WriteListBeginAsync(new TList(TType.Struct, _iter124.Count), cancellationToken);
              foreach (global::OptReqDefTest.RaceDetails _iter125 in _iter124)
              {
                await _iter125.WriteAsync(oprot, cancellationToken);
              }
              await oprot.WriteListEndAsync(cancellationToken);
            }
          }
          await oprot.WriteListEndAsync(cancellationToken);
        }
        await oprot.WriteFieldEndAsync(cancellationToken);
        await oprot.WriteFieldStopAsync(cancellationToken);
        await oprot.WriteStructEndAsync(cancellationToken);
      }
      finally
      {
        oprot.DecrementRecursionDepth();
      }
    }
  }

  public THashSet<List<global::OptReqDefTest.Distance>> As_far_set_list
  {
    get
    {
      return (310 == Isset) ? (THashSet<List<global::OptReqDefTest.Distance>>)Data : default(THashSet<List<global::OptReqDefTest.Distance>>);
    }
  }

  public class far_set_list : jack
  {
    private THashSet<List<global::OptReqDefTest.Distance>> _data;
    public override object Data { get { return _data; } }
    public far_set_list(THashSet<List<global::OptReqDefTest.Distance>> data) : base(310)
    {
      this._data = data;
    }
    public new far_set_list DeepCopy()
    {
      return new far_set_list(_data.DeepCopy());
    }

    public override bool Equals(object that)
    {
      if (!(that is jack other)) return false;
      if (ReferenceEquals(this, other)) return true;

      return Equals( _data, other.As_far_set_list);
    }

    public override int GetHashCode()
    {
      return _data.GetHashCode();
    }

    public override async global::System.Threading.Tasks.Task WriteAsync(TProtocol oprot, CancellationToken cancellationToken) {
      oprot.IncrementRecursionDepth();
      try
      {
        var struc = new TStruct("jack");
        await oprot.WriteStructBeginAsync(struc, cancellationToken);
        var field = new TField();
        field.Name = "far_set_list";
        field.Type = TType.Set;
        field.ID = 310;
        await oprot.WriteFieldBeginAsync(field, cancellationToken);
        {
          await oprot.WriteSetBeginAsync(new TSet(TType.List, _data.Count), cancellationToken);
          foreach (List<global::OptReqDefTest.Distance> _iter126 in _data)
          {
            {
              await oprot.WriteListBeginAsync(new TList(TType.I32, _iter126.Count), cancellationToken);
              foreach (global::OptReqDefTest.Distance _iter127 in _iter126)
              {
                await oprot.WriteI32Async((int)_iter127, cancellationToken);
              }
              await oprot.WriteListEndAsync(cancellationToken);
            }
          }
          await oprot.WriteSetEndAsync(cancellationToken);
        }
        await oprot.WriteFieldEndAsync(cancellationToken);
        await oprot.WriteFieldStopAsync(cancellationToken);
        await oprot.WriteStructEndAsync(cancellationToken);
      }
      finally
      {
        oprot.DecrementRecursionDepth();
      }
    }
  }

  public List<Dictionary<sbyte, THashSet<global::OptReqDefTest.Distance>>> As_far_list_map_set
  {
    get
    {
      return (311 == Isset) ? (List<Dictionary<sbyte, THashSet<global::OptReqDefTest.Distance>>>)Data : default(List<Dictionary<sbyte, THashSet<global::OptReqDefTest.Distance>>>);
    }
  }

  public class far_list_map_set : jack
  {
    private List<Dictionary<sbyte, THashSet<global::OptReqDefTest.Distance>>> _data;
    public override object Data { get { return _data; } }
    public far_list_map_set(List<Dictionary<sbyte, THashSet<global::OptReqDefTest.Distance>>> data) : base(311)
    {
      this._data = data;
    }
    public new far_list_map_set DeepCopy()
    {
      return new far_list_map_set(_data.DeepCopy());
    }

    public override bool Equals(object that)
    {
      if (!(that is jack other)) return false;
      if (ReferenceEquals(this, other)) return true;

      return Equals( _data, other.As_far_list_map_set);
    }

    public override int GetHashCode()
    {
      return _data.GetHashCode();
    }

    public override async global::System.Threading.Tasks.Task WriteAsync(TProtocol oprot, CancellationToken cancellationToken) {
      oprot.IncrementRecursionDepth();
      try
      {
        var struc = new TStruct("jack");
        await oprot.WriteStructBeginAsync(struc, cancellationToken);
        var field = new TField();
        field.Name = "far_list_map_set";
        field.Type = TType.List;
        field.ID = 311;
        await oprot.WriteFieldBeginAsync(field, cancellationToken);
        {
          await oprot.WriteListBeginAsync(new TList(TType.Map, _data.Count), cancellationToken);
          foreach (Dictionary<sbyte, THashSet<global::OptReqDefTest.Distance>> _iter128 in _data)
          {
            {
              await oprot.WriteMapBeginAsync(new TMap(TType.Byte, TType.Set, _iter128.Count), cancellationToken);
              foreach (sbyte _iter129 in _iter128.Keys)
              {
                await oprot.WriteByteAsync(_iter129, cancellationToken);
                {
                  await oprot.WriteSetBeginAsync(new TSet(TType.I32, _iter128[_iter129].Count), cancellationToken);
                  foreach (global::OptReqDefTest.Distance _iter130 in _iter128[_iter129])
                  {
                    await oprot.WriteI32Async((int)_iter130, cancellationToken);
                  }
                  await oprot.WriteSetEndAsync(cancellationToken);
                }
              }
              await oprot.WriteMapEndAsync(cancellationToken);
            }
          }
          await oprot.WriteListEndAsync(cancellationToken);
        }
        await oprot.WriteFieldEndAsync(cancellationToken);
        await oprot.WriteFieldStopAsync(cancellationToken);
        await oprot.WriteStructEndAsync(cancellationToken);
      }
      finally
      {
        oprot.DecrementRecursionDepth();
      }
    }
  }

  public Dictionary<global::OptReqDefTest.Distance, List<global::OptReqDefTest.RaceDetails>> As_far_map_dist_to_rds
  {
    get
    {
      return (312 == Isset) ? (Dictionary<global::OptReqDefTest.Distance, List<global::OptReqDefTest.RaceDetails>>)Data : default(Dictionary<global::OptReqDefTest.Distance, List<global::OptReqDefTest.RaceDetails>>);
    }
  }

  public class far_map_dist_to_rds : jack
  {
    private Dictionary<global::OptReqDefTest.Distance, List<global::OptReqDefTest.RaceDetails>> _data;
    public override object Data { get { return _data; } }
    public far_map_dist_to_rds(Dictionary<global::OptReqDefTest.Distance, List<global::OptReqDefTest.RaceDetails>> data) : base(312)
    {
      this._data = data;
    }
    public new far_map_dist_to_rds DeepCopy()
    {
      return new far_map_dist_to_rds(_data.DeepCopy());
    }

    public override bool Equals(object that)
    {
      if (!(that is jack other)) return false;
      if (ReferenceEquals(this, other)) return true;

      return Equals( _data, other.As_far_map_dist_to_rds);
    }

    public override int GetHashCode()
    {
      return _data.GetHashCode();
    }

    public override async global::System.Threading.Tasks.Task WriteAsync(TProtocol oprot, CancellationToken cancellationToken) {
      oprot.IncrementRecursionDepth();
      try
      {
        var struc = new TStruct("jack");
        await oprot.WriteStructBeginAsync(struc, cancellationToken);
        var field = new TField();
        field.Name = "far_map_dist_to_rds";
        field.Type = TType.Map;
        field.ID = 312;
        await oprot.WriteFieldBeginAsync(field, cancellationToken);
        {
          await oprot.WriteMapBeginAsync(new TMap(TType.I32, TType.List, _data.Count), cancellationToken);
          foreach (global::OptReqDefTest.Distance _iter131 in _data.Keys)
          {
            await oprot.WriteI32Async((int)_iter131, cancellationToken);
            {
              await oprot.WriteListBeginAsync(new TList(TType.Struct, _data[_iter131].Count), cancellationToken);
              foreach (global::OptReqDefTest.RaceDetails _iter132 in _data[_iter131])
              {
                await _iter132.WriteAsync(oprot, cancellationToken);
              }
              await oprot.WriteListEndAsync(cancellationToken);
            }
          }
          await oprot.WriteMapEndAsync(cancellationToken);
        }
        await oprot.WriteFieldEndAsync(cancellationToken);
        await oprot.WriteFieldStopAsync(cancellationToken);
        await oprot.WriteStructEndAsync(cancellationToken);
      }
      finally
      {
        oprot.DecrementRecursionDepth();
      }
    }
  }

  public global::OptReqDefTest.jack As_nested_union
  {
    get
    {
      return (320 == Isset) ? (global::OptReqDefTest.jack)Data : default(global::OptReqDefTest.jack);
    }
  }

  public class nested_union : jack
  {
    private global::OptReqDefTest.jack _data;
    public override object Data { get { return _data; } }
    public nested_union(global::OptReqDefTest.jack data) : base(320)
    {
      this._data = data;
    }
    public new nested_union DeepCopy()
    {
      return new nested_union(_data.DeepCopy());
    }

    public override bool Equals(object that)
    {
      if (!(that is jack other)) return false;
      if (ReferenceEquals(this, other)) return true;

      return Equals( _data, other.As_nested_union);
    }

    public override int GetHashCode()
    {
      return _data.GetHashCode();
    }

    public override async global::System.Threading.Tasks.Task WriteAsync(TProtocol oprot, CancellationToken cancellationToken) {
      oprot.IncrementRecursionDepth();
      try
      {
        var struc = new TStruct("jack");
        await oprot.WriteStructBeginAsync(struc, cancellationToken);
        var field = new TField();
        field.Name = "nested_union";
        field.Type = TType.Struct;
        field.ID = 320;
        await oprot.WriteFieldBeginAsync(field, cancellationToken);
        await _data.WriteAsync(oprot, cancellationToken);
        await oprot.WriteFieldEndAsync(cancellationToken);
        await oprot.WriteFieldStopAsync(cancellationToken);
        await oprot.WriteStructEndAsync(cancellationToken);
      }
      finally
      {
        oprot.DecrementRecursionDepth();
      }
    }
  }

  public global::OptReqDefTest.RaceDetails As_nested_struct
  {
    get
    {
      return (321 == Isset) ? (global::OptReqDefTest.RaceDetails)Data : default(global::OptReqDefTest.RaceDetails);
    }
  }

  public class nested_struct : jack
  {
    private global::OptReqDefTest.RaceDetails _data;
    public override object Data { get { return _data; } }
    public nested_struct(global::OptReqDefTest.RaceDetails data) : base(321)
    {
      this._data = data;
    }
    public new nested_struct DeepCopy()
    {
      return new nested_struct(_data.DeepCopy());
    }

    public override bool Equals(object that)
    {
      if (!(that is jack other)) return false;
      if (ReferenceEquals(this, other)) return true;

      return Equals( _data, other.As_nested_struct);
    }

    public override int GetHashCode()
    {
      return _data.GetHashCode();
    }

    public override async global::System.Threading.Tasks.Task WriteAsync(TProtocol oprot, CancellationToken cancellationToken) {
      oprot.IncrementRecursionDepth();
      try
      {
        var struc = new TStruct("jack");
        await oprot.WriteStructBeginAsync(struc, cancellationToken);
        var field = new TField();
        field.Name = "nested_struct";
        field.Type = TType.Struct;
        field.ID = 321;
        await oprot.WriteFieldBeginAsync(field, cancellationToken);
        await _data.WriteAsync(oprot, cancellationToken);
        await oprot.WriteFieldEndAsync(cancellationToken);
        await oprot.WriteFieldStopAsync(cancellationToken);
        await oprot.WriteStructEndAsync(cancellationToken);
      }
      finally
      {
        oprot.DecrementRecursionDepth();
      }
    }
  }

  public global::OptReqDefTest.Distance As_opt_one
  {
    get
    {
      return (401 == Isset) ? (global::OptReqDefTest.Distance)Data : default(global::OptReqDefTest.Distance);
    }
  }

  public class opt_one : jack
  {
    private global::OptReqDefTest.Distance _data;
    public override object Data { get { return _data; } }
    public opt_one(global::OptReqDefTest.Distance data) : base(401)
    {
      this._data = data;
    }
    public new opt_one DeepCopy()
    {
      return new opt_one(_data);
    }

    public override bool Equals(object that)
    {
      if (!(that is jack other)) return false;
      if (ReferenceEquals(this, other)) return true;

      return Equals( _data, other.As_opt_one);
    }

    public override int GetHashCode()
    {
      return _data.GetHashCode();
    }

    public override async global::System.Threading.Tasks.Task WriteAsync(TProtocol oprot, CancellationToken cancellationToken) {
      oprot.IncrementRecursionDepth();
      try
      {
        var struc = new TStruct("jack");
        await oprot.WriteStructBeginAsync(struc, cancellationToken);
        var field = new TField();
        field.Name = "opt_one";
        field.Type = TType.I32;
        field.ID = 401;
        await oprot.WriteFieldBeginAsync(field, cancellationToken);
        await oprot.WriteI32Async((int)_data, cancellationToken);
        await oprot.WriteFieldEndAsync(cancellationToken);
        await oprot.WriteFieldStopAsync(cancellationToken);
        await oprot.WriteStructEndAsync(cancellationToken);
      }
      finally
      {
        oprot.DecrementRecursionDepth();
      }
    }
  }

  public double As_opt_two
  {
    get
    {
      return (402 == Isset) ? (double)Data : default(double);
    }
  }

  public class opt_two : jack
  {
    private double _data;
    public override object Data { get { return _data; } }
    public opt_two(double data) : base(402)
    {
      this._data = data;
    }
    public new opt_two DeepCopy()
    {
      return new opt_two(_data);
    }

    public override bool Equals(object that)
    {
      if (!(that is jack other)) return false;
      if (ReferenceEquals(this, other)) return true;

      return Equals( _data, other.As_opt_two);
    }

    public override int GetHashCode()
    {
      return _data.GetHashCode();
    }

    public override async global::System.Threading.Tasks.Task WriteAsync(TProtocol oprot, CancellationToken cancellationToken) {
      oprot.IncrementRecursionDepth();
      try
      {
        var struc = new TStruct("jack");
        await oprot.WriteStructBeginAsync(struc, cancellationToken);
        var field = new TField();
        field.Name = "opt_two";
        field.Type = TType.Double;
        field.ID = 402;
        await oprot.WriteFieldBeginAsync(field, cancellationToken);
        await oprot.WriteDoubleAsync(_data, cancellationToken);
        await oprot.WriteFieldEndAsync(cancellationToken);
        await oprot.WriteFieldStopAsync(cancellationToken);
        await oprot.WriteStructEndAsync(cancellationToken);
      }
      finally
      {
        oprot.DecrementRecursionDepth();
      }
    }
  }

  public short As_opt_three
  {
    get
    {
      return (403 == Isset) ? (short)Data : default(short);
    }
  }

  public class opt_three : jack
  {
    private short _data;
    public override object Data { get { return _data; } }
    public opt_three(short data) : base(403)
    {
      this._data = data;
    }
    public new opt_three DeepCopy()
    {
      return new opt_three(_data);
    }

    public override bool Equals(object that)
    {
      if (!(that is jack other)) return false;
      if (ReferenceEquals(this, other)) return true;

      return Equals( _data, other.As_opt_three);
    }

    public override int GetHashCode()
    {
      return _data.GetHashCode();
    }

    public override async global::System.Threading.Tasks.Task WriteAsync(TProtocol oprot, CancellationToken cancellationToken) {
      oprot.IncrementRecursionDepth();
      try
      {
        var struc = new TStruct("jack");
        await oprot.WriteStructBeginAsync(struc, cancellationToken);
        var field = new TField();
        field.Name = "opt_three";
        field.Type = TType.I16;
        field.ID = 403;
        await oprot.WriteFieldBeginAsync(field, cancellationToken);
        await oprot.WriteI16Async(_data, cancellationToken);
        await oprot.WriteFieldEndAsync(cancellationToken);
        await oprot.WriteFieldStopAsync(cancellationToken);
        await oprot.WriteStructEndAsync(cancellationToken);
      }
      finally
      {
        oprot.DecrementRecursionDepth();
      }
    }
  }

  public string As_opt_four
  {
    get
    {
      return (404 == Isset) ? (string)Data : default(string);
    }
  }

  public class opt_four : jack
  {
    private string _data;
    public override object Data { get { return _data; } }
    public opt_four(string data) : base(404)
    {
      this._data = data;
    }
    public new opt_four DeepCopy()
    {
      return new opt_four(_data);
    }

    public override bool Equals(object that)
    {
      if (!(that is jack other)) return false;
      if (ReferenceEquals(this, other)) return true;

      return Equals( _data, other.As_opt_four);
    }

    public override int GetHashCode()
    {
      return _data.GetHashCode();
    }

    public override async global::System.Threading.Tasks.Task WriteAsync(TProtocol oprot, CancellationToken cancellationToken) {
      oprot.IncrementRecursionDepth();
      try
      {
        var struc = new TStruct("jack");
        await oprot.WriteStructBeginAsync(struc, cancellationToken);
        var field = new TField();
        field.Name = "opt_four";
        field.Type = TType.String;
        field.ID = 404;
        await oprot.WriteFieldBeginAsync(field, cancellationToken);
        await oprot.WriteStringAsync(_data, cancellationToken);
        await oprot.WriteFieldEndAsync(cancellationToken);
        await oprot.WriteFieldStopAsync(cancellationToken);
        await oprot.WriteStructEndAsync(cancellationToken);
      }
      finally
      {
        oprot.DecrementRecursionDepth();
      }
    }
  }

  public byte[] As_opt_five
  {
    get
    {
      return (405 == Isset) ? (byte[])Data : default(byte[]);
    }
  }

  public class opt_five : jack
  {
    private byte[] _data;
    public override object Data { get { return _data; } }
    public opt_five(byte[] data) : base(405)
    {
      this._data = data;
    }
    public new opt_five DeepCopy()
    {
      return new opt_five(_data.ToArray());
    }

    public override bool Equals(object that)
    {
      if (!(that is jack other)) return false;
      if (ReferenceEquals(this, other)) return true;

      return Equals( _data, other.As_opt_five);
    }

    public override int GetHashCode()
    {
      return _data.GetHashCode();
    }

    public override async global::System.Threading.Tasks.Task WriteAsync(TProtocol oprot, CancellationToken cancellationToken) {
      oprot.IncrementRecursionDepth();
      try
      {
        var struc = new TStruct("jack");
        await oprot.WriteStructBeginAsync(struc, cancellationToken);
        var field = new TField();
        field.Name = "opt_five";
        field.Type = TType.String;
        field.ID = 405;
        await oprot.WriteFieldBeginAsync(field, cancellationToken);
        await oprot.WriteBinaryAsync(_data, cancellationToken);
        await oprot.WriteFieldEndAsync(cancellationToken);
        await oprot.WriteFieldStopAsync(cancellationToken);
        await oprot.WriteStructEndAsync(cancellationToken);
      }
      finally
      {
        oprot.DecrementRecursionDepth();
      }
    }
  }

  public List<int> As_opt_six
  {
    get
    {
      return (406 == Isset) ? (List<int>)Data : default(List<int>);
    }
  }

  public class opt_six : jack
  {
    private List<int> _data;
    public override object Data { get { return _data; } }
    public opt_six(List<int> data) : base(406)
    {
      this._data = data;
    }
    public new opt_six DeepCopy()
    {
      return new opt_six(_data.DeepCopy());
    }

    public override bool Equals(object that)
    {
      if (!(that is jack other)) return false;
      if (ReferenceEquals(this, other)) return true;

      return Equals( _data, other.As_opt_six);
    }

    public override int GetHashCode()
    {
      return _data.GetHashCode();
    }

    public override async global::System.Threading.Tasks.Task WriteAsync(TProtocol oprot, CancellationToken cancellationToken) {
      oprot.IncrementRecursionDepth();
      try
      {
        var struc = new TStruct("jack");
        await oprot.WriteStructBeginAsync(struc, cancellationToken);
        var field = new TField();
        field.Name = "opt_six";
        field.Type = TType.List;
        field.ID = 406;
        await oprot.WriteFieldBeginAsync(field, cancellationToken);
        {
          await oprot.WriteListBeginAsync(new TList(TType.I32, _data.Count), cancellationToken);
          foreach (int _iter133 in _data)
          {
            await oprot.WriteI32Async(_iter133, cancellationToken);
          }
          await oprot.WriteListEndAsync(cancellationToken);
        }
        await oprot.WriteFieldEndAsync(cancellationToken);
        await oprot.WriteFieldStopAsync(cancellationToken);
        await oprot.WriteStructEndAsync(cancellationToken);
      }
      finally
      {
        oprot.DecrementRecursionDepth();
      }
    }
  }

  public THashSet<long> As_opt_seven
  {
    get
    {
      return (407 == Isset) ? (THashSet<long>)Data : default(THashSet<long>);
    }
  }

  public class opt_seven : jack
  {
    private THashSet<long> _data;
    public override object Data { get { return _data; } }
    public opt_seven(THashSet<long> data) : base(407)
    {
      this._data = data;
    }
    public new opt_seven DeepCopy()
    {
      return new opt_seven(_data.DeepCopy());
    }

    public override bool Equals(object that)
    {
      if (!(that is jack other)) return false;
      if (ReferenceEquals(this, other)) return true;

      return Equals( _data, other.As_opt_seven);
    }

    public override int GetHashCode()
    {
      return _data.GetHashCode();
    }

    public override async global::System.Threading.Tasks.Task WriteAsync(TProtocol oprot, CancellationToken cancellationToken) {
      oprot.IncrementRecursionDepth();
      try
      {
        var struc = new TStruct("jack");
        await oprot.WriteStructBeginAsync(struc, cancellationToken);
        var field = new TField();
        field.Name = "opt_seven";
        field.Type = TType.Set;
        field.ID = 407;
        await oprot.WriteFieldBeginAsync(field, cancellationToken);
        {
          await oprot.WriteSetBeginAsync(new TSet(TType.I64, _data.Count), cancellationToken);
          foreach (long _iter134 in _data)
          {
            await oprot.WriteI64Async(_iter134, cancellationToken);
          }
          await oprot.WriteSetEndAsync(cancellationToken);
        }
        await oprot.WriteFieldEndAsync(cancellationToken);
        await oprot.WriteFieldStopAsync(cancellationToken);
        await oprot.WriteStructEndAsync(cancellationToken);
      }
      finally
      {
        oprot.DecrementRecursionDepth();
      }
    }
  }

  public Dictionary<sbyte, short> As_opt_eight
  {
    get
    {
      return (408 == Isset) ? (Dictionary<sbyte, short>)Data : default(Dictionary<sbyte, short>);
    }
  }

  public class opt_eight : jack
  {
    private Dictionary<sbyte, short> _data;
    public override object Data { get { return _data; } }
    public opt_eight(Dictionary<sbyte, short> data) : base(408)
    {
      this._data = data;
    }
    public new opt_eight DeepCopy()
    {
      return new opt_eight(_data.DeepCopy());
    }

    public override bool Equals(object that)
    {
      if (!(that is jack other)) return false;
      if (ReferenceEquals(this, other)) return true;

      return Equals( _data, other.As_opt_eight);
    }

    public override int GetHashCode()
    {
      return _data.GetHashCode();
    }

    public override async global::System.Threading.Tasks.Task WriteAsync(TProtocol oprot, CancellationToken cancellationToken) {
      oprot.IncrementRecursionDepth();
      try
      {
        var struc = new TStruct("jack");
        await oprot.WriteStructBeginAsync(struc, cancellationToken);
        var field = new TField();
        field.Name = "opt_eight";
        field.Type = TType.Map;
        field.ID = 408;
        await oprot.WriteFieldBeginAsync(field, cancellationToken);
        {
          await oprot.WriteMapBeginAsync(new TMap(TType.Byte, TType.I16, _data.Count), cancellationToken);
          foreach (sbyte _iter135 in _data.Keys)
          {
            await oprot.WriteByteAsync(_iter135, cancellationToken);
            await oprot.WriteI16Async(_data[_iter135], cancellationToken);
          }
          await oprot.WriteMapEndAsync(cancellationToken);
        }
        await oprot.WriteFieldEndAsync(cancellationToken);
        await oprot.WriteFieldStopAsync(cancellationToken);
        await oprot.WriteStructEndAsync(cancellationToken);
      }
      finally
      {
        oprot.DecrementRecursionDepth();
      }
    }
  }

  public static async Task<jack> ReadAsync(TProtocol iprot, CancellationToken cancellationToken)
  {
    iprot.IncrementRecursionDepth();
    try
    {
      jack retval;
      await iprot.ReadStructBeginAsync(cancellationToken);
      TField field = await iprot.ReadFieldBeginAsync(cancellationToken);
      if (field.Type == TType.Stop)
      {
        await iprot.ReadFieldEndAsync(cancellationToken);
        retval = new ___undefined();
      }
      else
      {
        switch (field.ID)
        {
          case 1:
            if (field.Type == TType.List) {
              List<global::OptReqDefTest.RaceDetails> temp;
              {
                TList _list136 = await iprot.ReadListBeginAsync(cancellationToken);
                temp = new List<global::OptReqDefTest.RaceDetails>(_list136.Count);
                for(int _i137 = 0; _i137 < _list136.Count; ++_i137)
                {
                  global::OptReqDefTest.RaceDetails _elem138;
                  _elem138 = new global::OptReqDefTest.RaceDetails();
                  await _elem138.ReadAsync(iprot, cancellationToken);
                  temp.Add(_elem138);
                }
                await iprot.ReadListEndAsync(cancellationToken);
              }
              retval = new stars(temp);
            } else { 
             await TProtocolUtil.SkipAsync(iprot, field.Type, cancellationToken);
              retval = new ___undefined();
            }
            break;
          case 2:
            if (field.Type == TType.List) {
              List<List<global::OptReqDefTest.RaceDetails>> temp;
              {
                TList _list139 = await iprot.ReadListBeginAsync(cancellationToken);
                temp = new List<List<global::OptReqDefTest.RaceDetails>>(_list139.Count);
                for(int _i140 = 0; _i140 < _list139.Count; ++_i140)
                {
                  List<global::OptReqDefTest.RaceDetails> _elem141;
                  {
                    TList _list142 = await iprot.ReadListBeginAsync(cancellationToken);
                    _elem141 = new List<global::OptReqDefTest.RaceDetails>(_list142.Count);
                    for(int _i143 = 0; _i143 < _list142.Count; ++_i143)
                    {
                      global::OptReqDefTest.RaceDetails _elem144;
                      _elem144 = new global::OptReqDefTest.RaceDetails();
                      await _elem144.ReadAsync(iprot, cancellationToken);
                      _elem141.Add(_elem144);
                    }
                    await iprot.ReadListEndAsync(cancellationToken);
                  }
                  temp.Add(_elem141);
                }
                await iprot.ReadListEndAsync(cancellationToken);
              }
              retval = new stripes(temp);
            } else { 
             await TProtocolUtil.SkipAsync(iprot, field.Type, cancellationToken);
              retval = new ___undefined();
            }
            break;
          case 310:
            if (field.Type == TType.Set) {
              THashSet<List<global::OptReqDefTest.Distance>> temp;
              {
                TSet _set145 = await iprot.ReadSetBeginAsync(cancellationToken);
                temp = new THashSet<List<global::OptReqDefTest.Distance>>(_set145.Count);
                for(int _i146 = 0; _i146 < _set145.Count; ++_i146)
                {
                  List<global::OptReqDefTest.Distance> _elem147;
                  {
                    TList _list148 = await iprot.ReadListBeginAsync(cancellationToken);
                    _elem147 = new List<global::OptReqDefTest.Distance>(_list148.Count);
                    for(int _i149 = 0; _i149 < _list148.Count; ++_i149)
                    {
                      global::OptReqDefTest.Distance _elem150;
                      _elem150 = (global::OptReqDefTest.Distance)await iprot.ReadI32Async(cancellationToken);
                      _elem147.Add(_elem150);
                    }
                    await iprot.ReadListEndAsync(cancellationToken);
                  }
                  temp.Add(_elem147);
                }
                await iprot.ReadSetEndAsync(cancellationToken);
              }
              retval = new far_set_list(temp);
            } else { 
             await TProtocolUtil.SkipAsync(iprot, field.Type, cancellationToken);
              retval = new ___undefined();
            }
            break;
          case 311:
            if (field.Type == TType.List) {
              List<Dictionary<sbyte, THashSet<global::OptReqDefTest.Distance>>> temp;
              {
                TList _list151 = await iprot.ReadListBeginAsync(cancellationToken);
                temp = new List<Dictionary<sbyte, THashSet<global::OptReqDefTest.Distance>>>(_list151.Count);
                for(int _i152 = 0; _i152 < _list151.Count; ++_i152)
                {
                  Dictionary<sbyte, THashSet<global::OptReqDefTest.Distance>> _elem153;
                  {
                    TMap _map154 = await iprot.ReadMapBeginAsync(cancellationToken);
                    _elem153 = new Dictionary<sbyte, THashSet<global::OptReqDefTest.Distance>>(_map154.Count);
                    for(int _i155 = 0; _i155 < _map154.Count; ++_i155)
                    {
                      sbyte _key156;
                      THashSet<global::OptReqDefTest.Distance> _val157;
                      _key156 = await iprot.ReadByteAsync(cancellationToken);
                      {
                        TSet _set158 = await iprot.ReadSetBeginAsync(cancellationToken);
                        _val157 = new THashSet<global::OptReqDefTest.Distance>(_set158.Count);
                        for(int _i159 = 0; _i159 < _set158.Count; ++_i159)
                        {
                          global::OptReqDefTest.Distance _elem160;
                          _elem160 = (global::OptReqDefTest.Distance)await iprot.ReadI32Async(cancellationToken);
                          _val157.Add(_elem160);
                        }
                        await iprot.ReadSetEndAsync(cancellationToken);
                      }
                      _elem153[_key156] = _val157;
                    }
                    await iprot.ReadMapEndAsync(cancellationToken);
                  }
                  temp.Add(_elem153);
                }
                await iprot.ReadListEndAsync(cancellationToken);
              }
              retval = new far_list_map_set(temp);
            } else { 
             await TProtocolUtil.SkipAsync(iprot, field.Type, cancellationToken);
              retval = new ___undefined();
            }
            break;
          case 312:
            if (field.Type == TType.Map) {
              Dictionary<global::OptReqDefTest.Distance, List<global::OptReqDefTest.RaceDetails>> temp;
              {
                TMap _map161 = await iprot.ReadMapBeginAsync(cancellationToken);
                temp = new Dictionary<global::OptReqDefTest.Distance, List<global::OptReqDefTest.RaceDetails>>(_map161.Count);
                for(int _i162 = 0; _i162 < _map161.Count; ++_i162)
                {
                  global::OptReqDefTest.Distance _key163;
                  List<global::OptReqDefTest.RaceDetails> _val164;
                  _key163 = (global::OptReqDefTest.Distance)await iprot.ReadI32Async(cancellationToken);
                  {
                    TList _list165 = await iprot.ReadListBeginAsync(cancellationToken);
                    _val164 = new List<global::OptReqDefTest.RaceDetails>(_list165.Count);
                    for(int _i166 = 0; _i166 < _list165.Count; ++_i166)
                    {
                      global::OptReqDefTest.RaceDetails _elem167;
                      _elem167 = new global::OptReqDefTest.RaceDetails();
                      await _elem167.ReadAsync(iprot, cancellationToken);
                      _val164.Add(_elem167);
                    }
                    await iprot.ReadListEndAsync(cancellationToken);
                  }
                  temp[_key163] = _val164;
                }
                await iprot.ReadMapEndAsync(cancellationToken);
              }
              retval = new far_map_dist_to_rds(temp);
            } else { 
             await TProtocolUtil.SkipAsync(iprot, field.Type, cancellationToken);
              retval = new ___undefined();
            }
            break;
          case 320:
            if (field.Type == TType.Struct) {
              global::OptReqDefTest.jack temp;
              temp = await global::OptReqDefTest.jack.ReadAsync(iprot, cancellationToken);
              retval = new nested_union(temp);
            } else { 
             await TProtocolUtil.SkipAsync(iprot, field.Type, cancellationToken);
              retval = new ___undefined();
            }
            break;
          case 321:
            if (field.Type == TType.Struct) {
              global::OptReqDefTest.RaceDetails temp;
              temp = new global::OptReqDefTest.RaceDetails();
              await temp.ReadAsync(iprot, cancellationToken);
              retval = new nested_struct(temp);
            } else { 
             await TProtocolUtil.SkipAsync(iprot, field.Type, cancellationToken);
              retval = new ___undefined();
            }
            break;
          case 401:
            if (field.Type == TType.I32) {
              global::OptReqDefTest.Distance temp;
              temp = (global::OptReqDefTest.Distance)await iprot.ReadI32Async(cancellationToken);
              retval = new opt_one(temp);
            } else { 
             await TProtocolUtil.SkipAsync(iprot, field.Type, cancellationToken);
              retval = new ___undefined();
            }
            break;
          case 402:
            if (field.Type == TType.Double) {
              double temp;
              temp = await iprot.ReadDoubleAsync(cancellationToken);
              retval = new opt_two(temp);
            } else { 
             await TProtocolUtil.SkipAsync(iprot, field.Type, cancellationToken);
              retval = new ___undefined();
            }
            break;
          case 403:
            if (field.Type == TType.I16) {
              short temp;
              temp = await iprot.ReadI16Async(cancellationToken);
              retval = new opt_three(temp);
            } else { 
             await TProtocolUtil.SkipAsync(iprot, field.Type, cancellationToken);
              retval = new ___undefined();
            }
            break;
          case 404:
            if (field.Type == TType.String) {
              string temp;
              temp = await iprot.ReadStringAsync(cancellationToken);
              retval = new opt_four(temp);
            } else { 
             await TProtocolUtil.SkipAsync(iprot, field.Type, cancellationToken);
              retval = new ___undefined();
            }
            break;
          case 405:
            if (field.Type == TType.String) {
              byte[] temp;
              temp = await iprot.ReadBinaryAsync(cancellationToken);
              retval = new opt_five(temp);
            } else { 
             await TProtocolUtil.SkipAsync(iprot, field.Type, cancellationToken);
              retval = new ___undefined();
            }
            break;
          case 406:
            if (field.Type == TType.List) {
              List<int> temp;
              {
                TList _list168 = await iprot.ReadListBeginAsync(cancellationToken);
                temp = new List<int>(_list168.Count);
                for(int _i169 = 0; _i169 < _list168.Count; ++_i169)
                {
                  int _elem170;
                  _elem170 = await iprot.ReadI32Async(cancellationToken);
                  temp.Add(_elem170);
                }
                await iprot.ReadListEndAsync(cancellationToken);
              }
              retval = new opt_six(temp);
            } else { 
             await TProtocolUtil.SkipAsync(iprot, field.Type, cancellationToken);
              retval = new ___undefined();
            }
            break;
          case 407:
            if (field.Type == TType.Set) {
              THashSet<long> temp;
              {
                TSet _set171 = await iprot.ReadSetBeginAsync(cancellationToken);
                temp = new THashSet<long>(_set171.Count);
                for(int _i172 = 0; _i172 < _set171.Count; ++_i172)
                {
                  long _elem173;
                  _elem173 = await iprot.ReadI64Async(cancellationToken);
                  temp.Add(_elem173);
                }
                await iprot.ReadSetEndAsync(cancellationToken);
              }
              retval = new opt_seven(temp);
            } else { 
             await TProtocolUtil.SkipAsync(iprot, field.Type, cancellationToken);
              retval = new ___undefined();
            }
            break;
          case 408:
            if (field.Type == TType.Map) {
              Dictionary<sbyte, short> temp;
              {
                TMap _map174 = await iprot.ReadMapBeginAsync(cancellationToken);
                temp = new Dictionary<sbyte, short>(_map174.Count);
                for(int _i175 = 0; _i175 < _map174.Count; ++_i175)
                {
                  sbyte _key176;
                  short _val177;
                  _key176 = await iprot.ReadByteAsync(cancellationToken);
                  _val177 = await iprot.ReadI16Async(cancellationToken);
                  temp[_key176] = _val177;
                }
                await iprot.ReadMapEndAsync(cancellationToken);
              }
              retval = new opt_eight(temp);
            } else { 
             await TProtocolUtil.SkipAsync(iprot, field.Type, cancellationToken);
              retval = new ___undefined();
            }
            break;
          default: 
            await TProtocolUtil.SkipAsync(iprot, field.Type, cancellationToken);
            retval = new ___undefined();
            break;
        }
        await iprot.ReadFieldEndAsync(cancellationToken);
        if ((await iprot.ReadFieldBeginAsync(cancellationToken)).Type != TType.Stop)
        {
          throw new TProtocolException(TProtocolException.INVALID_DATA);
        }
      }
      await iprot.ReadStructEndAsync(cancellationToken);
      return retval;
  }
  finally
  {
    iprot.DecrementRecursionDepth();
  }
  }

}

}
