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 |