| OLD | NEW |
| (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 namespace Google\Protobuf\Internal; | |
| 34 | |
| 35 use Google\Protobuf\Internal\GPBType; | |
| 36 use Google\Protobuf\Internal\MessageOptions; | |
| 37 | |
| 38 class FileDescriptor | |
| 39 { | |
| 40 | |
| 41 private $package; | |
| 42 private $message_type = []; | |
| 43 private $enum_type = []; | |
| 44 | |
| 45 public function setPackage($package) | |
| 46 { | |
| 47 $this->package = $package; | |
| 48 } | |
| 49 | |
| 50 public function getPackage() | |
| 51 { | |
| 52 return $this->package; | |
| 53 } | |
| 54 | |
| 55 public function getMessageType() | |
| 56 { | |
| 57 return $this->message_type; | |
| 58 } | |
| 59 | |
| 60 public function addMessageType($desc) | |
| 61 { | |
| 62 $this->message_type[] = $desc; | |
| 63 } | |
| 64 | |
| 65 public function getEnumType() | |
| 66 { | |
| 67 return $this->enum_type; | |
| 68 } | |
| 69 | |
| 70 public function addEnumType($desc) | |
| 71 { | |
| 72 $this->enum_type[]= $desc; | |
| 73 } | |
| 74 | |
| 75 public static function buildFromProto($proto) | |
| 76 { | |
| 77 $file = new FileDescriptor(); | |
| 78 $file->setPackage($proto->getPackage()); | |
| 79 foreach ($proto->getMessageType() as $message_proto) { | |
| 80 $file->addMessageType(Descriptor::buildFromProto( | |
| 81 $message_proto, $file->getPackage(), "")); | |
| 82 } | |
| 83 foreach ($proto->getEnumType() as $enum_proto) { | |
| 84 $file->getEnumType()[] = | |
| 85 $file->addEnumType( | |
| 86 EnumDescriptor::buildFromProto( | |
| 87 $enum_proto, | |
| 88 $file->getPackage(), | |
| 89 "")); | |
| 90 } | |
| 91 return $file; | |
| 92 } | |
| 93 } | |
| 94 | |
| 95 class Descriptor | |
| 96 { | |
| 97 | |
| 98 private $full_name; | |
| 99 private $field = []; | |
| 100 private $nested_type = []; | |
| 101 private $enum_type = []; | |
| 102 private $klass; | |
| 103 private $options; | |
| 104 private $oneof_decl = []; | |
| 105 | |
| 106 public function addOneofDecl($oneof) | |
| 107 { | |
| 108 $this->oneof_decl[] = $oneof; | |
| 109 } | |
| 110 | |
| 111 public function getOneofDecl() | |
| 112 { | |
| 113 return $this->oneof_decl; | |
| 114 } | |
| 115 | |
| 116 public function setFullName($full_name) | |
| 117 { | |
| 118 $this->full_name = $full_name; | |
| 119 } | |
| 120 | |
| 121 public function getFullName() | |
| 122 { | |
| 123 return $this->full_name; | |
| 124 } | |
| 125 | |
| 126 public function addField($field) | |
| 127 { | |
| 128 $this->field[$field->getNumber()] = $field; | |
| 129 } | |
| 130 | |
| 131 public function getField() | |
| 132 { | |
| 133 return $this->field; | |
| 134 } | |
| 135 | |
| 136 public function addNestedType($desc) | |
| 137 { | |
| 138 $this->nested_type[] = $desc; | |
| 139 } | |
| 140 | |
| 141 public function getNestedType() | |
| 142 { | |
| 143 return $this->nested_type; | |
| 144 } | |
| 145 | |
| 146 public function addEnumType($desc) | |
| 147 { | |
| 148 $this->enum_type[] = $desc; | |
| 149 } | |
| 150 | |
| 151 public function getEnumType() | |
| 152 { | |
| 153 return $this->enum_type; | |
| 154 } | |
| 155 | |
| 156 public function getFieldByNumber($number) | |
| 157 { | |
| 158 return $this->field[$number]; | |
| 159 } | |
| 160 | |
| 161 public function setClass($klass) | |
| 162 { | |
| 163 $this->klass = $klass; | |
| 164 } | |
| 165 | |
| 166 public function getClass() | |
| 167 { | |
| 168 return $this->klass; | |
| 169 } | |
| 170 | |
| 171 public function setOptions($options) | |
| 172 { | |
| 173 $this->options = $options; | |
| 174 } | |
| 175 | |
| 176 public function getOptions() | |
| 177 { | |
| 178 return $this->options; | |
| 179 } | |
| 180 | |
| 181 public static function buildFromProto($proto, $package, $containing) | |
| 182 { | |
| 183 $desc = new Descriptor(); | |
| 184 | |
| 185 $message_name_without_package = ""; | |
| 186 $classname = ""; | |
| 187 $fullname = ""; | |
| 188 getFullClassName( | |
| 189 $proto, | |
| 190 $containing, | |
| 191 $package, | |
| 192 $message_name_without_package, | |
| 193 $classname, | |
| 194 $fullname); | |
| 195 $desc->setFullName($fullname); | |
| 196 $desc->setClass($classname); | |
| 197 $desc->setOptions($proto->getOptions()); | |
| 198 | |
| 199 foreach ($proto->getField() as $field_proto) { | |
| 200 $desc->addField(FieldDescriptor::buildFromProto($field_proto)); | |
| 201 } | |
| 202 | |
| 203 // Handle nested types. | |
| 204 foreach ($proto->getNestedType() as $nested_proto) { | |
| 205 $desc->addNestedType(Descriptor::buildFromProto( | |
| 206 $nested_proto, $package, $message_name_without_package)); | |
| 207 } | |
| 208 | |
| 209 // Handle oneof fields. | |
| 210 foreach ($proto->getOneofDecl() as $oneof_proto) { | |
| 211 $desc->addOneofDecl( | |
| 212 OneofDescriptor::buildFromProto($oneof_proto, $desc)); | |
| 213 } | |
| 214 | |
| 215 return $desc; | |
| 216 } | |
| 217 } | |
| 218 | |
| 219 function addPrefixIfSpecial( | |
| 220 $name, | |
| 221 $package) | |
| 222 { | |
| 223 if ($name === "Empty" && $package === "google.protobuf") { | |
| 224 return "GPBEmpty"; | |
| 225 } else { | |
| 226 return $name; | |
| 227 } | |
| 228 } | |
| 229 | |
| 230 function getFullClassName( | |
| 231 $proto, | |
| 232 $containing, | |
| 233 $package, | |
| 234 &$message_name_without_package, | |
| 235 &$classname, | |
| 236 &$fullname) | |
| 237 { | |
| 238 // Full name needs to start with '.'. | |
| 239 $message_name_without_package = | |
| 240 addPrefixIfSpecial($proto->getName(), $package); | |
| 241 if ($containing !== "") { | |
| 242 $message_name_without_package = | |
| 243 $containing . "." . $message_name_without_package; | |
| 244 } | |
| 245 if ($package === "") { | |
| 246 $fullname = "." . $message_name_without_package; | |
| 247 } else { | |
| 248 $fullname = "." . $package . "." . $message_name_without_package; | |
| 249 } | |
| 250 | |
| 251 // Nested message class names are seperated by '_', and package names are | |
| 252 // seperated by '\'. | |
| 253 $class_name_without_package = | |
| 254 implode('_', array_map('ucwords', | |
| 255 explode('.', $message_name_without_package))); | |
| 256 if ($package === "") { | |
| 257 $classname = $class_name_without_package; | |
| 258 } else { | |
| 259 $classname = | |
| 260 implode('\\', array_map('ucwords', explode('.', $package))). | |
| 261 "\\".$class_name_without_package; | |
| 262 } | |
| 263 } | |
| 264 | |
| 265 class OneofDescriptor | |
| 266 { | |
| 267 | |
| 268 private $name; | |
| 269 private $fields; | |
| 270 | |
| 271 public function setName($name) | |
| 272 { | |
| 273 $this->name = $name; | |
| 274 } | |
| 275 | |
| 276 public function getName() | |
| 277 { | |
| 278 return $this->name; | |
| 279 } | |
| 280 | |
| 281 public function addField(&$field) | |
| 282 { | |
| 283 $this->fields[] = $field; | |
| 284 } | |
| 285 | |
| 286 public function getFields() | |
| 287 { | |
| 288 return $this->fields; | |
| 289 } | |
| 290 | |
| 291 public static function buildFromProto($oneof_proto) | |
| 292 { | |
| 293 $oneof = new OneofDescriptor(); | |
| 294 $oneof->setName($oneof_proto->getName()); | |
| 295 return $oneof; | |
| 296 } | |
| 297 } | |
| 298 | |
| 299 | |
| 300 class EnumDescriptor | |
| 301 { | |
| 302 | |
| 303 private $klass; | |
| 304 private $full_name; | |
| 305 private $value; | |
| 306 | |
| 307 public function setFullName($full_name) | |
| 308 { | |
| 309 $this->full_name = $full_name; | |
| 310 } | |
| 311 | |
| 312 public function getFullName() | |
| 313 { | |
| 314 return $this->full_name; | |
| 315 } | |
| 316 | |
| 317 public function addValue($number, $value) | |
| 318 { | |
| 319 $this->value[$number] = $value; | |
| 320 } | |
| 321 | |
| 322 public function setClass($klass) | |
| 323 { | |
| 324 $this->klass = $klass; | |
| 325 } | |
| 326 | |
| 327 public function getClass() | |
| 328 { | |
| 329 return $this->klass; | |
| 330 } | |
| 331 | |
| 332 public static function buildFromProto($proto, $package, $containing) | |
| 333 { | |
| 334 $desc = new EnumDescriptor(); | |
| 335 | |
| 336 $enum_name_without_package = ""; | |
| 337 $classname = ""; | |
| 338 $fullname = ""; | |
| 339 getFullClassName( | |
| 340 $proto, | |
| 341 $containing, | |
| 342 $package, | |
| 343 $enum_name_without_package, | |
| 344 $classname, | |
| 345 $fullname); | |
| 346 $desc->setFullName($fullname); | |
| 347 $desc->setClass($classname); | |
| 348 | |
| 349 return $desc; | |
| 350 } | |
| 351 } | |
| 352 | |
| 353 class EnumValueDescriptor | |
| 354 { | |
| 355 } | |
| 356 | |
| 357 class FieldDescriptor | |
| 358 { | |
| 359 | |
| 360 private $name; | |
| 361 private $setter; | |
| 362 private $getter; | |
| 363 private $number; | |
| 364 private $label; | |
| 365 private $type; | |
| 366 private $message_type; | |
| 367 private $enum_type; | |
| 368 private $packed; | |
| 369 private $is_map; | |
| 370 private $oneof_index = -1; | |
| 371 | |
| 372 public function setOneofIndex($index) | |
| 373 { | |
| 374 $this->oneof_index = $index; | |
| 375 } | |
| 376 | |
| 377 public function getOneofIndex() | |
| 378 { | |
| 379 return $this->oneof_index; | |
| 380 } | |
| 381 | |
| 382 public function setName($name) | |
| 383 { | |
| 384 $this->name = $name; | |
| 385 } | |
| 386 | |
| 387 public function getName() | |
| 388 { | |
| 389 return $this->name; | |
| 390 } | |
| 391 | |
| 392 public function setSetter($setter) | |
| 393 { | |
| 394 $this->setter = $setter; | |
| 395 } | |
| 396 | |
| 397 public function getSetter() | |
| 398 { | |
| 399 return $this->setter; | |
| 400 } | |
| 401 | |
| 402 public function setGetter($getter) | |
| 403 { | |
| 404 $this->getter = $getter; | |
| 405 } | |
| 406 | |
| 407 public function getGetter() | |
| 408 { | |
| 409 return $this->getter; | |
| 410 } | |
| 411 | |
| 412 public function setNumber($number) | |
| 413 { | |
| 414 $this->number = $number; | |
| 415 } | |
| 416 | |
| 417 public function getNumber() | |
| 418 { | |
| 419 return $this->number; | |
| 420 } | |
| 421 | |
| 422 public function setLabel($label) | |
| 423 { | |
| 424 $this->label = $label; | |
| 425 } | |
| 426 | |
| 427 public function getLabel() | |
| 428 { | |
| 429 return $this->label; | |
| 430 } | |
| 431 | |
| 432 public function isRepeated() | |
| 433 { | |
| 434 return $this->label === GPBLabel::REPEATED; | |
| 435 } | |
| 436 | |
| 437 public function setType($type) | |
| 438 { | |
| 439 $this->type = $type; | |
| 440 } | |
| 441 | |
| 442 public function getType() | |
| 443 { | |
| 444 return $this->type; | |
| 445 } | |
| 446 | |
| 447 public function setMessageType($message_type) | |
| 448 { | |
| 449 $this->message_type = $message_type; | |
| 450 } | |
| 451 | |
| 452 public function getMessageType() | |
| 453 { | |
| 454 return $this->message_type; | |
| 455 } | |
| 456 | |
| 457 public function setEnumType($enum_type) | |
| 458 { | |
| 459 $this->enum_type = $enum_type; | |
| 460 } | |
| 461 | |
| 462 public function getEnumType() | |
| 463 { | |
| 464 return $this->enum_type; | |
| 465 } | |
| 466 | |
| 467 public function setPacked($packed) | |
| 468 { | |
| 469 $this->packed = $packed; | |
| 470 } | |
| 471 | |
| 472 public function getPacked() | |
| 473 { | |
| 474 return $this->packed; | |
| 475 } | |
| 476 | |
| 477 public function isPackable() | |
| 478 { | |
| 479 return $this->isRepeated() && self::isTypePackable($this->type); | |
| 480 } | |
| 481 | |
| 482 public function isMap() | |
| 483 { | |
| 484 return $this->getType() == GPBType::MESSAGE && | |
| 485 !is_null($this->getMessageType()->getOptions()) && | |
| 486 $this->getMessageType()->getOptions()->getMapEntry(); | |
| 487 } | |
| 488 | |
| 489 private static function isTypePackable($field_type) | |
| 490 { | |
| 491 return ($field_type !== GPBType::STRING && | |
| 492 $field_type !== GPBType::GROUP && | |
| 493 $field_type !== GPBType::MESSAGE && | |
| 494 $field_type !== GPBType::BYTES); | |
| 495 } | |
| 496 | |
| 497 public static function getFieldDescriptor( | |
| 498 $name, | |
| 499 $label, | |
| 500 $type, | |
| 501 $number, | |
| 502 $oneof_index, | |
| 503 $packed, | |
| 504 $type_name = null) | |
| 505 { | |
| 506 $field = new FieldDescriptor(); | |
| 507 $field->setName($name); | |
| 508 $camel_name = implode('', array_map('ucwords', explode('_', $name))); | |
| 509 $field->setGetter('get' . $camel_name); | |
| 510 $field->setSetter('set' . $camel_name); | |
| 511 $field->setType($type); | |
| 512 $field->setNumber($number); | |
| 513 $field->setLabel($label); | |
| 514 $field->setPacked($packed); | |
| 515 $field->setOneofIndex($oneof_index); | |
| 516 | |
| 517 // At this time, the message/enum type may have not been added to pool. | |
| 518 // So we use the type name as place holder and will replace it with the | |
| 519 // actual descriptor in cross building. | |
| 520 switch ($type) { | |
| 521 case GPBType::MESSAGE: | |
| 522 $field->setMessageType($type_name); | |
| 523 break; | |
| 524 case GPBType::ENUM: | |
| 525 $field->setEnumType($type_name); | |
| 526 break; | |
| 527 default: | |
| 528 break; | |
| 529 } | |
| 530 | |
| 531 return $field; | |
| 532 } | |
| 533 | |
| 534 public static function buildFromProto($proto) | |
| 535 { | |
| 536 $type_name = null; | |
| 537 switch ($proto->getType()) { | |
| 538 case GPBType::MESSAGE: | |
| 539 case GPBType::GROUP: | |
| 540 case GPBType::ENUM: | |
| 541 $type_name = $proto->getTypeName(); | |
| 542 break; | |
| 543 default: | |
| 544 break; | |
| 545 } | |
| 546 | |
| 547 $oneof_index = $proto->hasOneofIndex() ? $proto->getOneofIndex() : -1; | |
| 548 $packed = false; | |
| 549 $options = $proto->getOptions(); | |
| 550 if ($options !== null) { | |
| 551 $packed = $options->getPacked(); | |
| 552 } | |
| 553 | |
| 554 return FieldDescriptor::getFieldDescriptor( | |
| 555 $proto->getName(), $proto->getLabel(), $proto->getType(), | |
| 556 $proto->getNumber(), $oneof_index, $packed, $type_name); | |
| 557 } | |
| 558 } | |
| OLD | NEW |