1ffe3c632Sopenharmony_ci<?php 2ffe3c632Sopenharmony_ci 3ffe3c632Sopenharmony_ci// Protocol Buffers - Google's data interchange format 4ffe3c632Sopenharmony_ci// Copyright 2008 Google Inc. All rights reserved. 5ffe3c632Sopenharmony_ci// https://developers.google.com/protocol-buffers/ 6ffe3c632Sopenharmony_ci// 7ffe3c632Sopenharmony_ci// Redistribution and use in source and binary forms, with or without 8ffe3c632Sopenharmony_ci// modification, are permitted provided that the following conditions are 9ffe3c632Sopenharmony_ci// met: 10ffe3c632Sopenharmony_ci// 11ffe3c632Sopenharmony_ci// * Redistributions of source code must retain the above copyright 12ffe3c632Sopenharmony_ci// notice, this list of conditions and the following disclaimer. 13ffe3c632Sopenharmony_ci// * Redistributions in binary form must reproduce the above 14ffe3c632Sopenharmony_ci// copyright notice, this list of conditions and the following disclaimer 15ffe3c632Sopenharmony_ci// in the documentation and/or other materials provided with the 16ffe3c632Sopenharmony_ci// distribution. 17ffe3c632Sopenharmony_ci// * Neither the name of Google Inc. nor the names of its 18ffe3c632Sopenharmony_ci// contributors may be used to endorse or promote products derived from 19ffe3c632Sopenharmony_ci// this software without specific prior written permission. 20ffe3c632Sopenharmony_ci// 21ffe3c632Sopenharmony_ci// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22ffe3c632Sopenharmony_ci// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23ffe3c632Sopenharmony_ci// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24ffe3c632Sopenharmony_ci// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25ffe3c632Sopenharmony_ci// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26ffe3c632Sopenharmony_ci// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27ffe3c632Sopenharmony_ci// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28ffe3c632Sopenharmony_ci// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29ffe3c632Sopenharmony_ci// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30ffe3c632Sopenharmony_ci// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31ffe3c632Sopenharmony_ci// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32ffe3c632Sopenharmony_ci 33ffe3c632Sopenharmony_ci/** 34ffe3c632Sopenharmony_ci * Defines Message, the parent class extended by all protocol message classes. 35ffe3c632Sopenharmony_ci */ 36ffe3c632Sopenharmony_ci 37ffe3c632Sopenharmony_cinamespace Google\Protobuf\Internal; 38ffe3c632Sopenharmony_ci 39ffe3c632Sopenharmony_ciuse Google\Protobuf\Internal\CodedInputStream; 40ffe3c632Sopenharmony_ciuse Google\Protobuf\Internal\CodedOutputStream; 41ffe3c632Sopenharmony_ciuse Google\Protobuf\Internal\DescriptorPool; 42ffe3c632Sopenharmony_ciuse Google\Protobuf\Internal\GPBLabel; 43ffe3c632Sopenharmony_ciuse Google\Protobuf\Internal\GPBType; 44ffe3c632Sopenharmony_ciuse Google\Protobuf\Internal\GPBWire; 45ffe3c632Sopenharmony_ciuse Google\Protobuf\Internal\MapEntry; 46ffe3c632Sopenharmony_ciuse Google\Protobuf\Internal\RepeatedField; 47ffe3c632Sopenharmony_ciuse Google\Protobuf\ListValue; 48ffe3c632Sopenharmony_ciuse Google\Protobuf\Value; 49ffe3c632Sopenharmony_ciuse Google\Protobuf\Struct; 50ffe3c632Sopenharmony_ciuse Google\Protobuf\NullValue; 51ffe3c632Sopenharmony_ci 52ffe3c632Sopenharmony_ci/** 53ffe3c632Sopenharmony_ci * Parent class of all proto messages. Users should not instantiate this class 54ffe3c632Sopenharmony_ci * or extend this class or its child classes by their own. See the comment of 55ffe3c632Sopenharmony_ci * specific functions for more details. 56ffe3c632Sopenharmony_ci */ 57ffe3c632Sopenharmony_ciclass Message 58ffe3c632Sopenharmony_ci{ 59ffe3c632Sopenharmony_ci 60ffe3c632Sopenharmony_ci /** 61ffe3c632Sopenharmony_ci * @ignore 62ffe3c632Sopenharmony_ci */ 63ffe3c632Sopenharmony_ci private $desc; 64ffe3c632Sopenharmony_ci private $unknown = ""; 65ffe3c632Sopenharmony_ci 66ffe3c632Sopenharmony_ci /** 67ffe3c632Sopenharmony_ci * @ignore 68ffe3c632Sopenharmony_ci */ 69ffe3c632Sopenharmony_ci public function __construct($data = NULL) 70ffe3c632Sopenharmony_ci { 71ffe3c632Sopenharmony_ci // MapEntry message is shared by all types of map fields, whose 72ffe3c632Sopenharmony_ci // descriptors are different from each other. Thus, we cannot find a 73ffe3c632Sopenharmony_ci // specific descriptor from the descriptor pool. 74ffe3c632Sopenharmony_ci if ($this instanceof MapEntry) { 75ffe3c632Sopenharmony_ci $this->initWithDescriptor($data); 76ffe3c632Sopenharmony_ci } else { 77ffe3c632Sopenharmony_ci $this->initWithGeneratedPool(); 78ffe3c632Sopenharmony_ci if (is_array($data)) { 79ffe3c632Sopenharmony_ci $this->mergeFromArray($data); 80ffe3c632Sopenharmony_ci } else if (!empty($data)) { 81ffe3c632Sopenharmony_ci throw new \InvalidArgumentException( 82ffe3c632Sopenharmony_ci 'Message constructor must be an array or null.' 83ffe3c632Sopenharmony_ci ); 84ffe3c632Sopenharmony_ci } 85ffe3c632Sopenharmony_ci } 86ffe3c632Sopenharmony_ci } 87ffe3c632Sopenharmony_ci 88ffe3c632Sopenharmony_ci /** 89ffe3c632Sopenharmony_ci * @ignore 90ffe3c632Sopenharmony_ci */ 91ffe3c632Sopenharmony_ci private function initWithGeneratedPool() 92ffe3c632Sopenharmony_ci { 93ffe3c632Sopenharmony_ci $pool = DescriptorPool::getGeneratedPool(); 94ffe3c632Sopenharmony_ci $this->desc = $pool->getDescriptorByClassName(get_class($this)); 95ffe3c632Sopenharmony_ci if (is_null($this->desc)) { 96ffe3c632Sopenharmony_ci user_error(get_class($this) . " is not found in descriptor pool."); 97ffe3c632Sopenharmony_ci return; 98ffe3c632Sopenharmony_ci } 99ffe3c632Sopenharmony_ci foreach ($this->desc->getField() as $field) { 100ffe3c632Sopenharmony_ci $setter = $field->getSetter(); 101ffe3c632Sopenharmony_ci if ($field->isMap()) { 102ffe3c632Sopenharmony_ci $message_type = $field->getMessageType(); 103ffe3c632Sopenharmony_ci $key_field = $message_type->getFieldByNumber(1); 104ffe3c632Sopenharmony_ci $value_field = $message_type->getFieldByNumber(2); 105ffe3c632Sopenharmony_ci switch ($value_field->getType()) { 106ffe3c632Sopenharmony_ci case GPBType::MESSAGE: 107ffe3c632Sopenharmony_ci case GPBType::GROUP: 108ffe3c632Sopenharmony_ci $map_field = new MapField( 109ffe3c632Sopenharmony_ci $key_field->getType(), 110ffe3c632Sopenharmony_ci $value_field->getType(), 111ffe3c632Sopenharmony_ci $value_field->getMessageType()->getClass()); 112ffe3c632Sopenharmony_ci $this->$setter($map_field); 113ffe3c632Sopenharmony_ci break; 114ffe3c632Sopenharmony_ci case GPBType::ENUM: 115ffe3c632Sopenharmony_ci $map_field = new MapField( 116ffe3c632Sopenharmony_ci $key_field->getType(), 117ffe3c632Sopenharmony_ci $value_field->getType(), 118ffe3c632Sopenharmony_ci $value_field->getEnumType()->getClass()); 119ffe3c632Sopenharmony_ci $this->$setter($map_field); 120ffe3c632Sopenharmony_ci break; 121ffe3c632Sopenharmony_ci default: 122ffe3c632Sopenharmony_ci $map_field = new MapField( 123ffe3c632Sopenharmony_ci $key_field->getType(), 124ffe3c632Sopenharmony_ci $value_field->getType()); 125ffe3c632Sopenharmony_ci $this->$setter($map_field); 126ffe3c632Sopenharmony_ci break; 127ffe3c632Sopenharmony_ci } 128ffe3c632Sopenharmony_ci } else if ($field->getLabel() === GPBLabel::REPEATED) { 129ffe3c632Sopenharmony_ci switch ($field->getType()) { 130ffe3c632Sopenharmony_ci case GPBType::MESSAGE: 131ffe3c632Sopenharmony_ci case GPBType::GROUP: 132ffe3c632Sopenharmony_ci $repeated_field = new RepeatedField( 133ffe3c632Sopenharmony_ci $field->getType(), 134ffe3c632Sopenharmony_ci $field->getMessageType()->getClass()); 135ffe3c632Sopenharmony_ci $this->$setter($repeated_field); 136ffe3c632Sopenharmony_ci break; 137ffe3c632Sopenharmony_ci case GPBType::ENUM: 138ffe3c632Sopenharmony_ci $repeated_field = new RepeatedField( 139ffe3c632Sopenharmony_ci $field->getType(), 140ffe3c632Sopenharmony_ci $field->getEnumType()->getClass()); 141ffe3c632Sopenharmony_ci $this->$setter($repeated_field); 142ffe3c632Sopenharmony_ci break; 143ffe3c632Sopenharmony_ci default: 144ffe3c632Sopenharmony_ci $repeated_field = new RepeatedField($field->getType()); 145ffe3c632Sopenharmony_ci $this->$setter($repeated_field); 146ffe3c632Sopenharmony_ci break; 147ffe3c632Sopenharmony_ci } 148ffe3c632Sopenharmony_ci } else if ($field->getOneofIndex() !== -1) { 149ffe3c632Sopenharmony_ci $oneof = $this->desc->getOneofDecl()[$field->getOneofIndex()]; 150ffe3c632Sopenharmony_ci $oneof_name = $oneof->getName(); 151ffe3c632Sopenharmony_ci $this->$oneof_name = new OneofField($oneof); 152ffe3c632Sopenharmony_ci } else if ($field->getLabel() === GPBLabel::OPTIONAL && 153ffe3c632Sopenharmony_ci PHP_INT_SIZE == 4) { 154ffe3c632Sopenharmony_ci switch ($field->getType()) { 155ffe3c632Sopenharmony_ci case GPBType::INT64: 156ffe3c632Sopenharmony_ci case GPBType::UINT64: 157ffe3c632Sopenharmony_ci case GPBType::FIXED64: 158ffe3c632Sopenharmony_ci case GPBType::SFIXED64: 159ffe3c632Sopenharmony_ci case GPBType::SINT64: 160ffe3c632Sopenharmony_ci $this->$setter("0"); 161ffe3c632Sopenharmony_ci } 162ffe3c632Sopenharmony_ci } 163ffe3c632Sopenharmony_ci } 164ffe3c632Sopenharmony_ci } 165ffe3c632Sopenharmony_ci 166ffe3c632Sopenharmony_ci /** 167ffe3c632Sopenharmony_ci * @ignore 168ffe3c632Sopenharmony_ci */ 169ffe3c632Sopenharmony_ci private function initWithDescriptor(Descriptor $desc) 170ffe3c632Sopenharmony_ci { 171ffe3c632Sopenharmony_ci $this->desc = $desc; 172ffe3c632Sopenharmony_ci foreach ($desc->getField() as $field) { 173ffe3c632Sopenharmony_ci $setter = $field->getSetter(); 174ffe3c632Sopenharmony_ci $defaultValue = $this->defaultValue($field); 175ffe3c632Sopenharmony_ci $this->$setter($defaultValue); 176ffe3c632Sopenharmony_ci } 177ffe3c632Sopenharmony_ci } 178ffe3c632Sopenharmony_ci 179ffe3c632Sopenharmony_ci protected function readWrapperValue($member) 180ffe3c632Sopenharmony_ci { 181ffe3c632Sopenharmony_ci $field = $this->desc->getFieldByName($member); 182ffe3c632Sopenharmony_ci $oneof_index = $field->getOneofIndex(); 183ffe3c632Sopenharmony_ci if ($oneof_index === -1) { 184ffe3c632Sopenharmony_ci $wrapper = $this->$member; 185ffe3c632Sopenharmony_ci } else { 186ffe3c632Sopenharmony_ci $wrapper = $this->readOneof($field->getNumber()); 187ffe3c632Sopenharmony_ci } 188ffe3c632Sopenharmony_ci 189ffe3c632Sopenharmony_ci if (is_null($wrapper)) { 190ffe3c632Sopenharmony_ci return NULL; 191ffe3c632Sopenharmony_ci } else { 192ffe3c632Sopenharmony_ci return $wrapper->getValue(); 193ffe3c632Sopenharmony_ci } 194ffe3c632Sopenharmony_ci } 195ffe3c632Sopenharmony_ci 196ffe3c632Sopenharmony_ci protected function writeWrapperValue($member, $value) 197ffe3c632Sopenharmony_ci { 198ffe3c632Sopenharmony_ci $field = $this->desc->getFieldByName($member); 199ffe3c632Sopenharmony_ci $wrapped_value = $value; 200ffe3c632Sopenharmony_ci if (!is_null($value)) { 201ffe3c632Sopenharmony_ci $desc = $field->getMessageType(); 202ffe3c632Sopenharmony_ci $klass = $desc->getClass(); 203ffe3c632Sopenharmony_ci $wrapped_value = new $klass; 204ffe3c632Sopenharmony_ci $wrapped_value->setValue($value); 205ffe3c632Sopenharmony_ci } 206ffe3c632Sopenharmony_ci 207ffe3c632Sopenharmony_ci $oneof_index = $field->getOneofIndex(); 208ffe3c632Sopenharmony_ci if ($oneof_index === -1) { 209ffe3c632Sopenharmony_ci $this->$member = $wrapped_value; 210ffe3c632Sopenharmony_ci } else { 211ffe3c632Sopenharmony_ci $this->writeOneof($field->getNumber(), $wrapped_value); 212ffe3c632Sopenharmony_ci } 213ffe3c632Sopenharmony_ci } 214ffe3c632Sopenharmony_ci 215ffe3c632Sopenharmony_ci protected function readOneof($number) 216ffe3c632Sopenharmony_ci { 217ffe3c632Sopenharmony_ci $field = $this->desc->getFieldByNumber($number); 218ffe3c632Sopenharmony_ci $oneof = $this->desc->getOneofDecl()[$field->getOneofIndex()]; 219ffe3c632Sopenharmony_ci $oneof_name = $oneof->getName(); 220ffe3c632Sopenharmony_ci $oneof_field = $this->$oneof_name; 221ffe3c632Sopenharmony_ci if ($number === $oneof_field->getNumber()) { 222ffe3c632Sopenharmony_ci return $oneof_field->getValue(); 223ffe3c632Sopenharmony_ci } else { 224ffe3c632Sopenharmony_ci return $this->defaultValue($field); 225ffe3c632Sopenharmony_ci } 226ffe3c632Sopenharmony_ci } 227ffe3c632Sopenharmony_ci 228ffe3c632Sopenharmony_ci protected function hasOneof($number) 229ffe3c632Sopenharmony_ci { 230ffe3c632Sopenharmony_ci $field = $this->desc->getFieldByNumber($number); 231ffe3c632Sopenharmony_ci $oneof = $this->desc->getOneofDecl()[$field->getOneofIndex()]; 232ffe3c632Sopenharmony_ci $oneof_name = $oneof->getName(); 233ffe3c632Sopenharmony_ci $oneof_field = $this->$oneof_name; 234ffe3c632Sopenharmony_ci return $number === $oneof_field->getNumber(); 235ffe3c632Sopenharmony_ci } 236ffe3c632Sopenharmony_ci 237ffe3c632Sopenharmony_ci protected function writeOneof($number, $value) 238ffe3c632Sopenharmony_ci { 239ffe3c632Sopenharmony_ci $field = $this->desc->getFieldByNumber($number); 240ffe3c632Sopenharmony_ci $oneof = $this->desc->getOneofDecl()[$field->getOneofIndex()]; 241ffe3c632Sopenharmony_ci $oneof_name = $oneof->getName(); 242ffe3c632Sopenharmony_ci $oneof_field = $this->$oneof_name; 243ffe3c632Sopenharmony_ci $oneof_field->setValue($value); 244ffe3c632Sopenharmony_ci $oneof_field->setFieldName($field->getName()); 245ffe3c632Sopenharmony_ci $oneof_field->setNumber($number); 246ffe3c632Sopenharmony_ci } 247ffe3c632Sopenharmony_ci 248ffe3c632Sopenharmony_ci protected function whichOneof($oneof_name) 249ffe3c632Sopenharmony_ci { 250ffe3c632Sopenharmony_ci $oneof_field = $this->$oneof_name; 251ffe3c632Sopenharmony_ci $number = $oneof_field->getNumber(); 252ffe3c632Sopenharmony_ci if ($number == 0) { 253ffe3c632Sopenharmony_ci return ""; 254ffe3c632Sopenharmony_ci } 255ffe3c632Sopenharmony_ci $field = $this->desc->getFieldByNumber($number); 256ffe3c632Sopenharmony_ci return $field->getName(); 257ffe3c632Sopenharmony_ci } 258ffe3c632Sopenharmony_ci 259ffe3c632Sopenharmony_ci /** 260ffe3c632Sopenharmony_ci * @ignore 261ffe3c632Sopenharmony_ci */ 262ffe3c632Sopenharmony_ci private function defaultValue($field) 263ffe3c632Sopenharmony_ci { 264ffe3c632Sopenharmony_ci $value = null; 265ffe3c632Sopenharmony_ci 266ffe3c632Sopenharmony_ci switch ($field->getType()) { 267ffe3c632Sopenharmony_ci case GPBType::DOUBLE: 268ffe3c632Sopenharmony_ci case GPBType::FLOAT: 269ffe3c632Sopenharmony_ci return 0.0; 270ffe3c632Sopenharmony_ci case GPBType::UINT32: 271ffe3c632Sopenharmony_ci case GPBType::INT32: 272ffe3c632Sopenharmony_ci case GPBType::FIXED32: 273ffe3c632Sopenharmony_ci case GPBType::SFIXED32: 274ffe3c632Sopenharmony_ci case GPBType::SINT32: 275ffe3c632Sopenharmony_ci case GPBType::ENUM: 276ffe3c632Sopenharmony_ci return 0; 277ffe3c632Sopenharmony_ci case GPBType::INT64: 278ffe3c632Sopenharmony_ci case GPBType::UINT64: 279ffe3c632Sopenharmony_ci case GPBType::FIXED64: 280ffe3c632Sopenharmony_ci case GPBType::SFIXED64: 281ffe3c632Sopenharmony_ci case GPBType::SINT64: 282ffe3c632Sopenharmony_ci if (PHP_INT_SIZE === 4) { 283ffe3c632Sopenharmony_ci return '0'; 284ffe3c632Sopenharmony_ci } else { 285ffe3c632Sopenharmony_ci return 0; 286ffe3c632Sopenharmony_ci } 287ffe3c632Sopenharmony_ci case GPBType::BOOL: 288ffe3c632Sopenharmony_ci return false; 289ffe3c632Sopenharmony_ci case GPBType::STRING: 290ffe3c632Sopenharmony_ci case GPBType::BYTES: 291ffe3c632Sopenharmony_ci return ""; 292ffe3c632Sopenharmony_ci case GPBType::GROUP: 293ffe3c632Sopenharmony_ci case GPBType::MESSAGE: 294ffe3c632Sopenharmony_ci return null; 295ffe3c632Sopenharmony_ci default: 296ffe3c632Sopenharmony_ci user_error("Unsupported type."); 297ffe3c632Sopenharmony_ci return false; 298ffe3c632Sopenharmony_ci } 299ffe3c632Sopenharmony_ci } 300ffe3c632Sopenharmony_ci 301ffe3c632Sopenharmony_ci /** 302ffe3c632Sopenharmony_ci * @ignore 303ffe3c632Sopenharmony_ci */ 304ffe3c632Sopenharmony_ci private function skipField($input, $tag) 305ffe3c632Sopenharmony_ci { 306ffe3c632Sopenharmony_ci $number = GPBWire::getTagFieldNumber($tag); 307ffe3c632Sopenharmony_ci if ($number === 0) { 308ffe3c632Sopenharmony_ci throw new GPBDecodeException("Illegal field number zero."); 309ffe3c632Sopenharmony_ci } 310ffe3c632Sopenharmony_ci 311ffe3c632Sopenharmony_ci $start = $input->current(); 312ffe3c632Sopenharmony_ci switch (GPBWire::getTagWireType($tag)) { 313ffe3c632Sopenharmony_ci case GPBWireType::VARINT: 314ffe3c632Sopenharmony_ci $uint64 = 0; 315ffe3c632Sopenharmony_ci if (!$input->readVarint64($uint64)) { 316ffe3c632Sopenharmony_ci throw new GPBDecodeException( 317ffe3c632Sopenharmony_ci "Unexpected EOF inside varint."); 318ffe3c632Sopenharmony_ci } 319ffe3c632Sopenharmony_ci break; 320ffe3c632Sopenharmony_ci case GPBWireType::FIXED64: 321ffe3c632Sopenharmony_ci $uint64 = 0; 322ffe3c632Sopenharmony_ci if (!$input->readLittleEndian64($uint64)) { 323ffe3c632Sopenharmony_ci throw new GPBDecodeException( 324ffe3c632Sopenharmony_ci "Unexpected EOF inside fixed64."); 325ffe3c632Sopenharmony_ci } 326ffe3c632Sopenharmony_ci break; 327ffe3c632Sopenharmony_ci case GPBWireType::FIXED32: 328ffe3c632Sopenharmony_ci $uint32 = 0; 329ffe3c632Sopenharmony_ci if (!$input->readLittleEndian32($uint32)) { 330ffe3c632Sopenharmony_ci throw new GPBDecodeException( 331ffe3c632Sopenharmony_ci "Unexpected EOF inside fixed32."); 332ffe3c632Sopenharmony_ci } 333ffe3c632Sopenharmony_ci break; 334ffe3c632Sopenharmony_ci case GPBWireType::LENGTH_DELIMITED: 335ffe3c632Sopenharmony_ci $length = 0; 336ffe3c632Sopenharmony_ci if (!$input->readVarint32($length)) { 337ffe3c632Sopenharmony_ci throw new GPBDecodeException( 338ffe3c632Sopenharmony_ci "Unexpected EOF inside length."); 339ffe3c632Sopenharmony_ci } 340ffe3c632Sopenharmony_ci $data = NULL; 341ffe3c632Sopenharmony_ci if (!$input->readRaw($length, $data)) { 342ffe3c632Sopenharmony_ci throw new GPBDecodeException( 343ffe3c632Sopenharmony_ci "Unexpected EOF inside length delimited data."); 344ffe3c632Sopenharmony_ci } 345ffe3c632Sopenharmony_ci break; 346ffe3c632Sopenharmony_ci case GPBWireType::START_GROUP: 347ffe3c632Sopenharmony_ci case GPBWireType::END_GROUP: 348ffe3c632Sopenharmony_ci throw new GPBDecodeException("Unexpected wire type."); 349ffe3c632Sopenharmony_ci default: 350ffe3c632Sopenharmony_ci throw new GPBDecodeException("Unexpected wire type."); 351ffe3c632Sopenharmony_ci } 352ffe3c632Sopenharmony_ci $end = $input->current(); 353ffe3c632Sopenharmony_ci 354ffe3c632Sopenharmony_ci $bytes = str_repeat(chr(0), CodedOutputStream::MAX_VARINT64_BYTES); 355ffe3c632Sopenharmony_ci $size = CodedOutputStream::writeVarintToArray($tag, $bytes, true); 356ffe3c632Sopenharmony_ci $this->unknown .= substr($bytes, 0, $size) . $input->substr($start, $end); 357ffe3c632Sopenharmony_ci } 358ffe3c632Sopenharmony_ci 359ffe3c632Sopenharmony_ci /** 360ffe3c632Sopenharmony_ci * @ignore 361ffe3c632Sopenharmony_ci */ 362ffe3c632Sopenharmony_ci private static function parseFieldFromStreamNoTag($input, $field, &$value) 363ffe3c632Sopenharmony_ci { 364ffe3c632Sopenharmony_ci switch ($field->getType()) { 365ffe3c632Sopenharmony_ci case GPBType::DOUBLE: 366ffe3c632Sopenharmony_ci if (!GPBWire::readDouble($input, $value)) { 367ffe3c632Sopenharmony_ci throw new GPBDecodeException( 368ffe3c632Sopenharmony_ci "Unexpected EOF inside double field."); 369ffe3c632Sopenharmony_ci } 370ffe3c632Sopenharmony_ci break; 371ffe3c632Sopenharmony_ci case GPBType::FLOAT: 372ffe3c632Sopenharmony_ci if (!GPBWire::readFloat($input, $value)) { 373ffe3c632Sopenharmony_ci throw new GPBDecodeException( 374ffe3c632Sopenharmony_ci "Unexpected EOF inside float field."); 375ffe3c632Sopenharmony_ci } 376ffe3c632Sopenharmony_ci break; 377ffe3c632Sopenharmony_ci case GPBType::INT64: 378ffe3c632Sopenharmony_ci if (!GPBWire::readInt64($input, $value)) { 379ffe3c632Sopenharmony_ci throw new GPBDecodeException( 380ffe3c632Sopenharmony_ci "Unexpected EOF inside int64 field."); 381ffe3c632Sopenharmony_ci } 382ffe3c632Sopenharmony_ci break; 383ffe3c632Sopenharmony_ci case GPBType::UINT64: 384ffe3c632Sopenharmony_ci if (!GPBWire::readUint64($input, $value)) { 385ffe3c632Sopenharmony_ci throw new GPBDecodeException( 386ffe3c632Sopenharmony_ci "Unexpected EOF inside uint64 field."); 387ffe3c632Sopenharmony_ci } 388ffe3c632Sopenharmony_ci break; 389ffe3c632Sopenharmony_ci case GPBType::INT32: 390ffe3c632Sopenharmony_ci if (!GPBWire::readInt32($input, $value)) { 391ffe3c632Sopenharmony_ci throw new GPBDecodeException( 392ffe3c632Sopenharmony_ci "Unexpected EOF inside int32 field."); 393ffe3c632Sopenharmony_ci } 394ffe3c632Sopenharmony_ci break; 395ffe3c632Sopenharmony_ci case GPBType::FIXED64: 396ffe3c632Sopenharmony_ci if (!GPBWire::readFixed64($input, $value)) { 397ffe3c632Sopenharmony_ci throw new GPBDecodeException( 398ffe3c632Sopenharmony_ci "Unexpected EOF inside fixed64 field."); 399ffe3c632Sopenharmony_ci } 400ffe3c632Sopenharmony_ci break; 401ffe3c632Sopenharmony_ci case GPBType::FIXED32: 402ffe3c632Sopenharmony_ci if (!GPBWire::readFixed32($input, $value)) { 403ffe3c632Sopenharmony_ci throw new GPBDecodeException( 404ffe3c632Sopenharmony_ci "Unexpected EOF inside fixed32 field."); 405ffe3c632Sopenharmony_ci } 406ffe3c632Sopenharmony_ci break; 407ffe3c632Sopenharmony_ci case GPBType::BOOL: 408ffe3c632Sopenharmony_ci if (!GPBWire::readBool($input, $value)) { 409ffe3c632Sopenharmony_ci throw new GPBDecodeException( 410ffe3c632Sopenharmony_ci "Unexpected EOF inside bool field."); 411ffe3c632Sopenharmony_ci } 412ffe3c632Sopenharmony_ci break; 413ffe3c632Sopenharmony_ci case GPBType::STRING: 414ffe3c632Sopenharmony_ci // TODO(teboring): Add utf-8 check. 415ffe3c632Sopenharmony_ci if (!GPBWire::readString($input, $value)) { 416ffe3c632Sopenharmony_ci throw new GPBDecodeException( 417ffe3c632Sopenharmony_ci "Unexpected EOF inside string field."); 418ffe3c632Sopenharmony_ci } 419ffe3c632Sopenharmony_ci break; 420ffe3c632Sopenharmony_ci case GPBType::GROUP: 421ffe3c632Sopenharmony_ci trigger_error("Not implemented.", E_ERROR); 422ffe3c632Sopenharmony_ci break; 423ffe3c632Sopenharmony_ci case GPBType::MESSAGE: 424ffe3c632Sopenharmony_ci if ($field->isMap()) { 425ffe3c632Sopenharmony_ci $value = new MapEntry($field->getMessageType()); 426ffe3c632Sopenharmony_ci } else { 427ffe3c632Sopenharmony_ci $klass = $field->getMessageType()->getClass(); 428ffe3c632Sopenharmony_ci $value = new $klass; 429ffe3c632Sopenharmony_ci } 430ffe3c632Sopenharmony_ci if (!GPBWire::readMessage($input, $value)) { 431ffe3c632Sopenharmony_ci throw new GPBDecodeException( 432ffe3c632Sopenharmony_ci "Unexpected EOF inside message."); 433ffe3c632Sopenharmony_ci } 434ffe3c632Sopenharmony_ci break; 435ffe3c632Sopenharmony_ci case GPBType::BYTES: 436ffe3c632Sopenharmony_ci if (!GPBWire::readString($input, $value)) { 437ffe3c632Sopenharmony_ci throw new GPBDecodeException( 438ffe3c632Sopenharmony_ci "Unexpected EOF inside bytes field."); 439ffe3c632Sopenharmony_ci } 440ffe3c632Sopenharmony_ci break; 441ffe3c632Sopenharmony_ci case GPBType::UINT32: 442ffe3c632Sopenharmony_ci if (!GPBWire::readUint32($input, $value)) { 443ffe3c632Sopenharmony_ci throw new GPBDecodeException( 444ffe3c632Sopenharmony_ci "Unexpected EOF inside uint32 field."); 445ffe3c632Sopenharmony_ci } 446ffe3c632Sopenharmony_ci break; 447ffe3c632Sopenharmony_ci case GPBType::ENUM: 448ffe3c632Sopenharmony_ci // TODO(teboring): Check unknown enum value. 449ffe3c632Sopenharmony_ci if (!GPBWire::readInt32($input, $value)) { 450ffe3c632Sopenharmony_ci throw new GPBDecodeException( 451ffe3c632Sopenharmony_ci "Unexpected EOF inside enum field."); 452ffe3c632Sopenharmony_ci } 453ffe3c632Sopenharmony_ci break; 454ffe3c632Sopenharmony_ci case GPBType::SFIXED32: 455ffe3c632Sopenharmony_ci if (!GPBWire::readSfixed32($input, $value)) { 456ffe3c632Sopenharmony_ci throw new GPBDecodeException( 457ffe3c632Sopenharmony_ci "Unexpected EOF inside sfixed32 field."); 458ffe3c632Sopenharmony_ci } 459ffe3c632Sopenharmony_ci break; 460ffe3c632Sopenharmony_ci case GPBType::SFIXED64: 461ffe3c632Sopenharmony_ci if (!GPBWire::readSfixed64($input, $value)) { 462ffe3c632Sopenharmony_ci throw new GPBDecodeException( 463ffe3c632Sopenharmony_ci "Unexpected EOF inside sfixed64 field."); 464ffe3c632Sopenharmony_ci } 465ffe3c632Sopenharmony_ci break; 466ffe3c632Sopenharmony_ci case GPBType::SINT32: 467ffe3c632Sopenharmony_ci if (!GPBWire::readSint32($input, $value)) { 468ffe3c632Sopenharmony_ci throw new GPBDecodeException( 469ffe3c632Sopenharmony_ci "Unexpected EOF inside sint32 field."); 470ffe3c632Sopenharmony_ci } 471ffe3c632Sopenharmony_ci break; 472ffe3c632Sopenharmony_ci case GPBType::SINT64: 473ffe3c632Sopenharmony_ci if (!GPBWire::readSint64($input, $value)) { 474ffe3c632Sopenharmony_ci throw new GPBDecodeException( 475ffe3c632Sopenharmony_ci "Unexpected EOF inside sint64 field."); 476ffe3c632Sopenharmony_ci } 477ffe3c632Sopenharmony_ci break; 478ffe3c632Sopenharmony_ci default: 479ffe3c632Sopenharmony_ci user_error("Unsupported type."); 480ffe3c632Sopenharmony_ci return false; 481ffe3c632Sopenharmony_ci } 482ffe3c632Sopenharmony_ci return true; 483ffe3c632Sopenharmony_ci } 484ffe3c632Sopenharmony_ci 485ffe3c632Sopenharmony_ci /** 486ffe3c632Sopenharmony_ci * @ignore 487ffe3c632Sopenharmony_ci */ 488ffe3c632Sopenharmony_ci private function parseFieldFromStream($tag, $input, $field) 489ffe3c632Sopenharmony_ci { 490ffe3c632Sopenharmony_ci $value = null; 491ffe3c632Sopenharmony_ci 492ffe3c632Sopenharmony_ci if (is_null($field)) { 493ffe3c632Sopenharmony_ci $value_format = GPBWire::UNKNOWN; 494ffe3c632Sopenharmony_ci } elseif (GPBWire::getTagWireType($tag) === 495ffe3c632Sopenharmony_ci GPBWire::getWireType($field->getType())) { 496ffe3c632Sopenharmony_ci $value_format = GPBWire::NORMAL_FORMAT; 497ffe3c632Sopenharmony_ci } elseif ($field->isPackable() && 498ffe3c632Sopenharmony_ci GPBWire::getTagWireType($tag) === 499ffe3c632Sopenharmony_ci GPBWire::WIRETYPE_LENGTH_DELIMITED) { 500ffe3c632Sopenharmony_ci $value_format = GPBWire::PACKED_FORMAT; 501ffe3c632Sopenharmony_ci } else { 502ffe3c632Sopenharmony_ci // the wire type doesn't match. Put it in our unknown field set. 503ffe3c632Sopenharmony_ci $value_format = GPBWire::UNKNOWN; 504ffe3c632Sopenharmony_ci } 505ffe3c632Sopenharmony_ci 506ffe3c632Sopenharmony_ci if ($value_format === GPBWire::UNKNOWN) { 507ffe3c632Sopenharmony_ci $this->skipField($input, $tag); 508ffe3c632Sopenharmony_ci return; 509ffe3c632Sopenharmony_ci } elseif ($value_format === GPBWire::NORMAL_FORMAT) { 510ffe3c632Sopenharmony_ci self::parseFieldFromStreamNoTag($input, $field, $value); 511ffe3c632Sopenharmony_ci } elseif ($value_format === GPBWire::PACKED_FORMAT) { 512ffe3c632Sopenharmony_ci $length = 0; 513ffe3c632Sopenharmony_ci if (!GPBWire::readInt32($input, $length)) { 514ffe3c632Sopenharmony_ci throw new GPBDecodeException( 515ffe3c632Sopenharmony_ci "Unexpected EOF inside packed length."); 516ffe3c632Sopenharmony_ci } 517ffe3c632Sopenharmony_ci $limit = $input->pushLimit($length); 518ffe3c632Sopenharmony_ci $getter = $field->getGetter(); 519ffe3c632Sopenharmony_ci while ($input->bytesUntilLimit() > 0) { 520ffe3c632Sopenharmony_ci self::parseFieldFromStreamNoTag($input, $field, $value); 521ffe3c632Sopenharmony_ci $this->appendHelper($field, $value); 522ffe3c632Sopenharmony_ci } 523ffe3c632Sopenharmony_ci $input->popLimit($limit); 524ffe3c632Sopenharmony_ci return; 525ffe3c632Sopenharmony_ci } else { 526ffe3c632Sopenharmony_ci return; 527ffe3c632Sopenharmony_ci } 528ffe3c632Sopenharmony_ci 529ffe3c632Sopenharmony_ci if ($field->isMap()) { 530ffe3c632Sopenharmony_ci $this->kvUpdateHelper($field, $value->getKey(), $value->getValue()); 531ffe3c632Sopenharmony_ci } else if ($field->isRepeated()) { 532ffe3c632Sopenharmony_ci $this->appendHelper($field, $value); 533ffe3c632Sopenharmony_ci } else { 534ffe3c632Sopenharmony_ci $setter = $field->getSetter(); 535ffe3c632Sopenharmony_ci $this->$setter($value); 536ffe3c632Sopenharmony_ci } 537ffe3c632Sopenharmony_ci } 538ffe3c632Sopenharmony_ci 539ffe3c632Sopenharmony_ci /** 540ffe3c632Sopenharmony_ci * Clear all containing fields. 541ffe3c632Sopenharmony_ci * @return null. 542ffe3c632Sopenharmony_ci */ 543ffe3c632Sopenharmony_ci public function clear() 544ffe3c632Sopenharmony_ci { 545ffe3c632Sopenharmony_ci $this->unknown = ""; 546ffe3c632Sopenharmony_ci foreach ($this->desc->getField() as $field) { 547ffe3c632Sopenharmony_ci $setter = $field->getSetter(); 548ffe3c632Sopenharmony_ci if ($field->isMap()) { 549ffe3c632Sopenharmony_ci $message_type = $field->getMessageType(); 550ffe3c632Sopenharmony_ci $key_field = $message_type->getFieldByNumber(1); 551ffe3c632Sopenharmony_ci $value_field = $message_type->getFieldByNumber(2); 552ffe3c632Sopenharmony_ci switch ($value_field->getType()) { 553ffe3c632Sopenharmony_ci case GPBType::MESSAGE: 554ffe3c632Sopenharmony_ci case GPBType::GROUP: 555ffe3c632Sopenharmony_ci $map_field = new MapField( 556ffe3c632Sopenharmony_ci $key_field->getType(), 557ffe3c632Sopenharmony_ci $value_field->getType(), 558ffe3c632Sopenharmony_ci $value_field->getMessageType()->getClass()); 559ffe3c632Sopenharmony_ci $this->$setter($map_field); 560ffe3c632Sopenharmony_ci break; 561ffe3c632Sopenharmony_ci case GPBType::ENUM: 562ffe3c632Sopenharmony_ci $map_field = new MapField( 563ffe3c632Sopenharmony_ci $key_field->getType(), 564ffe3c632Sopenharmony_ci $value_field->getType(), 565ffe3c632Sopenharmony_ci $value_field->getEnumType()->getClass()); 566ffe3c632Sopenharmony_ci $this->$setter($map_field); 567ffe3c632Sopenharmony_ci break; 568ffe3c632Sopenharmony_ci default: 569ffe3c632Sopenharmony_ci $map_field = new MapField( 570ffe3c632Sopenharmony_ci $key_field->getType(), 571ffe3c632Sopenharmony_ci $value_field->getType()); 572ffe3c632Sopenharmony_ci $this->$setter($map_field); 573ffe3c632Sopenharmony_ci break; 574ffe3c632Sopenharmony_ci } 575ffe3c632Sopenharmony_ci } else if ($field->getLabel() === GPBLabel::REPEATED) { 576ffe3c632Sopenharmony_ci switch ($field->getType()) { 577ffe3c632Sopenharmony_ci case GPBType::MESSAGE: 578ffe3c632Sopenharmony_ci case GPBType::GROUP: 579ffe3c632Sopenharmony_ci $repeated_field = new RepeatedField( 580ffe3c632Sopenharmony_ci $field->getType(), 581ffe3c632Sopenharmony_ci $field->getMessageType()->getClass()); 582ffe3c632Sopenharmony_ci $this->$setter($repeated_field); 583ffe3c632Sopenharmony_ci break; 584ffe3c632Sopenharmony_ci case GPBType::ENUM: 585ffe3c632Sopenharmony_ci $repeated_field = new RepeatedField( 586ffe3c632Sopenharmony_ci $field->getType(), 587ffe3c632Sopenharmony_ci $field->getEnumType()->getClass()); 588ffe3c632Sopenharmony_ci $this->$setter($repeated_field); 589ffe3c632Sopenharmony_ci break; 590ffe3c632Sopenharmony_ci default: 591ffe3c632Sopenharmony_ci $repeated_field = new RepeatedField($field->getType()); 592ffe3c632Sopenharmony_ci $this->$setter($repeated_field); 593ffe3c632Sopenharmony_ci break; 594ffe3c632Sopenharmony_ci } 595ffe3c632Sopenharmony_ci } else if ($field->getOneofIndex() !== -1) { 596ffe3c632Sopenharmony_ci $oneof = $this->desc->getOneofDecl()[$field->getOneofIndex()]; 597ffe3c632Sopenharmony_ci $oneof_name = $oneof->getName(); 598ffe3c632Sopenharmony_ci $this->$oneof_name = new OneofField($oneof); 599ffe3c632Sopenharmony_ci } else if ($field->getLabel() === GPBLabel::OPTIONAL) { 600ffe3c632Sopenharmony_ci switch ($field->getType()) { 601ffe3c632Sopenharmony_ci case GPBType::DOUBLE : 602ffe3c632Sopenharmony_ci case GPBType::FLOAT : 603ffe3c632Sopenharmony_ci $this->$setter(0.0); 604ffe3c632Sopenharmony_ci break; 605ffe3c632Sopenharmony_ci case GPBType::INT32 : 606ffe3c632Sopenharmony_ci case GPBType::FIXED32 : 607ffe3c632Sopenharmony_ci case GPBType::UINT32 : 608ffe3c632Sopenharmony_ci case GPBType::SFIXED32 : 609ffe3c632Sopenharmony_ci case GPBType::SINT32 : 610ffe3c632Sopenharmony_ci case GPBType::ENUM : 611ffe3c632Sopenharmony_ci $this->$setter(0); 612ffe3c632Sopenharmony_ci break; 613ffe3c632Sopenharmony_ci case GPBType::BOOL : 614ffe3c632Sopenharmony_ci $this->$setter(false); 615ffe3c632Sopenharmony_ci break; 616ffe3c632Sopenharmony_ci case GPBType::STRING : 617ffe3c632Sopenharmony_ci case GPBType::BYTES : 618ffe3c632Sopenharmony_ci $this->$setter(""); 619ffe3c632Sopenharmony_ci break; 620ffe3c632Sopenharmony_ci case GPBType::GROUP : 621ffe3c632Sopenharmony_ci case GPBType::MESSAGE : 622ffe3c632Sopenharmony_ci $null = null; 623ffe3c632Sopenharmony_ci $this->$setter($null); 624ffe3c632Sopenharmony_ci break; 625ffe3c632Sopenharmony_ci } 626ffe3c632Sopenharmony_ci if (PHP_INT_SIZE == 4) { 627ffe3c632Sopenharmony_ci switch ($field->getType()) { 628ffe3c632Sopenharmony_ci case GPBType::INT64: 629ffe3c632Sopenharmony_ci case GPBType::UINT64: 630ffe3c632Sopenharmony_ci case GPBType::FIXED64: 631ffe3c632Sopenharmony_ci case GPBType::SFIXED64: 632ffe3c632Sopenharmony_ci case GPBType::SINT64: 633ffe3c632Sopenharmony_ci $this->$setter("0"); 634ffe3c632Sopenharmony_ci } 635ffe3c632Sopenharmony_ci } else { 636ffe3c632Sopenharmony_ci switch ($field->getType()) { 637ffe3c632Sopenharmony_ci case GPBType::INT64: 638ffe3c632Sopenharmony_ci case GPBType::UINT64: 639ffe3c632Sopenharmony_ci case GPBType::FIXED64: 640ffe3c632Sopenharmony_ci case GPBType::SFIXED64: 641ffe3c632Sopenharmony_ci case GPBType::SINT64: 642ffe3c632Sopenharmony_ci $this->$setter(0); 643ffe3c632Sopenharmony_ci } 644ffe3c632Sopenharmony_ci } 645ffe3c632Sopenharmony_ci } 646ffe3c632Sopenharmony_ci } 647ffe3c632Sopenharmony_ci } 648ffe3c632Sopenharmony_ci 649ffe3c632Sopenharmony_ci /** 650ffe3c632Sopenharmony_ci * Clear all unknown fields previously parsed. 651ffe3c632Sopenharmony_ci * @return null. 652ffe3c632Sopenharmony_ci */ 653ffe3c632Sopenharmony_ci public function discardUnknownFields() 654ffe3c632Sopenharmony_ci { 655ffe3c632Sopenharmony_ci $this->unknown = ""; 656ffe3c632Sopenharmony_ci foreach ($this->desc->getField() as $field) { 657ffe3c632Sopenharmony_ci if ($field->getType() != GPBType::MESSAGE) { 658ffe3c632Sopenharmony_ci continue; 659ffe3c632Sopenharmony_ci } 660ffe3c632Sopenharmony_ci if ($field->isMap()) { 661ffe3c632Sopenharmony_ci $value_field = $field->getMessageType()->getFieldByNumber(2); 662ffe3c632Sopenharmony_ci if ($value_field->getType() != GPBType::MESSAGE) { 663ffe3c632Sopenharmony_ci continue; 664ffe3c632Sopenharmony_ci } 665ffe3c632Sopenharmony_ci $getter = $field->getGetter(); 666ffe3c632Sopenharmony_ci $map = $this->$getter(); 667ffe3c632Sopenharmony_ci foreach ($map as $key => $value) { 668ffe3c632Sopenharmony_ci $value->discardUnknownFields(); 669ffe3c632Sopenharmony_ci } 670ffe3c632Sopenharmony_ci } else if ($field->getLabel() === GPBLabel::REPEATED) { 671ffe3c632Sopenharmony_ci $getter = $field->getGetter(); 672ffe3c632Sopenharmony_ci $arr = $this->$getter(); 673ffe3c632Sopenharmony_ci foreach ($arr as $sub) { 674ffe3c632Sopenharmony_ci $sub->discardUnknownFields(); 675ffe3c632Sopenharmony_ci } 676ffe3c632Sopenharmony_ci } else if ($field->getLabel() === GPBLabel::OPTIONAL) { 677ffe3c632Sopenharmony_ci $getter = $field->getGetter(); 678ffe3c632Sopenharmony_ci $sub = $this->$getter(); 679ffe3c632Sopenharmony_ci if (!is_null($sub)) { 680ffe3c632Sopenharmony_ci $sub->discardUnknownFields(); 681ffe3c632Sopenharmony_ci } 682ffe3c632Sopenharmony_ci } 683ffe3c632Sopenharmony_ci } 684ffe3c632Sopenharmony_ci } 685ffe3c632Sopenharmony_ci 686ffe3c632Sopenharmony_ci /** 687ffe3c632Sopenharmony_ci * Merges the contents of the specified message into current message. 688ffe3c632Sopenharmony_ci * 689ffe3c632Sopenharmony_ci * This method merges the contents of the specified message into the 690ffe3c632Sopenharmony_ci * current message. Singular fields that are set in the specified message 691ffe3c632Sopenharmony_ci * overwrite the corresponding fields in the current message. Repeated 692ffe3c632Sopenharmony_ci * fields are appended. Map fields key-value pairs are overwritten. 693ffe3c632Sopenharmony_ci * Singular/Oneof sub-messages are recursively merged. All overwritten 694ffe3c632Sopenharmony_ci * sub-messages are deep-copied. 695ffe3c632Sopenharmony_ci * 696ffe3c632Sopenharmony_ci * @param object $msg Protobuf message to be merged from. 697ffe3c632Sopenharmony_ci * @return null. 698ffe3c632Sopenharmony_ci */ 699ffe3c632Sopenharmony_ci public function mergeFrom($msg) 700ffe3c632Sopenharmony_ci { 701ffe3c632Sopenharmony_ci if (get_class($this) !== get_class($msg)) { 702ffe3c632Sopenharmony_ci user_error("Cannot merge messages with different class."); 703ffe3c632Sopenharmony_ci return; 704ffe3c632Sopenharmony_ci } 705ffe3c632Sopenharmony_ci 706ffe3c632Sopenharmony_ci foreach ($this->desc->getField() as $field) { 707ffe3c632Sopenharmony_ci $setter = $field->getSetter(); 708ffe3c632Sopenharmony_ci $getter = $field->getGetter(); 709ffe3c632Sopenharmony_ci if ($field->isMap()) { 710ffe3c632Sopenharmony_ci if (count($msg->$getter()) != 0) { 711ffe3c632Sopenharmony_ci $value_field = $field->getMessageType()->getFieldByNumber(2); 712ffe3c632Sopenharmony_ci foreach ($msg->$getter() as $key => $value) { 713ffe3c632Sopenharmony_ci if ($value_field->getType() == GPBType::MESSAGE) { 714ffe3c632Sopenharmony_ci $klass = $value_field->getMessageType()->getClass(); 715ffe3c632Sopenharmony_ci $copy = new $klass; 716ffe3c632Sopenharmony_ci $copy->mergeFrom($value); 717ffe3c632Sopenharmony_ci 718ffe3c632Sopenharmony_ci $this->kvUpdateHelper($field, $key, $copy); 719ffe3c632Sopenharmony_ci } else { 720ffe3c632Sopenharmony_ci $this->kvUpdateHelper($field, $key, $value); 721ffe3c632Sopenharmony_ci } 722ffe3c632Sopenharmony_ci } 723ffe3c632Sopenharmony_ci } 724ffe3c632Sopenharmony_ci } else if ($field->getLabel() === GPBLabel::REPEATED) { 725ffe3c632Sopenharmony_ci if (count($msg->$getter()) != 0) { 726ffe3c632Sopenharmony_ci foreach ($msg->$getter() as $tmp) { 727ffe3c632Sopenharmony_ci if ($field->getType() == GPBType::MESSAGE) { 728ffe3c632Sopenharmony_ci $klass = $field->getMessageType()->getClass(); 729ffe3c632Sopenharmony_ci $copy = new $klass; 730ffe3c632Sopenharmony_ci $copy->mergeFrom($tmp); 731ffe3c632Sopenharmony_ci $this->appendHelper($field, $copy); 732ffe3c632Sopenharmony_ci } else { 733ffe3c632Sopenharmony_ci $this->appendHelper($field, $tmp); 734ffe3c632Sopenharmony_ci } 735ffe3c632Sopenharmony_ci } 736ffe3c632Sopenharmony_ci } 737ffe3c632Sopenharmony_ci } else if ($field->getLabel() === GPBLabel::OPTIONAL) { 738ffe3c632Sopenharmony_ci if($msg->$getter() !== $this->defaultValue($field)) { 739ffe3c632Sopenharmony_ci $tmp = $msg->$getter(); 740ffe3c632Sopenharmony_ci if ($field->getType() == GPBType::MESSAGE) { 741ffe3c632Sopenharmony_ci if (is_null($this->$getter())) { 742ffe3c632Sopenharmony_ci $klass = $field->getMessageType()->getClass(); 743ffe3c632Sopenharmony_ci $new_msg = new $klass; 744ffe3c632Sopenharmony_ci $this->$setter($new_msg); 745ffe3c632Sopenharmony_ci } 746ffe3c632Sopenharmony_ci $this->$getter()->mergeFrom($tmp); 747ffe3c632Sopenharmony_ci } else { 748ffe3c632Sopenharmony_ci $this->$setter($tmp); 749ffe3c632Sopenharmony_ci } 750ffe3c632Sopenharmony_ci } 751ffe3c632Sopenharmony_ci } 752ffe3c632Sopenharmony_ci } 753ffe3c632Sopenharmony_ci } 754ffe3c632Sopenharmony_ci 755ffe3c632Sopenharmony_ci /** 756ffe3c632Sopenharmony_ci * Parses a protocol buffer contained in a string. 757ffe3c632Sopenharmony_ci * 758ffe3c632Sopenharmony_ci * This function takes a string in the (non-human-readable) binary wire 759ffe3c632Sopenharmony_ci * format, matching the encoding output by serializeToString(). 760ffe3c632Sopenharmony_ci * See mergeFrom() for merging behavior, if the field is already set in the 761ffe3c632Sopenharmony_ci * specified message. 762ffe3c632Sopenharmony_ci * 763ffe3c632Sopenharmony_ci * @param string $data Binary protobuf data. 764ffe3c632Sopenharmony_ci * @return null. 765ffe3c632Sopenharmony_ci * @throws \Exception Invalid data. 766ffe3c632Sopenharmony_ci */ 767ffe3c632Sopenharmony_ci public function mergeFromString($data) 768ffe3c632Sopenharmony_ci { 769ffe3c632Sopenharmony_ci $input = new CodedInputStream($data); 770ffe3c632Sopenharmony_ci $this->parseFromStream($input); 771ffe3c632Sopenharmony_ci } 772ffe3c632Sopenharmony_ci 773ffe3c632Sopenharmony_ci /** 774ffe3c632Sopenharmony_ci * Parses a json string to protobuf message. 775ffe3c632Sopenharmony_ci * 776ffe3c632Sopenharmony_ci * This function takes a string in the json wire format, matching the 777ffe3c632Sopenharmony_ci * encoding output by serializeToJsonString(). 778ffe3c632Sopenharmony_ci * See mergeFrom() for merging behavior, if the field is already set in the 779ffe3c632Sopenharmony_ci * specified message. 780ffe3c632Sopenharmony_ci * 781ffe3c632Sopenharmony_ci * @param string $data Json protobuf data. 782ffe3c632Sopenharmony_ci * @return null. 783ffe3c632Sopenharmony_ci * @throws \Exception Invalid data. 784ffe3c632Sopenharmony_ci */ 785ffe3c632Sopenharmony_ci public function mergeFromJsonString($data, $ignore_unknown = false) 786ffe3c632Sopenharmony_ci { 787ffe3c632Sopenharmony_ci $input = new RawInputStream($data); 788ffe3c632Sopenharmony_ci $this->parseFromJsonStream($input, $ignore_unknown); 789ffe3c632Sopenharmony_ci } 790ffe3c632Sopenharmony_ci 791ffe3c632Sopenharmony_ci /** 792ffe3c632Sopenharmony_ci * @ignore 793ffe3c632Sopenharmony_ci */ 794ffe3c632Sopenharmony_ci public function parseFromStream($input) 795ffe3c632Sopenharmony_ci { 796ffe3c632Sopenharmony_ci while (true) { 797ffe3c632Sopenharmony_ci $tag = $input->readTag(); 798ffe3c632Sopenharmony_ci // End of input. This is a valid place to end, so return true. 799ffe3c632Sopenharmony_ci if ($tag === 0) { 800ffe3c632Sopenharmony_ci return true; 801ffe3c632Sopenharmony_ci } 802ffe3c632Sopenharmony_ci 803ffe3c632Sopenharmony_ci $number = GPBWire::getTagFieldNumber($tag); 804ffe3c632Sopenharmony_ci $field = $this->desc->getFieldByNumber($number); 805ffe3c632Sopenharmony_ci 806ffe3c632Sopenharmony_ci $this->parseFieldFromStream($tag, $input, $field); 807ffe3c632Sopenharmony_ci } 808ffe3c632Sopenharmony_ci } 809ffe3c632Sopenharmony_ci 810ffe3c632Sopenharmony_ci private function convertJsonValueToProtoValue( 811ffe3c632Sopenharmony_ci $value, 812ffe3c632Sopenharmony_ci $field, 813ffe3c632Sopenharmony_ci $ignore_unknown, 814ffe3c632Sopenharmony_ci $is_map_key = false) 815ffe3c632Sopenharmony_ci { 816ffe3c632Sopenharmony_ci switch ($field->getType()) { 817ffe3c632Sopenharmony_ci case GPBType::MESSAGE: 818ffe3c632Sopenharmony_ci $klass = $field->getMessageType()->getClass(); 819ffe3c632Sopenharmony_ci $submsg = new $klass; 820ffe3c632Sopenharmony_ci 821ffe3c632Sopenharmony_ci if (is_a($submsg, "Google\Protobuf\Duration")) { 822ffe3c632Sopenharmony_ci if (is_null($value)) { 823ffe3c632Sopenharmony_ci return $this->defaultValue($field); 824ffe3c632Sopenharmony_ci } else if (!is_string($value)) { 825ffe3c632Sopenharmony_ci throw new GPBDecodeException("Expect string."); 826ffe3c632Sopenharmony_ci } 827ffe3c632Sopenharmony_ci return GPBUtil::parseDuration($value); 828ffe3c632Sopenharmony_ci } else if ($field->isTimestamp()) { 829ffe3c632Sopenharmony_ci if (is_null($value)) { 830ffe3c632Sopenharmony_ci return $this->defaultValue($field); 831ffe3c632Sopenharmony_ci } else if (!is_string($value)) { 832ffe3c632Sopenharmony_ci throw new GPBDecodeException("Expect string."); 833ffe3c632Sopenharmony_ci } 834ffe3c632Sopenharmony_ci try { 835ffe3c632Sopenharmony_ci $timestamp = GPBUtil::parseTimestamp($value); 836ffe3c632Sopenharmony_ci } catch (\Exception $e) { 837ffe3c632Sopenharmony_ci throw new GPBDecodeException( 838ffe3c632Sopenharmony_ci "Invalid RFC 3339 timestamp: ".$e->getMessage()); 839ffe3c632Sopenharmony_ci } 840ffe3c632Sopenharmony_ci 841ffe3c632Sopenharmony_ci $submsg->setSeconds($timestamp->getSeconds()); 842ffe3c632Sopenharmony_ci $submsg->setNanos($timestamp->getNanos()); 843ffe3c632Sopenharmony_ci } else if (is_a($submsg, "Google\Protobuf\FieldMask")) { 844ffe3c632Sopenharmony_ci if (is_null($value)) { 845ffe3c632Sopenharmony_ci return $this->defaultValue($field); 846ffe3c632Sopenharmony_ci } 847ffe3c632Sopenharmony_ci try { 848ffe3c632Sopenharmony_ci return GPBUtil::parseFieldMask($value); 849ffe3c632Sopenharmony_ci } catch (\Exception $e) { 850ffe3c632Sopenharmony_ci throw new GPBDecodeException( 851ffe3c632Sopenharmony_ci "Invalid FieldMask: ".$e->getMessage()); 852ffe3c632Sopenharmony_ci } 853ffe3c632Sopenharmony_ci } else { 854ffe3c632Sopenharmony_ci if (is_null($value) && 855ffe3c632Sopenharmony_ci !is_a($submsg, "Google\Protobuf\Value")) { 856ffe3c632Sopenharmony_ci return $this->defaultValue($field); 857ffe3c632Sopenharmony_ci } 858ffe3c632Sopenharmony_ci if (GPBUtil::hasSpecialJsonMapping($submsg)) { 859ffe3c632Sopenharmony_ci } elseif (!is_object($value) && !is_array($value)) { 860ffe3c632Sopenharmony_ci throw new GPBDecodeException("Expect message."); 861ffe3c632Sopenharmony_ci } 862ffe3c632Sopenharmony_ci $submsg->mergeFromJsonArray($value, $ignore_unknown); 863ffe3c632Sopenharmony_ci } 864ffe3c632Sopenharmony_ci return $submsg; 865ffe3c632Sopenharmony_ci case GPBType::ENUM: 866ffe3c632Sopenharmony_ci if (is_null($value)) { 867ffe3c632Sopenharmony_ci return $this->defaultValue($field); 868ffe3c632Sopenharmony_ci } 869ffe3c632Sopenharmony_ci if (is_integer($value)) { 870ffe3c632Sopenharmony_ci return $value; 871ffe3c632Sopenharmony_ci } 872ffe3c632Sopenharmony_ci $enum_value = $field->getEnumType()->getValueByName($value); 873ffe3c632Sopenharmony_ci if (!is_null($enum_value)) { 874ffe3c632Sopenharmony_ci return $enum_value->getNumber(); 875ffe3c632Sopenharmony_ci } else if ($ignore_unknown) { 876ffe3c632Sopenharmony_ci return $this->defaultValue($field); 877ffe3c632Sopenharmony_ci } else { 878ffe3c632Sopenharmony_ci throw new GPBDecodeException( 879ffe3c632Sopenharmony_ci "Enum field only accepts integer or enum value name"); 880ffe3c632Sopenharmony_ci } 881ffe3c632Sopenharmony_ci case GPBType::STRING: 882ffe3c632Sopenharmony_ci if (is_null($value)) { 883ffe3c632Sopenharmony_ci return $this->defaultValue($field); 884ffe3c632Sopenharmony_ci } 885ffe3c632Sopenharmony_ci if (is_numeric($value)) { 886ffe3c632Sopenharmony_ci return strval($value); 887ffe3c632Sopenharmony_ci } 888ffe3c632Sopenharmony_ci if (!is_string($value)) { 889ffe3c632Sopenharmony_ci throw new GPBDecodeException( 890ffe3c632Sopenharmony_ci "String field only accepts string value"); 891ffe3c632Sopenharmony_ci } 892ffe3c632Sopenharmony_ci return $value; 893ffe3c632Sopenharmony_ci case GPBType::BYTES: 894ffe3c632Sopenharmony_ci if (is_null($value)) { 895ffe3c632Sopenharmony_ci return $this->defaultValue($field); 896ffe3c632Sopenharmony_ci } 897ffe3c632Sopenharmony_ci if (!is_string($value)) { 898ffe3c632Sopenharmony_ci throw new GPBDecodeException( 899ffe3c632Sopenharmony_ci "Byte field only accepts string value"); 900ffe3c632Sopenharmony_ci } 901ffe3c632Sopenharmony_ci $proto_value = base64_decode($value, true); 902ffe3c632Sopenharmony_ci if ($proto_value === false) { 903ffe3c632Sopenharmony_ci throw new GPBDecodeException("Invalid base64 characters"); 904ffe3c632Sopenharmony_ci } 905ffe3c632Sopenharmony_ci return $proto_value; 906ffe3c632Sopenharmony_ci case GPBType::BOOL: 907ffe3c632Sopenharmony_ci if (is_null($value)) { 908ffe3c632Sopenharmony_ci return $this->defaultValue($field); 909ffe3c632Sopenharmony_ci } 910ffe3c632Sopenharmony_ci if ($is_map_key) { 911ffe3c632Sopenharmony_ci if ($value === "true") { 912ffe3c632Sopenharmony_ci return true; 913ffe3c632Sopenharmony_ci } 914ffe3c632Sopenharmony_ci if ($value === "false") { 915ffe3c632Sopenharmony_ci return false; 916ffe3c632Sopenharmony_ci } 917ffe3c632Sopenharmony_ci throw new GPBDecodeException( 918ffe3c632Sopenharmony_ci "Bool field only accepts bool value"); 919ffe3c632Sopenharmony_ci } 920ffe3c632Sopenharmony_ci if (!is_bool($value)) { 921ffe3c632Sopenharmony_ci throw new GPBDecodeException( 922ffe3c632Sopenharmony_ci "Bool field only accepts bool value"); 923ffe3c632Sopenharmony_ci } 924ffe3c632Sopenharmony_ci return $value; 925ffe3c632Sopenharmony_ci case GPBType::FLOAT: 926ffe3c632Sopenharmony_ci case GPBType::DOUBLE: 927ffe3c632Sopenharmony_ci if (is_null($value)) { 928ffe3c632Sopenharmony_ci return $this->defaultValue($field); 929ffe3c632Sopenharmony_ci } 930ffe3c632Sopenharmony_ci if ($value === "Infinity") { 931ffe3c632Sopenharmony_ci return INF; 932ffe3c632Sopenharmony_ci } 933ffe3c632Sopenharmony_ci if ($value === "-Infinity") { 934ffe3c632Sopenharmony_ci return -INF; 935ffe3c632Sopenharmony_ci } 936ffe3c632Sopenharmony_ci if ($value === "NaN") { 937ffe3c632Sopenharmony_ci return NAN; 938ffe3c632Sopenharmony_ci } 939ffe3c632Sopenharmony_ci return $value; 940ffe3c632Sopenharmony_ci case GPBType::INT32: 941ffe3c632Sopenharmony_ci case GPBType::SINT32: 942ffe3c632Sopenharmony_ci case GPBType::SFIXED32: 943ffe3c632Sopenharmony_ci if (is_null($value)) { 944ffe3c632Sopenharmony_ci return $this->defaultValue($field); 945ffe3c632Sopenharmony_ci } 946ffe3c632Sopenharmony_ci if (!is_numeric($value)) { 947ffe3c632Sopenharmony_ci throw new GPBDecodeException( 948ffe3c632Sopenharmony_ci "Invalid data type for int32 field"); 949ffe3c632Sopenharmony_ci } 950ffe3c632Sopenharmony_ci if (is_string($value) && trim($value) !== $value) { 951ffe3c632Sopenharmony_ci throw new GPBDecodeException( 952ffe3c632Sopenharmony_ci "Invalid data type for int32 field"); 953ffe3c632Sopenharmony_ci } 954ffe3c632Sopenharmony_ci if (bccomp($value, "2147483647") > 0) { 955ffe3c632Sopenharmony_ci throw new GPBDecodeException( 956ffe3c632Sopenharmony_ci "Int32 too large"); 957ffe3c632Sopenharmony_ci } 958ffe3c632Sopenharmony_ci if (bccomp($value, "-2147483648") < 0) { 959ffe3c632Sopenharmony_ci throw new GPBDecodeException( 960ffe3c632Sopenharmony_ci "Int32 too small"); 961ffe3c632Sopenharmony_ci } 962ffe3c632Sopenharmony_ci return $value; 963ffe3c632Sopenharmony_ci case GPBType::UINT32: 964ffe3c632Sopenharmony_ci case GPBType::FIXED32: 965ffe3c632Sopenharmony_ci if (is_null($value)) { 966ffe3c632Sopenharmony_ci return $this->defaultValue($field); 967ffe3c632Sopenharmony_ci } 968ffe3c632Sopenharmony_ci if (!is_numeric($value)) { 969ffe3c632Sopenharmony_ci throw new GPBDecodeException( 970ffe3c632Sopenharmony_ci "Invalid data type for uint32 field"); 971ffe3c632Sopenharmony_ci } 972ffe3c632Sopenharmony_ci if (is_string($value) && trim($value) !== $value) { 973ffe3c632Sopenharmony_ci throw new GPBDecodeException( 974ffe3c632Sopenharmony_ci "Invalid data type for int32 field"); 975ffe3c632Sopenharmony_ci } 976ffe3c632Sopenharmony_ci if (bccomp($value, 4294967295) > 0) { 977ffe3c632Sopenharmony_ci throw new GPBDecodeException( 978ffe3c632Sopenharmony_ci "Uint32 too large"); 979ffe3c632Sopenharmony_ci } 980ffe3c632Sopenharmony_ci return $value; 981ffe3c632Sopenharmony_ci case GPBType::INT64: 982ffe3c632Sopenharmony_ci case GPBType::SINT64: 983ffe3c632Sopenharmony_ci case GPBType::SFIXED64: 984ffe3c632Sopenharmony_ci if (is_null($value)) { 985ffe3c632Sopenharmony_ci return $this->defaultValue($field); 986ffe3c632Sopenharmony_ci } 987ffe3c632Sopenharmony_ci if (!is_numeric($value)) { 988ffe3c632Sopenharmony_ci throw new GPBDecodeException( 989ffe3c632Sopenharmony_ci "Invalid data type for int64 field"); 990ffe3c632Sopenharmony_ci } 991ffe3c632Sopenharmony_ci if (is_string($value) && trim($value) !== $value) { 992ffe3c632Sopenharmony_ci throw new GPBDecodeException( 993ffe3c632Sopenharmony_ci "Invalid data type for int64 field"); 994ffe3c632Sopenharmony_ci } 995ffe3c632Sopenharmony_ci if (bccomp($value, "9223372036854775807") > 0) { 996ffe3c632Sopenharmony_ci throw new GPBDecodeException( 997ffe3c632Sopenharmony_ci "Int64 too large"); 998ffe3c632Sopenharmony_ci } 999ffe3c632Sopenharmony_ci if (bccomp($value, "-9223372036854775808") < 0) { 1000ffe3c632Sopenharmony_ci throw new GPBDecodeException( 1001ffe3c632Sopenharmony_ci "Int64 too small"); 1002ffe3c632Sopenharmony_ci } 1003ffe3c632Sopenharmony_ci return $value; 1004ffe3c632Sopenharmony_ci case GPBType::UINT64: 1005ffe3c632Sopenharmony_ci case GPBType::FIXED64: 1006ffe3c632Sopenharmony_ci if (is_null($value)) { 1007ffe3c632Sopenharmony_ci return $this->defaultValue($field); 1008ffe3c632Sopenharmony_ci } 1009ffe3c632Sopenharmony_ci if (!is_numeric($value)) { 1010ffe3c632Sopenharmony_ci throw new GPBDecodeException( 1011ffe3c632Sopenharmony_ci "Invalid data type for int64 field"); 1012ffe3c632Sopenharmony_ci } 1013ffe3c632Sopenharmony_ci if (is_string($value) && trim($value) !== $value) { 1014ffe3c632Sopenharmony_ci throw new GPBDecodeException( 1015ffe3c632Sopenharmony_ci "Invalid data type for int64 field"); 1016ffe3c632Sopenharmony_ci } 1017ffe3c632Sopenharmony_ci if (bccomp($value, "18446744073709551615") > 0) { 1018ffe3c632Sopenharmony_ci throw new GPBDecodeException( 1019ffe3c632Sopenharmony_ci "Uint64 too large"); 1020ffe3c632Sopenharmony_ci } 1021ffe3c632Sopenharmony_ci if (bccomp($value, "9223372036854775807") > 0) { 1022ffe3c632Sopenharmony_ci $value = bcsub($value, "18446744073709551616"); 1023ffe3c632Sopenharmony_ci } 1024ffe3c632Sopenharmony_ci return $value; 1025ffe3c632Sopenharmony_ci default: 1026ffe3c632Sopenharmony_ci return $value; 1027ffe3c632Sopenharmony_ci } 1028ffe3c632Sopenharmony_ci } 1029ffe3c632Sopenharmony_ci 1030ffe3c632Sopenharmony_ci /** 1031ffe3c632Sopenharmony_ci * Populates the message from a user-supplied PHP array. Array keys 1032ffe3c632Sopenharmony_ci * correspond to Message properties and nested message properties. 1033ffe3c632Sopenharmony_ci * 1034ffe3c632Sopenharmony_ci * Example: 1035ffe3c632Sopenharmony_ci * ``` 1036ffe3c632Sopenharmony_ci * $message->mergeFromArray([ 1037ffe3c632Sopenharmony_ci * 'name' => 'This is a message name', 1038ffe3c632Sopenharmony_ci * 'interval' => [ 1039ffe3c632Sopenharmony_ci * 'startTime' => time() - 60, 1040ffe3c632Sopenharmony_ci * 'endTime' => time(), 1041ffe3c632Sopenharmony_ci * ] 1042ffe3c632Sopenharmony_ci * ]); 1043ffe3c632Sopenharmony_ci * ``` 1044ffe3c632Sopenharmony_ci * 1045ffe3c632Sopenharmony_ci * This method will trigger an error if it is passed data that cannot 1046ffe3c632Sopenharmony_ci * be converted to the correct type. For example, a StringValue field 1047ffe3c632Sopenharmony_ci * must receive data that is either a string or a StringValue object. 1048ffe3c632Sopenharmony_ci * 1049ffe3c632Sopenharmony_ci * @param array $array An array containing message properties and values. 1050ffe3c632Sopenharmony_ci * @return null. 1051ffe3c632Sopenharmony_ci */ 1052ffe3c632Sopenharmony_ci protected function mergeFromArray(array $array) 1053ffe3c632Sopenharmony_ci { 1054ffe3c632Sopenharmony_ci // Just call the setters for the field names 1055ffe3c632Sopenharmony_ci foreach ($array as $key => $value) { 1056ffe3c632Sopenharmony_ci $field = $this->desc->getFieldByName($key); 1057ffe3c632Sopenharmony_ci if (is_null($field)) { 1058ffe3c632Sopenharmony_ci throw new \UnexpectedValueException( 1059ffe3c632Sopenharmony_ci 'Invalid message property: ' . $key); 1060ffe3c632Sopenharmony_ci } 1061ffe3c632Sopenharmony_ci $setter = $field->getSetter(); 1062ffe3c632Sopenharmony_ci if ($field->isMap()) { 1063ffe3c632Sopenharmony_ci $valueField = $field->getMessageType()->getFieldByName('value'); 1064ffe3c632Sopenharmony_ci if (!is_null($valueField) && $valueField->isWrapperType()) { 1065ffe3c632Sopenharmony_ci self::normalizeArrayElementsToMessageType($value, $valueField->getMessageType()->getClass()); 1066ffe3c632Sopenharmony_ci } 1067ffe3c632Sopenharmony_ci } elseif ($field->isWrapperType()) { 1068ffe3c632Sopenharmony_ci $class = $field->getMessageType()->getClass(); 1069ffe3c632Sopenharmony_ci if ($field->isRepeated()) { 1070ffe3c632Sopenharmony_ci self::normalizeArrayElementsToMessageType($value, $class); 1071ffe3c632Sopenharmony_ci } else { 1072ffe3c632Sopenharmony_ci self::normalizeToMessageType($value, $class); 1073ffe3c632Sopenharmony_ci } 1074ffe3c632Sopenharmony_ci } 1075ffe3c632Sopenharmony_ci $this->$setter($value); 1076ffe3c632Sopenharmony_ci } 1077ffe3c632Sopenharmony_ci } 1078ffe3c632Sopenharmony_ci 1079ffe3c632Sopenharmony_ci /** 1080ffe3c632Sopenharmony_ci * Tries to normalize the elements in $value into a provided protobuf 1081ffe3c632Sopenharmony_ci * wrapper type $class. If $value is any type other than array, we do 1082ffe3c632Sopenharmony_ci * not do any conversion, and instead rely on the existing protobuf 1083ffe3c632Sopenharmony_ci * type checking. If $value is an array, we process each element and 1084ffe3c632Sopenharmony_ci * try to convert it to an instance of $class. 1085ffe3c632Sopenharmony_ci * 1086ffe3c632Sopenharmony_ci * @param mixed $value The array of values to normalize. 1087ffe3c632Sopenharmony_ci * @param string $class The expected wrapper class name 1088ffe3c632Sopenharmony_ci */ 1089ffe3c632Sopenharmony_ci private static function normalizeArrayElementsToMessageType(&$value, $class) 1090ffe3c632Sopenharmony_ci { 1091ffe3c632Sopenharmony_ci if (!is_array($value)) { 1092ffe3c632Sopenharmony_ci // In the case that $value is not an array, we do not want to 1093ffe3c632Sopenharmony_ci // attempt any conversion. Note that this includes the cases 1094ffe3c632Sopenharmony_ci // when $value is a RepeatedField of MapField. In those cases, 1095ffe3c632Sopenharmony_ci // we do not need to convert the elements, as they should 1096ffe3c632Sopenharmony_ci // already be the correct types. 1097ffe3c632Sopenharmony_ci return; 1098ffe3c632Sopenharmony_ci } else { 1099ffe3c632Sopenharmony_ci // Normalize each element in the array. 1100ffe3c632Sopenharmony_ci foreach ($value as $key => &$elementValue) { 1101ffe3c632Sopenharmony_ci self::normalizeToMessageType($elementValue, $class); 1102ffe3c632Sopenharmony_ci } 1103ffe3c632Sopenharmony_ci } 1104ffe3c632Sopenharmony_ci } 1105ffe3c632Sopenharmony_ci 1106ffe3c632Sopenharmony_ci /** 1107ffe3c632Sopenharmony_ci * Tries to normalize $value into a provided protobuf wrapper type $class. 1108ffe3c632Sopenharmony_ci * If $value is any type other than an object, we attempt to construct an 1109ffe3c632Sopenharmony_ci * instance of $class and assign $value to it using the setValue method 1110ffe3c632Sopenharmony_ci * shared by all wrapper types. 1111ffe3c632Sopenharmony_ci * 1112ffe3c632Sopenharmony_ci * This method will raise an error if it receives a type that cannot be 1113ffe3c632Sopenharmony_ci * assigned to the wrapper type via setValue. 1114ffe3c632Sopenharmony_ci * 1115ffe3c632Sopenharmony_ci * @param mixed $value The value to normalize. 1116ffe3c632Sopenharmony_ci * @param string $class The expected wrapper class name 1117ffe3c632Sopenharmony_ci */ 1118ffe3c632Sopenharmony_ci private static function normalizeToMessageType(&$value, $class) 1119ffe3c632Sopenharmony_ci { 1120ffe3c632Sopenharmony_ci if (is_null($value) || is_object($value)) { 1121ffe3c632Sopenharmony_ci // This handles the case that $value is an instance of $class. We 1122ffe3c632Sopenharmony_ci // choose not to do any more strict checking here, relying on the 1123ffe3c632Sopenharmony_ci // existing type checking done by GPBUtil. 1124ffe3c632Sopenharmony_ci return; 1125ffe3c632Sopenharmony_ci } else { 1126ffe3c632Sopenharmony_ci // Try to instantiate $class and set the value 1127ffe3c632Sopenharmony_ci try { 1128ffe3c632Sopenharmony_ci $msg = new $class; 1129ffe3c632Sopenharmony_ci $msg->setValue($value); 1130ffe3c632Sopenharmony_ci $value = $msg; 1131ffe3c632Sopenharmony_ci return; 1132ffe3c632Sopenharmony_ci } catch (\Exception $exception) { 1133ffe3c632Sopenharmony_ci trigger_error( 1134ffe3c632Sopenharmony_ci "Error normalizing value to type '$class': " . $exception->getMessage(), 1135ffe3c632Sopenharmony_ci E_USER_ERROR 1136ffe3c632Sopenharmony_ci ); 1137ffe3c632Sopenharmony_ci } 1138ffe3c632Sopenharmony_ci } 1139ffe3c632Sopenharmony_ci } 1140ffe3c632Sopenharmony_ci 1141ffe3c632Sopenharmony_ci protected function mergeFromJsonArray($array, $ignore_unknown) 1142ffe3c632Sopenharmony_ci { 1143ffe3c632Sopenharmony_ci if (is_a($this, "Google\Protobuf\Any")) { 1144ffe3c632Sopenharmony_ci $this->clear(); 1145ffe3c632Sopenharmony_ci $this->setTypeUrl($array["@type"]); 1146ffe3c632Sopenharmony_ci $msg = $this->unpack(); 1147ffe3c632Sopenharmony_ci if (GPBUtil::hasSpecialJsonMapping($msg)) { 1148ffe3c632Sopenharmony_ci $msg->mergeFromJsonArray($array["value"], $ignore_unknown); 1149ffe3c632Sopenharmony_ci } else { 1150ffe3c632Sopenharmony_ci unset($array["@type"]); 1151ffe3c632Sopenharmony_ci $msg->mergeFromJsonArray($array, $ignore_unknown); 1152ffe3c632Sopenharmony_ci } 1153ffe3c632Sopenharmony_ci $this->setValue($msg->serializeToString()); 1154ffe3c632Sopenharmony_ci return; 1155ffe3c632Sopenharmony_ci } 1156ffe3c632Sopenharmony_ci if (is_a($this, "Google\Protobuf\DoubleValue") || 1157ffe3c632Sopenharmony_ci is_a($this, "Google\Protobuf\FloatValue") || 1158ffe3c632Sopenharmony_ci is_a($this, "Google\Protobuf\Int64Value") || 1159ffe3c632Sopenharmony_ci is_a($this, "Google\Protobuf\UInt64Value") || 1160ffe3c632Sopenharmony_ci is_a($this, "Google\Protobuf\Int32Value") || 1161ffe3c632Sopenharmony_ci is_a($this, "Google\Protobuf\UInt32Value") || 1162ffe3c632Sopenharmony_ci is_a($this, "Google\Protobuf\BoolValue") || 1163ffe3c632Sopenharmony_ci is_a($this, "Google\Protobuf\StringValue")) { 1164ffe3c632Sopenharmony_ci $this->setValue($array); 1165ffe3c632Sopenharmony_ci return; 1166ffe3c632Sopenharmony_ci } 1167ffe3c632Sopenharmony_ci if (is_a($this, "Google\Protobuf\BytesValue")) { 1168ffe3c632Sopenharmony_ci $this->setValue(base64_decode($array)); 1169ffe3c632Sopenharmony_ci return; 1170ffe3c632Sopenharmony_ci } 1171ffe3c632Sopenharmony_ci if (is_a($this, "Google\Protobuf\Duration")) { 1172ffe3c632Sopenharmony_ci $this->mergeFrom(GPBUtil::parseDuration($array)); 1173ffe3c632Sopenharmony_ci return; 1174ffe3c632Sopenharmony_ci } 1175ffe3c632Sopenharmony_ci if (is_a($this, "Google\Protobuf\FieldMask")) { 1176ffe3c632Sopenharmony_ci $this->mergeFrom(GPBUtil::parseFieldMask($array)); 1177ffe3c632Sopenharmony_ci return; 1178ffe3c632Sopenharmony_ci } 1179ffe3c632Sopenharmony_ci if (is_a($this, "Google\Protobuf\Timestamp")) { 1180ffe3c632Sopenharmony_ci $this->mergeFrom(GPBUtil::parseTimestamp($array)); 1181ffe3c632Sopenharmony_ci return; 1182ffe3c632Sopenharmony_ci } 1183ffe3c632Sopenharmony_ci if (is_a($this, "Google\Protobuf\Struct")) { 1184ffe3c632Sopenharmony_ci $fields = $this->getFields(); 1185ffe3c632Sopenharmony_ci foreach($array as $key => $value) { 1186ffe3c632Sopenharmony_ci $v = new Value(); 1187ffe3c632Sopenharmony_ci $v->mergeFromJsonArray($value, $ignore_unknown); 1188ffe3c632Sopenharmony_ci $fields[$key] = $v; 1189ffe3c632Sopenharmony_ci } 1190ffe3c632Sopenharmony_ci } 1191ffe3c632Sopenharmony_ci if (is_a($this, "Google\Protobuf\Value")) { 1192ffe3c632Sopenharmony_ci if (is_bool($array)) { 1193ffe3c632Sopenharmony_ci $this->setBoolValue($array); 1194ffe3c632Sopenharmony_ci } elseif (is_string($array)) { 1195ffe3c632Sopenharmony_ci $this->setStringValue($array); 1196ffe3c632Sopenharmony_ci } elseif (is_null($array)) { 1197ffe3c632Sopenharmony_ci $this->setNullValue(0); 1198ffe3c632Sopenharmony_ci } elseif (is_double($array) || is_integer($array)) { 1199ffe3c632Sopenharmony_ci $this->setNumberValue($array); 1200ffe3c632Sopenharmony_ci } elseif (is_array($array)) { 1201ffe3c632Sopenharmony_ci if (array_values($array) !== $array) { 1202ffe3c632Sopenharmony_ci // Associative array 1203ffe3c632Sopenharmony_ci $struct_value = $this->getStructValue(); 1204ffe3c632Sopenharmony_ci if (is_null($struct_value)) { 1205ffe3c632Sopenharmony_ci $struct_value = new Struct(); 1206ffe3c632Sopenharmony_ci $this->setStructValue($struct_value); 1207ffe3c632Sopenharmony_ci } 1208ffe3c632Sopenharmony_ci foreach ($array as $key => $v) { 1209ffe3c632Sopenharmony_ci $value = new Value(); 1210ffe3c632Sopenharmony_ci $value->mergeFromJsonArray($v, $ignore_unknown); 1211ffe3c632Sopenharmony_ci $values = $struct_value->getFields(); 1212ffe3c632Sopenharmony_ci $values[$key]= $value; 1213ffe3c632Sopenharmony_ci } 1214ffe3c632Sopenharmony_ci } else { 1215ffe3c632Sopenharmony_ci // Array 1216ffe3c632Sopenharmony_ci $list_value = $this->getListValue(); 1217ffe3c632Sopenharmony_ci if (is_null($list_value)) { 1218ffe3c632Sopenharmony_ci $list_value = new ListValue(); 1219ffe3c632Sopenharmony_ci $this->setListValue($list_value); 1220ffe3c632Sopenharmony_ci } 1221ffe3c632Sopenharmony_ci foreach ($array as $v) { 1222ffe3c632Sopenharmony_ci $value = new Value(); 1223ffe3c632Sopenharmony_ci $value->mergeFromJsonArray($v, $ignore_unknown); 1224ffe3c632Sopenharmony_ci $values = $list_value->getValues(); 1225ffe3c632Sopenharmony_ci $values[]= $value; 1226ffe3c632Sopenharmony_ci } 1227ffe3c632Sopenharmony_ci } 1228ffe3c632Sopenharmony_ci } else { 1229ffe3c632Sopenharmony_ci throw new GPBDecodeException("Invalid type for Value."); 1230ffe3c632Sopenharmony_ci } 1231ffe3c632Sopenharmony_ci return; 1232ffe3c632Sopenharmony_ci } 1233ffe3c632Sopenharmony_ci $this->mergeFromArrayJsonImpl($array, $ignore_unknown); 1234ffe3c632Sopenharmony_ci } 1235ffe3c632Sopenharmony_ci 1236ffe3c632Sopenharmony_ci private function mergeFromArrayJsonImpl($array, $ignore_unknown) 1237ffe3c632Sopenharmony_ci { 1238ffe3c632Sopenharmony_ci foreach ($array as $key => $value) { 1239ffe3c632Sopenharmony_ci $field = $this->desc->getFieldByJsonName($key); 1240ffe3c632Sopenharmony_ci if (is_null($field)) { 1241ffe3c632Sopenharmony_ci $field = $this->desc->getFieldByName($key); 1242ffe3c632Sopenharmony_ci if (is_null($field)) { 1243ffe3c632Sopenharmony_ci continue; 1244ffe3c632Sopenharmony_ci } 1245ffe3c632Sopenharmony_ci } 1246ffe3c632Sopenharmony_ci if ($field->isMap()) { 1247ffe3c632Sopenharmony_ci if (is_null($value)) { 1248ffe3c632Sopenharmony_ci continue; 1249ffe3c632Sopenharmony_ci } 1250ffe3c632Sopenharmony_ci $key_field = $field->getMessageType()->getFieldByNumber(1); 1251ffe3c632Sopenharmony_ci $value_field = $field->getMessageType()->getFieldByNumber(2); 1252ffe3c632Sopenharmony_ci foreach ($value as $tmp_key => $tmp_value) { 1253ffe3c632Sopenharmony_ci if (is_null($tmp_value)) { 1254ffe3c632Sopenharmony_ci throw new \Exception( 1255ffe3c632Sopenharmony_ci "Map value field element cannot be null."); 1256ffe3c632Sopenharmony_ci } 1257ffe3c632Sopenharmony_ci $proto_key = $this->convertJsonValueToProtoValue( 1258ffe3c632Sopenharmony_ci $tmp_key, 1259ffe3c632Sopenharmony_ci $key_field, 1260ffe3c632Sopenharmony_ci $ignore_unknown, 1261ffe3c632Sopenharmony_ci true); 1262ffe3c632Sopenharmony_ci $proto_value = $this->convertJsonValueToProtoValue( 1263ffe3c632Sopenharmony_ci $tmp_value, 1264ffe3c632Sopenharmony_ci $value_field, 1265ffe3c632Sopenharmony_ci $ignore_unknown); 1266ffe3c632Sopenharmony_ci self::kvUpdateHelper($field, $proto_key, $proto_value); 1267ffe3c632Sopenharmony_ci } 1268ffe3c632Sopenharmony_ci } else if ($field->isRepeated()) { 1269ffe3c632Sopenharmony_ci if (is_null($value)) { 1270ffe3c632Sopenharmony_ci continue; 1271ffe3c632Sopenharmony_ci } 1272ffe3c632Sopenharmony_ci foreach ($value as $tmp) { 1273ffe3c632Sopenharmony_ci if (is_null($tmp)) { 1274ffe3c632Sopenharmony_ci throw new \Exception( 1275ffe3c632Sopenharmony_ci "Repeated field elements cannot be null."); 1276ffe3c632Sopenharmony_ci } 1277ffe3c632Sopenharmony_ci $proto_value = $this->convertJsonValueToProtoValue( 1278ffe3c632Sopenharmony_ci $tmp, 1279ffe3c632Sopenharmony_ci $field, 1280ffe3c632Sopenharmony_ci $ignore_unknown); 1281ffe3c632Sopenharmony_ci self::appendHelper($field, $proto_value); 1282ffe3c632Sopenharmony_ci } 1283ffe3c632Sopenharmony_ci } else { 1284ffe3c632Sopenharmony_ci $setter = $field->getSetter(); 1285ffe3c632Sopenharmony_ci $proto_value = $this->convertJsonValueToProtoValue( 1286ffe3c632Sopenharmony_ci $value, 1287ffe3c632Sopenharmony_ci $field, 1288ffe3c632Sopenharmony_ci $ignore_unknown); 1289ffe3c632Sopenharmony_ci if ($field->getType() === GPBType::MESSAGE) { 1290ffe3c632Sopenharmony_ci if (is_null($proto_value)) { 1291ffe3c632Sopenharmony_ci continue; 1292ffe3c632Sopenharmony_ci } 1293ffe3c632Sopenharmony_ci $getter = $field->getGetter(); 1294ffe3c632Sopenharmony_ci $submsg = $this->$getter(); 1295ffe3c632Sopenharmony_ci if (!is_null($submsg)) { 1296ffe3c632Sopenharmony_ci $submsg->mergeFrom($proto_value); 1297ffe3c632Sopenharmony_ci continue; 1298ffe3c632Sopenharmony_ci } 1299ffe3c632Sopenharmony_ci } 1300ffe3c632Sopenharmony_ci $this->$setter($proto_value); 1301ffe3c632Sopenharmony_ci } 1302ffe3c632Sopenharmony_ci } 1303ffe3c632Sopenharmony_ci } 1304ffe3c632Sopenharmony_ci 1305ffe3c632Sopenharmony_ci /** 1306ffe3c632Sopenharmony_ci * @ignore 1307ffe3c632Sopenharmony_ci */ 1308ffe3c632Sopenharmony_ci public function parseFromJsonStream($input, $ignore_unknown) 1309ffe3c632Sopenharmony_ci { 1310ffe3c632Sopenharmony_ci $array = json_decode($input->getData(), true, 512, JSON_BIGINT_AS_STRING); 1311ffe3c632Sopenharmony_ci if ($this instanceof \Google\Protobuf\ListValue) { 1312ffe3c632Sopenharmony_ci $array = ["values"=>$array]; 1313ffe3c632Sopenharmony_ci } 1314ffe3c632Sopenharmony_ci if (is_null($array)) { 1315ffe3c632Sopenharmony_ci if ($this instanceof \Google\Protobuf\Value) { 1316ffe3c632Sopenharmony_ci $this->setNullValue(\Google\Protobuf\NullValue::NULL_VALUE); 1317ffe3c632Sopenharmony_ci return; 1318ffe3c632Sopenharmony_ci } else { 1319ffe3c632Sopenharmony_ci throw new GPBDecodeException( 1320ffe3c632Sopenharmony_ci "Cannot decode json string: " . $input->getData()); 1321ffe3c632Sopenharmony_ci } 1322ffe3c632Sopenharmony_ci } 1323ffe3c632Sopenharmony_ci try { 1324ffe3c632Sopenharmony_ci $this->mergeFromJsonArray($array, $ignore_unknown); 1325ffe3c632Sopenharmony_ci } catch (\Exception $e) { 1326ffe3c632Sopenharmony_ci throw new GPBDecodeException($e->getMessage()); 1327ffe3c632Sopenharmony_ci } 1328ffe3c632Sopenharmony_ci } 1329ffe3c632Sopenharmony_ci 1330ffe3c632Sopenharmony_ci /** 1331ffe3c632Sopenharmony_ci * @ignore 1332ffe3c632Sopenharmony_ci */ 1333ffe3c632Sopenharmony_ci private function serializeSingularFieldToStream($field, &$output) 1334ffe3c632Sopenharmony_ci { 1335ffe3c632Sopenharmony_ci if (!$this->existField($field)) { 1336ffe3c632Sopenharmony_ci return true; 1337ffe3c632Sopenharmony_ci } 1338ffe3c632Sopenharmony_ci $getter = $field->getGetter(); 1339ffe3c632Sopenharmony_ci $value = $this->$getter(); 1340ffe3c632Sopenharmony_ci if (!GPBWire::serializeFieldToStream($value, $field, true, $output)) { 1341ffe3c632Sopenharmony_ci return false; 1342ffe3c632Sopenharmony_ci } 1343ffe3c632Sopenharmony_ci return true; 1344ffe3c632Sopenharmony_ci } 1345ffe3c632Sopenharmony_ci 1346ffe3c632Sopenharmony_ci /** 1347ffe3c632Sopenharmony_ci * @ignore 1348ffe3c632Sopenharmony_ci */ 1349ffe3c632Sopenharmony_ci private function serializeRepeatedFieldToStream($field, &$output) 1350ffe3c632Sopenharmony_ci { 1351ffe3c632Sopenharmony_ci $getter = $field->getGetter(); 1352ffe3c632Sopenharmony_ci $values = $this->$getter(); 1353ffe3c632Sopenharmony_ci $count = count($values); 1354ffe3c632Sopenharmony_ci if ($count === 0) { 1355ffe3c632Sopenharmony_ci return true; 1356ffe3c632Sopenharmony_ci } 1357ffe3c632Sopenharmony_ci 1358ffe3c632Sopenharmony_ci $packed = $field->getPacked(); 1359ffe3c632Sopenharmony_ci if ($packed) { 1360ffe3c632Sopenharmony_ci if (!GPBWire::writeTag( 1361ffe3c632Sopenharmony_ci $output, 1362ffe3c632Sopenharmony_ci GPBWire::makeTag($field->getNumber(), GPBType::STRING))) { 1363ffe3c632Sopenharmony_ci return false; 1364ffe3c632Sopenharmony_ci } 1365ffe3c632Sopenharmony_ci $size = 0; 1366ffe3c632Sopenharmony_ci foreach ($values as $value) { 1367ffe3c632Sopenharmony_ci $size += $this->fieldDataOnlyByteSize($field, $value); 1368ffe3c632Sopenharmony_ci } 1369ffe3c632Sopenharmony_ci if (!$output->writeVarint32($size, true)) { 1370ffe3c632Sopenharmony_ci return false; 1371ffe3c632Sopenharmony_ci } 1372ffe3c632Sopenharmony_ci } 1373ffe3c632Sopenharmony_ci 1374ffe3c632Sopenharmony_ci foreach ($values as $value) { 1375ffe3c632Sopenharmony_ci if (!GPBWire::serializeFieldToStream( 1376ffe3c632Sopenharmony_ci $value, 1377ffe3c632Sopenharmony_ci $field, 1378ffe3c632Sopenharmony_ci !$packed, 1379ffe3c632Sopenharmony_ci $output)) { 1380ffe3c632Sopenharmony_ci return false; 1381ffe3c632Sopenharmony_ci } 1382ffe3c632Sopenharmony_ci } 1383ffe3c632Sopenharmony_ci return true; 1384ffe3c632Sopenharmony_ci } 1385ffe3c632Sopenharmony_ci 1386ffe3c632Sopenharmony_ci /** 1387ffe3c632Sopenharmony_ci * @ignore 1388ffe3c632Sopenharmony_ci */ 1389ffe3c632Sopenharmony_ci private function serializeMapFieldToStream($field, $output) 1390ffe3c632Sopenharmony_ci { 1391ffe3c632Sopenharmony_ci $getter = $field->getGetter(); 1392ffe3c632Sopenharmony_ci $values = $this->$getter(); 1393ffe3c632Sopenharmony_ci $count = count($values); 1394ffe3c632Sopenharmony_ci if ($count === 0) { 1395ffe3c632Sopenharmony_ci return true; 1396ffe3c632Sopenharmony_ci } 1397ffe3c632Sopenharmony_ci 1398ffe3c632Sopenharmony_ci foreach ($values as $key => $value) { 1399ffe3c632Sopenharmony_ci $map_entry = new MapEntry($field->getMessageType()); 1400ffe3c632Sopenharmony_ci $map_entry->setKey($key); 1401ffe3c632Sopenharmony_ci $map_entry->setValue($value); 1402ffe3c632Sopenharmony_ci if (!GPBWire::serializeFieldToStream( 1403ffe3c632Sopenharmony_ci $map_entry, 1404ffe3c632Sopenharmony_ci $field, 1405ffe3c632Sopenharmony_ci true, 1406ffe3c632Sopenharmony_ci $output)) { 1407ffe3c632Sopenharmony_ci return false; 1408ffe3c632Sopenharmony_ci } 1409ffe3c632Sopenharmony_ci } 1410ffe3c632Sopenharmony_ci return true; 1411ffe3c632Sopenharmony_ci } 1412ffe3c632Sopenharmony_ci 1413ffe3c632Sopenharmony_ci /** 1414ffe3c632Sopenharmony_ci * @ignore 1415ffe3c632Sopenharmony_ci */ 1416ffe3c632Sopenharmony_ci private function serializeFieldToStream(&$output, $field) 1417ffe3c632Sopenharmony_ci { 1418ffe3c632Sopenharmony_ci if ($field->isMap()) { 1419ffe3c632Sopenharmony_ci return $this->serializeMapFieldToStream($field, $output); 1420ffe3c632Sopenharmony_ci } elseif ($field->isRepeated()) { 1421ffe3c632Sopenharmony_ci return $this->serializeRepeatedFieldToStream($field, $output); 1422ffe3c632Sopenharmony_ci } else { 1423ffe3c632Sopenharmony_ci return $this->serializeSingularFieldToStream($field, $output); 1424ffe3c632Sopenharmony_ci } 1425ffe3c632Sopenharmony_ci } 1426ffe3c632Sopenharmony_ci 1427ffe3c632Sopenharmony_ci /** 1428ffe3c632Sopenharmony_ci * @ignore 1429ffe3c632Sopenharmony_ci */ 1430ffe3c632Sopenharmony_ci private function serializeFieldToJsonStream(&$output, $field) 1431ffe3c632Sopenharmony_ci { 1432ffe3c632Sopenharmony_ci $getter = $field->getGetter(); 1433ffe3c632Sopenharmony_ci $values = $this->$getter(); 1434ffe3c632Sopenharmony_ci return GPBJsonWire::serializeFieldToStream( 1435ffe3c632Sopenharmony_ci $values, $field, $output, !GPBUtil::hasSpecialJsonMapping($this)); 1436ffe3c632Sopenharmony_ci } 1437ffe3c632Sopenharmony_ci 1438ffe3c632Sopenharmony_ci /** 1439ffe3c632Sopenharmony_ci * @ignore 1440ffe3c632Sopenharmony_ci */ 1441ffe3c632Sopenharmony_ci public function serializeToStream(&$output) 1442ffe3c632Sopenharmony_ci { 1443ffe3c632Sopenharmony_ci $fields = $this->desc->getField(); 1444ffe3c632Sopenharmony_ci foreach ($fields as $field) { 1445ffe3c632Sopenharmony_ci if (!$this->serializeFieldToStream($output, $field)) { 1446ffe3c632Sopenharmony_ci return false; 1447ffe3c632Sopenharmony_ci } 1448ffe3c632Sopenharmony_ci } 1449ffe3c632Sopenharmony_ci $output->writeRaw($this->unknown, strlen($this->unknown)); 1450ffe3c632Sopenharmony_ci return true; 1451ffe3c632Sopenharmony_ci } 1452ffe3c632Sopenharmony_ci 1453ffe3c632Sopenharmony_ci /** 1454ffe3c632Sopenharmony_ci * @ignore 1455ffe3c632Sopenharmony_ci */ 1456ffe3c632Sopenharmony_ci public function serializeToJsonStream(&$output) 1457ffe3c632Sopenharmony_ci { 1458ffe3c632Sopenharmony_ci if (is_a($this, 'Google\Protobuf\Any')) { 1459ffe3c632Sopenharmony_ci $output->writeRaw("{", 1); 1460ffe3c632Sopenharmony_ci $type_field = $this->desc->getFieldByNumber(1); 1461ffe3c632Sopenharmony_ci $value_msg = $this->unpack(); 1462ffe3c632Sopenharmony_ci 1463ffe3c632Sopenharmony_ci // Serialize type url. 1464ffe3c632Sopenharmony_ci $output->writeRaw("\"@type\":", 8); 1465ffe3c632Sopenharmony_ci $output->writeRaw("\"", 1); 1466ffe3c632Sopenharmony_ci $output->writeRaw($this->getTypeUrl(), strlen($this->getTypeUrl())); 1467ffe3c632Sopenharmony_ci $output->writeRaw("\"", 1); 1468ffe3c632Sopenharmony_ci 1469ffe3c632Sopenharmony_ci // Serialize value 1470ffe3c632Sopenharmony_ci if (GPBUtil::hasSpecialJsonMapping($value_msg)) { 1471ffe3c632Sopenharmony_ci $output->writeRaw(",\"value\":", 9); 1472ffe3c632Sopenharmony_ci $value_msg->serializeToJsonStream($output); 1473ffe3c632Sopenharmony_ci } else { 1474ffe3c632Sopenharmony_ci $value_fields = $value_msg->desc->getField(); 1475ffe3c632Sopenharmony_ci foreach ($value_fields as $field) { 1476ffe3c632Sopenharmony_ci if ($value_msg->existField($field)) { 1477ffe3c632Sopenharmony_ci $output->writeRaw(",", 1); 1478ffe3c632Sopenharmony_ci if (!$value_msg->serializeFieldToJsonStream($output, $field)) { 1479ffe3c632Sopenharmony_ci return false; 1480ffe3c632Sopenharmony_ci } 1481ffe3c632Sopenharmony_ci } 1482ffe3c632Sopenharmony_ci } 1483ffe3c632Sopenharmony_ci } 1484ffe3c632Sopenharmony_ci 1485ffe3c632Sopenharmony_ci $output->writeRaw("}", 1); 1486ffe3c632Sopenharmony_ci } elseif (is_a($this, 'Google\Protobuf\FieldMask')) { 1487ffe3c632Sopenharmony_ci $field_mask = GPBUtil::formatFieldMask($this); 1488ffe3c632Sopenharmony_ci $output->writeRaw("\"", 1); 1489ffe3c632Sopenharmony_ci $output->writeRaw($field_mask, strlen($field_mask)); 1490ffe3c632Sopenharmony_ci $output->writeRaw("\"", 1); 1491ffe3c632Sopenharmony_ci } elseif (is_a($this, 'Google\Protobuf\Duration')) { 1492ffe3c632Sopenharmony_ci $duration = GPBUtil::formatDuration($this) . "s"; 1493ffe3c632Sopenharmony_ci $output->writeRaw("\"", 1); 1494ffe3c632Sopenharmony_ci $output->writeRaw($duration, strlen($duration)); 1495ffe3c632Sopenharmony_ci $output->writeRaw("\"", 1); 1496ffe3c632Sopenharmony_ci } elseif (get_class($this) === 'Google\Protobuf\Timestamp') { 1497ffe3c632Sopenharmony_ci $timestamp = GPBUtil::formatTimestamp($this); 1498ffe3c632Sopenharmony_ci $timestamp = json_encode($timestamp); 1499ffe3c632Sopenharmony_ci $output->writeRaw($timestamp, strlen($timestamp)); 1500ffe3c632Sopenharmony_ci } elseif (get_class($this) === 'Google\Protobuf\ListValue') { 1501ffe3c632Sopenharmony_ci $field = $this->desc->getField()[1]; 1502ffe3c632Sopenharmony_ci if (!$this->existField($field)) { 1503ffe3c632Sopenharmony_ci $output->writeRaw("[]", 2); 1504ffe3c632Sopenharmony_ci } else { 1505ffe3c632Sopenharmony_ci if (!$this->serializeFieldToJsonStream($output, $field)) { 1506ffe3c632Sopenharmony_ci return false; 1507ffe3c632Sopenharmony_ci } 1508ffe3c632Sopenharmony_ci } 1509ffe3c632Sopenharmony_ci } elseif (get_class($this) === 'Google\Protobuf\Struct') { 1510ffe3c632Sopenharmony_ci $field = $this->desc->getField()[1]; 1511ffe3c632Sopenharmony_ci if (!$this->existField($field)) { 1512ffe3c632Sopenharmony_ci $output->writeRaw("{}", 2); 1513ffe3c632Sopenharmony_ci } else { 1514ffe3c632Sopenharmony_ci if (!$this->serializeFieldToJsonStream($output, $field)) { 1515ffe3c632Sopenharmony_ci return false; 1516ffe3c632Sopenharmony_ci } 1517ffe3c632Sopenharmony_ci } 1518ffe3c632Sopenharmony_ci } else { 1519ffe3c632Sopenharmony_ci if (!GPBUtil::hasSpecialJsonMapping($this)) { 1520ffe3c632Sopenharmony_ci $output->writeRaw("{", 1); 1521ffe3c632Sopenharmony_ci } 1522ffe3c632Sopenharmony_ci $fields = $this->desc->getField(); 1523ffe3c632Sopenharmony_ci $first = true; 1524ffe3c632Sopenharmony_ci foreach ($fields as $field) { 1525ffe3c632Sopenharmony_ci if ($this->existField($field) || 1526ffe3c632Sopenharmony_ci GPBUtil::hasJsonValue($this)) { 1527ffe3c632Sopenharmony_ci if ($first) { 1528ffe3c632Sopenharmony_ci $first = false; 1529ffe3c632Sopenharmony_ci } else { 1530ffe3c632Sopenharmony_ci $output->writeRaw(",", 1); 1531ffe3c632Sopenharmony_ci } 1532ffe3c632Sopenharmony_ci if (!$this->serializeFieldToJsonStream($output, $field)) { 1533ffe3c632Sopenharmony_ci return false; 1534ffe3c632Sopenharmony_ci } 1535ffe3c632Sopenharmony_ci } 1536ffe3c632Sopenharmony_ci } 1537ffe3c632Sopenharmony_ci if (!GPBUtil::hasSpecialJsonMapping($this)) { 1538ffe3c632Sopenharmony_ci $output->writeRaw("}", 1); 1539ffe3c632Sopenharmony_ci } 1540ffe3c632Sopenharmony_ci } 1541ffe3c632Sopenharmony_ci return true; 1542ffe3c632Sopenharmony_ci } 1543ffe3c632Sopenharmony_ci 1544ffe3c632Sopenharmony_ci /** 1545ffe3c632Sopenharmony_ci * Serialize the message to string. 1546ffe3c632Sopenharmony_ci * @return string Serialized binary protobuf data. 1547ffe3c632Sopenharmony_ci */ 1548ffe3c632Sopenharmony_ci public function serializeToString() 1549ffe3c632Sopenharmony_ci { 1550ffe3c632Sopenharmony_ci $output = new CodedOutputStream($this->byteSize()); 1551ffe3c632Sopenharmony_ci $this->serializeToStream($output); 1552ffe3c632Sopenharmony_ci return $output->getData(); 1553ffe3c632Sopenharmony_ci } 1554ffe3c632Sopenharmony_ci 1555ffe3c632Sopenharmony_ci /** 1556ffe3c632Sopenharmony_ci * Serialize the message to json string. 1557ffe3c632Sopenharmony_ci * @return string Serialized json protobuf data. 1558ffe3c632Sopenharmony_ci */ 1559ffe3c632Sopenharmony_ci public function serializeToJsonString() 1560ffe3c632Sopenharmony_ci { 1561ffe3c632Sopenharmony_ci $output = new CodedOutputStream($this->jsonByteSize()); 1562ffe3c632Sopenharmony_ci $this->serializeToJsonStream($output); 1563ffe3c632Sopenharmony_ci return $output->getData(); 1564ffe3c632Sopenharmony_ci } 1565ffe3c632Sopenharmony_ci 1566ffe3c632Sopenharmony_ci /** 1567ffe3c632Sopenharmony_ci * @ignore 1568ffe3c632Sopenharmony_ci */ 1569ffe3c632Sopenharmony_ci private function existField($field) 1570ffe3c632Sopenharmony_ci { 1571ffe3c632Sopenharmony_ci $getter = $field->getGetter(); 1572ffe3c632Sopenharmony_ci $hazzer = "has" . substr($getter, 3); 1573ffe3c632Sopenharmony_ci 1574ffe3c632Sopenharmony_ci if (method_exists($this, $hazzer)) { 1575ffe3c632Sopenharmony_ci return $this->$hazzer(); 1576ffe3c632Sopenharmony_ci } else if ($field->getOneofIndex() !== -1) { 1577ffe3c632Sopenharmony_ci // For old generated code, which does not have hazzers for oneof 1578ffe3c632Sopenharmony_ci // fields. 1579ffe3c632Sopenharmony_ci $oneof = $this->desc->getOneofDecl()[$field->getOneofIndex()]; 1580ffe3c632Sopenharmony_ci $oneof_name = $oneof->getName(); 1581ffe3c632Sopenharmony_ci return $this->$oneof_name->getNumber() === $field->getNumber(); 1582ffe3c632Sopenharmony_ci } 1583ffe3c632Sopenharmony_ci 1584ffe3c632Sopenharmony_ci $values = $this->$getter(); 1585ffe3c632Sopenharmony_ci if ($field->isMap()) { 1586ffe3c632Sopenharmony_ci return count($values) !== 0; 1587ffe3c632Sopenharmony_ci } elseif ($field->isRepeated()) { 1588ffe3c632Sopenharmony_ci return count($values) !== 0; 1589ffe3c632Sopenharmony_ci } else { 1590ffe3c632Sopenharmony_ci return $values !== $this->defaultValue($field); 1591ffe3c632Sopenharmony_ci } 1592ffe3c632Sopenharmony_ci } 1593ffe3c632Sopenharmony_ci 1594ffe3c632Sopenharmony_ci /** 1595ffe3c632Sopenharmony_ci * @ignore 1596ffe3c632Sopenharmony_ci */ 1597ffe3c632Sopenharmony_ci private function repeatedFieldDataOnlyByteSize($field) 1598ffe3c632Sopenharmony_ci { 1599ffe3c632Sopenharmony_ci $size = 0; 1600ffe3c632Sopenharmony_ci 1601ffe3c632Sopenharmony_ci $getter = $field->getGetter(); 1602ffe3c632Sopenharmony_ci $values = $this->$getter(); 1603ffe3c632Sopenharmony_ci $count = count($values); 1604ffe3c632Sopenharmony_ci if ($count !== 0) { 1605ffe3c632Sopenharmony_ci $size += $count * GPBWire::tagSize($field); 1606ffe3c632Sopenharmony_ci foreach ($values as $value) { 1607ffe3c632Sopenharmony_ci $size += $this->singularFieldDataOnlyByteSize($field); 1608ffe3c632Sopenharmony_ci } 1609ffe3c632Sopenharmony_ci } 1610ffe3c632Sopenharmony_ci } 1611ffe3c632Sopenharmony_ci 1612ffe3c632Sopenharmony_ci /** 1613ffe3c632Sopenharmony_ci * @ignore 1614ffe3c632Sopenharmony_ci */ 1615ffe3c632Sopenharmony_ci private function fieldDataOnlyByteSize($field, $value) 1616ffe3c632Sopenharmony_ci { 1617ffe3c632Sopenharmony_ci $size = 0; 1618ffe3c632Sopenharmony_ci 1619ffe3c632Sopenharmony_ci switch ($field->getType()) { 1620ffe3c632Sopenharmony_ci case GPBType::BOOL: 1621ffe3c632Sopenharmony_ci $size += 1; 1622ffe3c632Sopenharmony_ci break; 1623ffe3c632Sopenharmony_ci case GPBType::FLOAT: 1624ffe3c632Sopenharmony_ci case GPBType::FIXED32: 1625ffe3c632Sopenharmony_ci case GPBType::SFIXED32: 1626ffe3c632Sopenharmony_ci $size += 4; 1627ffe3c632Sopenharmony_ci break; 1628ffe3c632Sopenharmony_ci case GPBType::DOUBLE: 1629ffe3c632Sopenharmony_ci case GPBType::FIXED64: 1630ffe3c632Sopenharmony_ci case GPBType::SFIXED64: 1631ffe3c632Sopenharmony_ci $size += 8; 1632ffe3c632Sopenharmony_ci break; 1633ffe3c632Sopenharmony_ci case GPBType::INT32: 1634ffe3c632Sopenharmony_ci case GPBType::ENUM: 1635ffe3c632Sopenharmony_ci $size += GPBWire::varint32Size($value, true); 1636ffe3c632Sopenharmony_ci break; 1637ffe3c632Sopenharmony_ci case GPBType::UINT32: 1638ffe3c632Sopenharmony_ci $size += GPBWire::varint32Size($value); 1639ffe3c632Sopenharmony_ci break; 1640ffe3c632Sopenharmony_ci case GPBType::UINT64: 1641ffe3c632Sopenharmony_ci case GPBType::INT64: 1642ffe3c632Sopenharmony_ci $size += GPBWire::varint64Size($value); 1643ffe3c632Sopenharmony_ci break; 1644ffe3c632Sopenharmony_ci case GPBType::SINT32: 1645ffe3c632Sopenharmony_ci $size += GPBWire::sint32Size($value); 1646ffe3c632Sopenharmony_ci break; 1647ffe3c632Sopenharmony_ci case GPBType::SINT64: 1648ffe3c632Sopenharmony_ci $size += GPBWire::sint64Size($value); 1649ffe3c632Sopenharmony_ci break; 1650ffe3c632Sopenharmony_ci case GPBType::STRING: 1651ffe3c632Sopenharmony_ci case GPBType::BYTES: 1652ffe3c632Sopenharmony_ci $size += strlen($value); 1653ffe3c632Sopenharmony_ci $size += GPBWire::varint32Size($size); 1654ffe3c632Sopenharmony_ci break; 1655ffe3c632Sopenharmony_ci case GPBType::MESSAGE: 1656ffe3c632Sopenharmony_ci $size += $value->byteSize(); 1657ffe3c632Sopenharmony_ci $size += GPBWire::varint32Size($size); 1658ffe3c632Sopenharmony_ci break; 1659ffe3c632Sopenharmony_ci case GPBType::GROUP: 1660ffe3c632Sopenharmony_ci // TODO(teboring): Add support. 1661ffe3c632Sopenharmony_ci user_error("Unsupported type."); 1662ffe3c632Sopenharmony_ci break; 1663ffe3c632Sopenharmony_ci default: 1664ffe3c632Sopenharmony_ci user_error("Unsupported type."); 1665ffe3c632Sopenharmony_ci return 0; 1666ffe3c632Sopenharmony_ci } 1667ffe3c632Sopenharmony_ci 1668ffe3c632Sopenharmony_ci return $size; 1669ffe3c632Sopenharmony_ci } 1670ffe3c632Sopenharmony_ci 1671ffe3c632Sopenharmony_ci /** 1672ffe3c632Sopenharmony_ci * @ignore 1673ffe3c632Sopenharmony_ci */ 1674ffe3c632Sopenharmony_ci private function fieldDataOnlyJsonByteSize($field, $value) 1675ffe3c632Sopenharmony_ci { 1676ffe3c632Sopenharmony_ci $size = 0; 1677ffe3c632Sopenharmony_ci 1678ffe3c632Sopenharmony_ci switch ($field->getType()) { 1679ffe3c632Sopenharmony_ci case GPBType::SFIXED32: 1680ffe3c632Sopenharmony_ci case GPBType::SINT32: 1681ffe3c632Sopenharmony_ci case GPBType::INT32: 1682ffe3c632Sopenharmony_ci $size += strlen(strval($value)); 1683ffe3c632Sopenharmony_ci break; 1684ffe3c632Sopenharmony_ci case GPBType::FIXED32: 1685ffe3c632Sopenharmony_ci case GPBType::UINT32: 1686ffe3c632Sopenharmony_ci if ($value < 0) { 1687ffe3c632Sopenharmony_ci $value = bcadd($value, "4294967296"); 1688ffe3c632Sopenharmony_ci } 1689ffe3c632Sopenharmony_ci $size += strlen(strval($value)); 1690ffe3c632Sopenharmony_ci break; 1691ffe3c632Sopenharmony_ci case GPBType::FIXED64: 1692ffe3c632Sopenharmony_ci case GPBType::UINT64: 1693ffe3c632Sopenharmony_ci if ($value < 0) { 1694ffe3c632Sopenharmony_ci $value = bcadd($value, "18446744073709551616"); 1695ffe3c632Sopenharmony_ci } 1696ffe3c632Sopenharmony_ci // Intentional fall through. 1697ffe3c632Sopenharmony_ci case GPBType::SFIXED64: 1698ffe3c632Sopenharmony_ci case GPBType::INT64: 1699ffe3c632Sopenharmony_ci case GPBType::SINT64: 1700ffe3c632Sopenharmony_ci $size += 2; // size for "" 1701ffe3c632Sopenharmony_ci $size += strlen(strval($value)); 1702ffe3c632Sopenharmony_ci break; 1703ffe3c632Sopenharmony_ci case GPBType::FLOAT: 1704ffe3c632Sopenharmony_ci if (is_nan($value)) { 1705ffe3c632Sopenharmony_ci $size += strlen("NaN") + 2; 1706ffe3c632Sopenharmony_ci } elseif ($value === INF) { 1707ffe3c632Sopenharmony_ci $size += strlen("Infinity") + 2; 1708ffe3c632Sopenharmony_ci } elseif ($value === -INF) { 1709ffe3c632Sopenharmony_ci $size += strlen("-Infinity") + 2; 1710ffe3c632Sopenharmony_ci } else { 1711ffe3c632Sopenharmony_ci $size += strlen(sprintf("%.8g", $value)); 1712ffe3c632Sopenharmony_ci } 1713ffe3c632Sopenharmony_ci break; 1714ffe3c632Sopenharmony_ci case GPBType::DOUBLE: 1715ffe3c632Sopenharmony_ci if (is_nan($value)) { 1716ffe3c632Sopenharmony_ci $size += strlen("NaN") + 2; 1717ffe3c632Sopenharmony_ci } elseif ($value === INF) { 1718ffe3c632Sopenharmony_ci $size += strlen("Infinity") + 2; 1719ffe3c632Sopenharmony_ci } elseif ($value === -INF) { 1720ffe3c632Sopenharmony_ci $size += strlen("-Infinity") + 2; 1721ffe3c632Sopenharmony_ci } else { 1722ffe3c632Sopenharmony_ci $size += strlen(sprintf("%.17g", $value)); 1723ffe3c632Sopenharmony_ci } 1724ffe3c632Sopenharmony_ci break; 1725ffe3c632Sopenharmony_ci case GPBType::ENUM: 1726ffe3c632Sopenharmony_ci $enum_desc = $field->getEnumType(); 1727ffe3c632Sopenharmony_ci if ($enum_desc->getClass() === "Google\Protobuf\NullValue") { 1728ffe3c632Sopenharmony_ci $size += 4; 1729ffe3c632Sopenharmony_ci break; 1730ffe3c632Sopenharmony_ci } 1731ffe3c632Sopenharmony_ci $enum_value_desc = $enum_desc->getValueByNumber($value); 1732ffe3c632Sopenharmony_ci if (!is_null($enum_value_desc)) { 1733ffe3c632Sopenharmony_ci $size += 2; // size for "" 1734ffe3c632Sopenharmony_ci $size += strlen($enum_value_desc->getName()); 1735ffe3c632Sopenharmony_ci } else { 1736ffe3c632Sopenharmony_ci $str_value = strval($value); 1737ffe3c632Sopenharmony_ci $size += strlen($str_value); 1738ffe3c632Sopenharmony_ci } 1739ffe3c632Sopenharmony_ci break; 1740ffe3c632Sopenharmony_ci case GPBType::BOOL: 1741ffe3c632Sopenharmony_ci if ($value) { 1742ffe3c632Sopenharmony_ci $size += 4; 1743ffe3c632Sopenharmony_ci } else { 1744ffe3c632Sopenharmony_ci $size += 5; 1745ffe3c632Sopenharmony_ci } 1746ffe3c632Sopenharmony_ci break; 1747ffe3c632Sopenharmony_ci case GPBType::STRING: 1748ffe3c632Sopenharmony_ci $value = json_encode($value, JSON_UNESCAPED_UNICODE); 1749ffe3c632Sopenharmony_ci $size += strlen($value); 1750ffe3c632Sopenharmony_ci break; 1751ffe3c632Sopenharmony_ci case GPBType::BYTES: 1752ffe3c632Sopenharmony_ci # if (is_a($this, "Google\Protobuf\BytesValue")) { 1753ffe3c632Sopenharmony_ci # $size += strlen(json_encode($value)); 1754ffe3c632Sopenharmony_ci # } else { 1755ffe3c632Sopenharmony_ci # $size += strlen(base64_encode($value)); 1756ffe3c632Sopenharmony_ci # $size += 2; // size for \"\" 1757ffe3c632Sopenharmony_ci # } 1758ffe3c632Sopenharmony_ci $size += strlen(base64_encode($value)); 1759ffe3c632Sopenharmony_ci $size += 2; // size for \"\" 1760ffe3c632Sopenharmony_ci break; 1761ffe3c632Sopenharmony_ci case GPBType::MESSAGE: 1762ffe3c632Sopenharmony_ci $size += $value->jsonByteSize(); 1763ffe3c632Sopenharmony_ci break; 1764ffe3c632Sopenharmony_ci# case GPBType::GROUP: 1765ffe3c632Sopenharmony_ci# // TODO(teboring): Add support. 1766ffe3c632Sopenharmony_ci# user_error("Unsupported type."); 1767ffe3c632Sopenharmony_ci# break; 1768ffe3c632Sopenharmony_ci default: 1769ffe3c632Sopenharmony_ci user_error("Unsupported type " . $field->getType()); 1770ffe3c632Sopenharmony_ci return 0; 1771ffe3c632Sopenharmony_ci } 1772ffe3c632Sopenharmony_ci 1773ffe3c632Sopenharmony_ci return $size; 1774ffe3c632Sopenharmony_ci } 1775ffe3c632Sopenharmony_ci 1776ffe3c632Sopenharmony_ci /** 1777ffe3c632Sopenharmony_ci * @ignore 1778ffe3c632Sopenharmony_ci */ 1779ffe3c632Sopenharmony_ci private function fieldByteSize($field) 1780ffe3c632Sopenharmony_ci { 1781ffe3c632Sopenharmony_ci $size = 0; 1782ffe3c632Sopenharmony_ci if ($field->isMap()) { 1783ffe3c632Sopenharmony_ci $getter = $field->getGetter(); 1784ffe3c632Sopenharmony_ci $values = $this->$getter(); 1785ffe3c632Sopenharmony_ci $count = count($values); 1786ffe3c632Sopenharmony_ci if ($count !== 0) { 1787ffe3c632Sopenharmony_ci $size += $count * GPBWire::tagSize($field); 1788ffe3c632Sopenharmony_ci $message_type = $field->getMessageType(); 1789ffe3c632Sopenharmony_ci $key_field = $message_type->getFieldByNumber(1); 1790ffe3c632Sopenharmony_ci $value_field = $message_type->getFieldByNumber(2); 1791ffe3c632Sopenharmony_ci foreach ($values as $key => $value) { 1792ffe3c632Sopenharmony_ci $data_size = 0; 1793ffe3c632Sopenharmony_ci if ($key != $this->defaultValue($key_field)) { 1794ffe3c632Sopenharmony_ci $data_size += $this->fieldDataOnlyByteSize( 1795ffe3c632Sopenharmony_ci $key_field, 1796ffe3c632Sopenharmony_ci $key); 1797ffe3c632Sopenharmony_ci $data_size += GPBWire::tagSize($key_field); 1798ffe3c632Sopenharmony_ci } 1799ffe3c632Sopenharmony_ci if ($value != $this->defaultValue($value_field)) { 1800ffe3c632Sopenharmony_ci $data_size += $this->fieldDataOnlyByteSize( 1801ffe3c632Sopenharmony_ci $value_field, 1802ffe3c632Sopenharmony_ci $value); 1803ffe3c632Sopenharmony_ci $data_size += GPBWire::tagSize($value_field); 1804ffe3c632Sopenharmony_ci } 1805ffe3c632Sopenharmony_ci $size += GPBWire::varint32Size($data_size) + $data_size; 1806ffe3c632Sopenharmony_ci } 1807ffe3c632Sopenharmony_ci } 1808ffe3c632Sopenharmony_ci } elseif ($field->isRepeated()) { 1809ffe3c632Sopenharmony_ci $getter = $field->getGetter(); 1810ffe3c632Sopenharmony_ci $values = $this->$getter(); 1811ffe3c632Sopenharmony_ci $count = count($values); 1812ffe3c632Sopenharmony_ci if ($count !== 0) { 1813ffe3c632Sopenharmony_ci if ($field->getPacked()) { 1814ffe3c632Sopenharmony_ci $data_size = 0; 1815ffe3c632Sopenharmony_ci foreach ($values as $value) { 1816ffe3c632Sopenharmony_ci $data_size += $this->fieldDataOnlyByteSize($field, $value); 1817ffe3c632Sopenharmony_ci } 1818ffe3c632Sopenharmony_ci $size += GPBWire::tagSize($field); 1819ffe3c632Sopenharmony_ci $size += GPBWire::varint32Size($data_size); 1820ffe3c632Sopenharmony_ci $size += $data_size; 1821ffe3c632Sopenharmony_ci } else { 1822ffe3c632Sopenharmony_ci $size += $count * GPBWire::tagSize($field); 1823ffe3c632Sopenharmony_ci foreach ($values as $value) { 1824ffe3c632Sopenharmony_ci $size += $this->fieldDataOnlyByteSize($field, $value); 1825ffe3c632Sopenharmony_ci } 1826ffe3c632Sopenharmony_ci } 1827ffe3c632Sopenharmony_ci } 1828ffe3c632Sopenharmony_ci } elseif ($this->existField($field)) { 1829ffe3c632Sopenharmony_ci $size += GPBWire::tagSize($field); 1830ffe3c632Sopenharmony_ci $getter = $field->getGetter(); 1831ffe3c632Sopenharmony_ci $value = $this->$getter(); 1832ffe3c632Sopenharmony_ci $size += $this->fieldDataOnlyByteSize($field, $value); 1833ffe3c632Sopenharmony_ci } 1834ffe3c632Sopenharmony_ci return $size; 1835ffe3c632Sopenharmony_ci } 1836ffe3c632Sopenharmony_ci 1837ffe3c632Sopenharmony_ci /** 1838ffe3c632Sopenharmony_ci * @ignore 1839ffe3c632Sopenharmony_ci */ 1840ffe3c632Sopenharmony_ci private function fieldJsonByteSize($field) 1841ffe3c632Sopenharmony_ci { 1842ffe3c632Sopenharmony_ci $size = 0; 1843ffe3c632Sopenharmony_ci 1844ffe3c632Sopenharmony_ci if ($field->isMap()) { 1845ffe3c632Sopenharmony_ci $getter = $field->getGetter(); 1846ffe3c632Sopenharmony_ci $values = $this->$getter(); 1847ffe3c632Sopenharmony_ci $count = count($values); 1848ffe3c632Sopenharmony_ci if ($count !== 0) { 1849ffe3c632Sopenharmony_ci if (!GPBUtil::hasSpecialJsonMapping($this)) { 1850ffe3c632Sopenharmony_ci $size += 3; // size for "\"\":". 1851ffe3c632Sopenharmony_ci $size += strlen($field->getJsonName()); // size for field name 1852ffe3c632Sopenharmony_ci } 1853ffe3c632Sopenharmony_ci $size += 2; // size for "{}". 1854ffe3c632Sopenharmony_ci $size += $count - 1; // size for commas 1855ffe3c632Sopenharmony_ci $getter = $field->getGetter(); 1856ffe3c632Sopenharmony_ci $map_entry = $field->getMessageType(); 1857ffe3c632Sopenharmony_ci $key_field = $map_entry->getFieldByNumber(1); 1858ffe3c632Sopenharmony_ci $value_field = $map_entry->getFieldByNumber(2); 1859ffe3c632Sopenharmony_ci switch ($key_field->getType()) { 1860ffe3c632Sopenharmony_ci case GPBType::STRING: 1861ffe3c632Sopenharmony_ci case GPBType::SFIXED64: 1862ffe3c632Sopenharmony_ci case GPBType::INT64: 1863ffe3c632Sopenharmony_ci case GPBType::SINT64: 1864ffe3c632Sopenharmony_ci case GPBType::FIXED64: 1865ffe3c632Sopenharmony_ci case GPBType::UINT64: 1866ffe3c632Sopenharmony_ci $additional_quote = false; 1867ffe3c632Sopenharmony_ci break; 1868ffe3c632Sopenharmony_ci default: 1869ffe3c632Sopenharmony_ci $additional_quote = true; 1870ffe3c632Sopenharmony_ci } 1871ffe3c632Sopenharmony_ci foreach ($values as $key => $value) { 1872ffe3c632Sopenharmony_ci if ($additional_quote) { 1873ffe3c632Sopenharmony_ci $size += 2; // size for "" 1874ffe3c632Sopenharmony_ci } 1875ffe3c632Sopenharmony_ci $size += $this->fieldDataOnlyJsonByteSize($key_field, $key); 1876ffe3c632Sopenharmony_ci $size += $this->fieldDataOnlyJsonByteSize($value_field, $value); 1877ffe3c632Sopenharmony_ci $size += 1; // size for : 1878ffe3c632Sopenharmony_ci } 1879ffe3c632Sopenharmony_ci } 1880ffe3c632Sopenharmony_ci } elseif ($field->isRepeated()) { 1881ffe3c632Sopenharmony_ci $getter = $field->getGetter(); 1882ffe3c632Sopenharmony_ci $values = $this->$getter(); 1883ffe3c632Sopenharmony_ci $count = count($values); 1884ffe3c632Sopenharmony_ci if ($count !== 0) { 1885ffe3c632Sopenharmony_ci if (!GPBUtil::hasSpecialJsonMapping($this)) { 1886ffe3c632Sopenharmony_ci $size += 3; // size for "\"\":". 1887ffe3c632Sopenharmony_ci $size += strlen($field->getJsonName()); // size for field name 1888ffe3c632Sopenharmony_ci } 1889ffe3c632Sopenharmony_ci $size += 2; // size for "[]". 1890ffe3c632Sopenharmony_ci $size += $count - 1; // size for commas 1891ffe3c632Sopenharmony_ci $getter = $field->getGetter(); 1892ffe3c632Sopenharmony_ci foreach ($values as $value) { 1893ffe3c632Sopenharmony_ci $size += $this->fieldDataOnlyJsonByteSize($field, $value); 1894ffe3c632Sopenharmony_ci } 1895ffe3c632Sopenharmony_ci } 1896ffe3c632Sopenharmony_ci } elseif ($this->existField($field) || GPBUtil::hasJsonValue($this)) { 1897ffe3c632Sopenharmony_ci if (!GPBUtil::hasSpecialJsonMapping($this)) { 1898ffe3c632Sopenharmony_ci $size += 3; // size for "\"\":". 1899ffe3c632Sopenharmony_ci $size += strlen($field->getJsonName()); // size for field name 1900ffe3c632Sopenharmony_ci } 1901ffe3c632Sopenharmony_ci $getter = $field->getGetter(); 1902ffe3c632Sopenharmony_ci $value = $this->$getter(); 1903ffe3c632Sopenharmony_ci $size += $this->fieldDataOnlyJsonByteSize($field, $value); 1904ffe3c632Sopenharmony_ci } 1905ffe3c632Sopenharmony_ci return $size; 1906ffe3c632Sopenharmony_ci } 1907ffe3c632Sopenharmony_ci 1908ffe3c632Sopenharmony_ci /** 1909ffe3c632Sopenharmony_ci * @ignore 1910ffe3c632Sopenharmony_ci */ 1911ffe3c632Sopenharmony_ci public function byteSize() 1912ffe3c632Sopenharmony_ci { 1913ffe3c632Sopenharmony_ci $size = 0; 1914ffe3c632Sopenharmony_ci 1915ffe3c632Sopenharmony_ci $fields = $this->desc->getField(); 1916ffe3c632Sopenharmony_ci foreach ($fields as $field) { 1917ffe3c632Sopenharmony_ci $size += $this->fieldByteSize($field); 1918ffe3c632Sopenharmony_ci } 1919ffe3c632Sopenharmony_ci $size += strlen($this->unknown); 1920ffe3c632Sopenharmony_ci return $size; 1921ffe3c632Sopenharmony_ci } 1922ffe3c632Sopenharmony_ci 1923ffe3c632Sopenharmony_ci private function appendHelper($field, $append_value) 1924ffe3c632Sopenharmony_ci { 1925ffe3c632Sopenharmony_ci $getter = $field->getGetter(); 1926ffe3c632Sopenharmony_ci $setter = $field->getSetter(); 1927ffe3c632Sopenharmony_ci 1928ffe3c632Sopenharmony_ci $field_arr_value = $this->$getter(); 1929ffe3c632Sopenharmony_ci $field_arr_value[] = $append_value; 1930ffe3c632Sopenharmony_ci 1931ffe3c632Sopenharmony_ci if (!is_object($field_arr_value)) { 1932ffe3c632Sopenharmony_ci $this->$setter($field_arr_value); 1933ffe3c632Sopenharmony_ci } 1934ffe3c632Sopenharmony_ci } 1935ffe3c632Sopenharmony_ci 1936ffe3c632Sopenharmony_ci private function kvUpdateHelper($field, $update_key, $update_value) 1937ffe3c632Sopenharmony_ci { 1938ffe3c632Sopenharmony_ci $getter = $field->getGetter(); 1939ffe3c632Sopenharmony_ci $setter = $field->getSetter(); 1940ffe3c632Sopenharmony_ci 1941ffe3c632Sopenharmony_ci $field_arr_value = $this->$getter(); 1942ffe3c632Sopenharmony_ci $field_arr_value[$update_key] = $update_value; 1943ffe3c632Sopenharmony_ci 1944ffe3c632Sopenharmony_ci if (!is_object($field_arr_value)) { 1945ffe3c632Sopenharmony_ci $this->$setter($field_arr_value); 1946ffe3c632Sopenharmony_ci } 1947ffe3c632Sopenharmony_ci } 1948ffe3c632Sopenharmony_ci 1949ffe3c632Sopenharmony_ci /** 1950ffe3c632Sopenharmony_ci * @ignore 1951ffe3c632Sopenharmony_ci */ 1952ffe3c632Sopenharmony_ci public function jsonByteSize() 1953ffe3c632Sopenharmony_ci { 1954ffe3c632Sopenharmony_ci $size = 0; 1955ffe3c632Sopenharmony_ci if (is_a($this, 'Google\Protobuf\Any')) { 1956ffe3c632Sopenharmony_ci // Size for "{}". 1957ffe3c632Sopenharmony_ci $size += 2; 1958ffe3c632Sopenharmony_ci 1959ffe3c632Sopenharmony_ci // Size for "\"@type\":". 1960ffe3c632Sopenharmony_ci $size += 8; 1961ffe3c632Sopenharmony_ci 1962ffe3c632Sopenharmony_ci // Size for url. +2 for "" /. 1963ffe3c632Sopenharmony_ci $size += strlen($this->getTypeUrl()) + 2; 1964ffe3c632Sopenharmony_ci 1965ffe3c632Sopenharmony_ci $value_msg = $this->unpack(); 1966ffe3c632Sopenharmony_ci if (GPBUtil::hasSpecialJsonMapping($value_msg)) { 1967ffe3c632Sopenharmony_ci // Size for "\",value\":". 1968ffe3c632Sopenharmony_ci $size += 9; 1969ffe3c632Sopenharmony_ci $size += $value_msg->jsonByteSize(); 1970ffe3c632Sopenharmony_ci } else { 1971ffe3c632Sopenharmony_ci // Size for value. +1 for comma, -2 for "{}". 1972ffe3c632Sopenharmony_ci $size += $value_msg->jsonByteSize() -1; 1973ffe3c632Sopenharmony_ci } 1974ffe3c632Sopenharmony_ci } elseif (get_class($this) === 'Google\Protobuf\FieldMask') { 1975ffe3c632Sopenharmony_ci $field_mask = GPBUtil::formatFieldMask($this); 1976ffe3c632Sopenharmony_ci $size += strlen($field_mask) + 2; // 2 for "" 1977ffe3c632Sopenharmony_ci } elseif (get_class($this) === 'Google\Protobuf\Duration') { 1978ffe3c632Sopenharmony_ci $duration = GPBUtil::formatDuration($this) . "s"; 1979ffe3c632Sopenharmony_ci $size += strlen($duration) + 2; // 2 for "" 1980ffe3c632Sopenharmony_ci } elseif (get_class($this) === 'Google\Protobuf\Timestamp') { 1981ffe3c632Sopenharmony_ci $timestamp = GPBUtil::formatTimestamp($this); 1982ffe3c632Sopenharmony_ci $timestamp = json_encode($timestamp); 1983ffe3c632Sopenharmony_ci $size += strlen($timestamp); 1984ffe3c632Sopenharmony_ci } elseif (get_class($this) === 'Google\Protobuf\ListValue') { 1985ffe3c632Sopenharmony_ci $field = $this->desc->getField()[1]; 1986ffe3c632Sopenharmony_ci if ($this->existField($field)) { 1987ffe3c632Sopenharmony_ci $field_size = $this->fieldJsonByteSize($field); 1988ffe3c632Sopenharmony_ci $size += $field_size; 1989ffe3c632Sopenharmony_ci } else { 1990ffe3c632Sopenharmony_ci // Size for "[]". 1991ffe3c632Sopenharmony_ci $size += 2; 1992ffe3c632Sopenharmony_ci } 1993ffe3c632Sopenharmony_ci } elseif (get_class($this) === 'Google\Protobuf\Struct') { 1994ffe3c632Sopenharmony_ci $field = $this->desc->getField()[1]; 1995ffe3c632Sopenharmony_ci if ($this->existField($field)) { 1996ffe3c632Sopenharmony_ci $field_size = $this->fieldJsonByteSize($field); 1997ffe3c632Sopenharmony_ci $size += $field_size; 1998ffe3c632Sopenharmony_ci } else { 1999ffe3c632Sopenharmony_ci // Size for "{}". 2000ffe3c632Sopenharmony_ci $size += 2; 2001ffe3c632Sopenharmony_ci } 2002ffe3c632Sopenharmony_ci } else { 2003ffe3c632Sopenharmony_ci if (!GPBUtil::hasSpecialJsonMapping($this)) { 2004ffe3c632Sopenharmony_ci // Size for "{}". 2005ffe3c632Sopenharmony_ci $size += 2; 2006ffe3c632Sopenharmony_ci } 2007ffe3c632Sopenharmony_ci 2008ffe3c632Sopenharmony_ci $fields = $this->desc->getField(); 2009ffe3c632Sopenharmony_ci $count = 0; 2010ffe3c632Sopenharmony_ci foreach ($fields as $field) { 2011ffe3c632Sopenharmony_ci $field_size = $this->fieldJsonByteSize($field); 2012ffe3c632Sopenharmony_ci $size += $field_size; 2013ffe3c632Sopenharmony_ci if ($field_size != 0) { 2014ffe3c632Sopenharmony_ci $count++; 2015ffe3c632Sopenharmony_ci } 2016ffe3c632Sopenharmony_ci } 2017ffe3c632Sopenharmony_ci // size for comma 2018ffe3c632Sopenharmony_ci $size += $count > 0 ? ($count - 1) : 0; 2019ffe3c632Sopenharmony_ci } 2020ffe3c632Sopenharmony_ci return $size; 2021ffe3c632Sopenharmony_ci } 2022ffe3c632Sopenharmony_ci} 2023