Skip to main content
Drupal API
User account menu
  • Log in

Breadcrumb

  1. Drupal Core 11.1.x
  2. Message.php

class Message

Same name in this branch
  1. 11.1.x vendor/guzzlehttp/psr7/src/Message.php \GuzzleHttp\Psr7\Message
  2. 11.1.x vendor/symfony/mime/Message.php \Symfony\Component\Mime\Message
  3. 11.1.x composer/Plugin/ProjectMessage/Message.php \Drupal\Composer\Plugin\ProjectMessage\Message
  4. 11.1.x core/modules/contact/src/Entity/Message.php \Drupal\contact\Entity\Message

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.

Hierarchy

  • class \Google\Protobuf\Internal\Message

Expanded class hierarchy of Message

2 files declare their use of Message
MapEntry.php in vendor/google/protobuf/src/Google/Protobuf/Internal/MapEntry.php
ProtobufSerializer.php in vendor/open-telemetry/exporter-otlp/ProtobufSerializer.php
33 string references to 'Message'
AbstractWebDriver::curl in vendor/lullabot/php-webdriver/lib/WebDriver/AbstractWebDriver.php
Curl request to webdriver server.
Checkstyle::generateFileReport in vendor/squizlabs/php_codesniffer/src/Reports/Checkstyle.php
Generate a partial report for a single processed file.
Compiler::compile in vendor/symfony/dependency-injection/Compiler/Compiler.php
Run the Compiler and process all Passes.
ContactFormEditForm::form in core/modules/contact/src/ContactFormEditForm.php
Gets the actual form array to be built.
core.entity.schema.yml in core/config/schema/core.entity.schema.yml
core/config/schema/core.entity.schema.yml

... See full list

File

vendor/google/protobuf/src/Google/Protobuf/Internal/Message.php, line 34

Namespace

Google\Protobuf\Internal
View source
class Message {
    
    /**
     * @ignore
     */
    private $desc;
    private $unknown = "";
    
    /**
     * @ignore
     */
    public function __construct($data = NULL) {
        // MapEntry message is shared by all types of map fields, whose
        // descriptors are different from each other. Thus, we cannot find a
        // specific descriptor from the descriptor pool.
        if ($this instanceof MapEntry) {
            $this->initWithDescriptor($data);
        }
        else {
            $this->initWithGeneratedPool();
            if (is_array($data)) {
                $this->mergeFromArray($data);
            }
            else {
                if (!empty($data)) {
                    throw new \InvalidArgumentException('Message constructor must be an array or null.');
                }
            }
        }
    }
    
    /**
     * @ignore
     */
    private function initWithGeneratedPool() {
        $pool = DescriptorPool::getGeneratedPool();
        $this->desc = $pool->getDescriptorByClassName(get_class($this));
        if (is_null($this->desc)) {
            throw new \InvalidArgumentException(get_class($this) . " is not found in descriptor pool. " . 'Only generated classes may derive from Message.');
        }
        foreach ($this->desc
            ->getField() as $field) {
            $setter = $field->getSetter();
            if ($field->isMap()) {
                $message_type = $field->getMessageType();
                $key_field = $message_type->getFieldByNumber(1);
                $value_field = $message_type->getFieldByNumber(2);
                switch ($value_field->getType()) {
                    case GPBType::MESSAGE:
                    case GPBType::GROUP:
                        $map_field = new MapField($key_field->getType(), $value_field->getType(), $value_field->getMessageType()
                            ->getClass());
                        $this->{$setter}($map_field);
                        break;
                    case GPBType::ENUM:
                        $map_field = new MapField($key_field->getType(), $value_field->getType(), $value_field->getEnumType()
                            ->getClass());
                        $this->{$setter}($map_field);
                        break;
                    default:
                        $map_field = new MapField($key_field->getType(), $value_field->getType());
                        $this->{$setter}($map_field);
                        break;
                }
            }
            else {
                if ($field->getLabel() === GPBLabel::REPEATED) {
                    switch ($field->getType()) {
                        case GPBType::MESSAGE:
                        case GPBType::GROUP:
                            $repeated_field = new RepeatedField($field->getType(), $field->getMessageType()
                                ->getClass());
                            $this->{$setter}($repeated_field);
                            break;
                        case GPBType::ENUM:
                            $repeated_field = new RepeatedField($field->getType(), $field->getEnumType()
                                ->getClass());
                            $this->{$setter}($repeated_field);
                            break;
                        default:
                            $repeated_field = new RepeatedField($field->getType());
                            $this->{$setter}($repeated_field);
                            break;
                    }
                }
                else {
                    if ($field->getOneofIndex() !== -1) {
                        $oneof = $this->desc
                            ->getOneofDecl()[$field->getOneofIndex()];
                        $oneof_name = $oneof->getName();
                        $this->{$oneof_name} = new OneofField($oneof);
                    }
                    else {
                        if ($field->getLabel() === GPBLabel::OPTIONAL && PHP_INT_SIZE == 4) {
                            switch ($field->getType()) {
                                case GPBType::INT64:
                                case GPBType::UINT64:
                                case GPBType::FIXED64:
                                case GPBType::SFIXED64:
                                case GPBType::SINT64:
                                    $this->{$setter}("0");
                            }
                        }
                    }
                }
            }
        }
    }
    
    /**
     * @ignore
     */
    private function initWithDescriptor(Descriptor $desc) {
        $this->desc = $desc;
        foreach ($desc->getField() as $field) {
            $setter = $field->getSetter();
            $defaultValue = $this->defaultValue($field);
            $this->{$setter}($defaultValue);
        }
    }
    protected function readWrapperValue($member) {
        $field = $this->desc
            ->getFieldByName($member);
        $oneof_index = $field->getOneofIndex();
        if ($oneof_index === -1) {
            $wrapper = $this->{$member};
        }
        else {
            $wrapper = $this->readOneof($field->getNumber());
        }
        if (is_null($wrapper)) {
            return NULL;
        }
        else {
            return $wrapper->getValue();
        }
    }
    protected function writeWrapperValue($member, $value) {
        $field = $this->desc
            ->getFieldByName($member);
        $wrapped_value = $value;
        if (!is_null($value)) {
            $desc = $field->getMessageType();
            $klass = $desc->getClass();
            $wrapped_value = new $klass();
            $wrapped_value->setValue($value);
        }
        $oneof_index = $field->getOneofIndex();
        if ($oneof_index === -1) {
            $this->{$member} = $wrapped_value;
        }
        else {
            $this->writeOneof($field->getNumber(), $wrapped_value);
        }
    }
    protected function readOneof($number) {
        $field = $this->desc
            ->getFieldByNumber($number);
        $oneof = $this->desc
            ->getOneofDecl()[$field->getOneofIndex()];
        $oneof_name = $oneof->getName();
        $oneof_field = $this->{$oneof_name};
        if ($number === $oneof_field->getNumber()) {
            return $oneof_field->getValue();
        }
        else {
            return $this->defaultValue($field);
        }
    }
    protected function hasOneof($number) {
        $field = $this->desc
            ->getFieldByNumber($number);
        $oneof = $this->desc
            ->getOneofDecl()[$field->getOneofIndex()];
        $oneof_name = $oneof->getName();
        $oneof_field = $this->{$oneof_name};
        return $number === $oneof_field->getNumber();
    }
    protected function writeOneof($number, $value) {
        $field = $this->desc
            ->getFieldByNumber($number);
        $oneof = $this->desc
            ->getOneofDecl()[$field->getOneofIndex()];
        $oneof_name = $oneof->getName();
        if ($value === null) {
            $this->{$oneof_name} = new OneofField($oneof);
        }
        else {
            $oneof_field = $this->{$oneof_name};
            $oneof_field->setValue($value);
            $oneof_field->setFieldName($field->getName());
            $oneof_field->setNumber($number);
        }
    }
    protected function whichOneof($oneof_name) {
        $oneof_field = $this->{$oneof_name};
        $number = $oneof_field->getNumber();
        if ($number == 0) {
            return "";
        }
        $field = $this->desc
            ->getFieldByNumber($number);
        return $field->getName();
    }
    
    /**
     * @ignore
     */
    private function defaultValue($field) {
        $value = null;
        switch ($field->getType()) {
            case GPBType::DOUBLE:
            case GPBType::FLOAT:
                return 0.0;
            case GPBType::UINT32:
            case GPBType::INT32:
            case GPBType::FIXED32:
            case GPBType::SFIXED32:
            case GPBType::SINT32:
            case GPBType::ENUM:
                return 0;
            case GPBType::INT64:
            case GPBType::UINT64:
            case GPBType::FIXED64:
            case GPBType::SFIXED64:
            case GPBType::SINT64:
                if (PHP_INT_SIZE === 4) {
                    return '0';
                }
                else {
                    return 0;
                }
            case GPBType::BOOL:
                return false;
            case GPBType::STRING:
            case GPBType::BYTES:
                return "";
            case GPBType::GROUP:
            case GPBType::MESSAGE:
                return null;
            default:
                user_error("Unsupported type.");
                return false;
        }
    }
    
    /**
     * @ignore
     */
    private function skipField($input, $tag) {
        $number = GPBWire::getTagFieldNumber($tag);
        if ($number === 0) {
            throw new GPBDecodeException("Illegal field number zero.");
        }
        $start = $input->current();
        switch (GPBWire::getTagWireType($tag)) {
            case GPBWireType::VARINT:
                $uint64 = 0;
                if (!$input->readVarint64($uint64)) {
                    throw new GPBDecodeException("Unexpected EOF inside varint.");
                }
                break;
            case GPBWireType::FIXED64:
                $uint64 = 0;
                if (!$input->readLittleEndian64($uint64)) {
                    throw new GPBDecodeException("Unexpected EOF inside fixed64.");
                }
                break;
            case GPBWireType::FIXED32:
                $uint32 = 0;
                if (!$input->readLittleEndian32($uint32)) {
                    throw new GPBDecodeException("Unexpected EOF inside fixed32.");
                }
                break;
            case GPBWireType::LENGTH_DELIMITED:
                $length = 0;
                if (!$input->readVarint32($length)) {
                    throw new GPBDecodeException("Unexpected EOF inside length.");
                }
                $data = NULL;
                if (!$input->readRaw($length, $data)) {
                    throw new GPBDecodeException("Unexpected EOF inside length delimited data.");
                }
                break;
            case GPBWireType::START_GROUP:
            case GPBWireType::END_GROUP:
                throw new GPBDecodeException("Unexpected wire type.");
            default:
                throw new GPBDecodeException("Unexpected wire type.");
        }
        $end = $input->current();
        $bytes = str_repeat(chr(0), CodedOutputStream::MAX_VARINT64_BYTES);
        $size = CodedOutputStream::writeVarintToArray($tag, $bytes, true);
        $this->unknown .= substr($bytes, 0, $size) . $input->substr($start, $end);
    }
    
    /**
     * @ignore
     */
    private static function parseFieldFromStreamNoTag($input, $field, &$value) {
        switch ($field->getType()) {
            case GPBType::DOUBLE:
                if (!GPBWire::readDouble($input, $value)) {
                    throw new GPBDecodeException("Unexpected EOF inside double field.");
                }
                break;
            case GPBType::FLOAT:
                if (!GPBWire::readFloat($input, $value)) {
                    throw new GPBDecodeException("Unexpected EOF inside float field.");
                }
                break;
            case GPBType::INT64:
                if (!GPBWire::readInt64($input, $value)) {
                    throw new GPBDecodeException("Unexpected EOF inside int64 field.");
                }
                break;
            case GPBType::UINT64:
                if (!GPBWire::readUint64($input, $value)) {
                    throw new GPBDecodeException("Unexpected EOF inside uint64 field.");
                }
                break;
            case GPBType::INT32:
                if (!GPBWire::readInt32($input, $value)) {
                    throw new GPBDecodeException("Unexpected EOF inside int32 field.");
                }
                break;
            case GPBType::FIXED64:
                if (!GPBWire::readFixed64($input, $value)) {
                    throw new GPBDecodeException("Unexpected EOF inside fixed64 field.");
                }
                break;
            case GPBType::FIXED32:
                if (!GPBWire::readFixed32($input, $value)) {
                    throw new GPBDecodeException("Unexpected EOF inside fixed32 field.");
                }
                break;
            case GPBType::BOOL:
                if (!GPBWire::readBool($input, $value)) {
                    throw new GPBDecodeException("Unexpected EOF inside bool field.");
                }
                break;
            case GPBType::STRING:
                // We don't check UTF-8 here; that will be validated by the
                // setter later.
                if (!GPBWire::readString($input, $value)) {
                    throw new GPBDecodeException("Unexpected EOF inside string field.");
                }
                break;
            case GPBType::GROUP:
                trigger_error("Not implemented.", E_USER_ERROR);
                break;
            case GPBType::MESSAGE:
                if ($field->isMap()) {
                    $value = new MapEntry($field->getMessageType());
                }
                else {
                    $klass = $field->getMessageType()
                        ->getClass();
                    $value = new $klass();
                }
                if (!GPBWire::readMessage($input, $value)) {
                    throw new GPBDecodeException("Unexpected EOF inside message.");
                }
                break;
            case GPBType::BYTES:
                if (!GPBWire::readString($input, $value)) {
                    throw new GPBDecodeException("Unexpected EOF inside bytes field.");
                }
                break;
            case GPBType::UINT32:
                if (!GPBWire::readUint32($input, $value)) {
                    throw new GPBDecodeException("Unexpected EOF inside uint32 field.");
                }
                break;
            case GPBType::ENUM:
                // TODO: Check unknown enum value.
                if (!GPBWire::readInt32($input, $value)) {
                    throw new GPBDecodeException("Unexpected EOF inside enum field.");
                }
                break;
            case GPBType::SFIXED32:
                if (!GPBWire::readSfixed32($input, $value)) {
                    throw new GPBDecodeException("Unexpected EOF inside sfixed32 field.");
                }
                break;
            case GPBType::SFIXED64:
                if (!GPBWire::readSfixed64($input, $value)) {
                    throw new GPBDecodeException("Unexpected EOF inside sfixed64 field.");
                }
                break;
            case GPBType::SINT32:
                if (!GPBWire::readSint32($input, $value)) {
                    throw new GPBDecodeException("Unexpected EOF inside sint32 field.");
                }
                break;
            case GPBType::SINT64:
                if (!GPBWire::readSint64($input, $value)) {
                    throw new GPBDecodeException("Unexpected EOF inside sint64 field.");
                }
                break;
            default:
                user_error("Unsupported type.");
                return false;
        }
        return true;
    }
    
    /**
     * @ignore
     */
    private function parseFieldFromStream($tag, $input, $field) {
        $value = null;
        if (is_null($field)) {
            $value_format = GPBWire::UNKNOWN;
        }
        elseif (GPBWire::getTagWireType($tag) === GPBWire::getWireType($field->getType())) {
            $value_format = GPBWire::NORMAL_FORMAT;
        }
        elseif ($field->isPackable() && GPBWire::getTagWireType($tag) === GPBWire::WIRETYPE_LENGTH_DELIMITED) {
            $value_format = GPBWire::PACKED_FORMAT;
        }
        else {
            // the wire type doesn't match. Put it in our unknown field set.
            $value_format = GPBWire::UNKNOWN;
        }
        if ($value_format === GPBWire::UNKNOWN) {
            $this->skipField($input, $tag);
            return;
        }
        elseif ($value_format === GPBWire::NORMAL_FORMAT) {
            self::parseFieldFromStreamNoTag($input, $field, $value);
        }
        elseif ($value_format === GPBWire::PACKED_FORMAT) {
            $length = 0;
            if (!GPBWire::readInt32($input, $length)) {
                throw new GPBDecodeException("Unexpected EOF inside packed length.");
            }
            $limit = $input->pushLimit($length);
            $getter = $field->getGetter();
            while ($input->bytesUntilLimit() > 0) {
                self::parseFieldFromStreamNoTag($input, $field, $value);
                $this->appendHelper($field, $value);
            }
            $input->popLimit($limit);
            return;
        }
        else {
            return;
        }
        if ($field->isMap()) {
            $this->kvUpdateHelper($field, $value->getKey(), $value->getValue());
        }
        else {
            if ($field->isRepeated()) {
                $this->appendHelper($field, $value);
            }
            else {
                $setter = $field->getSetter();
                $this->{$setter}($value);
            }
        }
    }
    
    /**
     * Clear all containing fields.
     * @return null
     */
    public function clear() {
        $this->unknown = "";
        foreach ($this->desc
            ->getField() as $field) {
            $setter = $field->getSetter();
            if ($field->isMap()) {
                $message_type = $field->getMessageType();
                $key_field = $message_type->getFieldByNumber(1);
                $value_field = $message_type->getFieldByNumber(2);
                switch ($value_field->getType()) {
                    case GPBType::MESSAGE:
                    case GPBType::GROUP:
                        $map_field = new MapField($key_field->getType(), $value_field->getType(), $value_field->getMessageType()
                            ->getClass());
                        $this->{$setter}($map_field);
                        break;
                    case GPBType::ENUM:
                        $map_field = new MapField($key_field->getType(), $value_field->getType(), $value_field->getEnumType()
                            ->getClass());
                        $this->{$setter}($map_field);
                        break;
                    default:
                        $map_field = new MapField($key_field->getType(), $value_field->getType());
                        $this->{$setter}($map_field);
                        break;
                }
            }
            else {
                if ($field->getLabel() === GPBLabel::REPEATED) {
                    switch ($field->getType()) {
                        case GPBType::MESSAGE:
                        case GPBType::GROUP:
                            $repeated_field = new RepeatedField($field->getType(), $field->getMessageType()
                                ->getClass());
                            $this->{$setter}($repeated_field);
                            break;
                        case GPBType::ENUM:
                            $repeated_field = new RepeatedField($field->getType(), $field->getEnumType()
                                ->getClass());
                            $this->{$setter}($repeated_field);
                            break;
                        default:
                            $repeated_field = new RepeatedField($field->getType());
                            $this->{$setter}($repeated_field);
                            break;
                    }
                }
                else {
                    if ($field->getOneofIndex() !== -1) {
                        $oneof = $this->desc
                            ->getOneofDecl()[$field->getOneofIndex()];
                        $oneof_name = $oneof->getName();
                        $this->{$oneof_name} = new OneofField($oneof);
                    }
                    else {
                        if ($field->getLabel() === GPBLabel::OPTIONAL) {
                            switch ($field->getType()) {
                                case GPBType::DOUBLE:
                                case GPBType::FLOAT:
                                    $this->{$setter}(0.0);
                                    break;
                                case GPBType::INT32:
                                case GPBType::FIXED32:
                                case GPBType::UINT32:
                                case GPBType::SFIXED32:
                                case GPBType::SINT32:
                                case GPBType::ENUM:
                                    $this->{$setter}(0);
                                    break;
                                case GPBType::BOOL:
                                    $this->{$setter}(false);
                                    break;
                                case GPBType::STRING:
                                case GPBType::BYTES:
                                    $this->{$setter}("");
                                    break;
                                case GPBType::GROUP:
                                case GPBType::MESSAGE:
                                    $null = null;
                                    $this->{$setter}($null);
                                    break;
                            }
                            if (PHP_INT_SIZE == 4) {
                                switch ($field->getType()) {
                                    case GPBType::INT64:
                                    case GPBType::UINT64:
                                    case GPBType::FIXED64:
                                    case GPBType::SFIXED64:
                                    case GPBType::SINT64:
                                        $this->{$setter}("0");
                                }
                            }
                            else {
                                switch ($field->getType()) {
                                    case GPBType::INT64:
                                    case GPBType::UINT64:
                                    case GPBType::FIXED64:
                                    case GPBType::SFIXED64:
                                    case GPBType::SINT64:
                                        $this->{$setter}(0);
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    
    /**
     * Clear all unknown fields previously parsed.
     * @return null
     */
    public function discardUnknownFields() {
        $this->unknown = "";
        foreach ($this->desc
            ->getField() as $field) {
            if ($field->getType() != GPBType::MESSAGE) {
                continue;
            }
            if ($field->isMap()) {
                $value_field = $field->getMessageType()
                    ->getFieldByNumber(2);
                if ($value_field->getType() != GPBType::MESSAGE) {
                    continue;
                }
                $getter = $field->getGetter();
                $map = $this->{$getter}();
                foreach ($map as $key => $value) {
                    $value->discardUnknownFields();
                }
            }
            else {
                if ($field->getLabel() === GPBLabel::REPEATED) {
                    $getter = $field->getGetter();
                    $arr = $this->{$getter}();
                    foreach ($arr as $sub) {
                        $sub->discardUnknownFields();
                    }
                }
                else {
                    if ($field->getLabel() === GPBLabel::OPTIONAL) {
                        $getter = $field->getGetter();
                        $sub = $this->{$getter}();
                        if (!is_null($sub)) {
                            $sub->discardUnknownFields();
                        }
                    }
                }
            }
        }
    }
    
    /**
     * Merges the contents of the specified message into current message.
     *
     * This method merges the contents of the specified message into the
     * current message. Singular fields that are set in the specified message
     * overwrite the corresponding fields in the current message.  Repeated
     * fields are appended. Map fields key-value pairs are overwritten.
     * Singular/Oneof sub-messages are recursively merged. All overwritten
     * sub-messages are deep-copied.
     *
     * @param object $msg Protobuf message to be merged from.
     * @return null
     */
    public function mergeFrom($msg) {
        if (get_class($this) !== get_class($msg)) {
            user_error("Cannot merge messages with different class.");
            return;
        }
        foreach ($this->desc
            ->getField() as $field) {
            $setter = $field->getSetter();
            $getter = $field->getGetter();
            if ($field->isMap()) {
                if (count($msg->{$getter}()) != 0) {
                    $value_field = $field->getMessageType()
                        ->getFieldByNumber(2);
                    foreach ($msg->{$getter}() as $key => $value) {
                        if ($value_field->getType() == GPBType::MESSAGE) {
                            $klass = $value_field->getMessageType()
                                ->getClass();
                            $copy = new $klass();
                            $copy->mergeFrom($value);
                            $this->kvUpdateHelper($field, $key, $copy);
                        }
                        else {
                            $this->kvUpdateHelper($field, $key, $value);
                        }
                    }
                }
            }
            else {
                if ($field->getLabel() === GPBLabel::REPEATED) {
                    if (count($msg->{$getter}()) != 0) {
                        foreach ($msg->{$getter}() as $tmp) {
                            if ($field->getType() == GPBType::MESSAGE) {
                                $klass = $field->getMessageType()
                                    ->getClass();
                                $copy = new $klass();
                                $copy->mergeFrom($tmp);
                                $this->appendHelper($field, $copy);
                            }
                            else {
                                $this->appendHelper($field, $tmp);
                            }
                        }
                    }
                }
                else {
                    if ($field->getLabel() === GPBLabel::OPTIONAL) {
                        if ($msg->{$getter}() !== $this->defaultValue($field)) {
                            $tmp = $msg->{$getter}();
                            if ($field->getType() == GPBType::MESSAGE) {
                                if (is_null($this->{$getter}())) {
                                    $klass = $field->getMessageType()
                                        ->getClass();
                                    $new_msg = new $klass();
                                    $this->{$setter}($new_msg);
                                }
                                $this->{$getter}()
                                    ->mergeFrom($tmp);
                            }
                            else {
                                $this->{$setter}($tmp);
                            }
                        }
                    }
                }
            }
        }
    }
    
    /**
     * Parses a protocol buffer contained in a string.
     *
     * This function takes a string in the (non-human-readable) binary wire
     * format, matching the encoding output by serializeToString().
     * See mergeFrom() for merging behavior, if the field is already set in the
     * specified message.
     *
     * @param string $data Binary protobuf data.
     * @return null
     * @throws \Exception Invalid data.
     */
    public function mergeFromString($data) {
        $input = new CodedInputStream($data);
        $this->parseFromStream($input);
    }
    
    /**
     * Parses a json string to protobuf message.
     *
     * This function takes a string in the json wire format, matching the
     * encoding output by serializeToJsonString().
     * See mergeFrom() for merging behavior, if the field is already set in the
     * specified message.
     *
     * @param string $data Json protobuf data.
     * @param bool $ignore_unknown
     * @return null
     * @throws \Exception Invalid data.
     */
    public function mergeFromJsonString($data, $ignore_unknown = false) {
        $input = new RawInputStream($data);
        $this->parseFromJsonStream($input, $ignore_unknown);
    }
    
    /**
     * @ignore
     */
    public function parseFromStream($input) {
        while (true) {
            $tag = $input->readTag();
            // End of input.  This is a valid place to end, so return true.
            if ($tag === 0) {
                return true;
            }
            $number = GPBWire::getTagFieldNumber($tag);
            $field = $this->desc
                ->getFieldByNumber($number);
            $this->parseFieldFromStream($tag, $input, $field);
        }
    }
    private function convertJsonValueToProtoValue($value, $field, $ignore_unknown, $is_map_key = false) {
        switch ($field->getType()) {
            case GPBType::MESSAGE:
                $klass = $field->getMessageType()
                    ->getClass();
                $submsg = new $klass();
                if (is_a($submsg, "Google\\Protobuf\\Duration")) {
                    if (is_null($value)) {
                        return $this->defaultValue($field);
                    }
                    else {
                        if (!is_string($value)) {
                            throw new GPBDecodeException("Expect string.");
                        }
                    }
                    return GPBUtil::parseDuration($value);
                }
                else {
                    if ($field->isTimestamp()) {
                        if (is_null($value)) {
                            return $this->defaultValue($field);
                        }
                        else {
                            if (!is_string($value)) {
                                throw new GPBDecodeException("Expect string.");
                            }
                        }
                        try {
                            $timestamp = GPBUtil::parseTimestamp($value);
                        } catch (\Exception $e) {
                            throw new GPBDecodeException("Invalid RFC 3339 timestamp: " . $e->getMessage());
                        }
                        $submsg->setSeconds($timestamp->getSeconds());
                        $submsg->setNanos($timestamp->getNanos());
                    }
                    else {
                        if (is_a($submsg, "Google\\Protobuf\\FieldMask")) {
                            if (is_null($value)) {
                                return $this->defaultValue($field);
                            }
                            try {
                                return GPBUtil::parseFieldMask($value);
                            } catch (\Exception $e) {
                                throw new GPBDecodeException("Invalid FieldMask: " . $e->getMessage());
                            }
                        }
                        else {
                            if (is_null($value) && !is_a($submsg, "Google\\Protobuf\\Value")) {
                                return $this->defaultValue($field);
                            }
                            if (GPBUtil::hasSpecialJsonMapping($submsg)) {
                            }
                            elseif (!is_object($value) && !is_array($value)) {
                                throw new GPBDecodeException("Expect message.");
                            }
                            $submsg->mergeFromJsonArray($value, $ignore_unknown);
                        }
                    }
                }
                return $submsg;
            case GPBType::ENUM:
                if (is_null($value)) {
                    return $this->defaultValue($field);
                }
                if (is_integer($value)) {
                    return $value;
                }
                $enum_value = $field->getEnumType()
                    ->getValueByName($value);
                if (!is_null($enum_value)) {
                    return $enum_value->getNumber();
                }
                else {
                    if ($ignore_unknown) {
                        return $this->defaultValue($field);
                    }
                    else {
                        throw new GPBDecodeException("Enum field only accepts integer or enum value name");
                    }
                }
            case GPBType::STRING:
                if (is_null($value)) {
                    return $this->defaultValue($field);
                }
                if (is_numeric($value)) {
                    return strval($value);
                }
                if (!is_string($value)) {
                    throw new GPBDecodeException("String field only accepts string value");
                }
                return $value;
            case GPBType::BYTES:
                if (is_null($value)) {
                    return $this->defaultValue($field);
                }
                if (!is_string($value)) {
                    throw new GPBDecodeException("Byte field only accepts string value");
                }
                $proto_value = base64_decode($value, true);
                if ($proto_value === false) {
                    throw new GPBDecodeException("Invalid base64 characters");
                }
                return $proto_value;
            case GPBType::BOOL:
                if (is_null($value)) {
                    return $this->defaultValue($field);
                }
                if ($is_map_key) {
                    if ($value === "true") {
                        return true;
                    }
                    if ($value === "false") {
                        return false;
                    }
                    throw new GPBDecodeException("Bool field only accepts bool value");
                }
                if (!is_bool($value)) {
                    throw new GPBDecodeException("Bool field only accepts bool value");
                }
                return $value;
            case GPBType::FLOAT:
            case GPBType::DOUBLE:
                if (is_null($value)) {
                    return $this->defaultValue($field);
                }
                if ($value === "Infinity") {
                    return INF;
                }
                if ($value === "-Infinity") {
                    return -INF;
                }
                if ($value === "NaN") {
                    return NAN;
                }
                return $value;
            case GPBType::INT32:
            case GPBType::SINT32:
            case GPBType::SFIXED32:
                if (is_null($value)) {
                    return $this->defaultValue($field);
                }
                if (!is_numeric($value)) {
                    throw new GPBDecodeException("Invalid data type for int32 field");
                }
                if (is_string($value) && trim($value) !== $value) {
                    throw new GPBDecodeException("Invalid data type for int32 field");
                }
                if (bccomp($value, "2147483647") > 0) {
                    throw new GPBDecodeException("Int32 too large");
                }
                if (bccomp($value, "-2147483648") < 0) {
                    throw new GPBDecodeException("Int32 too small");
                }
                return $value;
            case GPBType::UINT32:
            case GPBType::FIXED32:
                if (is_null($value)) {
                    return $this->defaultValue($field);
                }
                if (!is_numeric($value)) {
                    throw new GPBDecodeException("Invalid data type for uint32 field");
                }
                if (is_string($value) && trim($value) !== $value) {
                    throw new GPBDecodeException("Invalid data type for int32 field");
                }
                if (bccomp($value, 4294967295) > 0) {
                    throw new GPBDecodeException("Uint32 too large");
                }
                return $value;
            case GPBType::INT64:
            case GPBType::SINT64:
            case GPBType::SFIXED64:
                if (is_null($value)) {
                    return $this->defaultValue($field);
                }
                if (!is_numeric($value)) {
                    throw new GPBDecodeException("Invalid data type for int64 field");
                }
                if (is_string($value) && trim($value) !== $value) {
                    throw new GPBDecodeException("Invalid data type for int64 field");
                }
                if (bccomp($value, "9223372036854775807") > 0) {
                    throw new GPBDecodeException("Int64 too large");
                }
                if (bccomp($value, "-9223372036854775808") < 0) {
                    throw new GPBDecodeException("Int64 too small");
                }
                return $value;
            case GPBType::UINT64:
            case GPBType::FIXED64:
                if (is_null($value)) {
                    return $this->defaultValue($field);
                }
                if (!is_numeric($value)) {
                    throw new GPBDecodeException("Invalid data type for int64 field");
                }
                if (is_string($value) && trim($value) !== $value) {
                    throw new GPBDecodeException("Invalid data type for int64 field");
                }
                if (bccomp($value, "18446744073709551615") > 0) {
                    throw new GPBDecodeException("Uint64 too large");
                }
                if (bccomp($value, "9223372036854775807") > 0) {
                    $value = bcsub($value, "18446744073709551616");
                }
                return $value;
            default:
                return $value;
        }
    }
    
    /**
     * Populates the message from a user-supplied PHP array. Array keys
     * correspond to Message properties and nested message properties.
     *
     * Example:
     * ```
     * $message->mergeFromArray([
     *     'name' => 'This is a message name',
     *     'interval' => [
     *          'startTime' => time() - 60,
     *          'endTime' => time(),
     *     ]
     * ]);
     * ```
     *
     * This method will trigger an error if it is passed data that cannot
     * be converted to the correct type. For example, a StringValue field
     * must receive data that is either a string or a StringValue object.
     *
     * @param array $array An array containing message properties and values.
     * @return null
     */
    protected function mergeFromArray(array $array) {
        // Just call the setters for the field names
        foreach ($array as $key => $value) {
            $field = $this->desc
                ->getFieldByName($key);
            if (is_null($field)) {
                throw new \UnexpectedValueException('Invalid message property: ' . $key);
            }
            $setter = $field->getSetter();
            if ($field->isMap()) {
                $valueField = $field->getMessageType()
                    ->getFieldByName('value');
                if (!is_null($valueField) && $valueField->isWrapperType()) {
                    self::normalizeArrayElementsToMessageType($value, $valueField->getMessageType()
                        ->getClass());
                }
            }
            elseif ($field->isWrapperType()) {
                $class = $field->getMessageType()
                    ->getClass();
                if ($field->isRepeated()) {
                    self::normalizeArrayElementsToMessageType($value, $class);
                }
                else {
                    self::normalizeToMessageType($value, $class);
                }
            }
            $this->{$setter}($value);
        }
    }
    
    /**
     * Tries to normalize the elements in $value into a provided protobuf
     * wrapper type $class. If $value is any type other than array, we do
     * not do any conversion, and instead rely on the existing protobuf
     * type checking. If $value is an array, we process each element and
     * try to convert it to an instance of $class.
     *
     * @param mixed $value The array of values to normalize.
     * @param string $class The expected wrapper class name
     */
    private static function normalizeArrayElementsToMessageType(&$value, $class) {
        if (!is_array($value)) {
            // In the case that $value is not an array, we do not want to
            // attempt any conversion. Note that this includes the cases
            // when $value is a RepeatedField of MapField. In those cases,
            // we do not need to convert the elements, as they should
            // already be the correct types.
            return;
        }
        else {
            // Normalize each element in the array.
            foreach ($value as $key => &$elementValue) {
                self::normalizeToMessageType($elementValue, $class);
            }
        }
    }
    
    /**
     * Tries to normalize $value into a provided protobuf wrapper type $class.
     * If $value is any type other than an object, we attempt to construct an
     * instance of $class and assign $value to it using the setValue method
     * shared by all wrapper types.
     *
     * This method will raise an error if it receives a type that cannot be
     * assigned to the wrapper type via setValue.
     *
     * @param mixed $value The value to normalize.
     * @param string $class The expected wrapper class name
     */
    private static function normalizeToMessageType(&$value, $class) {
        if (is_null($value) || is_object($value)) {
            // This handles the case that $value is an instance of $class. We
            // choose not to do any more strict checking here, relying on the
            // existing type checking done by GPBUtil.
            return;
        }
        else {
            // Try to instantiate $class and set the value
            try {
                $msg = new $class();
                $msg->setValue($value);
                $value = $msg;
                return;
            } catch (\Exception $exception) {
                trigger_error("Error normalizing value to type '{$class}': " . $exception->getMessage(), E_USER_ERROR);
            }
        }
    }
    protected function mergeFromJsonArray($array, $ignore_unknown) {
        if (is_a($this, "Google\\Protobuf\\Any")) {
            $this->clear();
            $this->setTypeUrl($array["@type"]);
            $msg = $this->unpack();
            if (GPBUtil::hasSpecialJsonMapping($msg)) {
                $msg->mergeFromJsonArray($array["value"], $ignore_unknown);
            }
            else {
                unset($array["@type"]);
                $msg->mergeFromJsonArray($array, $ignore_unknown);
            }
            $this->setValue($msg->serializeToString());
            return;
        }
        if (is_a($this, "Google\\Protobuf\\DoubleValue") || is_a($this, "Google\\Protobuf\\FloatValue") || is_a($this, "Google\\Protobuf\\Int64Value") || is_a($this, "Google\\Protobuf\\UInt64Value") || is_a($this, "Google\\Protobuf\\Int32Value") || is_a($this, "Google\\Protobuf\\UInt32Value") || is_a($this, "Google\\Protobuf\\BoolValue") || is_a($this, "Google\\Protobuf\\StringValue")) {
            $this->setValue($array);
            return;
        }
        if (is_a($this, "Google\\Protobuf\\BytesValue")) {
            $this->setValue(base64_decode($array));
            return;
        }
        if (is_a($this, "Google\\Protobuf\\Duration")) {
            $this->mergeFrom(GPBUtil::parseDuration($array));
            return;
        }
        if (is_a($this, "Google\\Protobuf\\FieldMask")) {
            $this->mergeFrom(GPBUtil::parseFieldMask($array));
            return;
        }
        if (is_a($this, "Google\\Protobuf\\Timestamp")) {
            $this->mergeFrom(GPBUtil::parseTimestamp($array));
            return;
        }
        if (is_a($this, "Google\\Protobuf\\Struct")) {
            $fields = $this->getFields();
            foreach ($array as $key => $value) {
                $v = new Value();
                $v->mergeFromJsonArray($value, $ignore_unknown);
                $fields[$key] = $v;
            }
            return;
        }
        if (is_a($this, "Google\\Protobuf\\Value")) {
            if (is_bool($array)) {
                $this->setBoolValue($array);
            }
            elseif (is_string($array)) {
                $this->setStringValue($array);
            }
            elseif (is_null($array)) {
                $this->setNullValue(0);
            }
            elseif (is_double($array) || is_integer($array)) {
                $this->setNumberValue($array);
            }
            elseif (is_array($array)) {
                if (array_values($array) !== $array) {
                    // Associative array
                    $struct_value = $this->getStructValue();
                    if (is_null($struct_value)) {
                        $struct_value = new Struct();
                        $this->setStructValue($struct_value);
                    }
                    foreach ($array as $key => $v) {
                        $value = new Value();
                        $value->mergeFromJsonArray($v, $ignore_unknown);
                        $values = $struct_value->getFields();
                        $values[$key] = $value;
                    }
                }
                else {
                    // Array
                    $list_value = $this->getListValue();
                    if (is_null($list_value)) {
                        $list_value = new ListValue();
                        $this->setListValue($list_value);
                    }
                    foreach ($array as $v) {
                        $value = new Value();
                        $value->mergeFromJsonArray($v, $ignore_unknown);
                        $values = $list_value->getValues();
                        $values[] = $value;
                    }
                }
            }
            else {
                throw new GPBDecodeException("Invalid type for Value.");
            }
            return;
        }
        $this->mergeFromArrayJsonImpl($array, $ignore_unknown);
    }
    private function mergeFromArrayJsonImpl($array, $ignore_unknown) {
        foreach ($array as $key => $value) {
            $field = $this->desc
                ->getFieldByJsonName($key);
            if (is_null($field)) {
                $field = $this->desc
                    ->getFieldByName($key);
                if (is_null($field)) {
                    if ($ignore_unknown) {
                        continue;
                    }
                    else {
                        throw new GPBDecodeException($key . ' is unknown.');
                    }
                }
            }
            if ($field->isMap()) {
                if (is_null($value)) {
                    continue;
                }
                $key_field = $field->getMessageType()
                    ->getFieldByNumber(1);
                $value_field = $field->getMessageType()
                    ->getFieldByNumber(2);
                foreach ($value as $tmp_key => $tmp_value) {
                    if (is_null($tmp_value)) {
                        throw new \Exception("Map value field element cannot be null.");
                    }
                    $proto_key = $this->convertJsonValueToProtoValue($tmp_key, $key_field, $ignore_unknown, true);
                    $proto_value = $this->convertJsonValueToProtoValue($tmp_value, $value_field, $ignore_unknown);
                    self::kvUpdateHelper($field, $proto_key, $proto_value);
                }
            }
            else {
                if ($field->isRepeated()) {
                    if (is_null($value)) {
                        continue;
                    }
                    foreach ($value as $tmp) {
                        if (is_null($tmp)) {
                            throw new \Exception("Repeated field elements cannot be null.");
                        }
                        $proto_value = $this->convertJsonValueToProtoValue($tmp, $field, $ignore_unknown);
                        self::appendHelper($field, $proto_value);
                    }
                }
                else {
                    $setter = $field->getSetter();
                    $proto_value = $this->convertJsonValueToProtoValue($value, $field, $ignore_unknown);
                    if ($field->getType() === GPBType::MESSAGE) {
                        if (is_null($proto_value)) {
                            continue;
                        }
                        $getter = $field->getGetter();
                        $submsg = $this->{$getter}();
                        if (!is_null($submsg)) {
                            $submsg->mergeFrom($proto_value);
                            continue;
                        }
                    }
                    $this->{$setter}($proto_value);
                }
            }
        }
    }
    
    /**
     * @ignore
     */
    public function parseFromJsonStream($input, $ignore_unknown) {
        $array = json_decode($input->getData(), true, 512, JSON_BIGINT_AS_STRING);
        if ($this instanceof \Google\Protobuf\ListValue) {
            $array = [
                "values" => $array,
            ];
        }
        if (is_null($array)) {
            if ($this instanceof \Google\Protobuf\Value) {
                $this->setNullValue(\Google\Protobuf\NullValue::NULL_VALUE);
                return;
            }
            else {
                throw new GPBDecodeException("Cannot decode json string: " . $input->getData());
            }
        }
        try {
            $this->mergeFromJsonArray($array, $ignore_unknown);
        } catch (\Exception $e) {
            throw new GPBDecodeException($e->getMessage(), $e->getCode(), $e);
        }
    }
    
    /**
     * @ignore
     */
    private function serializeSingularFieldToStream($field, &$output) {
        if (!$this->existField($field)) {
            return true;
        }
        $getter = $field->getGetter();
        $value = $this->{$getter}();
        if (!GPBWire::serializeFieldToStream($value, $field, true, $output)) {
            return false;
        }
        return true;
    }
    
    /**
     * @ignore
     */
    private function serializeRepeatedFieldToStream($field, &$output) {
        $getter = $field->getGetter();
        $values = $this->{$getter}();
        $count = count($values);
        if ($count === 0) {
            return true;
        }
        $packed = $field->getPacked();
        if ($packed) {
            if (!GPBWire::writeTag($output, GPBWire::makeTag($field->getNumber(), GPBType::STRING))) {
                return false;
            }
            $size = 0;
            foreach ($values as $value) {
                $size += $this->fieldDataOnlyByteSize($field, $value);
            }
            if (!$output->writeVarint32($size, true)) {
                return false;
            }
        }
        foreach ($values as $value) {
            if (!GPBWire::serializeFieldToStream($value, $field, !$packed, $output)) {
                return false;
            }
        }
        return true;
    }
    
    /**
     * @ignore
     */
    private function serializeMapFieldToStream($field, $output) {
        $getter = $field->getGetter();
        $values = $this->{$getter}();
        $count = count($values);
        if ($count === 0) {
            return true;
        }
        foreach ($values as $key => $value) {
            $map_entry = new MapEntry($field->getMessageType());
            $map_entry->setKey($key);
            $map_entry->setValue($value);
            if (!GPBWire::serializeFieldToStream($map_entry, $field, true, $output)) {
                return false;
            }
        }
        return true;
    }
    
    /**
     * @ignore
     */
    private function serializeFieldToStream(&$output, $field) {
        if ($field->isMap()) {
            return $this->serializeMapFieldToStream($field, $output);
        }
        elseif ($field->isRepeated()) {
            return $this->serializeRepeatedFieldToStream($field, $output);
        }
        else {
            return $this->serializeSingularFieldToStream($field, $output);
        }
    }
    
    /**
     * @ignore
     */
    private function serializeFieldToJsonStream(&$output, $field) {
        $getter = $field->getGetter();
        $values = $this->{$getter}();
        return GPBJsonWire::serializeFieldToStream($values, $field, $output, !GPBUtil::hasSpecialJsonMapping($this));
    }
    
    /**
     * @ignore
     */
    public function serializeToStream(&$output) {
        $fields = $this->desc
            ->getField();
        foreach ($fields as $field) {
            if (!$this->serializeFieldToStream($output, $field)) {
                return false;
            }
        }
        $output->writeRaw($this->unknown, strlen($this->unknown));
        return true;
    }
    
    /**
     * @ignore
     */
    public function serializeToJsonStream(&$output) {
        if (is_a($this, 'Google\\Protobuf\\Any')) {
            $output->writeRaw("{", 1);
            $type_field = $this->desc
                ->getFieldByNumber(1);
            $value_msg = $this->unpack();
            // Serialize type url.
            $output->writeRaw("\"@type\":", 8);
            $output->writeRaw("\"", 1);
            $output->writeRaw($this->getTypeUrl(), strlen($this->getTypeUrl()));
            $output->writeRaw("\"", 1);
            // Serialize value
            if (GPBUtil::hasSpecialJsonMapping($value_msg)) {
                $output->writeRaw(",\"value\":", 9);
                $value_msg->serializeToJsonStream($output);
            }
            else {
                $value_fields = $value_msg->desc
                    ->getField();
                foreach ($value_fields as $field) {
                    if ($value_msg->existField($field)) {
                        $output->writeRaw(",", 1);
                        if (!$value_msg->serializeFieldToJsonStream($output, $field)) {
                            return false;
                        }
                    }
                }
            }
            $output->writeRaw("}", 1);
        }
        elseif (is_a($this, 'Google\\Protobuf\\FieldMask')) {
            $field_mask = GPBUtil::formatFieldMask($this);
            $output->writeRaw("\"", 1);
            $output->writeRaw($field_mask, strlen($field_mask));
            $output->writeRaw("\"", 1);
        }
        elseif (is_a($this, 'Google\\Protobuf\\Duration')) {
            $duration = GPBUtil::formatDuration($this) . "s";
            $output->writeRaw("\"", 1);
            $output->writeRaw($duration, strlen($duration));
            $output->writeRaw("\"", 1);
        }
        elseif (get_class($this) === 'Google\\Protobuf\\Timestamp') {
            $timestamp = GPBUtil::formatTimestamp($this);
            $timestamp = json_encode($timestamp);
            $output->writeRaw($timestamp, strlen($timestamp));
        }
        elseif (get_class($this) === 'Google\\Protobuf\\ListValue') {
            $field = $this->desc
                ->getField()[1];
            if (!$this->existField($field)) {
                $output->writeRaw("[]", 2);
            }
            else {
                if (!$this->serializeFieldToJsonStream($output, $field)) {
                    return false;
                }
            }
        }
        elseif (get_class($this) === 'Google\\Protobuf\\Struct') {
            $field = $this->desc
                ->getField()[1];
            if (!$this->existField($field)) {
                $output->writeRaw("{}", 2);
            }
            else {
                if (!$this->serializeFieldToJsonStream($output, $field)) {
                    return false;
                }
            }
        }
        else {
            if (!GPBUtil::hasSpecialJsonMapping($this)) {
                $output->writeRaw("{", 1);
            }
            $fields = $this->desc
                ->getField();
            $first = true;
            foreach ($fields as $field) {
                if ($this->existField($field) || GPBUtil::hasJsonValue($this)) {
                    if ($first) {
                        $first = false;
                    }
                    else {
                        $output->writeRaw(",", 1);
                    }
                    if (!$this->serializeFieldToJsonStream($output, $field)) {
                        return false;
                    }
                }
            }
            if (!GPBUtil::hasSpecialJsonMapping($this)) {
                $output->writeRaw("}", 1);
            }
        }
        return true;
    }
    
    /**
     * Serialize the message to string.
     * @return string Serialized binary protobuf data.
     */
    public function serializeToString() {
        $output = new CodedOutputStream($this->byteSize());
        $this->serializeToStream($output);
        return $output->getData();
    }
    
    /**
     * Serialize the message to json string.
     * @return string Serialized json protobuf data.
     */
    public function serializeToJsonString() {
        $output = new CodedOutputStream($this->jsonByteSize());
        $this->serializeToJsonStream($output);
        return $output->getData();
    }
    
    /**
     * @ignore
     */
    private function existField($field) {
        $getter = $field->getGetter();
        $hazzer = "has" . substr($getter, 3);
        if (method_exists($this, $hazzer)) {
            return $this->{$hazzer}();
        }
        else {
            if ($field->getOneofIndex() !== -1) {
                // For old generated code, which does not have hazzers for oneof
                // fields.
                $oneof = $this->desc
                    ->getOneofDecl()[$field->getOneofIndex()];
                $oneof_name = $oneof->getName();
                return $this->{$oneof_name}
                    ->getNumber() === $field->getNumber();
            }
        }
        $values = $this->{$getter}();
        if ($field->isMap()) {
            return count($values) !== 0;
        }
        elseif ($field->isRepeated()) {
            return count($values) !== 0;
        }
        else {
            return $values !== $this->defaultValue($field);
        }
    }
    
    /**
     * @ignore
     */
    private function repeatedFieldDataOnlyByteSize($field) {
        $size = 0;
        $getter = $field->getGetter();
        $values = $this->{$getter}();
        $count = count($values);
        if ($count !== 0) {
            $size += $count * GPBWire::tagSize($field);
            foreach ($values as $value) {
                $size += $this->singularFieldDataOnlyByteSize($field);
            }
        }
    }
    
    /**
     * @ignore
     */
    private function fieldDataOnlyByteSize($field, $value) {
        $size = 0;
        switch ($field->getType()) {
            case GPBType::BOOL:
                $size += 1;
                break;
            case GPBType::FLOAT:
            case GPBType::FIXED32:
            case GPBType::SFIXED32:
                $size += 4;
                break;
            case GPBType::DOUBLE:
            case GPBType::FIXED64:
            case GPBType::SFIXED64:
                $size += 8;
                break;
            case GPBType::INT32:
            case GPBType::ENUM:
                $size += GPBWire::varint32Size($value, true);
                break;
            case GPBType::UINT32:
                $size += GPBWire::varint32Size($value);
                break;
            case GPBType::UINT64:
            case GPBType::INT64:
                $size += GPBWire::varint64Size($value);
                break;
            case GPBType::SINT32:
                $size += GPBWire::sint32Size($value);
                break;
            case GPBType::SINT64:
                $size += GPBWire::sint64Size($value);
                break;
            case GPBType::STRING:
            case GPBType::BYTES:
                $size += strlen($value);
                $size += GPBWire::varint32Size($size);
                break;
            case GPBType::MESSAGE:
                $size += $value->byteSize();
                $size += GPBWire::varint32Size($size);
                break;
            case GPBType::GROUP:
                // TODO: Add support.
                user_error("Unsupported type.");
                break;
            default:
                user_error("Unsupported type.");
                return 0;
        }
        return $size;
    }
    
    /**
     * @ignore
     */
    private function fieldDataOnlyJsonByteSize($field, $value) {
        $size = 0;
        switch ($field->getType()) {
            case GPBType::SFIXED32:
            case GPBType::SINT32:
            case GPBType::INT32:
                $size += strlen(strval($value));
                break;
            case GPBType::FIXED32:
            case GPBType::UINT32:
                if ($value < 0) {
                    $value = bcadd($value, "4294967296");
                }
                $size += strlen(strval($value));
                break;
            case GPBType::FIXED64:
            case GPBType::UINT64:
                if ($value < 0) {
                    $value = bcadd($value, "18446744073709551616");
                }
            // Intentional fall through.
            case GPBType::SFIXED64:
            case GPBType::INT64:
            case GPBType::SINT64:
                $size += 2;
                // size for ""
                $size += strlen(strval($value));
                break;
            case GPBType::FLOAT:
                if (is_nan($value)) {
                    $size += strlen("NaN") + 2;
                }
                elseif ($value === INF) {
                    $size += strlen("Infinity") + 2;
                }
                elseif ($value === -INF) {
                    $size += strlen("-Infinity") + 2;
                }
                else {
                    $size += strlen(sprintf("%.8g", $value));
                }
                break;
            case GPBType::DOUBLE:
                if (is_nan($value)) {
                    $size += strlen("NaN") + 2;
                }
                elseif ($value === INF) {
                    $size += strlen("Infinity") + 2;
                }
                elseif ($value === -INF) {
                    $size += strlen("-Infinity") + 2;
                }
                else {
                    $size += strlen(sprintf("%.17g", $value));
                }
                break;
            case GPBType::ENUM:
                $enum_desc = $field->getEnumType();
                if ($enum_desc->getClass() === "Google\\Protobuf\\NullValue") {
                    $size += 4;
                    break;
                }
                $enum_value_desc = $enum_desc->getValueByNumber($value);
                if (!is_null($enum_value_desc)) {
                    $size += 2;
                    // size for ""
                    $size += strlen($enum_value_desc->getName());
                }
                else {
                    $str_value = strval($value);
                    $size += strlen($str_value);
                }
                break;
            case GPBType::BOOL:
                if ($value) {
                    $size += 4;
                }
                else {
                    $size += 5;
                }
                break;
            case GPBType::STRING:
                $value = json_encode($value, JSON_UNESCAPED_UNICODE);
                $size += strlen($value);
                break;
            case GPBType::BYTES:
                
                # if (is_a($this, "Google\Protobuf\BytesValue")) {
                
                #     $size += strlen(json_encode($value));
                
                # } else {
                
                #     $size += strlen(base64_encode($value));
                
                #     $size += 2;  // size for \"\"
                
                # }
                $size += strlen(base64_encode($value));
                $size += 2;
                // size for \"\"
                break;
            case GPBType::MESSAGE:
                $size += $value->jsonByteSize();
                break;
            
            #             case GPBType::GROUP:
            
            #                 // TODO: Add support.
            
            #                 user_error("Unsupported type.");
            
            #                 break;
            default:
                user_error("Unsupported type " . $field->getType());
                return 0;
        }
        return $size;
    }
    
    /**
     * @ignore
     */
    private function fieldByteSize($field) {
        $size = 0;
        if ($field->isMap()) {
            $getter = $field->getGetter();
            $values = $this->{$getter}();
            $count = count($values);
            if ($count !== 0) {
                $size += $count * GPBWire::tagSize($field);
                $message_type = $field->getMessageType();
                $key_field = $message_type->getFieldByNumber(1);
                $value_field = $message_type->getFieldByNumber(2);
                foreach ($values as $key => $value) {
                    $data_size = 0;
                    if ($key != $this->defaultValue($key_field)) {
                        $data_size += $this->fieldDataOnlyByteSize($key_field, $key);
                        $data_size += GPBWire::tagSize($key_field);
                    }
                    if ($value != $this->defaultValue($value_field)) {
                        $data_size += $this->fieldDataOnlyByteSize($value_field, $value);
                        $data_size += GPBWire::tagSize($value_field);
                    }
                    $size += GPBWire::varint32Size($data_size) + $data_size;
                }
            }
        }
        elseif ($field->isRepeated()) {
            $getter = $field->getGetter();
            $values = $this->{$getter}();
            $count = count($values);
            if ($count !== 0) {
                if ($field->getPacked()) {
                    $data_size = 0;
                    foreach ($values as $value) {
                        $data_size += $this->fieldDataOnlyByteSize($field, $value);
                    }
                    $size += GPBWire::tagSize($field);
                    $size += GPBWire::varint32Size($data_size);
                    $size += $data_size;
                }
                else {
                    $size += $count * GPBWire::tagSize($field);
                    foreach ($values as $value) {
                        $size += $this->fieldDataOnlyByteSize($field, $value);
                    }
                }
            }
        }
        elseif ($this->existField($field)) {
            $size += GPBWire::tagSize($field);
            $getter = $field->getGetter();
            $value = $this->{$getter}();
            $size += $this->fieldDataOnlyByteSize($field, $value);
        }
        return $size;
    }
    
    /**
     * @ignore
     */
    private function fieldJsonByteSize($field) {
        $size = 0;
        if ($field->isMap()) {
            $getter = $field->getGetter();
            $values = $this->{$getter}();
            $count = count($values);
            if ($count !== 0) {
                if (!GPBUtil::hasSpecialJsonMapping($this)) {
                    $size += 3;
                    // size for "\"\":".
                    $size += strlen($field->getJsonName());
                    // size for field name
                }
                $size += 2;
                // size for "{}".
                $size += $count - 1;
                // size for commas
                $getter = $field->getGetter();
                $map_entry = $field->getMessageType();
                $key_field = $map_entry->getFieldByNumber(1);
                $value_field = $map_entry->getFieldByNumber(2);
                switch ($key_field->getType()) {
                    case GPBType::STRING:
                    case GPBType::SFIXED64:
                    case GPBType::INT64:
                    case GPBType::SINT64:
                    case GPBType::FIXED64:
                    case GPBType::UINT64:
                        $additional_quote = false;
                        break;
                    default:
                        $additional_quote = true;
                }
                foreach ($values as $key => $value) {
                    if ($additional_quote) {
                        $size += 2;
                        // size for ""
                    }
                    $size += $this->fieldDataOnlyJsonByteSize($key_field, $key);
                    $size += $this->fieldDataOnlyJsonByteSize($value_field, $value);
                    $size += 1;
                    // size for :
                }
            }
        }
        elseif ($field->isRepeated()) {
            $getter = $field->getGetter();
            $values = $this->{$getter}();
            $count = count($values);
            if ($count !== 0) {
                if (!GPBUtil::hasSpecialJsonMapping($this)) {
                    $size += 3;
                    // size for "\"\":".
                    $size += strlen($field->getJsonName());
                    // size for field name
                }
                $size += 2;
                // size for "[]".
                $size += $count - 1;
                // size for commas
                $getter = $field->getGetter();
                foreach ($values as $value) {
                    $size += $this->fieldDataOnlyJsonByteSize($field, $value);
                }
            }
        }
        elseif ($this->existField($field) || GPBUtil::hasJsonValue($this)) {
            if (!GPBUtil::hasSpecialJsonMapping($this)) {
                $size += 3;
                // size for "\"\":".
                $size += strlen($field->getJsonName());
                // size for field name
            }
            $getter = $field->getGetter();
            $value = $this->{$getter}();
            $size += $this->fieldDataOnlyJsonByteSize($field, $value);
        }
        return $size;
    }
    
    /**
     * @ignore
     */
    public function byteSize() {
        $size = 0;
        $fields = $this->desc
            ->getField();
        foreach ($fields as $field) {
            $size += $this->fieldByteSize($field);
        }
        $size += strlen($this->unknown);
        return $size;
    }
    private function appendHelper($field, $append_value) {
        $getter = $field->getGetter();
        $setter = $field->getSetter();
        $field_arr_value = $this->{$getter}();
        $field_arr_value[] = $append_value;
        if (!is_object($field_arr_value)) {
            $this->{$setter}($field_arr_value);
        }
    }
    private function kvUpdateHelper($field, $update_key, $update_value) {
        $getter = $field->getGetter();
        $setter = $field->getSetter();
        $field_arr_value = $this->{$getter}();
        $field_arr_value[$update_key] = $update_value;
        if (!is_object($field_arr_value)) {
            $this->{$setter}($field_arr_value);
        }
    }
    
    /**
     * @ignore
     */
    public function jsonByteSize() {
        $size = 0;
        if (is_a($this, 'Google\\Protobuf\\Any')) {
            // Size for "{}".
            $size += 2;
            // Size for "\"@type\":".
            $size += 8;
            // Size for url. +2 for "" /.
            $size += strlen($this->getTypeUrl()) + 2;
            $value_msg = $this->unpack();
            if (GPBUtil::hasSpecialJsonMapping($value_msg)) {
                // Size for "\",value\":".
                $size += 9;
                $size += $value_msg->jsonByteSize();
            }
            else {
                $value_size = $value_msg->jsonByteSize();
                // size === 2 it's empty message {} which is not serialized inside any
                if ($value_size !== 2) {
                    // Size for value. +1 for comma, -2 for "{}".
                    $size += $value_size - 1;
                }
            }
        }
        elseif (get_class($this) === 'Google\\Protobuf\\FieldMask') {
            $field_mask = GPBUtil::formatFieldMask($this);
            $size += strlen($field_mask) + 2;
            // 2 for ""
        }
        elseif (get_class($this) === 'Google\\Protobuf\\Duration') {
            $duration = GPBUtil::formatDuration($this) . "s";
            $size += strlen($duration) + 2;
            // 2 for ""
        }
        elseif (get_class($this) === 'Google\\Protobuf\\Timestamp') {
            $timestamp = GPBUtil::formatTimestamp($this);
            $timestamp = json_encode($timestamp);
            $size += strlen($timestamp);
        }
        elseif (get_class($this) === 'Google\\Protobuf\\ListValue') {
            $field = $this->desc
                ->getField()[1];
            if ($this->existField($field)) {
                $field_size = $this->fieldJsonByteSize($field);
                $size += $field_size;
            }
            else {
                // Size for "[]".
                $size += 2;
            }
        }
        elseif (get_class($this) === 'Google\\Protobuf\\Struct') {
            $field = $this->desc
                ->getField()[1];
            if ($this->existField($field)) {
                $field_size = $this->fieldJsonByteSize($field);
                $size += $field_size;
            }
            else {
                // Size for "{}".
                $size += 2;
            }
        }
        else {
            if (!GPBUtil::hasSpecialJsonMapping($this)) {
                // Size for "{}".
                $size += 2;
            }
            $fields = $this->desc
                ->getField();
            $count = 0;
            foreach ($fields as $field) {
                $field_size = $this->fieldJsonByteSize($field);
                $size += $field_size;
                if ($field_size != 0) {
                    $count++;
                }
            }
            // size for comma
            $size += $count > 0 ? $count - 1 : 0;
        }
        return $size;
    }
    public function __debugInfo() {
        if (is_a($this, 'Google\\Protobuf\\FieldMask')) {
            return [
                'paths' => $this->getPaths()
                    ->__debugInfo(),
            ];
        }
        if (is_a($this, 'Google\\Protobuf\\Value')) {
            switch ($this->getKind()) {
                case 'null_value':
                    return [
                        'nullValue' => $this->getNullValue(),
                    ];
                case 'number_value':
                    return [
                        'numberValue' => $this->getNumberValue(),
                    ];
                case 'string_value':
                    return [
                        'stringValue' => $this->getStringValue(),
                    ];
                case 'bool_value':
                    return [
                        'boolValue' => $this->getBoolValue(),
                    ];
                case 'struct_value':
                    return [
                        'structValue' => $this->getStructValue()
                            ->__debugInfo(),
                    ];
                case 'list_value':
                    return [
                        'listValue' => $this->getListValue()
                            ->__debugInfo(),
                    ];
            }
            return [];
        }
        if (is_a($this, 'Google\\Protobuf\\BoolValue') || is_a($this, 'Google\\Protobuf\\BytesValue') || is_a($this, 'Google\\Protobuf\\DoubleValue') || is_a($this, 'Google\\Protobuf\\FloatValue') || is_a($this, 'Google\\Protobuf\\StringValue') || is_a($this, 'Google\\Protobuf\\Int32Value') || is_a($this, 'Google\\Protobuf\\Int64Value') || is_a($this, 'Google\\Protobuf\\UInt32Value') || is_a($this, 'Google\\Protobuf\\UInt64Value')) {
            return [
                'value' => json_decode($this->serializeToJsonString(), true),
            ];
        }
        if (is_a($this, 'Google\\Protobuf\\Duration') || is_a($this, 'Google\\Protobuf\\Timestamp')) {
            return [
                'seconds' => $this->getSeconds(),
                'nanos' => $this->getNanos(),
            ];
        }
        return json_decode($this->serializeToJsonString(), true);
    }

}

Members

Title Sort descending Modifiers Object type Summary Overrides
Message::$desc private property @ignore
Message::$unknown private property
Message::appendHelper private function
Message::byteSize public function @ignore
Message::clear public function Clear all containing fields.
Message::convertJsonValueToProtoValue private function
Message::defaultValue private function @ignore
Message::discardUnknownFields public function Clear all unknown fields previously parsed.
Message::existField private function @ignore
Message::fieldByteSize private function @ignore
Message::fieldDataOnlyByteSize private function @ignore
Message::fieldDataOnlyJsonByteSize private function @ignore
Message::fieldJsonByteSize private function @ignore
Message::hasOneof protected function
Message::initWithDescriptor private function @ignore
Message::initWithGeneratedPool private function @ignore
Message::jsonByteSize public function @ignore
Message::kvUpdateHelper private function
Message::mergeFrom public function Merges the contents of the specified message into current message.
Message::mergeFromArray protected function Populates the message from a user-supplied PHP array. Array keys
correspond to Message properties and nested message properties.
Message::mergeFromArrayJsonImpl private function
Message::mergeFromJsonArray protected function
Message::mergeFromJsonString public function Parses a json string to protobuf message.
Message::mergeFromString public function Parses a protocol buffer contained in a string.
Message::normalizeArrayElementsToMessageType private static function 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…
Message::normalizeToMessageType private static function 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.
Message::parseFieldFromStream private function @ignore
Message::parseFieldFromStreamNoTag private static function @ignore
Message::parseFromJsonStream public function @ignore
Message::parseFromStream public function @ignore
Message::readOneof protected function
Message::readWrapperValue protected function
Message::repeatedFieldDataOnlyByteSize private function @ignore
Message::serializeFieldToJsonStream private function @ignore
Message::serializeFieldToStream private function @ignore
Message::serializeMapFieldToStream private function @ignore
Message::serializeRepeatedFieldToStream private function @ignore
Message::serializeSingularFieldToStream private function @ignore
Message::serializeToJsonStream public function @ignore
Message::serializeToJsonString public function Serialize the message to json string.
Message::serializeToStream public function @ignore
Message::serializeToString public function Serialize the message to string.
Message::skipField private function @ignore
Message::whichOneof protected function
Message::writeOneof protected function
Message::writeWrapperValue protected function
Message::__construct public function @ignore 115
Message::__debugInfo public function

API Navigation

  • Drupal Core 11.1.x
  • Topics
  • Classes
  • Functions
  • Constants
  • Globals
  • Files
  • Namespaces
  • Deprecated
  • Services
RSS feed
Powered by Drupal