<?php
/**
 * Autogenerated by Thrift Compiler (0.16.0)
 *
 * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 *  @generated
 */
use Thrift\Base\TBase;
use Thrift\Type\TType;
use Thrift\Type\TMessageType;
use Thrift\Exception\TException;
use Thrift\Exception\TProtocolException;
use Thrift\Protocol\TProtocol;
use Thrift\Protocol\TBinaryProtocolAccelerated;
use Thrift\Exception\TApplicationException;

class TTypeEntry
{
    static public $isValidate = false;

    static public $_TSPEC = array(
        1 => array(
            'var' => 'primitiveEntry',
            'isRequired' => false,
            'type' => TType::STRUCT,
            'class' => '\TPrimitiveTypeEntry',
        ),
        2 => array(
            'var' => 'arrayEntry',
            'isRequired' => false,
            'type' => TType::STRUCT,
            'class' => '\TArrayTypeEntry',
        ),
        3 => array(
            'var' => 'mapEntry',
            'isRequired' => false,
            'type' => TType::STRUCT,
            'class' => '\TMapTypeEntry',
        ),
        4 => array(
            'var' => 'structEntry',
            'isRequired' => false,
            'type' => TType::STRUCT,
            'class' => '\TStructTypeEntry',
        ),
        5 => array(
            'var' => 'unionEntry',
            'isRequired' => false,
            'type' => TType::STRUCT,
            'class' => '\TUnionTypeEntry',
        ),
        6 => array(
            'var' => 'userDefinedTypeEntry',
            'isRequired' => false,
            'type' => TType::STRUCT,
            'class' => '\TUserDefinedTypeEntry',
        ),
    );

    /**
     * @var \TPrimitiveTypeEntry
     */
    public $primitiveEntry = null;
    /**
     * @var \TArrayTypeEntry
     */
    public $arrayEntry = null;
    /**
     * @var \TMapTypeEntry
     */
    public $mapEntry = null;
    /**
     * @var \TStructTypeEntry
     */
    public $structEntry = null;
    /**
     * @var \TUnionTypeEntry
     */
    public $unionEntry = null;
    /**
     * @var \TUserDefinedTypeEntry
     */
    public $userDefinedTypeEntry = null;

    public function __construct($vals = null)
    {
        if (is_array($vals)) {
            if (isset($vals['primitiveEntry'])) {
                $this->primitiveEntry = $vals['primitiveEntry'];
            }
            if (isset($vals['arrayEntry'])) {
                $this->arrayEntry = $vals['arrayEntry'];
            }
            if (isset($vals['mapEntry'])) {
                $this->mapEntry = $vals['mapEntry'];
            }
            if (isset($vals['structEntry'])) {
                $this->structEntry = $vals['structEntry'];
            }
            if (isset($vals['unionEntry'])) {
                $this->unionEntry = $vals['unionEntry'];
            }
            if (isset($vals['userDefinedTypeEntry'])) {
                $this->userDefinedTypeEntry = $vals['userDefinedTypeEntry'];
            }
        }
    }

    public function getName()
    {
        return 'TTypeEntry';
    }


    public function read($input)
    {
        $xfer = 0;
        $fname = null;
        $ftype = 0;
        $fid = 0;
        $xfer += $input->readStructBegin($fname);
        while (true) {
            $xfer += $input->readFieldBegin($fname, $ftype, $fid);
            if ($ftype == TType::STOP) {
                break;
            }
            switch ($fid) {
                case 1:
                    if ($ftype == TType::STRUCT) {
                        $this->primitiveEntry = new \TPrimitiveTypeEntry();
                        $xfer += $this->primitiveEntry->read($input);
                    } else {
                        $xfer += $input->skip($ftype);
                    }
                    break;
                case 2:
                    if ($ftype == TType::STRUCT) {
                        $this->arrayEntry = new \TArrayTypeEntry();
                        $xfer += $this->arrayEntry->read($input);
                    } else {
                        $xfer += $input->skip($ftype);
                    }
                    break;
                case 3:
                    if ($ftype == TType::STRUCT) {
                        $this->mapEntry = new \TMapTypeEntry();
                        $xfer += $this->mapEntry->read($input);
                    } else {
                        $xfer += $input->skip($ftype);
                    }
                    break;
                case 4:
                    if ($ftype == TType::STRUCT) {
                        $this->structEntry = new \TStructTypeEntry();
                        $xfer += $this->structEntry->read($input);
                    } else {
                        $xfer += $input->skip($ftype);
                    }
                    break;
                case 5:
                    if ($ftype == TType::STRUCT) {
                        $this->unionEntry = new \TUnionTypeEntry();
                        $xfer += $this->unionEntry->read($input);
                    } else {
                        $xfer += $input->skip($ftype);
                    }
                    break;
                case 6:
                    if ($ftype == TType::STRUCT) {
                        $this->userDefinedTypeEntry = new \TUserDefinedTypeEntry();
                        $xfer += $this->userDefinedTypeEntry->read($input);
                    } else {
                        $xfer += $input->skip($ftype);
                    }
                    break;
                default:
                    $xfer += $input->skip($ftype);
                    break;
            }
            $xfer += $input->readFieldEnd();
        }
        $xfer += $input->readStructEnd();
        return $xfer;
    }

    public function write($output)
    {
        $xfer = 0;
        $xfer += $output->writeStructBegin('TTypeEntry');
        if ($this->primitiveEntry !== null) {
            if (!is_object($this->primitiveEntry)) {
                throw new TProtocolException('Bad type in structure.', TProtocolException::INVALID_DATA);
            }
            $xfer += $output->writeFieldBegin('primitiveEntry', TType::STRUCT, 1);
            $xfer += $this->primitiveEntry->write($output);
            $xfer += $output->writeFieldEnd();
        }
        if ($this->arrayEntry !== null) {
            if (!is_object($this->arrayEntry)) {
                throw new TProtocolException('Bad type in structure.', TProtocolException::INVALID_DATA);
            }
            $xfer += $output->writeFieldBegin('arrayEntry', TType::STRUCT, 2);
            $xfer += $this->arrayEntry->write($output);
            $xfer += $output->writeFieldEnd();
        }
        if ($this->mapEntry !== null) {
            if (!is_object($this->mapEntry)) {
                throw new TProtocolException('Bad type in structure.', TProtocolException::INVALID_DATA);
            }
            $xfer += $output->writeFieldBegin('mapEntry', TType::STRUCT, 3);
            $xfer += $this->mapEntry->write($output);
            $xfer += $output->writeFieldEnd();
        }
        if ($this->structEntry !== null) {
            if (!is_object($this->structEntry)) {
                throw new TProtocolException('Bad type in structure.', TProtocolException::INVALID_DATA);
            }
            $xfer += $output->writeFieldBegin('structEntry', TType::STRUCT, 4);
            $xfer += $this->structEntry->write($output);
            $xfer += $output->writeFieldEnd();
        }
        if ($this->unionEntry !== null) {
            if (!is_object($this->unionEntry)) {
                throw new TProtocolException('Bad type in structure.', TProtocolException::INVALID_DATA);
            }
            $xfer += $output->writeFieldBegin('unionEntry', TType::STRUCT, 5);
            $xfer += $this->unionEntry->write($output);
            $xfer += $output->writeFieldEnd();
        }
        if ($this->userDefinedTypeEntry !== null) {
            if (!is_object($this->userDefinedTypeEntry)) {
                throw new TProtocolException('Bad type in structure.', TProtocolException::INVALID_DATA);
            }
            $xfer += $output->writeFieldBegin('userDefinedTypeEntry', TType::STRUCT, 6);
            $xfer += $this->userDefinedTypeEntry->write($output);
            $xfer += $output->writeFieldEnd();
        }
        $xfer += $output->writeFieldStop();
        $xfer += $output->writeStructEnd();
        return $xfer;
    }
}
