Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(529)

Side by Side Diff: third_party/protobuf/php/src/Google/Protobuf/Internal/Message.php

Issue 2495533002: third_party/protobuf: Update to HEAD (83d681ee2c) (Closed)
Patch Set: Make chrome settings proto generated file a component Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 <?php
2
3 // Protocol Buffers - Google's data interchange format
4 // Copyright 2008 Google Inc. All rights reserved.
5 // https://developers.google.com/protocol-buffers/
6 //
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions are
9 // met:
10 //
11 // * Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
13 // * Redistributions in binary form must reproduce the above
14 // copyright notice, this list of conditions and the following disclaimer
15 // in the documentation and/or other materials provided with the
16 // distribution.
17 // * Neither the name of Google Inc. nor the names of its
18 // contributors may be used to endorse or promote products derived from
19 // this software without specific prior written permission.
20 //
21 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
33 /**
34 * Defines Message, the parent class extended by all protocol message classes.
35 */
36
37 namespace Google\Protobuf\Internal;
38
39 use Google\Protobuf\Internal\InputStream;
40 use Google\Protobuf\Internal\OutputStream;
41 use Google\Protobuf\Internal\DescriptorPool;
42 use Google\Protobuf\Internal\GPBLabel;
43 use Google\Protobuf\Internal\GPBType;
44 use Google\Protobuf\Internal\GPBWire;
45 use Google\Protobuf\Internal\MapEntry;
46 use Google\Protobuf\Internal\RepeatedField;
47
48 /**
49 * Parent class of all proto messages. Users should not instantiate this class
50 * or extend this class or its child classes by their own. See the comment of
51 * specific functions for more details.
52 */
53 class Message
54 {
55
56 /**
57 * @ignore
58 */
59 private $desc;
60
61 /**
62 * @ignore
63 */
64 public function __construct($desc = NULL)
65 {
66 // MapEntry message is shared by all types of map fields, whose
67 // descriptors are different from each other. Thus, we cannot find a
68 // specific descriptor from the descriptor pool.
69 if (get_class($this) === 'Google\Protobuf\Internal\MapEntry') {
70 $this->desc = $desc;
71 return;
72 }
73 $pool = DescriptorPool::getGeneratedPool();
74 $this->desc = $pool->getDescriptorByClassName(get_class($this));
75 foreach ($this->desc->getField() as $field) {
76 $setter = $field->getSetter();
77 if ($field->isMap()) {
78 $message_type = $field->getMessageType();
79 $key_field = $message_type->getFieldByNumber(1);
80 $value_field = $message_type->getFieldByNumber(2);
81 switch ($value_field->getType()) {
82 case GPBType::MESSAGE:
83 case GPBType::GROUP:
84 $map_field = new MapField(
85 $key_field->getType(),
86 $value_field->getType(),
87 $value_field->getMessageType()->getClass());
88 $this->$setter($map_field);
89 break;
90 case GPBType::ENUM:
91 $map_field = new MapField(
92 $key_field->getType(),
93 $value_field->getType(),
94 $value_field->getEnumType()->getClass());
95 $this->$setter($map_field);
96 break;
97 default:
98 $map_field = new MapField(
99 $key_field->getType(),
100 $value_field->getType());
101 $this->$setter($map_field);
102 break;
103 }
104 } else if ($field->getLabel() === GPBLabel::REPEATED) {
105 switch ($field->getType()) {
106 case GPBType::MESSAGE:
107 case GPBType::GROUP:
108 $repeated_field = new RepeatedField(
109 $field->getType(),
110 $field->getMessageType()->getClass());
111 $this->$setter($repeated_field);
112 break;
113 case GPBType::ENUM:
114 $repeated_field = new RepeatedField(
115 $field->getType(),
116 $field->getEnumType()->getClass());
117 $this->$setter($repeated_field);
118 break;
119 default:
120 $repeated_field = new RepeatedField($field->getType());
121 $this->$setter($repeated_field);
122 break;
123 }
124 } else if ($field->getOneofIndex() !== -1) {
125 $oneof = $this->desc->getOneofDecl()[$field->getOneofIndex()];
126 $oneof_name = $oneof->getName();
127 $this->$oneof_name = new OneofField($oneof);
128 } else if ($field->getLabel() === GPBLabel::OPTIONAL &&
129 PHP_INT_SIZE == 4) {
130 switch ($field->getType()) {
131 case GPBType::INT64:
132 case GPBType::UINT64:
133 case GPBType::FIXED64:
134 case GPBType::SFIXED64:
135 case GPBType::SINT64:
136 $this->$setter("0");
137 }
138 }
139 }
140 }
141
142 protected function readOneof($number)
143 {
144 $field = $this->desc->getFieldByNumber($number);
145 $oneof = $this->desc->getOneofDecl()[$field->getOneofIndex()];
146 $oneof_name = $oneof->getName();
147 $oneof_field = $this->$oneof_name;
148 if ($number === $oneof_field->getNumber()) {
149 return $oneof_field->getValue();
150 } else {
151 return $this->defaultValue($field);
152 }
153 }
154
155 protected function writeOneof($number, $value)
156 {
157 $field = $this->desc->getFieldByNumber($number);
158 $oneof = $this->desc->getOneofDecl()[$field->getOneofIndex()];
159 $oneof_name = $oneof->getName();
160 $oneof_field = $this->$oneof_name;
161 $oneof_field->setValue($value);
162 $oneof_field->setFieldName($field->getName());
163 $oneof_field->setNumber($number);
164 }
165
166 /**
167 * @ignore
168 */
169 private function defaultValue($field)
170 {
171 $value = null;
172
173 switch ($field->getType()) {
174 case GPBType::DOUBLE:
175 case GPBType::FLOAT:
176 return 0.0;
177 case GPBType::UINT32:
178 case GPBType::UINT64:
179 case GPBType::INT32:
180 case GPBType::INT64:
181 case GPBType::FIXED32:
182 case GPBType::FIXED64:
183 case GPBType::SFIXED32:
184 case GPBType::SFIXED64:
185 case GPBType::SINT32:
186 case GPBType::SINT64:
187 case GPBType::ENUM:
188 return 0;
189 case GPBType::BOOL:
190 return false;
191 case GPBType::STRING:
192 case GPBType::BYTES:
193 return "";
194 case GPBType::GROUP:
195 case GPBType::MESSAGE:
196 return null;
197 default:
198 user_error("Unsupported type.");
199 return false;
200 }
201 }
202
203 /**
204 * @ignore
205 */
206 private static function parseFieldFromStreamNoTag($input, $field, &$value)
207 {
208 switch ($field->getType()) {
209 case GPBType::DOUBLE:
210 if (!GPBWire::readDouble($input, $value)) {
211 return false;
212 }
213 break;
214 case GPBType::FLOAT:
215 if (!GPBWire::readFloat($input, $value)) {
216 return false;
217 }
218 break;
219 case GPBType::INT64:
220 if (!GPBWire::readInt64($input, $value)) {
221 return false;
222 }
223 break;
224 case GPBType::UINT64:
225 if (!GPBWire::readUint64($input, $value)) {
226 return false;
227 }
228 break;
229 case GPBType::INT32:
230 if (!GPBWire::readInt32($input, $value)) {
231 return false;
232 }
233 break;
234 case GPBType::FIXED64:
235 if (!GPBWire::readFixed64($input, $value)) {
236 return false;
237 }
238 break;
239 case GPBType::FIXED32:
240 if (!GPBWire::readFixed32($input, $value)) {
241 return false;
242 }
243 break;
244 case GPBType::BOOL:
245 if (!GPBWire::readBool($input, $value)) {
246 return false;
247 }
248 break;
249 case GPBType::STRING:
250 // TODO(teboring): Add utf-8 check.
251 if (!GPBWire::readString($input, $value)) {
252 return false;
253 }
254 break;
255 case GPBType::GROUP:
256 echo "GROUP\xA";
257 trigger_error("Not implemented.", E_ERROR);
258 break;
259 case GPBType::MESSAGE:
260 if ($field->isMap()) {
261 $value = new MapEntry($field->getMessageType());
262 } else {
263 $klass = $field->getMessageType()->getClass();
264 $value = new $klass;
265 }
266 if (!GPBWire::readMessage($input, $value)) {
267 return false;
268 }
269 break;
270 case GPBType::BYTES:
271 if (!GPBWire::readString($input, $value)) {
272 return false;
273 }
274 break;
275 case GPBType::UINT32:
276 if (!GPBWire::readUint32($input, $value)) {
277 return false;
278 }
279 break;
280 case GPBType::ENUM:
281 // TODO(teboring): Check unknown enum value.
282 if (!GPBWire::readInt32($input, $value)) {
283 return false;
284 }
285 break;
286 case GPBType::SFIXED32:
287 if (!GPBWire::readSfixed32($input, $value)) {
288 return false;
289 }
290 break;
291 case GPBType::SFIXED64:
292 if (!GPBWire::readSfixed64($input, $value)) {
293 return false;
294 }
295 break;
296 case GPBType::SINT32:
297 if (!GPBWire::readSint32($input, $value)) {
298 return false;
299 }
300 break;
301 case GPBType::SINT64:
302 if (!GPBWire::readSint64($input, $value)) {
303 return false;
304 }
305 break;
306 default:
307 user_error("Unsupported type.");
308 return false;
309 }
310 return true;
311 }
312
313 /**
314 * @ignore
315 */
316 private function parseFieldFromStream($tag, $input, $field)
317 {
318 $value = null;
319 $field_type = $field->getType();
320
321 $value_format = GPBWire::UNKNOWN;
322 if (GPBWire::getTagWireType($tag) ===
323 GPBWire::getWireType($field_type)) {
324 $value_format = GPBWire::NORMAL_FORMAT;
325 } elseif ($field->isPackable() &&
326 GPBWire::getTagWireType($tag) ===
327 GPBWire::WIRETYPE_LENGTH_DELIMITED) {
328 $value_format = GPBWire::PACKED_FORMAT;
329 }
330
331 if ($value_format === GPBWire::NORMAL_FORMAT) {
332 if (!self::parseFieldFromStreamNoTag($input, $field, $value)) {
333 return false;
334 }
335 } elseif ($value_format === GPBWire::PACKED_FORMAT) {
336 $length = 0;
337 if (!GPBWire::readInt32($input, $length)) {
338 return false;
339 }
340 $limit = $input->pushLimit($length);
341 $getter = $field->getGetter();
342 while ($input->bytesUntilLimit() > 0) {
343 if (!self::parseFieldFromStreamNoTag($input, $field, $value)) {
344 return false;
345 }
346 $this->$getter()[] = $value;
347 }
348 $input->popLimit($limit);
349 return true;
350 } else {
351 return false;
352 }
353
354 if ($field->isMap()) {
355 $getter = $field->getGetter();
356 $this->$getter()[$value->getKey()] = $value->getValue();
357 } else if ($field->isRepeated()) {
358 $getter = $field->getGetter();
359 $this->$getter()[] = $value;
360 } else {
361 $setter = $field->getSetter();
362 $this->$setter($value);
363 }
364
365 return true;
366 }
367
368 /**
369 * Parses a protocol buffer contained in a string.
370 *
371 * This function takes a string in the (non-human-readable) binary wire
372 * format, matching the encoding output by encode().
373 *
374 * @param string $data Binary protobuf data.
375 * @return bool Return true on success.
376 */
377 public function decode($data)
378 {
379 $input = new InputStream($data);
380 $this->parseFromStream($input);
381 }
382
383 /**
384 * @ignore
385 */
386 public function parseFromStream($input)
387 {
388 while (true) {
389 $tag = $input->readTag();
390 // End of input. This is a valid place to end, so return true.
391 if ($tag === 0) {
392 return true;
393 }
394
395 $number = GPBWire::getTagFieldNumber($tag);
396 $field = $this->desc->getFieldByNumber($number);
397
398 if (!$this->parseFieldFromStream($tag, $input, $field)) {
399 return false;
400 }
401 }
402 }
403
404 /**
405 * @ignore
406 */
407 private function serializeSingularFieldToStream($field, &$output)
408 {
409 if (!$this->existField($field)) {
410 return true;
411 }
412 $getter = $field->getGetter();
413 $value = $this->$getter();
414 if (!GPBWire::serializeFieldToStream($value, $field, true, $output)) {
415 return false;
416 }
417 return true;
418 }
419
420 /**
421 * @ignore
422 */
423 private function serializeRepeatedFieldToStream($field, &$output)
424 {
425 $getter = $field->getGetter();
426 $values = $this->$getter();
427 $count = count($values);
428 if ($count === 0) {
429 return true;
430 }
431
432 $packed = $field->getPacked();
433 if ($packed) {
434 if (!GPBWire::writeTag(
435 $output,
436 GPBWire::makeTag($field->getNumber(), GPBType::STRING))) {
437 return false;
438 }
439 $size = 0;
440 foreach ($values as $value) {
441 $size += $this->fieldDataOnlyByteSize($field, $value);
442 }
443 if (!$output->writeVarint32($size)) {
444 return false;
445 }
446 }
447
448 foreach ($values as $value) {
449 if (!GPBWire::serializeFieldToStream(
450 $value,
451 $field,
452 !$packed,
453 $output)) {
454 return false;
455 }
456 }
457 return true;
458 }
459
460 /**
461 * @ignore
462 */
463 private function serializeMapFieldToStream($field, $output)
464 {
465 $getter = $field->getGetter();
466 $values = $this->$getter();
467 $count = count($values);
468 if ($count === 0) {
469 return true;
470 }
471
472 foreach ($values as $key => $value) {
473 $map_entry = new MapEntry($field->getMessageType());
474 $map_entry->setKey($key);
475 $map_entry->setValue($value);
476 if (!GPBWire::serializeFieldToStream(
477 $map_entry,
478 $field,
479 true,
480 $output)) {
481 return false;
482 }
483 }
484 return true;
485 }
486
487 /**
488 * @ignore
489 */
490 private function serializeFieldToStream(&$output, $field)
491 {
492 if ($field->isMap()) {
493 return $this->serializeMapFieldToStream($field, $output);
494 } elseif ($field->isRepeated()) {
495 return $this->serializeRepeatedFieldToStream($field, $output);
496 } else {
497 return $this->serializeSingularFieldToStream($field, $output);
498 }
499 }
500
501 /**
502 * @ignore
503 */
504 public function serializeToStream(&$output)
505 {
506 $fields = $this->desc->getField();
507 foreach ($fields as $field) {
508 if (!$this->serializeFieldToStream($output, $field)) {
509 return false;
510 }
511 }
512 return true;
513 }
514
515 /**
516 * Serialize the message to string.
517 * @return string Serialized binary protobuf data.
518 */
519 public function encode()
520 {
521 $output = new OutputStream($this->byteSize());
522 $this->serializeToStream($output);
523 return $output->getData();
524 }
525
526 /**
527 * @ignore
528 */
529 private function existField($field)
530 {
531 $getter = $field->getGetter();
532 $value = $this->$getter();
533 return $value !== $this->defaultValue($field);
534 }
535
536 /**
537 * @ignore
538 */
539 private function repeatedFieldDataOnlyByteSize($field)
540 {
541 $size = 0;
542
543 $getter = $field->getGetter();
544 $values = $this->$getter();
545 $count = count($values);
546 if ($count !== 0) {
547 $size += $count * GPBWire::tagSize($field);
548 foreach ($values as $value) {
549 $size += $this->singularFieldDataOnlyByteSize($field);
550 }
551 }
552 }
553
554 /**
555 * @ignore
556 */
557 private function fieldDataOnlyByteSize($field, $value)
558 {
559 $size = 0;
560
561 switch ($field->getType()) {
562 case GPBType::BOOL:
563 $size += 1;
564 break;
565 case GPBType::FLOAT:
566 case GPBType::FIXED32:
567 case GPBType::SFIXED32:
568 $size += 4;
569 break;
570 case GPBType::DOUBLE:
571 case GPBType::FIXED64:
572 case GPBType::SFIXED64:
573 $size += 8;
574 break;
575 case GPBType::UINT32:
576 case GPBType::INT32:
577 case GPBType::ENUM:
578 $size += GPBWire::varint32Size($value);
579 break;
580 case GPBType::UINT64:
581 case GPBType::INT64:
582 $size += GPBWire::varint64Size($value);
583 break;
584 case GPBType::SINT32:
585 $size += GPBWire::sint32Size($value);
586 break;
587 case GPBType::SINT64:
588 $size += GPBWire::sint64Size($value);
589 break;
590 case GPBType::STRING:
591 case GPBType::BYTES:
592 $size += strlen($value);
593 $size += GPBWire::varint32Size($size);
594 break;
595 case GPBType::MESSAGE:
596 $size += $value->byteSize();
597 $size += GPBWire::varint32Size($size);
598 break;
599 case GPBType::GROUP:
600 // TODO(teboring): Add support.
601 user_error("Unsupported type.");
602 break;
603 default:
604 user_error("Unsupported type.");
605 return 0;
606 }
607
608 return $size;
609 }
610
611 /**
612 * @ignore
613 */
614 private function fieldByteSize($field)
615 {
616 $size = 0;
617 if ($field->isMap()) {
618 $getter = $field->getGetter();
619 $values = $this->$getter();
620 $count = count($values);
621 if ($count !== 0) {
622 $size += $count * GPBWire::tagSize($field);
623 $message_type = $field->getMessageType();
624 $key_field = $message_type->getFieldByNumber(1);
625 $value_field = $message_type->getFieldByNumber(2);
626 foreach ($values as $key => $value) {
627 $data_size = 0;
628 $data_size += $this->fieldDataOnlyByteSize($key_field, $key) ;
629 $data_size += $this->fieldDataOnlyByteSize(
630 $value_field,
631 $value);
632 $data_size += GPBWire::tagSize($key_field);
633 $data_size += GPBWire::tagSize($value_field);
634 $size += GPBWire::varint32Size($data_size) + $data_size;
635 }
636 }
637 } elseif ($field->isRepeated()) {
638 $getter = $field->getGetter();
639 $values = $this->$getter();
640 $count = count($values);
641 if ($count !== 0) {
642 if ($field->getPacked()) {
643 $data_size = 0;
644 foreach ($values as $value) {
645 $data_size += $this->fieldDataOnlyByteSize($field, $valu e);
646 }
647 $size += GPBWire::tagSize($field);
648 $size += GPBWire::varint32Size($data_size);
649 $size += $data_size;
650 } else {
651 $size += $count * GPBWire::tagSize($field);
652 foreach ($values as $value) {
653 $size += $this->fieldDataOnlyByteSize($field, $value);
654 }
655 }
656 }
657 } elseif ($this->existField($field)) {
658 $size += GPBWire::tagSize($field);
659 $getter = $field->getGetter();
660 $value = $this->$getter();
661 $size += $this->fieldDataOnlyByteSize($field, $value);
662 }
663 return $size;
664 }
665
666 /**
667 * @ignore
668 */
669 public function byteSize()
670 {
671 $size = 0;
672
673 $fields = $this->desc->getField();
674 foreach ($fields as $field) {
675 $size += $this->fieldByteSize($field);
676 }
677 return $size;
678 }
679 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698