| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903 |
- <?php
- // Protocol Buffers - Google's data interchange format
- // Copyright 2008 Google Inc. All rights reserved.
- // https://developers.google.com/protocol-buffers/
- //
- // Redistribution and use in source and binary forms, with or without
- // modification, are permitted provided that the following conditions are
- // met:
- //
- // * Redistributions of source code must retain the above copyright
- // notice, this list of conditions and the following disclaimer.
- // * Redistributions in binary form must reproduce the above
- // copyright notice, this list of conditions and the following disclaimer
- // in the documentation and/or other materials provided with the
- // distribution.
- // * Neither the name of Google Inc. nor the names of its
- // contributors may be used to endorse or promote products derived from
- // this software without specific prior written permission.
- //
- // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- /**
- * Defines Message, the parent class extended by all protocol message classes.
- */
- namespace Google\Protobuf\Internal;
- use Google\Protobuf\Internal\CodedInputStream;
- use Google\Protobuf\Internal\CodedOutputStream;
- use Google\Protobuf\Internal\DescriptorPool;
- use Google\Protobuf\Internal\GPBLabel;
- use Google\Protobuf\Internal\GPBType;
- use Google\Protobuf\Internal\GPBWire;
- use Google\Protobuf\Internal\MapEntry;
- use Google\Protobuf\Internal\RepeatedField;
- use Google\Protobuf\ListValue;
- use Google\Protobuf\Value;
- use Google\Protobuf\Struct;
- use Google\Protobuf\NullValue;
- /**
- * Parent class of all proto messages. Users should not instantiate this class
- * or extend this class or its child classes by their own. See the comment of
- * specific functions for more details.
- */
- class Message
- {
- /**
- * @ignore
- */
- private $desc;
- private $unknown = "";
- /**
- * @ignore
- */
- public function __construct($data = NULL)
- {
- // MapEntry message is shared by all types of map fields, whose
- // descriptors are different from each other. Thus, we cannot find a
- // specific descriptor from the descriptor pool.
- if ($this instanceof MapEntry) {
- $this->initWithDescriptor($data);
- } else {
- $this->initWithGeneratedPool();
- if (is_array($data)) {
- $this->mergeFromArray($data);
- } else if (!empty($data)) {
- throw new \InvalidArgumentException(
- 'Message constructor must be an array or null.'
- );
- }
- }
- }
- /**
- * @ignore
- */
- private function initWithGeneratedPool()
- {
- $pool = DescriptorPool::getGeneratedPool();
- $this->desc = $pool->getDescriptorByClassName(get_class($this));
- if (is_null($this->desc)) {
- user_error(get_class($this) . " is not found in descriptor pool.");
- }
- foreach ($this->desc->getField() as $field) {
- $setter = $field->getSetter();
- if ($field->isMap()) {
- $message_type = $field->getMessageType();
- $key_field = $message_type->getFieldByNumber(1);
- $value_field = $message_type->getFieldByNumber(2);
- switch ($value_field->getType()) {
- case GPBType::MESSAGE:
- case GPBType::GROUP:
- $map_field = new MapField(
- $key_field->getType(),
- $value_field->getType(),
- $value_field->getMessageType()->getClass());
- $this->$setter($map_field);
- break;
- case GPBType::ENUM:
- $map_field = new MapField(
- $key_field->getType(),
- $value_field->getType(),
- $value_field->getEnumType()->getClass());
- $this->$setter($map_field);
- break;
- default:
- $map_field = new MapField(
- $key_field->getType(),
- $value_field->getType());
- $this->$setter($map_field);
- break;
- }
- } else if ($field->getLabel() === GPBLabel::REPEATED) {
- switch ($field->getType()) {
- case GPBType::MESSAGE:
- case GPBType::GROUP:
- $repeated_field = new RepeatedField(
- $field->getType(),
- $field->getMessageType()->getClass());
- $this->$setter($repeated_field);
- break;
- case GPBType::ENUM:
- $repeated_field = new RepeatedField(
- $field->getType(),
- $field->getEnumType()->getClass());
- $this->$setter($repeated_field);
- break;
- default:
- $repeated_field = new RepeatedField($field->getType());
- $this->$setter($repeated_field);
- break;
- }
- } else if ($field->getOneofIndex() !== -1) {
- $oneof = $this->desc->getOneofDecl()[$field->getOneofIndex()];
- $oneof_name = $oneof->getName();
- $this->$oneof_name = new OneofField($oneof);
- } else if ($field->getLabel() === GPBLabel::OPTIONAL &&
- PHP_INT_SIZE == 4) {
- switch ($field->getType()) {
- case GPBType::INT64:
- case GPBType::UINT64:
- case GPBType::FIXED64:
- case GPBType::SFIXED64:
- case GPBType::SINT64:
- $this->$setter("0");
- }
- }
- }
- }
- /**
- * @ignore
- */
- private function initWithDescriptor(Descriptor $desc)
- {
- $this->desc = $desc;
- foreach ($desc->getField() as $field) {
- $setter = $field->getSetter();
- $defaultValue = $this->defaultValue($field);
- $this->$setter($defaultValue);
- }
- }
- protected function readOneof($number)
- {
- $field = $this->desc->getFieldByNumber($number);
- $oneof = $this->desc->getOneofDecl()[$field->getOneofIndex()];
- $oneof_name = $oneof->getName();
- $oneof_field = $this->$oneof_name;
- if ($number === $oneof_field->getNumber()) {
- return $oneof_field->getValue();
- } else {
- return $this->defaultValue($field);
- }
- }
- protected function writeOneof($number, $value)
- {
- $field = $this->desc->getFieldByNumber($number);
- $oneof = $this->desc->getOneofDecl()[$field->getOneofIndex()];
- $oneof_name = $oneof->getName();
- $oneof_field = $this->$oneof_name;
- $oneof_field->setValue($value);
- $oneof_field->setFieldName($field->getName());
- $oneof_field->setNumber($number);
- }
- protected function whichOneof($oneof_name)
- {
- $oneof_field = $this->$oneof_name;
- $number = $oneof_field->getNumber();
- if ($number == 0) {
- return "";
- }
- $field = $this->desc->getFieldByNumber($number);
- return $field->getName();
- }
- /**
- * @ignore
- */
- private function defaultValue($field)
- {
- $value = null;
- switch ($field->getType()) {
- case GPBType::DOUBLE:
- case GPBType::FLOAT:
- return 0.0;
- case GPBType::UINT32:
- case GPBType::INT32:
- case GPBType::FIXED32:
- case GPBType::SFIXED32:
- case GPBType::SINT32:
- case GPBType::ENUM:
- return 0;
- case GPBType::INT64:
- case GPBType::UINT64:
- case GPBType::FIXED64:
- case GPBType::SFIXED64:
- case GPBType::SINT64:
- if (PHP_INT_SIZE === 4) {
- return '0';
- } else {
- return 0;
- }
- case GPBType::BOOL:
- return false;
- case GPBType::STRING:
- case GPBType::BYTES:
- return "";
- case GPBType::GROUP:
- case GPBType::MESSAGE:
- return null;
- default:
- user_error("Unsupported type.");
- return false;
- }
- }
- /**
- * @ignore
- */
- private function skipField($input, $tag)
- {
- $number = GPBWire::getTagFieldNumber($tag);
- if ($number === 0) {
- throw new GPBDecodeException("Illegal field number zero.");
- }
- $start = $input->current();
- switch (GPBWire::getTagWireType($tag)) {
- case GPBWireType::VARINT:
- $uint64 = 0;
- if (!$input->readVarint64($uint64)) {
- throw new GPBDecodeException(
- "Unexpected EOF inside varint.");
- }
- break;
- case GPBWireType::FIXED64:
- $uint64 = 0;
- if (!$input->readLittleEndian64($uint64)) {
- throw new GPBDecodeException(
- "Unexpected EOF inside fixed64.");
- }
- break;
- case GPBWireType::FIXED32:
- $uint32 = 0;
- if (!$input->readLittleEndian32($uint32)) {
- throw new GPBDecodeException(
- "Unexpected EOF inside fixed32.");
- }
- break;
- case GPBWireType::LENGTH_DELIMITED:
- $length = 0;
- if (!$input->readVarint32($length)) {
- throw new GPBDecodeException(
- "Unexpected EOF inside length.");
- }
- $data = NULL;
- if (!$input->readRaw($length, $data)) {
- throw new GPBDecodeException(
- "Unexpected EOF inside length delimited data.");
- }
- break;
- case GPBWireType::START_GROUP:
- case GPBWireType::END_GROUP:
- throw new GPBDecodeException("Unexpected wire type.");
- default:
- throw new GPBDecodeException("Unexpected wire type.");
- }
- $end = $input->current();
- $bytes = str_repeat(chr(0), CodedOutputStream::MAX_VARINT64_BYTES);
- $size = CodedOutputStream::writeVarintToArray($tag, $bytes, true);
- $this->unknown .= substr($bytes, 0, $size) . $input->substr($start, $end);
- }
- /**
- * @ignore
- */
- private static function parseFieldFromStreamNoTag($input, $field, &$value)
- {
- switch ($field->getType()) {
- case GPBType::DOUBLE:
- if (!GPBWire::readDouble($input, $value)) {
- throw new GPBDecodeException(
- "Unexpected EOF inside double field.");
- }
- break;
- case GPBType::FLOAT:
- if (!GPBWire::readFloat($input, $value)) {
- throw new GPBDecodeException(
- "Unexpected EOF inside float field.");
- }
- break;
- case GPBType::INT64:
- if (!GPBWire::readInt64($input, $value)) {
- throw new GPBDecodeException(
- "Unexpected EOF inside int64 field.");
- }
- break;
- case GPBType::UINT64:
- if (!GPBWire::readUint64($input, $value)) {
- throw new GPBDecodeException(
- "Unexpected EOF inside uint64 field.");
- }
- break;
- case GPBType::INT32:
- if (!GPBWire::readInt32($input, $value)) {
- throw new GPBDecodeException(
- "Unexpected EOF inside int32 field.");
- }
- break;
- case GPBType::FIXED64:
- if (!GPBWire::readFixed64($input, $value)) {
- throw new GPBDecodeException(
- "Unexpected EOF inside fixed64 field.");
- }
- break;
- case GPBType::FIXED32:
- if (!GPBWire::readFixed32($input, $value)) {
- throw new GPBDecodeException(
- "Unexpected EOF inside fixed32 field.");
- }
- break;
- case GPBType::BOOL:
- if (!GPBWire::readBool($input, $value)) {
- throw new GPBDecodeException(
- "Unexpected EOF inside bool field.");
- }
- break;
- case GPBType::STRING:
- // TODO(teboring): Add utf-8 check.
- if (!GPBWire::readString($input, $value)) {
- throw new GPBDecodeException(
- "Unexpected EOF inside string field.");
- }
- break;
- case GPBType::GROUP:
- trigger_error("Not implemented.", E_ERROR);
- break;
- case GPBType::MESSAGE:
- if ($field->isMap()) {
- $value = new MapEntry($field->getMessageType());
- } else {
- $klass = $field->getMessageType()->getClass();
- $value = new $klass;
- }
- if (!GPBWire::readMessage($input, $value)) {
- throw new GPBDecodeException(
- "Unexpected EOF inside message.");
- }
- break;
- case GPBType::BYTES:
- if (!GPBWire::readString($input, $value)) {
- throw new GPBDecodeException(
- "Unexpected EOF inside bytes field.");
- }
- break;
- case GPBType::UINT32:
- if (!GPBWire::readUint32($input, $value)) {
- throw new GPBDecodeException(
- "Unexpected EOF inside uint32 field.");
- }
- break;
- case GPBType::ENUM:
- // TODO(teboring): Check unknown enum value.
- if (!GPBWire::readInt32($input, $value)) {
- throw new GPBDecodeException(
- "Unexpected EOF inside enum field.");
- }
- break;
- case GPBType::SFIXED32:
- if (!GPBWire::readSfixed32($input, $value)) {
- throw new GPBDecodeException(
- "Unexpected EOF inside sfixed32 field.");
- }
- break;
- case GPBType::SFIXED64:
- if (!GPBWire::readSfixed64($input, $value)) {
- throw new GPBDecodeException(
- "Unexpected EOF inside sfixed64 field.");
- }
- break;
- case GPBType::SINT32:
- if (!GPBWire::readSint32($input, $value)) {
- throw new GPBDecodeException(
- "Unexpected EOF inside sint32 field.");
- }
- break;
- case GPBType::SINT64:
- if (!GPBWire::readSint64($input, $value)) {
- throw new GPBDecodeException(
- "Unexpected EOF inside sint64 field.");
- }
- break;
- default:
- user_error("Unsupported type.");
- return false;
- }
- return true;
- }
- /**
- * @ignore
- */
- private function parseFieldFromStream($tag, $input, $field)
- {
- $value = null;
- if (is_null($field)) {
- $value_format = GPBWire::UNKNOWN;
- } elseif (GPBWire::getTagWireType($tag) ===
- GPBWire::getWireType($field->getType())) {
- $value_format = GPBWire::NORMAL_FORMAT;
- } elseif ($field->isPackable() &&
- GPBWire::getTagWireType($tag) ===
- GPBWire::WIRETYPE_LENGTH_DELIMITED) {
- $value_format = GPBWire::PACKED_FORMAT;
- } else {
- // the wire type doesn't match. Put it in our unknown field set.
- $value_format = GPBWire::UNKNOWN;
- }
- if ($value_format === GPBWire::UNKNOWN) {
- $this->skipField($input, $tag);
- return;
- } elseif ($value_format === GPBWire::NORMAL_FORMAT) {
- self::parseFieldFromStreamNoTag($input, $field, $value);
- } elseif ($value_format === GPBWire::PACKED_FORMAT) {
- $length = 0;
- if (!GPBWire::readInt32($input, $length)) {
- throw new GPBDecodeException(
- "Unexpected EOF inside packed length.");
- }
- $limit = $input->pushLimit($length);
- $getter = $field->getGetter();
- while ($input->bytesUntilLimit() > 0) {
- self::parseFieldFromStreamNoTag($input, $field, $value);
- $this->appendHelper($field, $value);
- }
- $input->popLimit($limit);
- return;
- } else {
- return;
- }
- if ($field->isMap()) {
- $this->kvUpdateHelper($field, $value->getKey(), $value->getValue());
- } else if ($field->isRepeated()) {
- $this->appendHelper($field, $value);
- } else {
- $setter = $field->getSetter();
- $this->$setter($value);
- }
- }
- /**
- * Clear all containing fields.
- * @return null.
- */
- public function clear()
- {
- $this->unknown = "";
- foreach ($this->desc->getField() as $field) {
- $setter = $field->getSetter();
- if ($field->isMap()) {
- $message_type = $field->getMessageType();
- $key_field = $message_type->getFieldByNumber(1);
- $value_field = $message_type->getFieldByNumber(2);
- switch ($value_field->getType()) {
- case GPBType::MESSAGE:
- case GPBType::GROUP:
- $map_field = new MapField(
- $key_field->getType(),
- $value_field->getType(),
- $value_field->getMessageType()->getClass());
- $this->$setter($map_field);
- break;
- case GPBType::ENUM:
- $map_field = new MapField(
- $key_field->getType(),
- $value_field->getType(),
- $value_field->getEnumType()->getClass());
- $this->$setter($map_field);
- break;
- default:
- $map_field = new MapField(
- $key_field->getType(),
- $value_field->getType());
- $this->$setter($map_field);
- break;
- }
- } else if ($field->getLabel() === GPBLabel::REPEATED) {
- switch ($field->getType()) {
- case GPBType::MESSAGE:
- case GPBType::GROUP:
- $repeated_field = new RepeatedField(
- $field->getType(),
- $field->getMessageType()->getClass());
- $this->$setter($repeated_field);
- break;
- case GPBType::ENUM:
- $repeated_field = new RepeatedField(
- $field->getType(),
- $field->getEnumType()->getClass());
- $this->$setter($repeated_field);
- break;
- default:
- $repeated_field = new RepeatedField($field->getType());
- $this->$setter($repeated_field);
- break;
- }
- } else if ($field->getOneofIndex() !== -1) {
- $oneof = $this->desc->getOneofDecl()[$field->getOneofIndex()];
- $oneof_name = $oneof->getName();
- $this->$oneof_name = new OneofField($oneof);
- } else if ($field->getLabel() === GPBLabel::OPTIONAL) {
- switch ($field->getType()) {
- case GPBType::DOUBLE :
- case GPBType::FLOAT :
- $this->$setter(0.0);
- break;
- case GPBType::INT32 :
- case GPBType::FIXED32 :
- case GPBType::UINT32 :
- case GPBType::SFIXED32 :
- case GPBType::SINT32 :
- case GPBType::ENUM :
- $this->$setter(0);
- break;
- case GPBType::BOOL :
- $this->$setter(false);
- break;
- case GPBType::STRING :
- case GPBType::BYTES :
- $this->$setter("");
- break;
- case GPBType::GROUP :
- case GPBType::MESSAGE :
- $null = null;
- $this->$setter($null);
- break;
- }
- if (PHP_INT_SIZE == 4) {
- switch ($field->getType()) {
- case GPBType::INT64:
- case GPBType::UINT64:
- case GPBType::FIXED64:
- case GPBType::SFIXED64:
- case GPBType::SINT64:
- $this->$setter("0");
- }
- } else {
- switch ($field->getType()) {
- case GPBType::INT64:
- case GPBType::UINT64:
- case GPBType::FIXED64:
- case GPBType::SFIXED64:
- case GPBType::SINT64:
- $this->$setter(0);
- }
- }
- }
- }
- }
- /**
- * Clear all unknown fields previously parsed.
- * @return null.
- */
- public function discardUnknownFields()
- {
- $this->unknown = "";
- foreach ($this->desc->getField() as $field) {
- if ($field->getType() != GPBType::MESSAGE) {
- continue;
- }
- if ($field->isMap()) {
- $value_field = $field->getMessageType()->getFieldByNumber(2);
- if ($value_field->getType() != GPBType::MESSAGE) {
- continue;
- }
- $getter = $field->getGetter();
- $map = $this->$getter();
- foreach ($map as $key => $value) {
- $value->discardUnknownFields();
- }
- } else if ($field->getLabel() === GPBLabel::REPEATED) {
- $getter = $field->getGetter();
- $arr = $this->$getter();
- foreach ($arr as $sub) {
- $sub->discardUnknownFields();
- }
- } else if ($field->getLabel() === GPBLabel::OPTIONAL) {
- $getter = $field->getGetter();
- $sub = $this->$getter();
- if (!is_null($sub)) {
- $sub->discardUnknownFields();
- }
- }
- }
- }
- /**
- * Merges the contents of the specified message into current message.
- *
- * This method merges the contents of the specified message into the
- * current message. Singular fields that are set in the specified message
- * overwrite the corresponding fields in the current message. Repeated
- * fields are appended. Map fields key-value pairs are overritten.
- * Singular/Oneof sub-messages are recursively merged. All overritten
- * sub-messages are deep-copied.
- *
- * @param object $msg Protobuf message to be merged from.
- * @return null.
- */
- public function mergeFrom($msg)
- {
- if (get_class($this) !== get_class($msg)) {
- user_error("Cannot merge messages with different class.");
- return;
- }
- foreach ($this->desc->getField() as $field) {
- $setter = $field->getSetter();
- $getter = $field->getGetter();
- if ($field->isMap()) {
- if (count($msg->$getter()) != 0) {
- $value_field = $field->getMessageType()->getFieldByNumber(2);
- foreach ($msg->$getter() as $key => $value) {
- if ($value_field->getType() == GPBType::MESSAGE) {
- $klass = $value_field->getMessageType()->getClass();
- $copy = new $klass;
- $copy->mergeFrom($value);
- $this->kvUpdateHelper($field, $key, $copy);
- } else {
- $this->kvUpdateHelper($field, $key, $value);
- }
- }
- }
- } else if ($field->getLabel() === GPBLabel::REPEATED) {
- if (count($msg->$getter()) != 0) {
- foreach ($msg->$getter() as $tmp) {
- if ($field->getType() == GPBType::MESSAGE) {
- $klass = $field->getMessageType()->getClass();
- $copy = new $klass;
- $copy->mergeFrom($tmp);
- $this->appendHelper($field, $copy);
- } else {
- $this->appendHelper($field, $tmp);
- }
- }
- }
- } else if ($field->getLabel() === GPBLabel::OPTIONAL) {
- if($msg->$getter() !== $this->defaultValue($field)) {
- $tmp = $msg->$getter();
- if ($field->getType() == GPBType::MESSAGE) {
- if (is_null($this->$getter())) {
- $klass = $field->getMessageType()->getClass();
- $new_msg = new $klass;
- $this->$setter($new_msg);
- }
- $this->$getter()->mergeFrom($tmp);
- } else {
- $this->$setter($tmp);
- }
- }
- }
- }
- }
- /**
- * Parses a protocol buffer contained in a string.
- *
- * This function takes a string in the (non-human-readable) binary wire
- * format, matching the encoding output by serializeToString().
- * See mergeFrom() for merging behavior, if the field is already set in the
- * specified message.
- *
- * @param string $data Binary protobuf data.
- * @return null.
- * @throws Exception Invalid data.
- */
- public function mergeFromString($data)
- {
- $input = new CodedInputStream($data);
- $this->parseFromStream($input);
- }
- /**
- * Parses a json string to protobuf message.
- *
- * This function takes a string in the json wire format, matching the
- * encoding output by serializeToJsonString().
- * See mergeFrom() for merging behavior, if the field is already set in the
- * specified message.
- *
- * @param string $data Json protobuf data.
- * @return null.
- * @throws Exception Invalid data.
- */
- public function mergeFromJsonString($data)
- {
- $input = new RawInputStream($data);
- $this->parseFromJsonStream($input);
- }
- /**
- * @ignore
- */
- public function parseFromStream($input)
- {
- while (true) {
- $tag = $input->readTag();
- // End of input. This is a valid place to end, so return true.
- if ($tag === 0) {
- return true;
- }
- $number = GPBWire::getTagFieldNumber($tag);
- $field = $this->desc->getFieldByNumber($number);
- $this->parseFieldFromStream($tag, $input, $field);
- }
- }
- private function convertJsonValueToProtoValue(
- $value,
- $field,
- $is_map_key = false)
- {
- switch ($field->getType()) {
- case GPBType::MESSAGE:
- $klass = $field->getMessageType()->getClass();
- $submsg = new $klass;
- if (is_a($submsg, "Google\Protobuf\Duration")) {
- if (is_null($value)) {
- return $this->defaultValue($field);
- } else if (!is_string($value)) {
- throw new GPBDecodeException("Expect string.");
- }
- return GPBUtil::parseDuration($value);
- } else if ($field->isTimestamp()) {
- if (is_null($value)) {
- return $this->defaultValue($field);
- } else if (!is_string($value)) {
- throw new GPBDecodeException("Expect string.");
- }
- try {
- $timestamp = GPBUtil::parseTimestamp($value);
- } catch (\Exception $e) {
- throw new GPBDecodeException(
- "Invalid RFC 3339 timestamp: ".$e->getMessage());
- }
- $submsg->setSeconds($timestamp->getSeconds());
- $submsg->setNanos($timestamp->getNanos());
- } else if (is_a($submsg, "Google\Protobuf\FieldMask")) {
- if (is_null($value)) {
- return $this->defaultValue($field);
- }
- try {
- return GPBUtil::parseFieldMask($value);
- } catch (\Exception $e) {
- throw new GPBDecodeException(
- "Invalid FieldMask: ".$e->getMessage());
- }
- } else {
- if (is_null($value) &&
- !is_a($submsg, "Google\Protobuf\Value")) {
- return $this->defaultValue($field);
- }
- if (GPBUtil::hasSpecialJsonMapping($submsg)) {
- } elseif (!is_object($value) && !is_array($value)) {
- throw new GPBDecodeException("Expect message.");
- }
- $submsg->mergeFromJsonArray($value);
- }
- return $submsg;
- case GPBType::ENUM:
- if (is_null($value)) {
- return $this->defaultValue($field);
- }
- if (is_integer($value)) {
- return $value;
- }
- $enum_value = $field->getEnumType()->getValueByName($value);
- if (!is_null($enum_value)) {
- return $enum_value->getNumber();
- }
- throw new GPBDecodeException(
- "Enum field only accepts integer or enum value name");
- case GPBType::STRING:
- if (is_null($value)) {
- return $this->defaultValue($field);
- }
- if (!is_string($value)) {
- throw new GPBDecodeException(
- "String field only accepts string value");
- }
- return $value;
- case GPBType::BYTES:
- if (is_null($value)) {
- return $this->defaultValue($field);
- }
- if (!is_string($value)) {
- throw new GPBDecodeException(
- "Byte field only accepts string value");
- }
- $proto_value = base64_decode($value, true);
- if ($proto_value === false) {
- throw new GPBDecodeException("Invalid base64 characters");
- }
- return $proto_value;
- case GPBType::BOOL:
- if (is_null($value)) {
- return $this->defaultValue($field);
- }
- if ($is_map_key) {
- if ($value === "true") {
- return true;
- }
- if ($value === "false") {
- return false;
- }
- throw new GPBDecodeException(
- "Bool field only accepts bool value");
- }
- if (!is_bool($value)) {
- throw new GPBDecodeException(
- "Bool field only accepts bool value");
- }
- return $value;
- case GPBType::FLOAT:
- case GPBType::DOUBLE:
- if (is_null($value)) {
- return $this->defaultValue($field);
- }
- if ($value === "Infinity") {
- return INF;
- }
- if ($value === "-Infinity") {
- return -INF;
- }
- if ($value === "NaN") {
- return NAN;
- }
- return $value;
- case GPBType::INT32:
- case GPBType::SINT32:
- case GPBType::SFIXED32:
- if (is_null($value)) {
- return $this->defaultValue($field);
- }
- if (!is_numeric($value)) {
- throw new GPBDecodeException(
- "Invalid data type for int32 field");
- }
- if (bccomp($value, "2147483647") > 0) {
- throw new GPBDecodeException(
- "Int32 too large");
- }
- if (bccomp($value, "-2147483648") < 0) {
- throw new GPBDecodeException(
- "Int32 too small");
- }
- return $value;
- case GPBType::UINT32:
- case GPBType::FIXED32:
- if (is_null($value)) {
- return $this->defaultValue($field);
- }
- if (!is_numeric($value)) {
- throw new GPBDecodeException(
- "Invalid data type for uint32 field");
- }
- if (bccomp($value, 4294967295) > 0) {
- throw new GPBDecodeException(
- "Uint32 too large");
- }
- return $value;
- case GPBType::INT64:
- case GPBType::SINT64:
- case GPBType::SFIXED64:
- if (is_null($value)) {
- return $this->defaultValue($field);
- }
- if (!is_numeric($value)) {
- throw new GPBDecodeException(
- "Invalid data type for int64 field");
- }
- if (bccomp($value, "9223372036854775807") > 0) {
- throw new GPBDecodeException(
- "Int64 too large");
- }
- if (bccomp($value, "-9223372036854775808") < 0) {
- throw new GPBDecodeException(
- "Int64 too small");
- }
- return $value;
- case GPBType::UINT64:
- case GPBType::FIXED64:
- if (is_null($value)) {
- return $this->defaultValue($field);
- }
- if (!is_numeric($value)) {
- throw new GPBDecodeException(
- "Invalid data type for int64 field");
- }
- if (bccomp($value, "18446744073709551615") > 0) {
- throw new GPBDecodeException(
- "Uint64 too large");
- }
- if (bccomp($value, "9223372036854775807") > 0) {
- $value = bcsub($value, "18446744073709551616");
- }
- return $value;
- default:
- return $value;
- }
- }
- /**
- * Populates the message from a user-supplied PHP array. Array keys
- * correspond to Message properties and nested message properties.
- *
- * Example:
- * ```
- * $message->mergeFromArray([
- * 'name' => 'This is a message name',
- * 'interval' => [
- * 'startTime' => time() - 60,
- * 'endTime' => time(),
- * ]
- * ]);
- * ```
- *
- * @param array $array An array containing message properties and values.
- * @return null.
- * @throws \Exception Invalid data.
- */
- protected function mergeFromArray(array $array)
- {
- // Just call the setters for the field names
- foreach ($array as $key => $value) {
- $field = $this->desc->getFieldByName($key);
- if (is_null($field)) {
- throw new \UnexpectedValueException(
- 'Invalid message property: ' . $key);
- }
- $setter = $field->getSetter();
- if ($field->isWrapperType()) {
- self::normalizeToMessageType($value, $field->getMessageType()->getClass());
- }
- $this->$setter($value);
- }
- }
- /**
- * Tries to normalize $value into a provided protobuf wrapper type $class.
- * If $value is any type other than an object, we attempt to construct an
- * instance of $class and assign $value to it using the setValue method
- * shared by all wrapper types.
- *
- * @param mixed $value The value to normalize.
- * @param string $class The expected wrapper class name
- * @throws \Exception If $value cannot be converted to a wrapper type
- */
- private static function normalizeToMessageType(&$value, $class)
- {
- if (is_null($value) || is_object($value)) {
- // This handles the case that $value is an instance of $class. We
- // choose not to do any more strict checking here, relying on the
- // existing type checking done by GPBUtil.
- return;
- } else {
- // Try to instantiate $class and set the value
- try {
- $msg = new $class;
- $msg->setValue($value);
- $value = $msg;
- return;
- } catch (\Exception $exception) {
- throw new \Exception(
- "Error normalizing value to type '$class': " . $exception->getMessage(),
- $exception->getCode(),
- $exception
- );
- }
- }
- }
- protected function mergeFromJsonArray($array)
- {
- if (is_a($this, "Google\Protobuf\Any")) {
- $this->clear();
- $this->setTypeUrl($array["@type"]);
- $msg = $this->unpack();
- if (GPBUtil::hasSpecialJsonMapping($msg)) {
- $msg->mergeFromJsonArray($array["value"]);
- } else {
- unset($array["@type"]);
- $msg->mergeFromJsonArray($array);
- }
- $this->setValue($msg->serializeToString());
- return;
- }
- if (is_a($this, "Google\Protobuf\DoubleValue") ||
- is_a($this, "Google\Protobuf\FloatValue") ||
- is_a($this, "Google\Protobuf\Int64Value") ||
- is_a($this, "Google\Protobuf\UInt64Value") ||
- is_a($this, "Google\Protobuf\Int32Value") ||
- is_a($this, "Google\Protobuf\UInt32Value") ||
- is_a($this, "Google\Protobuf\BoolValue") ||
- is_a($this, "Google\Protobuf\StringValue")) {
- $this->setValue($array);
- return;
- }
- if (is_a($this, "Google\Protobuf\BytesValue")) {
- $this->setValue(base64_decode($array));
- return;
- }
- if (is_a($this, "Google\Protobuf\Duration")) {
- $this->mergeFrom(GPBUtil::parseDuration($array));
- return;
- }
- if (is_a($this, "Google\Protobuf\FieldMask")) {
- $this->mergeFrom(GPBUtil::parseFieldMask($array));
- return;
- }
- if (is_a($this, "Google\Protobuf\Timestamp")) {
- $this->mergeFrom(GPBUtil::parseTimestamp($array));
- return;
- }
- if (is_a($this, "Google\Protobuf\Struct")) {
- $fields = $this->getFields();
- foreach($array as $key => $value) {
- $v = new Value();
- $v->mergeFromJsonArray($value);
- $fields[$key] = $v;
- }
- }
- if (is_a($this, "Google\Protobuf\Value")) {
- if (is_bool($array)) {
- $this->setBoolValue($array);
- } elseif (is_string($array)) {
- $this->setStringValue($array);
- } elseif (is_null($array)) {
- $this->setNullValue(0);
- } elseif (is_double($array) || is_integer($array)) {
- $this->setNumberValue($array);
- } elseif (is_array($array)) {
- if (array_values($array) !== $array) {
- // Associative array
- $struct_value = $this->getStructValue();
- if (is_null($struct_value)) {
- $struct_value = new Struct();
- $this->setStructValue($struct_value);
- }
- foreach ($array as $key => $v) {
- $value = new Value();
- $value->mergeFromJsonArray($v);
- $values = $struct_value->getFields();
- $values[$key]= $value;
- }
- } else {
- // Array
- $list_value = $this->getListValue();
- if (is_null($list_value)) {
- $list_value = new ListValue();
- $this->setListValue($list_value);
- }
- foreach ($array as $v) {
- $value = new Value();
- $value->mergeFromJsonArray($v);
- $values = $list_value->getValues();
- $values[]= $value;
- }
- }
- } else {
- throw new GPBDecodeException("Invalid type for Value.");
- }
- return;
- }
- $this->mergeFromArrayJsonImpl($array);
- }
- private function mergeFromArrayJsonImpl($array)
- {
- foreach ($array as $key => $value) {
- $field = $this->desc->getFieldByJsonName($key);
- if (is_null($field)) {
- $field = $this->desc->getFieldByName($key);
- if (is_null($field)) {
- continue;
- }
- }
- if ($field->isMap()) {
- if (is_null($value)) {
- continue;
- }
- $key_field = $field->getMessageType()->getFieldByNumber(1);
- $value_field = $field->getMessageType()->getFieldByNumber(2);
- foreach ($value as $tmp_key => $tmp_value) {
- if (is_null($tmp_value)) {
- throw new \Exception(
- "Map value field element cannot be null.");
- }
- $proto_key = $this->convertJsonValueToProtoValue(
- $tmp_key,
- $key_field,
- true);
- $proto_value = $this->convertJsonValueToProtoValue(
- $tmp_value,
- $value_field);
- self::kvUpdateHelper($field, $proto_key, $proto_value);
- }
- } else if ($field->isRepeated()) {
- if (is_null($value)) {
- continue;
- }
- foreach ($value as $tmp) {
- if (is_null($tmp)) {
- throw new \Exception(
- "Repeated field elements cannot be null.");
- }
- $proto_value = $this->convertJsonValueToProtoValue(
- $tmp,
- $field);
- self::appendHelper($field, $proto_value);
- }
- } else {
- $setter = $field->getSetter();
- $proto_value = $this->convertJsonValueToProtoValue(
- $value,
- $field);
- if ($field->getType() === GPBType::MESSAGE) {
- if (is_null($proto_value)) {
- continue;
- }
- $getter = $field->getGetter();
- $submsg = $this->$getter();
- if (!is_null($submsg)) {
- $submsg->mergeFrom($proto_value);
- continue;
- }
- }
- $this->$setter($proto_value);
- }
- }
- }
- /**
- * @ignore
- */
- public function parseFromJsonStream($input)
- {
- $array = json_decode($input->getData(), true, 512, JSON_BIGINT_AS_STRING);
- if ($this instanceof \Google\Protobuf\ListValue) {
- $array = ["values"=>$array];
- }
- if (is_null($array)) {
- if ($this instanceof \Google\Protobuf\Value) {
- $this->setNullValue(\Google\Protobuf\NullValue::NULL_VALUE);
- return;
- } else {
- throw new GPBDecodeException(
- "Cannot decode json string: " . $input->getData());
- }
- }
- try {
- $this->mergeFromJsonArray($array);
- } catch (\Exception $e) {
- throw new GPBDecodeException($e->getMessage());
- }
- }
- /**
- * @ignore
- */
- private function serializeSingularFieldToStream($field, &$output)
- {
- if (!$this->existField($field)) {
- return true;
- }
- $getter = $field->getGetter();
- $value = $this->$getter();
- if (!GPBWire::serializeFieldToStream($value, $field, true, $output)) {
- return false;
- }
- return true;
- }
- /**
- * @ignore
- */
- private function serializeRepeatedFieldToStream($field, &$output)
- {
- $getter = $field->getGetter();
- $values = $this->$getter();
- $count = count($values);
- if ($count === 0) {
- return true;
- }
- $packed = $field->getPacked();
- if ($packed) {
- if (!GPBWire::writeTag(
- $output,
- GPBWire::makeTag($field->getNumber(), GPBType::STRING))) {
- return false;
- }
- $size = 0;
- foreach ($values as $value) {
- $size += $this->fieldDataOnlyByteSize($field, $value);
- }
- if (!$output->writeVarint32($size, true)) {
- return false;
- }
- }
- foreach ($values as $value) {
- if (!GPBWire::serializeFieldToStream(
- $value,
- $field,
- !$packed,
- $output)) {
- return false;
- }
- }
- return true;
- }
- /**
- * @ignore
- */
- private function serializeMapFieldToStream($field, $output)
- {
- $getter = $field->getGetter();
- $values = $this->$getter();
- $count = count($values);
- if ($count === 0) {
- return true;
- }
- foreach ($values as $key => $value) {
- $map_entry = new MapEntry($field->getMessageType());
- $map_entry->setKey($key);
- $map_entry->setValue($value);
- if (!GPBWire::serializeFieldToStream(
- $map_entry,
- $field,
- true,
- $output)) {
- return false;
- }
- }
- return true;
- }
- /**
- * @ignore
- */
- private function serializeFieldToStream(&$output, $field)
- {
- if ($field->isMap()) {
- return $this->serializeMapFieldToStream($field, $output);
- } elseif ($field->isRepeated()) {
- return $this->serializeRepeatedFieldToStream($field, $output);
- } else {
- return $this->serializeSingularFieldToStream($field, $output);
- }
- }
- /**
- * @ignore
- */
- private function serializeFieldToJsonStream(&$output, $field)
- {
- $getter = $field->getGetter();
- $values = $this->$getter();
- return GPBJsonWire::serializeFieldToStream(
- $values, $field, $output, !GPBUtil::hasSpecialJsonMapping($this));
- }
- /**
- * @ignore
- */
- public function serializeToStream(&$output)
- {
- $fields = $this->desc->getField();
- foreach ($fields as $field) {
- if (!$this->serializeFieldToStream($output, $field)) {
- return false;
- }
- }
- $output->writeRaw($this->unknown, strlen($this->unknown));
- return true;
- }
- /**
- * @ignore
- */
- public function serializeToJsonStream(&$output)
- {
- if (is_a($this, 'Google\Protobuf\Any')) {
- $output->writeRaw("{", 1);
- $type_field = $this->desc->getFieldByNumber(1);
- $value_msg = $this->unpack();
- // Serialize type url.
- $output->writeRaw("\"@type\":", 8);
- $output->writeRaw("\"", 1);
- $output->writeRaw($this->getTypeUrl(), strlen($this->getTypeUrl()));
- $output->writeRaw("\"", 1);
- // Serialize value
- if (GPBUtil::hasSpecialJsonMapping($value_msg)) {
- $output->writeRaw(",\"value\":", 9);
- $value_msg->serializeToJsonStream($output);
- } else {
- $value_fields = $value_msg->desc->getField();
- foreach ($value_fields as $field) {
- if ($value_msg->existField($field)) {
- $output->writeRaw(",", 1);
- if (!$value_msg->serializeFieldToJsonStream($output, $field)) {
- return false;
- }
- }
- }
- }
- $output->writeRaw("}", 1);
- } elseif (is_a($this, 'Google\Protobuf\FieldMask')) {
- $field_mask = GPBUtil::formatFieldMask($this);
- $output->writeRaw("\"", 1);
- $output->writeRaw($field_mask, strlen($field_mask));
- $output->writeRaw("\"", 1);
- } elseif (is_a($this, 'Google\Protobuf\Duration')) {
- $duration = GPBUtil::formatDuration($this) . "s";
- $output->writeRaw("\"", 1);
- $output->writeRaw($duration, strlen($duration));
- $output->writeRaw("\"", 1);
- } elseif (get_class($this) === 'Google\Protobuf\Timestamp') {
- $timestamp = GPBUtil::formatTimestamp($this);
- $timestamp = json_encode($timestamp);
- $output->writeRaw($timestamp, strlen($timestamp));
- } elseif (get_class($this) === 'Google\Protobuf\ListValue') {
- $field = $this->desc->getField()[1];
- if (!$this->existField($field)) {
- $output->writeRaw("[]", 2);
- } else {
- if (!$this->serializeFieldToJsonStream($output, $field)) {
- return false;
- }
- }
- } elseif (get_class($this) === 'Google\Protobuf\Struct') {
- $field = $this->desc->getField()[1];
- if (!$this->existField($field)) {
- $output->writeRaw("{}", 2);
- } else {
- if (!$this->serializeFieldToJsonStream($output, $field)) {
- return false;
- }
- }
- } else {
- if (!GPBUtil::hasSpecialJsonMapping($this)) {
- $output->writeRaw("{", 1);
- }
- $fields = $this->desc->getField();
- $first = true;
- foreach ($fields as $field) {
- if ($this->existField($field) ||
- GPBUtil::hasJsonValue($this)) {
- if ($first) {
- $first = false;
- } else {
- $output->writeRaw(",", 1);
- }
- if (!$this->serializeFieldToJsonStream($output, $field)) {
- return false;
- }
- }
- }
- if (!GPBUtil::hasSpecialJsonMapping($this)) {
- $output->writeRaw("}", 1);
- }
- }
- return true;
- }
- /**
- * Serialize the message to string.
- * @return string Serialized binary protobuf data.
- */
- public function serializeToString()
- {
- $output = new CodedOutputStream($this->byteSize());
- $this->serializeToStream($output);
- return $output->getData();
- }
- /**
- * Serialize the message to json string.
- * @return string Serialized json protobuf data.
- */
- public function serializeToJsonString()
- {
- $output = new CodedOutputStream($this->jsonByteSize());
- $this->serializeToJsonStream($output);
- return $output->getData();
- }
- /**
- * @ignore
- */
- private function existField($field)
- {
- $oneof_index = $field->getOneofIndex();
- if ($oneof_index !== -1) {
- $oneof = $this->desc->getOneofDecl()[$oneof_index];
- $oneof_name = $oneof->getName();
- return $this->$oneof_name->getNumber() === $field->getNumber();
- }
- $getter = $field->getGetter();
- $values = $this->$getter();
- if ($field->isMap()) {
- return count($values) !== 0;
- } elseif ($field->isRepeated()) {
- return count($values) !== 0;
- } else {
- return $values !== $this->defaultValue($field);
- }
- }
- /**
- * @ignore
- */
- private function repeatedFieldDataOnlyByteSize($field)
- {
- $size = 0;
- $getter = $field->getGetter();
- $values = $this->$getter();
- $count = count($values);
- if ($count !== 0) {
- $size += $count * GPBWire::tagSize($field);
- foreach ($values as $value) {
- $size += $this->singularFieldDataOnlyByteSize($field);
- }
- }
- }
- /**
- * @ignore
- */
- private function fieldDataOnlyByteSize($field, $value)
- {
- $size = 0;
- switch ($field->getType()) {
- case GPBType::BOOL:
- $size += 1;
- break;
- case GPBType::FLOAT:
- case GPBType::FIXED32:
- case GPBType::SFIXED32:
- $size += 4;
- break;
- case GPBType::DOUBLE:
- case GPBType::FIXED64:
- case GPBType::SFIXED64:
- $size += 8;
- break;
- case GPBType::INT32:
- case GPBType::ENUM:
- $size += GPBWire::varint32Size($value, true);
- break;
- case GPBType::UINT32:
- $size += GPBWire::varint32Size($value);
- break;
- case GPBType::UINT64:
- case GPBType::INT64:
- $size += GPBWire::varint64Size($value);
- break;
- case GPBType::SINT32:
- $size += GPBWire::sint32Size($value);
- break;
- case GPBType::SINT64:
- $size += GPBWire::sint64Size($value);
- break;
- case GPBType::STRING:
- case GPBType::BYTES:
- $size += strlen($value);
- $size += GPBWire::varint32Size($size);
- break;
- case GPBType::MESSAGE:
- $size += $value->byteSize();
- $size += GPBWire::varint32Size($size);
- break;
- case GPBType::GROUP:
- // TODO(teboring): Add support.
- user_error("Unsupported type.");
- break;
- default:
- user_error("Unsupported type.");
- return 0;
- }
- return $size;
- }
- /**
- * @ignore
- */
- private function fieldDataOnlyJsonByteSize($field, $value)
- {
- $size = 0;
- switch ($field->getType()) {
- case GPBType::SFIXED32:
- case GPBType::SINT32:
- case GPBType::INT32:
- $size += strlen(strval($value));
- break;
- case GPBType::FIXED32:
- case GPBType::UINT32:
- if ($value < 0) {
- $value = bcadd($value, "4294967296");
- }
- $size += strlen(strval($value));
- break;
- case GPBType::FIXED64:
- case GPBType::UINT64:
- if ($value < 0) {
- $value = bcadd($value, "18446744073709551616");
- }
- // Intentional fall through.
- case GPBType::SFIXED64:
- case GPBType::INT64:
- case GPBType::SINT64:
- $size += 2; // size for ""
- $size += strlen(strval($value));
- break;
- case GPBType::FLOAT:
- if (is_nan($value)) {
- $size += strlen("NaN") + 2;
- } elseif ($value === INF) {
- $size += strlen("Infinity") + 2;
- } elseif ($value === -INF) {
- $size += strlen("-Infinity") + 2;
- } else {
- $size += strlen(sprintf("%.8g", $value));
- }
- break;
- case GPBType::DOUBLE:
- if (is_nan($value)) {
- $size += strlen("NaN") + 2;
- } elseif ($value === INF) {
- $size += strlen("Infinity") + 2;
- } elseif ($value === -INF) {
- $size += strlen("-Infinity") + 2;
- } else {
- $size += strlen(sprintf("%.17g", $value));
- }
- break;
- case GPBType::ENUM:
- $enum_desc = $field->getEnumType();
- if ($enum_desc->getClass() === "Google\Protobuf\NullValue") {
- $size += 4;
- break;
- }
- $enum_value_desc = $enum_desc->getValueByNumber($value);
- if (!is_null($enum_value_desc)) {
- $size += 2; // size for ""
- $size += strlen($enum_value_desc->getName());
- } else {
- $str_value = strval($value);
- $size += strlen($str_value);
- }
- break;
- case GPBType::BOOL:
- if ($value) {
- $size += 4;
- } else {
- $size += 5;
- }
- break;
- case GPBType::STRING:
- $value = json_encode($value, JSON_UNESCAPED_UNICODE);
- $size += strlen($value);
- break;
- case GPBType::BYTES:
- # if (is_a($this, "Google\Protobuf\BytesValue")) {
- # $size += strlen(json_encode($value));
- # } else {
- # $size += strlen(base64_encode($value));
- # $size += 2; // size for \"\"
- # }
- $size += strlen(base64_encode($value));
- $size += 2; // size for \"\"
- break;
- case GPBType::MESSAGE:
- $size += $value->jsonByteSize();
- break;
- # case GPBType::GROUP:
- # // TODO(teboring): Add support.
- # user_error("Unsupported type.");
- # break;
- default:
- user_error("Unsupported type " . $field->getType());
- return 0;
- }
- return $size;
- }
- /**
- * @ignore
- */
- private function fieldByteSize($field)
- {
- $size = 0;
- if ($field->isMap()) {
- $getter = $field->getGetter();
- $values = $this->$getter();
- $count = count($values);
- if ($count !== 0) {
- $size += $count * GPBWire::tagSize($field);
- $message_type = $field->getMessageType();
- $key_field = $message_type->getFieldByNumber(1);
- $value_field = $message_type->getFieldByNumber(2);
- foreach ($values as $key => $value) {
- $data_size = 0;
- if ($key != $this->defaultValue($key_field)) {
- $data_size += $this->fieldDataOnlyByteSize(
- $key_field,
- $key);
- $data_size += GPBWire::tagSize($key_field);
- }
- if ($value != $this->defaultValue($value_field)) {
- $data_size += $this->fieldDataOnlyByteSize(
- $value_field,
- $value);
- $data_size += GPBWire::tagSize($value_field);
- }
- $size += GPBWire::varint32Size($data_size) + $data_size;
- }
- }
- } elseif ($field->isRepeated()) {
- $getter = $field->getGetter();
- $values = $this->$getter();
- $count = count($values);
- if ($count !== 0) {
- if ($field->getPacked()) {
- $data_size = 0;
- foreach ($values as $value) {
- $data_size += $this->fieldDataOnlyByteSize($field, $value);
- }
- $size += GPBWire::tagSize($field);
- $size += GPBWire::varint32Size($data_size);
- $size += $data_size;
- } else {
- $size += $count * GPBWire::tagSize($field);
- foreach ($values as $value) {
- $size += $this->fieldDataOnlyByteSize($field, $value);
- }
- }
- }
- } elseif ($this->existField($field)) {
- $size += GPBWire::tagSize($field);
- $getter = $field->getGetter();
- $value = $this->$getter();
- $size += $this->fieldDataOnlyByteSize($field, $value);
- }
- return $size;
- }
- /**
- * @ignore
- */
- private function fieldJsonByteSize($field)
- {
- $size = 0;
- if ($field->isMap()) {
- $getter = $field->getGetter();
- $values = $this->$getter();
- $count = count($values);
- if ($count !== 0) {
- if (!GPBUtil::hasSpecialJsonMapping($this)) {
- $size += 3; // size for "\"\":".
- $size += strlen($field->getJsonName()); // size for field name
- }
- $size += 2; // size for "{}".
- $size += $count - 1; // size for commas
- $getter = $field->getGetter();
- $map_entry = $field->getMessageType();
- $key_field = $map_entry->getFieldByNumber(1);
- $value_field = $map_entry->getFieldByNumber(2);
- switch ($key_field->getType()) {
- case GPBType::STRING:
- case GPBType::SFIXED64:
- case GPBType::INT64:
- case GPBType::SINT64:
- case GPBType::FIXED64:
- case GPBType::UINT64:
- $additional_quote = false;
- break;
- default:
- $additional_quote = true;
- }
- foreach ($values as $key => $value) {
- if ($additional_quote) {
- $size += 2; // size for ""
- }
- $size += $this->fieldDataOnlyJsonByteSize($key_field, $key);
- $size += $this->fieldDataOnlyJsonByteSize($value_field, $value);
- $size += 1; // size for :
- }
- }
- } elseif ($field->isRepeated()) {
- $getter = $field->getGetter();
- $values = $this->$getter();
- $count = count($values);
- if ($count !== 0) {
- if (!GPBUtil::hasSpecialJsonMapping($this)) {
- $size += 3; // size for "\"\":".
- $size += strlen($field->getJsonName()); // size for field name
- }
- $size += 2; // size for "[]".
- $size += $count - 1; // size for commas
- $getter = $field->getGetter();
- foreach ($values as $value) {
- $size += $this->fieldDataOnlyJsonByteSize($field, $value);
- }
- }
- } elseif ($this->existField($field) || GPBUtil::hasJsonValue($this)) {
- if (!GPBUtil::hasSpecialJsonMapping($this)) {
- $size += 3; // size for "\"\":".
- $size += strlen($field->getJsonName()); // size for field name
- }
- $getter = $field->getGetter();
- $value = $this->$getter();
- $size += $this->fieldDataOnlyJsonByteSize($field, $value);
- }
- return $size;
- }
- /**
- * @ignore
- */
- public function byteSize()
- {
- $size = 0;
- $fields = $this->desc->getField();
- foreach ($fields as $field) {
- $size += $this->fieldByteSize($field);
- }
- $size += strlen($this->unknown);
- return $size;
- }
- private function appendHelper($field, $append_value)
- {
- $getter = $field->getGetter();
- $setter = $field->getSetter();
- $field_arr_value = $this->$getter();
- $field_arr_value[] = $append_value;
- if (!is_object($field_arr_value)) {
- $this->$setter($field_arr_value);
- }
- }
- private function kvUpdateHelper($field, $update_key, $update_value)
- {
- $getter = $field->getGetter();
- $setter = $field->getSetter();
- $field_arr_value = $this->$getter();
- $field_arr_value[$update_key] = $update_value;
- if (!is_object($field_arr_value)) {
- $this->$setter($field_arr_value);
- }
- }
- /**
- * @ignore
- */
- public function jsonByteSize()
- {
- $size = 0;
- if (is_a($this, 'Google\Protobuf\Any')) {
- // Size for "{}".
- $size += 2;
- // Size for "\"@type\":".
- $size += 8;
- // Size for url. +2 for "" /.
- $size += strlen($this->getTypeUrl()) + 2;
- $value_msg = $this->unpack();
- if (GPBUtil::hasSpecialJsonMapping($value_msg)) {
- // Size for "\",value\":".
- $size += 9;
- $size += $value_msg->jsonByteSize();
- } else {
- // Size for value. +1 for comma, -2 for "{}".
- $size += $value_msg->jsonByteSize() -1;
- }
- } elseif (get_class($this) === 'Google\Protobuf\FieldMask') {
- $field_mask = GPBUtil::formatFieldMask($this);
- $size += strlen($field_mask) + 2; // 2 for ""
- } elseif (get_class($this) === 'Google\Protobuf\Duration') {
- $duration = GPBUtil::formatDuration($this) . "s";
- $size += strlen($duration) + 2; // 2 for ""
- } elseif (get_class($this) === 'Google\Protobuf\Timestamp') {
- $timestamp = GPBUtil::formatTimestamp($this);
- $timestamp = json_encode($timestamp);
- $size += strlen($timestamp);
- } elseif (get_class($this) === 'Google\Protobuf\ListValue') {
- $field = $this->desc->getField()[1];
- if ($this->existField($field)) {
- $field_size = $this->fieldJsonByteSize($field);
- $size += $field_size;
- } else {
- // Size for "[]".
- $size += 2;
- }
- } elseif (get_class($this) === 'Google\Protobuf\Struct') {
- $field = $this->desc->getField()[1];
- if ($this->existField($field)) {
- $field_size = $this->fieldJsonByteSize($field);
- $size += $field_size;
- } else {
- // Size for "{}".
- $size += 2;
- }
- } else {
- if (!GPBUtil::hasSpecialJsonMapping($this)) {
- // Size for "{}".
- $size += 2;
- }
- $fields = $this->desc->getField();
- $count = 0;
- foreach ($fields as $field) {
- $field_size = $this->fieldJsonByteSize($field);
- $size += $field_size;
- if ($field_size != 0) {
- $count++;
- }
- }
- // size for comma
- $size += $count > 0 ? ($count - 1) : 0;
- }
- return $size;
- }
- }
|