<?php

// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc.  All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd

/**
 * Defines Message, the parent class extended by all protocol message classes.
 */

namespace Google\Protobuf\Internal;

use Google\Protobuf\Internal\CodedInputStream;
use Google\Protobuf\Internal\CodedOutputStream;
use Google\Protobuf\Internal\DescriptorPool;
use Google\Protobuf\Internal\GPBLabel;
use Google\Protobuf\Internal\GPBType;
use Google\Protobuf\Internal\GPBWire;
use Google\Protobuf\Internal\MapEntry;
use Google\Protobuf\Internal\RepeatedField;
use Google\Protobuf\ListValue;
use Google\Protobuf\Value;
use Google\Protobuf\Struct;
use Google\Protobuf\NullValue;

/**
 * Parent class of all proto messages. Users should not instantiate this class
 * or extend this class or its child classes by their own.  See the comment of
 * specific functions for more details.
 */
#[\AllowDynamicProperties]
class Message
{

    /**
     * @ignore
     */
    private $desc;
    private $unknown = "";

    /**
     * @ignore
     */
    public function __construct($data = NULL)
    {
        // MapEntry message is shared by all types of map fields, whose
        // descriptors are different from each other. Thus, we cannot find a
        // specific descriptor from the descriptor pool.
        if ($this instanceof MapEntry) {
            $this->initWithDescriptor($data);
        } else {
            $this->initWithGeneratedPool();
            if (is_array($data)) {
                $this->mergeFromArray($data);
            } else if (!empty($data)) {
                throw new \InvalidArgumentException(
                    'Message constructor must be an array or null.'
                );
            }
        }
    }

    /**
     * @ignore
     */
    private function initWithGeneratedPool()
    {
        $pool = DescriptorPool::getGeneratedPool();
        $this->desc = $pool->getDescriptorByClassName(get_class($this));
        if (is_null($this->desc)) {
          throw new \InvalidArgumentException(
            get_class($this) ." is not found in descriptor pool. " .
            'Only generated classes may derive from Message.');
        }
        foreach ($this->desc->getField() as $field) {
            $setter = $field->getSetter();
            if ($field->isMap()) {
                $message_type = $field->getMessageType();
                $key_field = $message_type->getFieldByNumber(1);
                $value_field = $message_type->getFieldByNumber(2);
                switch ($value_field->getType()) {
                    case GPBType::MESSAGE:
                    case GPBType::GROUP:
                        $map_field = new MapField(
                            $key_field->getType(),
                            $value_field->getType(),
                            $value_field->getMessageType()->getClass());
                        $this->$setter($map_field);
                        break;
                    case GPBType::ENUM:
                        $map_field = new MapField(
                            $key_field->getType(),
                            $value_field->getType(),
                            $value_field->getEnumType()->getClass());
                        $this->$setter($map_field);
                        break;
                    default:
                        $map_field = new MapField(
                            $key_field->getType(),
                            $value_field->getType());
                        $this->$setter($map_field);
                        break;
                }
            } else if ($field->getLabel() === GPBLabel::REPEATED) {
                switch ($field->getType()) {
                    case GPBType::MESSAGE:
                    case GPBType::GROUP:
                        $repeated_field = new RepeatedField(
                            $field->getType(),
                            $field->getMessageType()->getClass());
                        $this->$setter($repeated_field);
                        break;
                    case GPBType::ENUM:
                        $repeated_field = new RepeatedField(
                            $field->getType(),
                            $field->getEnumType()->getClass());
                        $this->$setter($repeated_field);
                        break;
                    default:
                        $repeated_field = new RepeatedField($field->getType());
                        $this->$setter($repeated_field);
                        break;
                }
            } else if ($field->getOneofIndex() !== -1) {
                $oneof = $this->desc->getOneofDecl()[$field->getOneofIndex()];
                $oneof_name = $oneof->getName();
                $this->$oneof_name = new OneofField($oneof);
            } else if ($field->getLabel() === GPBLabel::OPTIONAL &&
                       PHP_INT_SIZE == 4) {
                switch ($field->getType()) {
                    case GPBType::INT64:
                    case GPBType::UINT64:
                    case GPBType::FIXED64:
                    case GPBType::SFIXED64:
                    case GPBType::SINT64:
                        $this->$setter("0");
                }
            }
        }
    }

    /**
     * @ignore
     */
    private function initWithDescriptor(Descriptor $desc)
    {
        $this->desc = $desc;
        foreach ($desc->getField() as $field) {
            $setter = $field->getSetter();
            $defaultValue = $this->defaultValue($field);
            $this->$setter($defaultValue);
        }
    }

    protected function readWrapperValue($member)
    {
        $field = $this->desc->getFieldByName($member);
        $oneof_index = $field->getOneofIndex();
        if ($oneof_index === -1) {
            $wrapper = $this->$member;
        } else {
            $wrapper = $this->readOneof($field->getNumber());
        }

        if (is_null($wrapper)) {
            return NULL;
        } else {
            return $wrapper->getValue();
        }
    }

    protected function writeWrapperValue($member, $value)
    {
        $field = $this->desc->getFieldByName($member);
        $wrapped_value = $value;
        if (!is_null($value)) {
            $desc = $field->getMessageType();
            $klass = $desc->getClass();
            $wrapped_value = new $klass;
            $wrapped_value->setValue($value);
        }

        $oneof_index = $field->getOneofIndex();
        if ($oneof_index === -1) {
            $this->$member = $wrapped_value;
        } else {
            $this->writeOneof($field->getNumber(), $wrapped_value);
        }
    }

    protected function readOneof($number)
    {
        $field = $this->desc->getFieldByNumber($number);
        $oneof = $this->desc->getOneofDecl()[$field->getOneofIndex()];
        $oneof_name = $oneof->getName();
        $oneof_field = $this->$oneof_name;
        if ($number === $oneof_field->getNumber()) {
            return $oneof_field->getValue();
        } else {
            return $this->defaultValue($field);
        }
    }

    protected function hasOneof($number)
    {
        $field = $this->desc->getFieldByNumber($number);
        $oneof = $this->desc->getOneofDecl()[$field->getOneofIndex()];
        $oneof_name = $oneof->getName();
        $oneof_field = $this->$oneof_name;
        return $number === $oneof_field->getNumber();
    }

    protected function writeOneof($number, $value)
    {
        $field = $this->desc->getFieldByNumber($number);
        $oneof = $this->desc->getOneofDecl()[$field->getOneofIndex()];
        $oneof_name = $oneof->getName();
        if ($value === null) {
            $this->$oneof_name = new OneofField($oneof);
        } else {
            $oneof_field = $this->$oneof_name;
            $oneof_field->setValue($value);
            $oneof_field->setFieldName($field->getName());
            $oneof_field->setNumber($number);
        }
    }

    protected function whichOneof($oneof_name)
    {
        $oneof_field = $this->$oneof_name;
        $number = $oneof_field->getNumber();
        if ($number == 0) {
          return "";
        }
        $field = $this->desc->getFieldByNumber($number);
        return $field->getName();
    }

    /**
     * @ignore
     */
    private function defaultValue($field)
    {
        $value = null;

        switch ($field->getType()) {
            case GPBType::DOUBLE:
            case GPBType::FLOAT:
                return 0.0;
            case GPBType::UINT32:
            case GPBType::INT32:
            case GPBType::FIXED32:
            case GPBType::SFIXED32:
            case GPBType::SINT32:
            case GPBType::ENUM:
                return 0;
            case GPBType::INT64:
            case GPBType::UINT64:
            case GPBType::FIXED64:
            case GPBType::SFIXED64:
            case GPBType::SINT64:
                if (PHP_INT_SIZE === 4) {
                    return '0';
                } else {
                    return 0;
                }
            case GPBType::BOOL:
                return false;
            case GPBType::STRING:
            case GPBType::BYTES:
                return "";
            case GPBType::GROUP:
            case GPBType::MESSAGE:
                return null;
            default:
                user_error("Unsupported type.");
                return false;
        }
    }

    /**
     * @ignore
     */
    private function skipField($input, $tag)
    {
        $number = GPBWire::getTagFieldNumber($tag);
        if ($number === 0) {
            throw new GPBDecodeException("Illegal field number zero.");
        }

        $start = $input->current();
        switch (GPBWire::getTagWireType($tag)) {
            case GPBWireType::VARINT:
                $uint64 = 0;
                if (!$input->readVarint64($uint64)) {
                    throw new GPBDecodeException(
                        "Unexpected EOF inside varint.");
                }
                break;
            case GPBWireType::FIXED64:
                $uint64 = 0;
                if (!$input->readLittleEndian64($uint64)) {
                    throw new GPBDecodeException(
                        "Unexpected EOF inside fixed64.");
                }
                break;
            case GPBWireType::FIXED32:
                $uint32 = 0;
                if (!$input->readLittleEndian32($uint32)) {
                    throw new GPBDecodeException(
                        "Unexpected EOF inside fixed32.");
                }
                break;
            case GPBWireType::LENGTH_DELIMITED:
                $length = 0;
                if (!$input->readVarint32($length)) {
                    throw new GPBDecodeException(
                        "Unexpected EOF inside length.");
                }
                $data = NULL;
                if (!$input->readRaw($length, $data)) {
                    throw new GPBDecodeException(
                        "Unexpected EOF inside length delimited data.");
                }
                break;
            case GPBWireType::START_GROUP:
            case GPBWireType::END_GROUP:
                throw new GPBDecodeException("Unexpected wire type.");
            default:
                throw new GPBDecodeException("Unexpected wire type.");
        }
        $end = $input->current();

        $bytes = str_repeat(chr(0), CodedOutputStream::MAX_VARINT64_BYTES);
        $size = CodedOutputStream::writeVarintToArray($tag, $bytes, true);
        $this->unknown .= substr($bytes, 0, $size) . $input->substr($start, $end);
    }

    /**
     * @ignore
     */
    private static function parseFieldFromStreamNoTag($input, $field, &$value)
    {
        switch ($field->getType()) {
            case GPBType::DOUBLE:
                if (!GPBWire::readDouble($input, $value)) {
                    throw new GPBDecodeException(
                        "Unexpected EOF inside double field.");
                }
                break;
            case GPBType::FLOAT:
                if (!GPBWire::readFloat($input, $value)) {
                    throw new GPBDecodeException(
                        "Unexpected EOF inside float field.");
                }
                break;
            case GPBType::INT64:
                if (!GPBWire::readInt64($input, $value)) {
                    throw new GPBDecodeException(
                        "Unexpected EOF inside int64 field.");
                }
                break;
            case GPBType::UINT64:
                if (!GPBWire::readUint64($input, $value)) {
                    throw new GPBDecodeException(
                        "Unexpected EOF inside uint64 field.");
                }
                break;
            case GPBType::INT32:
                if (!GPBWire::readInt32($input, $value)) {
                    throw new GPBDecodeException(
                        "Unexpected EOF inside int32 field.");
                }
                break;
            case GPBType::FIXED64:
                if (!GPBWire::readFixed64($input, $value)) {
                    throw new GPBDecodeException(
                        "Unexpected EOF inside fixed64 field.");
                }
                break;
            case GPBType::FIXED32:
                if (!GPBWire::readFixed32($input, $value)) {
                    throw new GPBDecodeException(
                        "Unexpected EOF inside fixed32 field.");
                }
                break;
            case GPBType::BOOL:
                if (!GPBWire::readBool($input, $value)) {
                    throw new GPBDecodeException(
                        "Unexpected EOF inside bool field.");
                }
                break;
            case GPBType::STRING:
                // TODO: Add utf-8 check.
                if (!GPBWire::readString($input, $value)) {
                    throw new GPBDecodeException(
                        "Unexpected EOF inside string field.");
                }
                break;
            case GPBType::GROUP:
                trigger_error("Not implemented.", E_USER_ERROR);
                break;
            case GPBType::MESSAGE:
                if ($field->isMap()) {
                    $value = new MapEntry($field->getMessageType());
                } else {
                    $klass = $field->getMessageType()->getClass();
                    $value = new $klass;
                }
                if (!GPBWire::readMessage($input, $value)) {
                    throw new GPBDecodeException(
                        "Unexpected EOF inside message.");
                }
                break;
            case GPBType::BYTES:
                if (!GPBWire::readString($input, $value)) {
                    throw new GPBDecodeException(
                        "Unexpected EOF inside bytes field.");
                }
                break;
            case GPBType::UINT32:
                if (!GPBWire::readUint32($input, $value)) {
                    throw new GPBDecodeException(
                        "Unexpected EOF inside uint32 field.");
                }
                break;
            case GPBType::ENUM:
                // TODO: Check unknown enum value.
                if (!GPBWire::readInt32($input, $value)) {
                    throw new GPBDecodeException(
                        "Unexpected EOF inside enum field.");
                }
                break;
            case GPBType::SFIXED32:
                if (!GPBWire::readSfixed32($input, $value)) {
                    throw new GPBDecodeException(
                        "Unexpected EOF inside sfixed32 field.");
                }
                break;
            case GPBType::SFIXED64:
                if (!GPBWire::readSfixed64($input, $value)) {
                    throw new GPBDecodeException(
                        "Unexpected EOF inside sfixed64 field.");
                }
                break;
            case GPBType::SINT32:
                if (!GPBWire::readSint32($input, $value)) {
                    throw new GPBDecodeException(
                        "Unexpected EOF inside sint32 field.");
                }
                break;
            case GPBType::SINT64:
                if (!GPBWire::readSint64($input, $value)) {
                    throw new GPBDecodeException(
                        "Unexpected EOF inside sint64 field.");
                }
                break;
            default:
                user_error("Unsupported type.");
                return false;
        }
        return true;
    }

    /**
     * @ignore
     */
    private function parseFieldFromStream($tag, $input, $field)
    {
        $value = null;

        if (is_null($field)) {
            $value_format = GPBWire::UNKNOWN;
        } elseif (GPBWire::getTagWireType($tag) ===
            GPBWire::getWireType($field->getType())) {
            $value_format = GPBWire::NORMAL_FORMAT;
        } elseif ($field->isPackable() &&
            GPBWire::getTagWireType($tag) ===
            GPBWire::WIRETYPE_LENGTH_DELIMITED) {
            $value_format = GPBWire::PACKED_FORMAT;
        } else {
            // the wire type doesn't match. Put it in our unknown field set.
            $value_format = GPBWire::UNKNOWN;
        }

        if ($value_format === GPBWire::UNKNOWN) {
            $this->skipField($input, $tag);
            return;
        } elseif ($value_format === GPBWire::NORMAL_FORMAT) {
            self::parseFieldFromStreamNoTag($input, $field, $value);
        } elseif ($value_format === GPBWire::PACKED_FORMAT) {
            $length = 0;
            if (!GPBWire::readInt32($input, $length)) {
                throw new GPBDecodeException(
                    "Unexpected EOF inside packed length.");
            }
            $limit = $input->pushLimit($length);
            $getter = $field->getGetter();
            while ($input->bytesUntilLimit() > 0) {
                self::parseFieldFromStreamNoTag($input, $field, $value);
                $this->appendHelper($field, $value);
            }
            $input->popLimit($limit);
            return;
        } else {
            return;
        }

        if ($field->isMap()) {
            $this->kvUpdateHelper($field, $value->getKey(), $value->getValue());
        } else if ($field->isRepeated()) {
            $this->appendHelper($field, $value);
        } else {
            $setter = $field->getSetter();
            $this->$setter($value);
        }
    }

    /**
     * Clear all containing fields.
     * @return null
     */
    public function clear()
    {
        $this->unknown = "";
        foreach ($this->desc->getField() as $field) {
            $setter = $field->getSetter();
            if ($field->isMap()) {
                $message_type = $field->getMessageType();
                $key_field = $message_type->getFieldByNumber(1);
                $value_field = $message_type->getFieldByNumber(2);
                switch ($value_field->getType()) {
                    case GPBType::MESSAGE:
                    case GPBType::GROUP:
                        $map_field = new MapField(
                            $key_field->getType(),
                            $value_field->getType(),
                            $value_field->getMessageType()->getClass());
                        $this->$setter($map_field);
                        break;
                    case GPBType::ENUM:
                        $map_field = new MapField(
                            $key_field->getType(),
                            $value_field->getType(),
                            $value_field->getEnumType()->getClass());
                        $this->$setter($map_field);
                        break;
                    default:
                        $map_field = new MapField(
                            $key_field->getType(),
                            $value_field->getType());
                        $this->$setter($map_field);
                        break;
                }
            } else if ($field->getLabel() === GPBLabel::REPEATED) {
                switch ($field->getType()) {
                    case GPBType::MESSAGE:
                    case GPBType::GROUP:
                        $repeated_field = new RepeatedField(
                            $field->getType(),
                            $field->getMessageType()->getClass());
                        $this->$setter($repeated_field);
                        break;
                    case GPBType::ENUM:
                        $repeated_field = new RepeatedField(
                            $field->getType(),
                            $field->getEnumType()->getClass());
                        $this->$setter($repeated_field);
                        break;
                    default:
                        $repeated_field = new RepeatedField($field->getType());
                        $this->$setter($repeated_field);
                        break;
                }
            } else if ($field->getOneofIndex() !== -1) {
                $oneof = $this->desc->getOneofDecl()[$field->getOneofIndex()];
                $oneof_name = $oneof->getName();
                $this->$oneof_name = new OneofField($oneof);
            } else if ($field->getLabel() === GPBLabel::OPTIONAL) {
                switch ($field->getType()) {
                    case GPBType::DOUBLE   :
                    case GPBType::FLOAT    :
                        $this->$setter(0.0);
                        break;
                    case GPBType::INT32    :
                    case GPBType::FIXED32  :
                    case GPBType::UINT32   :
                    case GPBType::SFIXED32 :
                    case GPBType::SINT32   :
                    case GPBType::ENUM     :
                        $this->$setter(0);
                        break;
                    case GPBType::BOOL     :
                        $this->$setter(false);
                        break;
                    case GPBType::STRING   :
                    case GPBType::BYTES    :
                        $this->$setter("");
                        break;
                    case GPBType::GROUP    :
                    case GPBType::MESSAGE  :
                        $null = null;
                        $this->$setter($null);
                        break;
                }
                if (PHP_INT_SIZE == 4) {
                    switch ($field->getType()) {
                        case GPBType::INT64:
                        case GPBType::UINT64:
                        case GPBType::FIXED64:
                        case GPBType::SFIXED64:
                        case GPBType::SINT64:
                            $this->$setter("0");
                    }
                } else {
                    switch ($field->getType()) {
                        case GPBType::INT64:
                        case GPBType::UINT64:
                        case GPBType::FIXED64:
                        case GPBType::SFIXED64:
                        case GPBType::SINT64:
                            $this->$setter(0);
                    }
                }
            }
        }
    }

    /**
     * Clear all unknown fields previously parsed.
     * @return null
     */
    public function discardUnknownFields()
    {
        $this->unknown = "";
        foreach ($this->desc->getField() as $field) {
            if ($field->getType() != GPBType::MESSAGE) {
                continue;
            }
            if ($field->isMap()) {
                $value_field = $field->getMessageType()->getFieldByNumber(2);
                if ($value_field->getType() != GPBType::MESSAGE) {
                    continue;
                }
                $getter = $field->getGetter();
                $map = $this->$getter();
                foreach ($map as $key => $value) {
                    $value->discardUnknownFields();
                }
            } else if ($field->getLabel() === GPBLabel::REPEATED) {
                $getter = $field->getGetter();
                $arr = $this->$getter();
                foreach ($arr as $sub) {
                    $sub->discardUnknownFields();
                }
            } else if ($field->getLabel() === GPBLabel::OPTIONAL) {
                $getter = $field->getGetter();
                $sub = $this->$getter();
                if (!is_null($sub)) {
                    $sub->discardUnknownFields();
                }
            }
        }
    }

    /**
     * Merges the contents of the specified message into current message.
     *
     * This method merges the contents of the specified message into the
     * current message. Singular fields that are set in the specified message
     * overwrite the corresponding fields in the current message.  Repeated
     * fields are appended. Map fields key-value pairs are overwritten.
     * Singular/Oneof sub-messages are recursively merged. All overwritten
     * sub-messages are deep-copied.
     *
     * @param object $msg Protobuf message to be merged from.
     * @return null
     */
    public function mergeFrom($msg)
    {
        if (get_class($this) !== get_class($msg)) {
            user_error("Cannot merge messages with different class.");
            return;
        }

        foreach ($this->desc->getField() as $field) {
            $setter = $field->getSetter();
            $getter = $field->getGetter();
            if ($field->isMap()) {
                if (count($msg->$getter()) != 0) {
                    $value_field = $field->getMessageType()->getFieldByNumber(2);
                    foreach ($msg->$getter() as $key => $value) {
                        if ($value_field->getType() == GPBType::MESSAGE) {
                            $klass = $value_field->getMessageType()->getClass();
                            $copy = new $klass;
                            $copy->mergeFrom($value);

                            $this->kvUpdateHelper($field, $key, $copy);
                        } else {
                            $this->kvUpdateHelper($field, $key, $value);
                        }
                    }
                }
            } else if ($field->getLabel() === GPBLabel::REPEATED) {
                if (count($msg->$getter()) != 0) {
                    foreach ($msg->$getter() as $tmp) {
                        if ($field->getType() == GPBType::MESSAGE) {
                            $klass = $field->getMessageType()->getClass();
                            $copy = new $klass;
                            $copy->mergeFrom($tmp);
                            $this->appendHelper($field, $copy);
                        } else {
                            $this->appendHelper($field, $tmp);
                        }
                    }
                }
            } else if ($field->getLabel() === GPBLabel::OPTIONAL) {
                if($msg->$getter() !== $this->defaultValue($field)) {
                    $tmp = $msg->$getter();
                    if ($field->getType() == GPBType::MESSAGE) {
                        if (is_null($this->$getter())) {
                            $klass = $field->getMessageType()->getClass();
                            $new_msg = new $klass;
                            $this->$setter($new_msg);
                        }
                        $this->$getter()->mergeFrom($tmp);
                    } else {
                        $this->$setter($tmp);
                    }
                }
            }
        }
    }

    /**
     * Parses a protocol buffer contained in a string.
     *
     * This function takes a string in the (non-human-readable) binary wire
     * format, matching the encoding output by serializeToString().
     * See mergeFrom() for merging behavior, if the field is already set in the
     * specified message.
     *
     * @param string $data Binary protobuf data.
     * @return null
     * @throws \Exception Invalid data.
     */
    public function mergeFromString($data)
    {
        $input = new CodedInputStream($data);
        $this->parseFromStream($input);
    }

    /**
     * Parses a json string to protobuf message.
     *
     * This function takes a string in the json wire format, matching the
     * encoding output by serializeToJsonString().
     * See mergeFrom() for merging behavior, if the field is already set in the
     * specified message.
     *
     * @param string $data Json protobuf data.
     * @param bool $ignore_unknown
     * @return null
     * @throws \Exception Invalid data.
     */
    public function mergeFromJsonString($data, $ignore_unknown = false)
    {
        $input = new RawInputStream($data);
        $this->parseFromJsonStream($input, $ignore_unknown);
    }

    /**
     * @ignore
     */
    public function parseFromStream($input)
    {
        while (true) {
            $tag = $input->readTag();
            // End of input.  This is a valid place to end, so return true.
            if ($tag === 0) {
                return true;
            }

            $number = GPBWire::getTagFieldNumber($tag);
            $field = $this->desc->getFieldByNumber($number);

            $this->parseFieldFromStream($tag, $input, $field);
        }
    }

    private function convertJsonValueToProtoValue(
        $value,
        $field,
        $ignore_unknown,
        $is_map_key = false)
    {
        switch ($field->getType()) {
            case GPBType::MESSAGE:
                $klass = $field->getMessageType()->getClass();
                $submsg = new $klass;

                if (is_a($submsg, "Google\Protobuf\Duration")) {
                    if (is_null($value)) {
                        return $this->defaultValue($field);
                    } else if (!is_string($value)) {
                        throw new GPBDecodeException("Expect string.");
                    }
                    return GPBUtil::parseDuration($value);
                } else if ($field->isTimestamp()) {
                    if (is_null($value)) {
                        return $this->defaultValue($field);
                    } else if (!is_string($value)) {
                        throw new GPBDecodeException("Expect string.");
                    }
                    try {
                        $timestamp = GPBUtil::parseTimestamp($value);
                    } catch (\Exception $e) {
                        throw new GPBDecodeException(
                            "Invalid RFC 3339 timestamp: ".$e->getMessage());
                    }

                    $submsg->setSeconds($timestamp->getSeconds());
                    $submsg->setNanos($timestamp->getNanos());
                } else if (is_a($submsg, "Google\Protobuf\FieldMask")) {
                    if (is_null($value)) {
                        return $this->defaultValue($field);
                    }
                    try {
                        return GPBUtil::parseFieldMask($value);
                    } catch (\Exception $e) {
                        throw new GPBDecodeException(
                            "Invalid FieldMask: ".$e->getMessage());
                    }
                } else {
                    if (is_null($value) &&
                        !is_a($submsg, "Google\Protobuf\Value")) {
                        return $this->defaultValue($field);
                    }
                    if (GPBUtil::hasSpecialJsonMapping($submsg)) {
                    } elseif (!is_object($value) && !is_array($value)) {
                        throw new GPBDecodeException("Expect message.");
                    }
                    $submsg->mergeFromJsonArray($value, $ignore_unknown);
                }
                return $submsg;
            case GPBType::ENUM:
                if (is_null($value)) {
                    return $this->defaultValue($field);
                }
                if (is_integer($value)) {
                    return $value;
                }
                $enum_value = $field->getEnumType()->getValueByName($value);
                if (!is_null($enum_value)) {
                    return $enum_value->getNumber();
                } else if ($ignore_unknown) {
                    return $this->defaultValue($field);
                } else {
                  throw new GPBDecodeException(
                          "Enum field only accepts integer or enum value name");
                }
            case GPBType::STRING:
                if (is_null($value)) {
                    return $this->defaultValue($field);
                }
                if (is_numeric($value)) {
                    return strval($value);
                }
                if (!is_string($value)) {
                    throw new GPBDecodeException(
                        "String field only accepts string value");
                }
                return $value;
            case GPBType::BYTES:
                if (is_null($value)) {
                    return $this->defaultValue($field);
                }
                if (!is_string($value)) {
                    throw new GPBDecodeException(
                        "Byte field only accepts string value");
                }
                $proto_value = base64_decode($value, true);
                if ($proto_value === false) {
                    throw new GPBDecodeException("Invalid base64 characters");
                }
                return $proto_value;
            case GPBType::BOOL:
                if (is_null($value)) {
                    return $this->defaultValue($field);
                }
                if ($is_map_key) {
                    if ($value === "true") {
                        return true;
                    }
                    if ($value === "false") {
                        return false;
                    }
                    throw new GPBDecodeException(
                        "Bool field only accepts bool value");
                }
                if (!is_bool($value)) {
                    throw new GPBDecodeException(
                        "Bool field only accepts bool value");
                }
                return $value;
            case GPBType::FLOAT:
            case GPBType::DOUBLE:
                if (is_null($value)) {
                    return $this->defaultValue($field);
                }
                if ($value === "Infinity") {
                    return INF;
                }
                if ($value === "-Infinity") {
                    return -INF;
                }
                if ($value === "NaN") {
                    return NAN;
                }
                return $value;
            case GPBType::INT32:
            case GPBType::SINT32:
            case GPBType::SFIXED32:
                if (is_null($value)) {
                    return $this->defaultValue($field);
                }
                if (!is_numeric($value)) {
                   throw new GPBDecodeException(
                       "Invalid data type for int32 field");
                }
                if (is_string($value) && trim($value) !== $value) {
                   throw new GPBDecodeException(
                       "Invalid data type for int32 field");
                }
                if (bccomp($value, "2147483647") > 0) {
                   throw new GPBDecodeException(
                       "Int32 too large");
                }
                if (bccomp($value, "-2147483648") < 0) {
                   throw new GPBDecodeException(
                       "Int32 too small");
                }
                return $value;
            case GPBType::UINT32:
            case GPBType::FIXED32:
                if (is_null($value)) {
                    return $this->defaultValue($field);
                }
                if (!is_numeric($value)) {
                   throw new GPBDecodeException(
                       "Invalid data type for uint32 field");
                }
                if (is_string($value) && trim($value) !== $value) {
                   throw new GPBDecodeException(
                       "Invalid data type for int32 field");
                }
                if (bccomp($value, 4294967295) > 0) {
                    throw new GPBDecodeException(
                        "Uint32 too large");
                }
                return $value;
            case GPBType::INT64:
            case GPBType::SINT64:
            case GPBType::SFIXED64:
                if (is_null($value)) {
                    return $this->defaultValue($field);
                }
                if (!is_numeric($value)) {
                   throw new GPBDecodeException(
                       "Invalid data type for int64 field");
                }
                if (is_string($value) && trim($value) !== $value) {
                   throw new GPBDecodeException(
                       "Invalid data type for int64 field");
                }
                if (bccomp($value, "9223372036854775807") > 0) {
                    throw new GPBDecodeException(
                        "Int64 too large");
                }
                if (bccomp($value, "-9223372036854775808") < 0) {
                    throw new GPBDecodeException(
                        "Int64 too small");
                }
                return $value;
            case GPBType::UINT64:
            case GPBType::FIXED64:
                if (is_null($value)) {
                    return $this->defaultValue($field);
                }
                if (!is_numeric($value)) {
                   throw new GPBDecodeException(
                       "Invalid data type for int64 field");
                }
                if (is_string($value) && trim($value) !== $value) {
                   throw new GPBDecodeException(
                       "Invalid data type for int64 field");
                }
                if (bccomp($value, "18446744073709551615") > 0) {
                    throw new GPBDecodeException(
                        "Uint64 too large");
                }
                if (bccomp($value, "9223372036854775807") > 0) {
                    $value = bcsub($value, "18446744073709551616");
                }
                return $value;
            default:
                return $value;
        }
    }

    /**
     * Populates the message from a user-supplied PHP array. Array keys
     * correspond to Message properties and nested message properties.
     *
     * Example:
     * ```
     * $message->mergeFromArray([
     *     'name' => 'This is a message name',
     *     'interval' => [
     *          'startTime' => time() - 60,
     *          'endTime' => time(),
     *     ]
     * ]);
     * ```
     *
     * This method will trigger an error if it is passed data that cannot
     * be converted to the correct type. For example, a StringValue field
     * must receive data that is either a string or a StringValue object.
     *
     * @param array $array An array containing message properties and values.
     * @return null
     */
    protected function mergeFromArray(array $array)
    {
        // Just call the setters for the field names
        foreach ($array as $key => $value) {
            $field = $this->desc->getFieldByName($key);
            if (is_null($field)) {
                throw new \UnexpectedValueException(
                    'Invalid message property: ' . $key);
            }
            $setter = $field->getSetter();
            if ($field->isMap()) {
                $valueField = $field->getMessageType()->getFieldByName('value');
                if (!is_null($valueField) && $valueField->isWrapperType()) {
                    self::normalizeArrayElementsToMessageType($value, $valueField->getMessageType()->getClass());
                }
            } elseif ($field->isWrapperType()) {
                $class = $field->getMessageType()->getClass();
                if ($field->isRepeated()) {
                    self::normalizeArrayElementsToMessageType($value, $class);
                } else {
                    self::normalizeToMessageType($value, $class);
                }
            }
            $this->$setter($value);
        }
    }

    /**
     * Tries to normalize the elements in $value into a provided protobuf
     * wrapper type $class. If $value is any type other than array, we do
     * not do any conversion, and instead rely on the existing protobuf
     * type checking. If $value is an array, we process each element and
     * try to convert it to an instance of $class.
     *
     * @param mixed $value The array of values to normalize.
     * @param string $class The expected wrapper class name
     */
    private static function normalizeArrayElementsToMessageType(&$value, $class)
    {
        if (!is_array($value)) {
            // In the case that $value is not an array, we do not want to
            // attempt any conversion. Note that this includes the cases
            // when $value is a RepeatedField of MapField. In those cases,
            // we do not need to convert the elements, as they should
            // already be the correct types.
            return;
        } else {
            // Normalize each element in the array.
            foreach ($value as $key => &$elementValue) {
              self::normalizeToMessageType($elementValue, $class);
            }
        }
    }

    /**
     * Tries to normalize $value into a provided protobuf wrapper type $class.
     * If $value is any type other than an object, we attempt to construct an
     * instance of $class and assign $value to it using the setValue method
     * shared by all wrapper types.
     *
     * This method will raise an error if it receives a type that cannot be
     * assigned to the wrapper type via setValue.
     *
     * @param mixed $value The value to normalize.
     * @param string $class The expected wrapper class name
     */
    private static function normalizeToMessageType(&$value, $class)
    {
        if (is_null($value) || is_object($value)) {
            // This handles the case that $value is an instance of $class. We
            // choose not to do any more strict checking here, relying on the
            // existing type checking done by GPBUtil.
            return;
        } else {
            // Try to instantiate $class and set the value
            try {
                $msg = new $class;
                $msg->setValue($value);
                $value = $msg;
                return;
            } catch (\Exception $exception) {
                trigger_error(
                    "Error normalizing value to type '$class': " . $exception->getMessage(),
                    E_USER_ERROR
                );
            }
        }
    }

    protected function mergeFromJsonArray($array, $ignore_unknown)
    {
        if (is_a($this, "Google\Protobuf\Any")) {
            $this->clear();
            $this->setTypeUrl($array["@type"]);
            $msg = $this->unpack();
            if (GPBUtil::hasSpecialJsonMapping($msg)) {
                $msg->mergeFromJsonArray($array["value"], $ignore_unknown);
            } else {
                unset($array["@type"]);
                $msg->mergeFromJsonArray($array, $ignore_unknown);
            }
            $this->setValue($msg->serializeToString());
            return;
        }
        if (is_a($this, "Google\Protobuf\DoubleValue") ||
            is_a($this, "Google\Protobuf\FloatValue")  ||
            is_a($this, "Google\Protobuf\Int64Value")  ||
            is_a($this, "Google\Protobuf\UInt64Value") ||
            is_a($this, "Google\Protobuf\Int32Value")  ||
            is_a($this, "Google\Protobuf\UInt32Value") ||
            is_a($this, "Google\Protobuf\BoolValue")   ||
            is_a($this, "Google\Protobuf\StringValue")) {
            $this->setValue($array);
            return;
        }
        if (is_a($this, "Google\Protobuf\BytesValue")) {
            $this->setValue(base64_decode($array));
            return;
        }
        if (is_a($this, "Google\Protobuf\Duration")) {
            $this->mergeFrom(GPBUtil::parseDuration($array));
            return;
        }
        if (is_a($this, "Google\Protobuf\FieldMask")) {
            $this->mergeFrom(GPBUtil::parseFieldMask($array));
            return;
        }
        if (is_a($this, "Google\Protobuf\Timestamp")) {
            $this->mergeFrom(GPBUtil::parseTimestamp($array));
            return;
        }
        if (is_a($this, "Google\Protobuf\Struct")) {
            $fields = $this->getFields();
            foreach($array as $key => $value) {
                $v = new Value();
                $v->mergeFromJsonArray($value, $ignore_unknown);
                $fields[$key] = $v;
            }
            return;
        }
        if (is_a($this, "Google\Protobuf\Value")) {
            if (is_bool($array)) {
                $this->setBoolValue($array);
            } elseif (is_string($array)) {
                $this->setStringValue($array);
            } elseif (is_null($array)) {
                $this->setNullValue(0);
            } elseif (is_double($array) || is_integer($array)) {
                $this->setNumberValue($array);
            } elseif (is_array($array)) {
                if (array_values($array) !== $array) {
                    // Associative array
                    $struct_value = $this->getStructValue();
                    if (is_null($struct_value)) {
                        $struct_value = new Struct();
                        $this->setStructValue($struct_value);
                    }
                    foreach ($array as $key => $v) {
                        $value = new Value();
                        $value->mergeFromJsonArray($v, $ignore_unknown);
                        $values = $struct_value->getFields();
                        $values[$key]= $value;
                    }
                } else {
                    // Array
                    $list_value = $this->getListValue();
                    if (is_null($list_value)) {
                        $list_value = new ListValue();
                        $this->setListValue($list_value);
                    }
                    foreach ($array as $v) {
                        $value = new Value();
                        $value->mergeFromJsonArray($v, $ignore_unknown);
                        $values = $list_value->getValues();
                        $values[]= $value;
                    }
                }
            } else {
                throw new GPBDecodeException("Invalid type for Value.");
            }
            return;
        }
        $this->mergeFromArrayJsonImpl($array, $ignore_unknown);
    }

    private function mergeFromArrayJsonImpl($array, $ignore_unknown)
    {
        foreach ($array as $key => $value) {
            $field = $this->desc->getFieldByJsonName($key);
            if (is_null($field)) {
                $field = $this->desc->getFieldByName($key);
                if (is_null($field)) {
                    if ($ignore_unknown) {
                        continue;
                    } else {
                        throw new GPBDecodeException(
                            $key . ' is unknown.'
                        );
                    }
                }
            }
            if ($field->isMap()) {
                if (is_null($value)) {
                    continue;
                }
                $key_field = $field->getMessageType()->getFieldByNumber(1);
                $value_field = $field->getMessageType()->getFieldByNumber(2);
                foreach ($value as $tmp_key => $tmp_value) {
                    if (is_null($tmp_value)) {
                        throw new \Exception(
                            "Map value field element cannot be null.");
                    }
                    $proto_key = $this->convertJsonValueToProtoValue(
                        $tmp_key,
                        $key_field,
                        $ignore_unknown,
                        true);
                    $proto_value = $this->convertJsonValueToProtoValue(
                        $tmp_value,
                        $value_field,
                        $ignore_unknown);
                    self::kvUpdateHelper($field, $proto_key, $proto_value);
                }
            } else if ($field->isRepeated()) {
                if (is_null($value)) {
                    continue;
                }
                foreach ($value as $tmp) {
                    if (is_null($tmp)) {
                        throw new \Exception(
                            "Repeated field elements cannot be null.");
                    }
                    $proto_value = $this->convertJsonValueToProtoValue(
                        $tmp,
                        $field,
                        $ignore_unknown);
                    self::appendHelper($field, $proto_value);
                }
            } else {
                $setter = $field->getSetter();
                $proto_value = $this->convertJsonValueToProtoValue(
                    $value,
                    $field,
                    $ignore_unknown);
                if ($field->getType() === GPBType::MESSAGE) {
                    if (is_null($proto_value)) {
                        continue;
                    }
                    $getter = $field->getGetter();
                    $submsg = $this->$getter();
                    if (!is_null($submsg)) {
                        $submsg->mergeFrom($proto_value);
                        continue;
                    }
                }
                $this->$setter($proto_value);
            }
        }
    }

    /**
     * @ignore
     */
    public function parseFromJsonStream($input, $ignore_unknown)
    {
        $array = json_decode($input->getData(), true, 512, JSON_BIGINT_AS_STRING);
        if ($this instanceof \Google\Protobuf\ListValue) {
            $array = ["values"=>$array];
        }
        if (is_null($array)) {
            if ($this instanceof \Google\Protobuf\Value) {
              $this->setNullValue(\Google\Protobuf\NullValue::NULL_VALUE);
              return;
            } else {
              throw new GPBDecodeException(
                  "Cannot decode json string: " . $input->getData());
            }
        }
        try {
            $this->mergeFromJsonArray($array, $ignore_unknown);
        } catch (\Exception $e) {
            throw new GPBDecodeException($e->getMessage());
        }
    }

    /**
     * @ignore
     */
    private function serializeSingularFieldToStream($field, &$output)
    {
        if (!$this->existField($field)) {
            return true;
        }
        $getter = $field->getGetter();
        $value = $this->$getter();
        if (!GPBWire::serializeFieldToStream($value, $field, true, $output)) {
            return false;
        }
        return true;
    }

    /**
     * @ignore
     */
    private function serializeRepeatedFieldToStream($field, &$output)
    {
        $getter = $field->getGetter();
        $values = $this->$getter();
        $count = count($values);
        if ($count === 0) {
            return true;
        }

        $packed = $field->getPacked();
        if ($packed) {
            if (!GPBWire::writeTag(
                $output,
                GPBWire::makeTag($field->getNumber(), GPBType::STRING))) {
                return false;
            }
            $size = 0;
            foreach ($values as $value) {
                $size += $this->fieldDataOnlyByteSize($field, $value);
            }
            if (!$output->writeVarint32($size, true)) {
                return false;
            }
        }

        foreach ($values as $value) {
            if (!GPBWire::serializeFieldToStream(
                $value,
                $field,
                !$packed,
                $output)) {
                return false;
            }
        }
        return true;
    }

    /**
     * @ignore
     */
    private function serializeMapFieldToStream($field, $output)
    {
        $getter = $field->getGetter();
        $values = $this->$getter();
        $count = count($values);
        if ($count === 0) {
            return true;
        }

        foreach ($values as $key => $value) {
            $map_entry = new MapEntry($field->getMessageType());
            $map_entry->setKey($key);
            $map_entry->setValue($value);
            if (!GPBWire::serializeFieldToStream(
                $map_entry,
                $field,
                true,
                $output)) {
                return false;
            }
        }
        return true;
    }

    /**
     * @ignore
     */
    private function serializeFieldToStream(&$output, $field)
    {
        if ($field->isMap()) {
            return $this->serializeMapFieldToStream($field, $output);
        } elseif ($field->isRepeated()) {
            return $this->serializeRepeatedFieldToStream($field, $output);
        } else {
            return $this->serializeSingularFieldToStream($field, $output);
        }
    }

    /**
     * @ignore
     */
    private function serializeFieldToJsonStream(&$output, $field)
    {
        $getter = $field->getGetter();
        $values = $this->$getter();
        return GPBJsonWire::serializeFieldToStream(
            $values, $field, $output, !GPBUtil::hasSpecialJsonMapping($this));
    }

    /**
     * @ignore
     */
    public function serializeToStream(&$output)
    {
        $fields = $this->desc->getField();
        foreach ($fields as $field) {
            if (!$this->serializeFieldToStream($output, $field)) {
                return false;
            }
        }
        $output->writeRaw($this->unknown, strlen($this->unknown));
        return true;
    }

    /**
     * @ignore
     */
    public function serializeToJsonStream(&$output)
    {
        if (is_a($this, 'Google\Protobuf\Any')) {
            $output->writeRaw("{", 1);
            $type_field = $this->desc->getFieldByNumber(1);
            $value_msg = $this->unpack();

            // Serialize type url.
            $output->writeRaw("\"@type\":", 8);
            $output->writeRaw("\"", 1);
            $output->writeRaw($this->getTypeUrl(), strlen($this->getTypeUrl()));
            $output->writeRaw("\"", 1);

            // Serialize value
            if (GPBUtil::hasSpecialJsonMapping($value_msg)) {
                $output->writeRaw(",\"value\":", 9);
                $value_msg->serializeToJsonStream($output);
            } else {
                $value_fields = $value_msg->desc->getField();
                foreach ($value_fields as $field) {
                    if ($value_msg->existField($field)) {
                        $output->writeRaw(",", 1);
                        if (!$value_msg->serializeFieldToJsonStream($output, $field)) {
                            return false;
                        }
                    }
                }
            }

            $output->writeRaw("}", 1);
        } elseif (is_a($this, 'Google\Protobuf\FieldMask')) {
            $field_mask = GPBUtil::formatFieldMask($this);
            $output->writeRaw("\"", 1);
            $output->writeRaw($field_mask, strlen($field_mask));
            $output->writeRaw("\"", 1);
        } elseif (is_a($this, 'Google\Protobuf\Duration')) {
            $duration = GPBUtil::formatDuration($this) . "s";
            $output->writeRaw("\"", 1);
            $output->writeRaw($duration, strlen($duration));
            $output->writeRaw("\"", 1);
        } elseif (get_class($this) === 'Google\Protobuf\Timestamp') {
            $timestamp = GPBUtil::formatTimestamp($this);
            $timestamp = json_encode($timestamp);
            $output->writeRaw($timestamp, strlen($timestamp));
        } elseif (get_class($this) === 'Google\Protobuf\ListValue') {
            $field = $this->desc->getField()[1];
            if (!$this->existField($field)) {
                $output->writeRaw("[]", 2);
            } else {
                if (!$this->serializeFieldToJsonStream($output, $field)) {
                    return false;
                }
            }
        } elseif (get_class($this) === 'Google\Protobuf\Struct') {
            $field = $this->desc->getField()[1];
            if (!$this->existField($field)) {
                $output->writeRaw("{}", 2);
            } else {
                if (!$this->serializeFieldToJsonStream($output, $field)) {
                    return false;
                }
            }
        } else {
            if (!GPBUtil::hasSpecialJsonMapping($this)) {
                $output->writeRaw("{", 1);
            }
            $fields = $this->desc->getField();
            $first = true;
            foreach ($fields as $field) {
                if ($this->existField($field) ||
                    GPBUtil::hasJsonValue($this)) {
                    if ($first) {
                        $first = false;
                    } else {
                        $output->writeRaw(",", 1);
                    }
                    if (!$this->serializeFieldToJsonStream($output, $field)) {
                        return false;
                    }
                }
            }
            if (!GPBUtil::hasSpecialJsonMapping($this)) {
                $output->writeRaw("}", 1);
            }
        }
        return true;
    }

    /**
     * Serialize the message to string.
     * @return string Serialized binary protobuf data.
     */
    public function serializeToString()
    {
        $output = new CodedOutputStream($this->byteSize());
        $this->serializeToStream($output);
        return $output->getData();
    }

    /**
     * Serialize the message to json string.
     * @return string Serialized json protobuf data.
     */
    public function serializeToJsonString()
    {
        $output = new CodedOutputStream($this->jsonByteSize());
        $this->serializeToJsonStream($output);
        return $output->getData();
    }

    /**
     * @ignore
     */
    private function existField($field)
    {
        $getter = $field->getGetter();
        $hazzer = "has" . substr($getter, 3);

        if (method_exists($this, $hazzer)) {
          return $this->$hazzer();
        } else if ($field->getOneofIndex() !== -1) {
          // For old generated code, which does not have hazzers for oneof
          // fields.
          $oneof = $this->desc->getOneofDecl()[$field->getOneofIndex()];
          $oneof_name = $oneof->getName();
          return $this->$oneof_name->getNumber() === $field->getNumber();
        }

        $values = $this->$getter();
        if ($field->isMap()) {
            return count($values) !== 0;
        } elseif ($field->isRepeated()) {
            return count($values) !== 0;
        } else {
            return $values !== $this->defaultValue($field);
        }
    }

    /**
     * @ignore
     */
    private function repeatedFieldDataOnlyByteSize($field)
    {
        $size = 0;

        $getter = $field->getGetter();
        $values = $this->$getter();
        $count = count($values);
        if ($count !== 0) {
            $size += $count * GPBWire::tagSize($field);
            foreach ($values as $value) {
                $size += $this->singularFieldDataOnlyByteSize($field);
            }
        }
    }

    /**
     * @ignore
     */
    private function fieldDataOnlyByteSize($field, $value)
    {
        $size = 0;

        switch ($field->getType()) {
            case GPBType::BOOL:
                $size += 1;
                break;
            case GPBType::FLOAT:
            case GPBType::FIXED32:
            case GPBType::SFIXED32:
                $size += 4;
                break;
            case GPBType::DOUBLE:
            case GPBType::FIXED64:
            case GPBType::SFIXED64:
                $size += 8;
                break;
            case GPBType::INT32:
            case GPBType::ENUM:
                $size += GPBWire::varint32Size($value, true);
                break;
            case GPBType::UINT32:
                $size += GPBWire::varint32Size($value);
                break;
            case GPBType::UINT64:
            case GPBType::INT64:
                $size += GPBWire::varint64Size($value);
                break;
            case GPBType::SINT32:
                $size += GPBWire::sint32Size($value);
                break;
            case GPBType::SINT64:
                $size += GPBWire::sint64Size($value);
                break;
            case GPBType::STRING:
            case GPBType::BYTES:
                $size += strlen($value);
                $size += GPBWire::varint32Size($size);
                break;
            case GPBType::MESSAGE:
                $size += $value->byteSize();
                $size += GPBWire::varint32Size($size);
                break;
            case GPBType::GROUP:
                // TODO: Add support.
                user_error("Unsupported type.");
                break;
            default:
                user_error("Unsupported type.");
                return 0;
        }

        return $size;
    }

    /**
     * @ignore
     */
    private function fieldDataOnlyJsonByteSize($field, $value)
    {
        $size = 0;

        switch ($field->getType()) {
            case GPBType::SFIXED32:
            case GPBType::SINT32:
            case GPBType::INT32:
                $size += strlen(strval($value));
                break;
            case GPBType::FIXED32:
            case GPBType::UINT32:
                if ($value < 0) {
                    $value = bcadd($value, "4294967296");
                }
                $size += strlen(strval($value));
                break;
            case GPBType::FIXED64:
            case GPBType::UINT64:
                if ($value < 0) {
                    $value = bcadd($value, "18446744073709551616");
                }
                // Intentional fall through.
            case GPBType::SFIXED64:
            case GPBType::INT64:
            case GPBType::SINT64:
                $size += 2;  // size for ""
                $size += strlen(strval($value));
                break;
            case GPBType::FLOAT:
                if (is_nan($value)) {
                    $size += strlen("NaN") + 2;
                } elseif ($value === INF) {
                    $size += strlen("Infinity") + 2;
                } elseif ($value === -INF) {
                    $size += strlen("-Infinity") + 2;
                } else {
                    $size += strlen(sprintf("%.8g", $value));
                }
                break;
            case GPBType::DOUBLE:
                if (is_nan($value)) {
                    $size += strlen("NaN") + 2;
                } elseif ($value === INF) {
                    $size += strlen("Infinity") + 2;
                } elseif ($value === -INF) {
                    $size += strlen("-Infinity") + 2;
                } else {
                    $size += strlen(sprintf("%.17g", $value));
                }
                break;
            case GPBType::ENUM:
                $enum_desc = $field->getEnumType();
                if ($enum_desc->getClass() === "Google\Protobuf\NullValue") {
                    $size += 4;
                    break;
                }
                $enum_value_desc = $enum_desc->getValueByNumber($value);
                if (!is_null($enum_value_desc)) {
                    $size += 2;  // size for ""
                    $size += strlen($enum_value_desc->getName());
                } else {
                    $str_value = strval($value);
                    $size += strlen($str_value);
                }
                break;
            case GPBType::BOOL:
                if ($value) {
                    $size += 4;
                } else {
                    $size += 5;
                }
                break;
            case GPBType::STRING:
                $value = json_encode($value, JSON_UNESCAPED_UNICODE);
                $size += strlen($value);
                break;
            case GPBType::BYTES:
                # if (is_a($this, "Google\Protobuf\BytesValue")) {
                #     $size += strlen(json_encode($value));
                # } else {
                #     $size += strlen(base64_encode($value));
                #     $size += 2;  // size for \"\"
                # }
                $size += strlen(base64_encode($value));
                $size += 2;  // size for \"\"
                break;
            case GPBType::MESSAGE:
                $size += $value->jsonByteSize();
                break;
#             case GPBType::GROUP:
#                 // TODO: Add support.
#                 user_error("Unsupported type.");
#                 break;
            default:
                user_error("Unsupported type " . $field->getType());
                return 0;
        }

        return $size;
    }

    /**
     * @ignore
     */
    private function fieldByteSize($field)
    {
        $size = 0;
        if ($field->isMap()) {
            $getter = $field->getGetter();
            $values = $this->$getter();
            $count = count($values);
            if ($count !== 0) {
                $size += $count * GPBWire::tagSize($field);
                $message_type = $field->getMessageType();
                $key_field = $message_type->getFieldByNumber(1);
                $value_field = $message_type->getFieldByNumber(2);
                foreach ($values as $key => $value) {
                    $data_size = 0;
                    if ($key != $this->defaultValue($key_field)) {
                        $data_size += $this->fieldDataOnlyByteSize(
                            $key_field,
                            $key);
                        $data_size += GPBWire::tagSize($key_field);
                    }
                    if ($value != $this->defaultValue($value_field)) {
                        $data_size += $this->fieldDataOnlyByteSize(
                            $value_field,
                            $value);
                        $data_size += GPBWire::tagSize($value_field);
                    }
                    $size += GPBWire::varint32Size($data_size) + $data_size;
                }
            }
        } elseif ($field->isRepeated()) {
            $getter = $field->getGetter();
            $values = $this->$getter();
            $count = count($values);
            if ($count !== 0) {
                if ($field->getPacked()) {
                    $data_size = 0;
                    foreach ($values as $value) {
                        $data_size += $this->fieldDataOnlyByteSize($field, $value);
                    }
                    $size += GPBWire::tagSize($field);
                    $size += GPBWire::varint32Size($data_size);
                    $size += $data_size;
                } else {
                    $size += $count * GPBWire::tagSize($field);
                    foreach ($values as $value) {
                        $size += $this->fieldDataOnlyByteSize($field, $value);
                    }
                }
            }
        } elseif ($this->existField($field)) {
            $size += GPBWire::tagSize($field);
            $getter = $field->getGetter();
            $value = $this->$getter();
            $size += $this->fieldDataOnlyByteSize($field, $value);
        }
        return $size;
    }

    /**
     * @ignore
     */
    private function fieldJsonByteSize($field)
    {
        $size = 0;

        if ($field->isMap()) {
            $getter = $field->getGetter();
            $values = $this->$getter();
            $count = count($values);
            if ($count !== 0) {
                if (!GPBUtil::hasSpecialJsonMapping($this)) {
                    $size += 3;                              // size for "\"\":".
                    $size += strlen($field->getJsonName());  // size for field name
                }
                $size += 2;  // size for "{}".
                $size += $count - 1;                     // size for commas
                $getter = $field->getGetter();
                $map_entry = $field->getMessageType();
                $key_field = $map_entry->getFieldByNumber(1);
                $value_field = $map_entry->getFieldByNumber(2);
                switch ($key_field->getType()) {
                case GPBType::STRING:
                case GPBType::SFIXED64:
                case GPBType::INT64:
                case GPBType::SINT64:
                case GPBType::FIXED64:
                case GPBType::UINT64:
                    $additional_quote = false;
                    break;
                default:
                    $additional_quote = true;
                }
                foreach ($values as $key => $value) {
                    if ($additional_quote) {
                        $size += 2;  // size for ""
                    }
                    $size += $this->fieldDataOnlyJsonByteSize($key_field, $key);
                    $size += $this->fieldDataOnlyJsonByteSize($value_field, $value);
                    $size += 1;  // size for :
                }
            }
        } elseif ($field->isRepeated()) {
            $getter = $field->getGetter();
            $values = $this->$getter();
            $count = count($values);
            if ($count !== 0) {
                if (!GPBUtil::hasSpecialJsonMapping($this)) {
                    $size += 3;                              // size for "\"\":".
                    $size += strlen($field->getJsonName());  // size for field name
                }
                $size += 2;  // size for "[]".
                $size += $count - 1;                     // size for commas
                $getter = $field->getGetter();
                foreach ($values as $value) {
                    $size += $this->fieldDataOnlyJsonByteSize($field, $value);
                }
            }
        } elseif ($this->existField($field) || GPBUtil::hasJsonValue($this)) {
            if (!GPBUtil::hasSpecialJsonMapping($this)) {
                $size += 3;                              // size for "\"\":".
                $size += strlen($field->getJsonName());  // size for field name
            }
            $getter = $field->getGetter();
            $value = $this->$getter();
            $size += $this->fieldDataOnlyJsonByteSize($field, $value);
        }
        return $size;
    }

    /**
     * @ignore
     */
    public function byteSize()
    {
        $size = 0;

        $fields = $this->desc->getField();
        foreach ($fields as $field) {
            $size += $this->fieldByteSize($field);
        }
        $size += strlen($this->unknown);
        return $size;
    }

    private function appendHelper($field, $append_value)
    {
        $getter = $field->getGetter();
        $setter = $field->getSetter();

        $field_arr_value = $this->$getter();
        $field_arr_value[] = $append_value;

        if (!is_object($field_arr_value)) {
            $this->$setter($field_arr_value);
        }
    }

    private function kvUpdateHelper($field, $update_key, $update_value)
    {
        $getter = $field->getGetter();
        $setter = $field->getSetter();

        $field_arr_value = $this->$getter();
        $field_arr_value[$update_key] = $update_value;

        if (!is_object($field_arr_value)) {
            $this->$setter($field_arr_value);
        }
    }

    /**
     * @ignore
     */
    public function jsonByteSize()
    {
        $size = 0;
        if (is_a($this, 'Google\Protobuf\Any')) {
            // Size for "{}".
            $size += 2;

            // Size for "\"@type\":".
            $size += 8;

            // Size for url. +2 for "" /.
            $size += strlen($this->getTypeUrl()) + 2;

            $value_msg = $this->unpack();
            if (GPBUtil::hasSpecialJsonMapping($value_msg)) {
                // Size for "\",value\":".
                $size += 9;
                $size += $value_msg->jsonByteSize();
            } else {
                $value_size = $value_msg->jsonByteSize();
                // size === 2 it's empty message {} which is not serialized inside any
                if ($value_size !== 2) {
                    // Size for value. +1 for comma, -2 for "{}".
                    $size += $value_size -1;
                }
            }
        } elseif (get_class($this) === 'Google\Protobuf\FieldMask') {
            $field_mask = GPBUtil::formatFieldMask($this);
            $size += strlen($field_mask) + 2;  // 2 for ""
        } elseif (get_class($this) === 'Google\Protobuf\Duration') {
            $duration = GPBUtil::formatDuration($this) . "s";
            $size += strlen($duration) + 2;  // 2 for ""
        } elseif (get_class($this) === 'Google\Protobuf\Timestamp') {
            $timestamp = GPBUtil::formatTimestamp($this);
            $timestamp = json_encode($timestamp);
            $size += strlen($timestamp);
        } elseif (get_class($this) === 'Google\Protobuf\ListValue') {
            $field = $this->desc->getField()[1];
            if ($this->existField($field)) {
                $field_size = $this->fieldJsonByteSize($field);
                $size += $field_size;
            } else {
                // Size for "[]".
                $size += 2;
            }
        } elseif (get_class($this) === 'Google\Protobuf\Struct') {
            $field = $this->desc->getField()[1];
            if ($this->existField($field)) {
                $field_size = $this->fieldJsonByteSize($field);
                $size += $field_size;
            } else {
                // Size for "{}".
                $size += 2;
            }
        } else {
            if (!GPBUtil::hasSpecialJsonMapping($this)) {
                // Size for "{}".
                $size += 2;
            }

            $fields = $this->desc->getField();
            $count = 0;
            foreach ($fields as $field) {
                $field_size = $this->fieldJsonByteSize($field);
                $size += $field_size;
                if ($field_size != 0) {
                  $count++;
                }
            }
            // size for comma
            $size += $count > 0 ? ($count - 1) : 0;
        }
        return $size;
    }

    public function __debugInfo()
    {
        if (is_a($this, 'Google\Protobuf\FieldMask')) {
            return ['paths' => $this->getPaths()->__debugInfo()];
        }

        if (is_a($this, 'Google\Protobuf\Value')) {
            switch ($this->getKind()) {
                case 'null_value':
                    return ['nullValue' => $this->getNullValue()];
                case 'number_value':
                    return ['numberValue' => $this->getNumberValue()];
                case 'string_value':
                    return ['stringValue' => $this->getStringValue()];
                case 'bool_value':
                    return ['boolValue' => $this->getBoolValue()];
                case 'struct_value':
                    return ['structValue' => $this->getStructValue()->__debugInfo()];
                case 'list_value':
                    return ['listValue' => $this->getListValue()->__debugInfo()];
            }
            return [];
        }

        if (is_a($this, 'Google\Protobuf\BoolValue')
            || is_a($this, 'Google\Protobuf\BytesValue')
            || is_a($this, 'Google\Protobuf\DoubleValue')
            || is_a($this, 'Google\Protobuf\FloatValue')
            || is_a($this, 'Google\Protobuf\StringValue')
            || is_a($this, 'Google\Protobuf\Int32Value')
            || is_a($this, 'Google\Protobuf\Int64Value')
            || is_a($this, 'Google\Protobuf\UInt32Value')
            || is_a($this, 'Google\Protobuf\UInt64Value')
        ) {
            return [
                'value' => json_decode($this->serializeToJsonString(), true),
            ];
        }

        if (
            is_a($this, 'Google\Protobuf\Duration')
            || is_a($this, 'Google\Protobuf\Timestamp')
        ) {
            return [
                'seconds' => $this->getSeconds(),
                'nanos' => $this->getNanos(),
            ];
        }

        return json_decode($this->serializeToJsonString(), true);
    }
}
