| 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 function getFullClassName( |
| 219 $proto, |
| 220 $containing, |
| 221 $package, |
| 222 &$message_name_without_package, |
| 223 &$classname, |
| 224 &$fullname) |
| 225 { |
| 226 // Full name needs to start with '.'. |
| 227 $message_name_without_package = $proto->getName(); |
| 228 if ($containing !== "") { |
| 229 $message_name_without_package = |
| 230 $containing . "." . $message_name_without_package; |
| 231 } |
| 232 if ($package === "") { |
| 233 $fullname = "." . $message_name_without_package; |
| 234 } else { |
| 235 $fullname = "." . $package . "." . $message_name_without_package; |
| 236 } |
| 237 |
| 238 // Nested message class names are seperated by '_', and package names are |
| 239 // seperated by '\'. |
| 240 $class_name_without_package = |
| 241 implode('_', array_map('ucwords', |
| 242 explode('.', $message_name_without_package))); |
| 243 if ($package === "") { |
| 244 $classname = $class_name_without_package; |
| 245 } else { |
| 246 $classname = |
| 247 implode('\\', array_map('ucwords', explode('.', $package))). |
| 248 "\\".$class_name_without_package; |
| 249 } |
| 250 } |
| 251 |
| 252 class OneofDescriptor |
| 253 { |
| 254 |
| 255 private $name; |
| 256 private $fields; |
| 257 |
| 258 public function setName($name) |
| 259 { |
| 260 $this->name = $name; |
| 261 } |
| 262 |
| 263 public function getName() |
| 264 { |
| 265 return $this->name; |
| 266 } |
| 267 |
| 268 public function addField(&$field) |
| 269 { |
| 270 $this->fields[] = $field; |
| 271 } |
| 272 |
| 273 public function getFields() |
| 274 { |
| 275 return $this->fields; |
| 276 } |
| 277 |
| 278 public static function buildFromProto($oneof_proto) |
| 279 { |
| 280 $oneof = new OneofDescriptor(); |
| 281 $oneof->setName($oneof_proto->getName()); |
| 282 return $oneof; |
| 283 } |
| 284 } |
| 285 |
| 286 |
| 287 class EnumDescriptor |
| 288 { |
| 289 |
| 290 private $klass; |
| 291 private $full_name; |
| 292 private $value; |
| 293 |
| 294 public function setFullName($full_name) |
| 295 { |
| 296 $this->full_name = $full_name; |
| 297 } |
| 298 |
| 299 public function getFullName() |
| 300 { |
| 301 return $this->full_name; |
| 302 } |
| 303 |
| 304 public function addValue($number, $value) |
| 305 { |
| 306 $this->value[$number] = $value; |
| 307 } |
| 308 |
| 309 public function setClass($klass) |
| 310 { |
| 311 $this->klass = $klass; |
| 312 } |
| 313 |
| 314 public function getClass() |
| 315 { |
| 316 return $this->klass; |
| 317 } |
| 318 |
| 319 public static function buildFromProto($proto, $package, $containing) |
| 320 { |
| 321 $desc = new EnumDescriptor(); |
| 322 |
| 323 $enum_name_without_package = ""; |
| 324 $classname = ""; |
| 325 $fullname = ""; |
| 326 getFullClassName( |
| 327 $proto, |
| 328 $containing, |
| 329 $package, |
| 330 $enum_name_without_package, |
| 331 $classname, |
| 332 $fullname); |
| 333 $desc->setFullName($fullname); |
| 334 $desc->setClass($classname); |
| 335 |
| 336 return $desc; |
| 337 } |
| 338 } |
| 339 |
| 340 class EnumValueDescriptor |
| 341 { |
| 342 } |
| 343 |
| 344 class FieldDescriptor |
| 345 { |
| 346 |
| 347 private $name; |
| 348 private $setter; |
| 349 private $getter; |
| 350 private $number; |
| 351 private $label; |
| 352 private $type; |
| 353 private $message_type; |
| 354 private $enum_type; |
| 355 private $packed; |
| 356 private $is_map; |
| 357 private $oneof_index = -1; |
| 358 |
| 359 public function setOneofIndex($index) |
| 360 { |
| 361 $this->oneof_index = $index; |
| 362 } |
| 363 |
| 364 public function getOneofIndex() |
| 365 { |
| 366 return $this->oneof_index; |
| 367 } |
| 368 |
| 369 public function setName($name) |
| 370 { |
| 371 $this->name = $name; |
| 372 } |
| 373 |
| 374 public function getName() |
| 375 { |
| 376 return $this->name; |
| 377 } |
| 378 |
| 379 public function setSetter($setter) |
| 380 { |
| 381 $this->setter = $setter; |
| 382 } |
| 383 |
| 384 public function getSetter() |
| 385 { |
| 386 return $this->setter; |
| 387 } |
| 388 |
| 389 public function setGetter($getter) |
| 390 { |
| 391 $this->getter = $getter; |
| 392 } |
| 393 |
| 394 public function getGetter() |
| 395 { |
| 396 return $this->getter; |
| 397 } |
| 398 |
| 399 public function setNumber($number) |
| 400 { |
| 401 $this->number = $number; |
| 402 } |
| 403 |
| 404 public function getNumber() |
| 405 { |
| 406 return $this->number; |
| 407 } |
| 408 |
| 409 public function setLabel($label) |
| 410 { |
| 411 $this->label = $label; |
| 412 } |
| 413 |
| 414 public function getLabel() |
| 415 { |
| 416 return $this->label; |
| 417 } |
| 418 |
| 419 public function isRepeated() |
| 420 { |
| 421 return $this->label === GPBLabel::REPEATED; |
| 422 } |
| 423 |
| 424 public function setType($type) |
| 425 { |
| 426 $this->type = $type; |
| 427 } |
| 428 |
| 429 public function getType() |
| 430 { |
| 431 return $this->type; |
| 432 } |
| 433 |
| 434 public function setMessageType($message_type) |
| 435 { |
| 436 $this->message_type = $message_type; |
| 437 } |
| 438 |
| 439 public function getMessageType() |
| 440 { |
| 441 return $this->message_type; |
| 442 } |
| 443 |
| 444 public function setEnumType($enum_type) |
| 445 { |
| 446 $this->enum_type = $enum_type; |
| 447 } |
| 448 |
| 449 public function getEnumType() |
| 450 { |
| 451 return $this->enum_type; |
| 452 } |
| 453 |
| 454 public function setPacked($packed) |
| 455 { |
| 456 $this->packed = $packed; |
| 457 } |
| 458 |
| 459 public function getPacked() |
| 460 { |
| 461 return $this->packed; |
| 462 } |
| 463 |
| 464 public function isPackable() |
| 465 { |
| 466 return $this->isRepeated() && self::isTypePackable($this->type); |
| 467 } |
| 468 |
| 469 public function isMap() |
| 470 { |
| 471 return $this->getType() == GPBType::MESSAGE && |
| 472 !is_null($this->getMessageType()->getOptions()) && |
| 473 $this->getMessageType()->getOptions()->getMapEntry(); |
| 474 } |
| 475 |
| 476 private static function isTypePackable($field_type) |
| 477 { |
| 478 return ($field_type !== GPBType::STRING && |
| 479 $field_type !== GPBType::GROUP && |
| 480 $field_type !== GPBType::MESSAGE && |
| 481 $field_type !== GPBType::BYTES); |
| 482 } |
| 483 |
| 484 public static function getFieldDescriptor( |
| 485 $name, |
| 486 $label, |
| 487 $type, |
| 488 $number, |
| 489 $oneof_index, |
| 490 $packed, |
| 491 $type_name = null) |
| 492 { |
| 493 $field = new FieldDescriptor(); |
| 494 $field->setName($name); |
| 495 $camel_name = implode('', array_map('ucwords', explode('_', $name))); |
| 496 $field->setGetter('get' . $camel_name); |
| 497 $field->setSetter('set' . $camel_name); |
| 498 $field->setType($type); |
| 499 $field->setNumber($number); |
| 500 $field->setLabel($label); |
| 501 $field->setPacked($packed); |
| 502 $field->setOneofIndex($oneof_index); |
| 503 |
| 504 // At this time, the message/enum type may have not been added to pool. |
| 505 // So we use the type name as place holder and will replace it with the |
| 506 // actual descriptor in cross building. |
| 507 switch ($type) { |
| 508 case GPBType::MESSAGE: |
| 509 $field->setMessageType($type_name); |
| 510 break; |
| 511 case GPBType::ENUM: |
| 512 $field->setEnumType($type_name); |
| 513 break; |
| 514 default: |
| 515 break; |
| 516 } |
| 517 |
| 518 return $field; |
| 519 } |
| 520 |
| 521 public static function buildFromProto($proto) |
| 522 { |
| 523 $type_name = null; |
| 524 switch ($proto->getType()) { |
| 525 case GPBType::MESSAGE: |
| 526 case GPBType::GROUP: |
| 527 case GPBType::ENUM: |
| 528 $type_name = $proto->getTypeName(); |
| 529 break; |
| 530 default: |
| 531 break; |
| 532 } |
| 533 |
| 534 $oneof_index = $proto->hasOneofIndex() ? $proto->getOneofIndex() : -1; |
| 535 $packed = false; |
| 536 $options = $proto->getOptions(); |
| 537 if ($options !== null) { |
| 538 $packed = $options->getPacked(); |
| 539 } |
| 540 |
| 541 return FieldDescriptor::getFieldDescriptor( |
| 542 $proto->getName(), $proto->getLabel(), $proto->getType(), |
| 543 $proto->getNumber(), $oneof_index, $packed, $type_name); |
| 544 } |
| 545 } |
| OLD | NEW |