<?php

// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc.  All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

/**
 * 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.
 */
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)) {
            user_error(get_class($this) . " is not found in descriptor pool.");
        }
        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 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 writeOneof($number, $value)
    {
        $field = $this->desc->getFieldByNumber($number);
        $oneof = $this->desc->getOneofDecl()[$field->getOneofIndex()];
        $oneof_name = $oneof->getName();
        $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(teboring): 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_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(teboring): 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 overritten.
     * Singular/Oneof sub-messages are recursively merged. All overritten
     * 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.
     * @return null.
     * @throws Exception Invalid data.
     */
    public function mergeFromJsonString($data)
    {
        $input = new RawInputStream($data);
        $this->parseFromJsonStream($input);
    }

    /**
     * @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,
        $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);
                }
                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();
                }
                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_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 (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 (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 (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 (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(),
     *     ]
     * ]);
     * ```
     *
     * @param array $array An array containing message properties and values.
     * @return null.
     * @throws \Exception Invalid data.
     */
    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->isWrapperType()) {
                self::normalizeToMessageType($value, $field->getMessageType()->getClass());
            }
            $this->$setter($value);
        }
    }

    /**
     * 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.
     *
     * @param mixed $value The value to normalize.
     * @param string $class The expected wrapper class name
     * @throws \Exception If $value cannot be converted to a wrapper type
     */
    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) {
                throw new \Exception(
                    "Error normalizing value to type '$class': " . $exception->getMessage(),
                    $exception->getCode(),
                    $exception
                );
            }
        }
    }

    protected function mergeFromJsonArray($array)
    {
        if (is_a($this, "Google\Protobuf\Any")) {
            $this->clear();
            $this->setTypeUrl($array["@type"]);
            $msg = $this->unpack();
            if (GPBUtil::hasSpecialJsonMapping($msg)) {
                $msg->mergeFromJsonArray($array["value"]);
            } else {
                unset($array["@type"]);
                $msg->mergeFromJsonArray($array);
            }
            $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);
                $fields[$key] = $v;
            }
        }
        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);
                        $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);
                        $values = $list_value->getValues();
                        $values[]= $value;
                    }
                }
            } else {
                throw new GPBDecodeException("Invalid type for Value.");
            }
            return;
        }
        $this->mergeFromArrayJsonImpl($array);
    }

    private function mergeFromArrayJsonImpl($array)
    {
        foreach ($array as $key => $value) {
            $field = $this->desc->getFieldByJsonName($key);
            if (is_null($field)) {
                $field = $this->desc->getFieldByName($key);
                if (is_null($field)) {
                    continue;
                }
            }
            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,
                        true);
                    $proto_value = $this->convertJsonValueToProtoValue(
                        $tmp_value,
                        $value_field);
                    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);
                    self::appendHelper($field, $proto_value);
                }
            } else {
                $setter = $field->getSetter();
                $proto_value = $this->convertJsonValueToProtoValue(
                    $value,
                    $field);
                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)
    {
        $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);
        } 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));
        } 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)
    {
        $oneof_index = $field->getOneofIndex();
        if ($oneof_index !== -1) {
            $oneof = $this->desc->getOneofDecl()[$oneof_index];
            $oneof_name = $oneof->getName();
            return $this->$oneof_name->getNumber() === $field->getNumber();
        }

        $getter = $field->getGetter();
        $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(teboring): 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(teboring): 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 {
                // Size for value. +1 for comma, -2 for "{}".
                $size += $value_msg->jsonByteSize() -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);
        } 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;
    }
}
