diff --git a/vendor/google/protobuf/src/Google/Protobuf/Internal/Message.php b/vendor/google/protobuf/src/Google/Protobuf/Internal/Message.php
new file mode 100644
index 0000000..1ffb245
--- /dev/null
+++ b/vendor/google/protobuf/src/Google/Protobuf/Internal/Message.php
@@ -0,0 +1,1983 @@
+<?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 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 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_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 (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(),
+     *     ]
+     * ]);
+     * ```
+     *
+     * 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)
+    {
+        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));
+        } elseif (get_class($this) === 'Google\Protobuf\ListValue') {
+            $field = $this->desc->getField()[1];
+            if (!$this->existField($field)) {
+                $output->writeRaw("[]", 2);
+            } else {
+                if (!$this->serializeFieldToJsonStream($output, $field)) {
+                    return false;
+                }
+            }
+        } elseif (get_class($this) === 'Google\Protobuf\Struct') {
+            $field = $this->desc->getField()[1];
+            if (!$this->existField($field)) {
+                $output->writeRaw("{}", 2);
+            } else {
+                if (!$this->serializeFieldToJsonStream($output, $field)) {
+                    return false;
+                }
+            }
+        } else {
+            if (!GPBUtil::hasSpecialJsonMapping($this)) {
+                $output->writeRaw("{", 1);
+            }
+            $fields = $this->desc->getField();
+            $first = true;
+            foreach ($fields as $field) {
+                if ($this->existField($field) ||
+                    GPBUtil::hasJsonValue($this)) {
+                    if ($first) {
+                        $first = false;
+                    } else {
+                        $output->writeRaw(",", 1);
+                    }
+                    if (!$this->serializeFieldToJsonStream($output, $field)) {
+                        return false;
+                    }
+                }
+            }
+            if (!GPBUtil::hasSpecialJsonMapping($this)) {
+                $output->writeRaw("}", 1);
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Serialize the message to string.
+     * @return string Serialized binary protobuf data.
+     */
+    public function serializeToString()
+    {
+        $output = new CodedOutputStream($this->byteSize());
+        $this->serializeToStream($output);
+        return $output->getData();
+    }
+
+    /**
+     * Serialize the message to json string.
+     * @return string Serialized json protobuf data.
+     */
+    public function serializeToJsonString()
+    {
+        $output = new CodedOutputStream($this->jsonByteSize());
+        $this->serializeToJsonStream($output);
+        return $output->getData();
+    }
+
+    /**
+     * @ignore
+     */
+    private function existField($field)
+    {
+        $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);
+        } elseif (get_class($this) === 'Google\Protobuf\ListValue') {
+            $field = $this->desc->getField()[1];
+            if ($this->existField($field)) {
+                $field_size = $this->fieldJsonByteSize($field);
+                $size += $field_size;
+            } else {
+                // Size for "[]".
+                $size += 2;
+            }
+        } elseif (get_class($this) === 'Google\Protobuf\Struct') {
+            $field = $this->desc->getField()[1];
+            if ($this->existField($field)) {
+                $field_size = $this->fieldJsonByteSize($field);
+                $size += $field_size;
+            } else {
+                // Size for "{}".
+                $size += 2;
+            }
+        } else {
+            if (!GPBUtil::hasSpecialJsonMapping($this)) {
+                // Size for "{}".
+                $size += 2;
+            }
+
+            $fields = $this->desc->getField();
+            $count = 0;
+            foreach ($fields as $field) {
+                $field_size = $this->fieldJsonByteSize($field);
+                $size += $field_size;
+                if ($field_size != 0) {
+                  $count++;
+                }
+            }
+            // size for comma
+            $size += $count > 0 ? ($count - 1) : 0;
+        }
+        return $size;
+    }
+}
