<?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\GPBType;
use Google\Protobuf\Internal\GPBWire;
use Google\Protobuf\Internal\MapEntry;
use Google\Protobuf\ListValue;
use Google\Protobuf\RepeatedField;
use Google\Protobuf\PrintOptions;
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();
            $getter = $field->getGetter();
            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->isRepeated()) {
                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->isRequired() && !$field->isRepeated() &&
                PHP_INT_SIZE == 4 && $this->$getter() === 0) {
                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 shouldEmitDefaults($options): bool
    {
        return ($options & \Google\Protobuf\PrintOptions::EMIT_DEFAULTS) !== 0;
    }

    /**
     * @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:
                // We don't check UTF-8 here; that will be validated by the
                // setter later.
                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->isRepeated()) {
                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->isRequired() && !$field->isRepeated()) {
                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->isRepeated()) {
                $getter = $field->getGetter();
                $arr = $this->$getter();
                foreach ($arr as $sub) {
                    $sub->discardUnknownFields();
                }
            } else if (!$field->isRequired() && !$field->isRepeated()) {
                $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->isRepeated()) {
                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->isRequired() && !$field->isRepeated()) {
                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);

                    // Mapped unknown enum string values should be silently
                    // ignored if ignore_unknown is set.
                    if ($value_field->getType() == GPBType::ENUM &&
                        is_string($tmp_value) &&
                        is_null(
                          $value_field->getEnumType()->getValueByName($tmp_value)
                        ) &&
                        $ignore_unknown) {
                        continue;
                    }

                    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);

                    // Repeated unknown enum string values should be silently
                    // ignored if ignore_unknown is set.
                    if ($field->getType() == GPBType::ENUM &&
                        is_string($tmp) &&
                        is_null($field->getEnumType()->getValueByName($tmp)) &&
                        $ignore_unknown) {
                        continue;
                    }

                    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(), $e->getCode(), $e);
        }
    }

    /**
     * @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)
    {
        $options = $output->getOptions();
        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, $options)) {
                        $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, $options)) {
                $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, $options)) {
                $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, $options) ||
                    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($options = 0)
    {
        $output = new CodedOutputStream($this->jsonByteSize($options), $options);
        $this->serializeToJsonStream($output);
        return $output->getData();
    }

    /**
     * @ignore
     */
    private function existField($field, $options = 0)
    {
        $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()) {
            if ($this->shouldEmitDefaults($options)) {
                return true;
            }
            return count($values) !== 0;
        } elseif ($field->isRepeated()) {
            if ($this->shouldEmitDefaults($options)) {
                return true;
            }
            return count($values) !== 0;
        } else {
            if ($this->shouldEmitDefaults($options)) {
                return true;
            }
            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, $options = 0)
    {
        $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;
                }
                if ($options & PrintOptions::ALWAYS_PRINT_ENUMS_AS_INTS) {
                    $size += strlen(strval($value)); // size for integer length
                } else {
                    $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($options);
                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, $options = 0)
    {
        $size = 0;

        if ($field->isMap()) {
            $getter = $field->getGetter();
            $values = $this->$getter();
            $count = count($values);
            if ($count !== 0 || $this->shouldEmitDefaults($options)) {
                if (!GPBUtil::hasSpecialJsonMapping($this)) {
                    $size += 3;                              // size for "\"\":".
                    if ($options & PrintOptions::PRESERVE_PROTO_FIELD_NAMES) {
                        $size += strlen($field->getName());
                    } else {
                        $size += strlen($field->getJsonName());
                    } // size for field name
                }
                $size += 2;  // size for "{}".
                if ($count > 0) {
                    $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, $options);
                        $size += $this->fieldDataOnlyJsonByteSize($value_field, $value, $options);
                        $size += 1;  // size for :
                    }
                }
            }
        } elseif ($field->isRepeated()) {
            $getter = $field->getGetter();
            $values = $this->$getter();
            $count = count($values);
            if ($count !== 0 || $this->shouldEmitDefaults($options)) {
                if (!GPBUtil::hasSpecialJsonMapping($this)) {
                    $size += 3;                              // size for "\"\":".
                    if ($options & PrintOptions::PRESERVE_PROTO_FIELD_NAMES) {
                        $size += strlen($field->getName());
                    } else {
                        $size += strlen($field->getJsonName());
                    } // size for field name
                }
                $size += 2;  // size for "[]".
                if ($count > 0) {
                    $size += $count - 1;                     // size for commas
                    $getter = $field->getGetter();
                    foreach ($values as $value) {
                        $size += $this->fieldDataOnlyJsonByteSize($field, $value, $options);
                    }
                }
            }
        } elseif ($this->existField($field, $options) || GPBUtil::hasJsonValue($this)) {
            if (!GPBUtil::hasSpecialJsonMapping($this)) {
                $size += 3;                              // size for "\"\":".
                if ($options & PrintOptions::PRESERVE_PROTO_FIELD_NAMES) {
                    $size += strlen($field->getName());
                } else {
                    $size += strlen($field->getJsonName());
                } // size for field name
            }
            $getter = $field->getGetter();
            $value = $this->$getter();
            $size += $this->fieldDataOnlyJsonByteSize($field, $value, $options);
        }
        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($options = 0)
    {
        $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($options);
            } else {
                $value_size = $value_msg->jsonByteSize($options);
                // 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, $options)) {
                $field_size = $this->fieldJsonByteSize($field, $options);
                $size += $field_size;
            } else {
                // Size for "[]".
                $size += 2;
            }
        } elseif (get_class($this) === 'Google\Protobuf\Struct') {
            $field = $this->desc->getField()[1];
            if ($this->existField($field, $options)) {
                $field_size = $this->fieldJsonByteSize($field, $options);
                $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, $options);
                $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);
    }
}
