From b27dd18676054c3dcb5cbcff39e5c2c581feaaeb Mon Sep 17 00:00:00 2001 From: "Thanet (Knack) Praneenararat" Date: Fri, 3 Jun 2022 00:08:44 +0900 Subject: [PATCH 1/4] Exposed more functions in FieldDescriptor and OneofDescriptor. --- php/src/Google/Protobuf/FieldDescriptor.php | 25 +++++++++++++------ .../Protobuf/Internal/FieldDescriptor.php | 17 ++++++++++++- .../Protobuf/Internal/OneofDescriptor.php | 6 +++++ php/src/Google/Protobuf/OneofDescriptor.php | 3 ++- 4 files changed, 41 insertions(+), 10 deletions(-) diff --git a/php/src/Google/Protobuf/FieldDescriptor.php b/php/src/Google/Protobuf/FieldDescriptor.php index 6d08cea9da..128f0f08bd 100644 --- a/php/src/Google/Protobuf/FieldDescriptor.php +++ b/php/src/Google/Protobuf/FieldDescriptor.php @@ -39,6 +39,7 @@ class FieldDescriptor { use GetPublicDescriptorTrait; + /** @var \Google\Protobuf\Internal\FieldDescriptor $internal_desc */ private $internal_desc; /** @@ -81,6 +82,22 @@ class FieldDescriptor return $this->internal_desc->getType(); } + /** + * @return int + */ + public function getOneofIndex() + { + return $this->internal_desc->getOneofIndex(); + } + + /** + * @return boolean + */ + public function getProto3Optional() + { + return $this->internal_desc->getProto3Optional(); + } + /** * @return Descriptor Returns a descriptor for the field type if the field type is a message, otherwise throws \Exception * @throws \Exception @@ -114,12 +131,4 @@ class FieldDescriptor { return $this->internal_desc->isMap(); } - - /** - * @return boolean - */ - public function hasOptionalKeyword() - { - return $this->internal_desc->hasOptionalKeyword(); - } } diff --git a/php/src/Google/Protobuf/Internal/FieldDescriptor.php b/php/src/Google/Protobuf/Internal/FieldDescriptor.php index ce83f63a2b..368797b340 100644 --- a/php/src/Google/Protobuf/Internal/FieldDescriptor.php +++ b/php/src/Google/Protobuf/Internal/FieldDescriptor.php @@ -46,8 +46,8 @@ class FieldDescriptor private $message_type; private $enum_type; private $packed; - private $is_map; private $oneof_index = -1; + private $proto3_optional; public function __construct() { @@ -169,6 +169,16 @@ class FieldDescriptor return $this->packed; } + public function getProto3Optional() + { + return $this->proto3_optional; + } + + public function setProto3Optional($proto3_optional) + { + $this->proto3_optional = $proto3_optional; + } + public function isPackable() { return $this->isRepeated() && self::isTypePackable($this->type); @@ -214,6 +224,10 @@ class FieldDescriptor $field_type !== GPBType::BYTES); } + /** + * @param FieldDescriptorProto $proto + * @return FieldDescriptor + */ public static function getFieldDescriptor($proto) { $type_name = null; @@ -269,6 +283,7 @@ class FieldDescriptor $field->setLabel($proto->getLabel()); $field->setPacked($packed); $field->setOneofIndex($oneof_index); + $field->setProto3Optional($proto->getProto3Optional()); // At this time, the message/enum type may have not been added to pool. // So we use the type name as place holder and will replace it with the diff --git a/php/src/Google/Protobuf/Internal/OneofDescriptor.php b/php/src/Google/Protobuf/Internal/OneofDescriptor.php index 67b107f6a4..e685b26701 100644 --- a/php/src/Google/Protobuf/Internal/OneofDescriptor.php +++ b/php/src/Google/Protobuf/Internal/OneofDescriptor.php @@ -37,6 +37,7 @@ class OneofDescriptor use HasPublicDescriptorTrait; private $name; + /** @var \Google\Protobuf\FieldDescriptor[] $fields */ private $fields; public function __construct() @@ -64,6 +65,11 @@ class OneofDescriptor return $this->fields; } + public function isSynthetic() + { + return count($this->fields) === 1 && $this->fields[0]->getProto3Optional(); + } + public static function buildFromProto($oneof_proto, $desc, $index) { $oneof = new OneofDescriptor(); diff --git a/php/src/Google/Protobuf/OneofDescriptor.php b/php/src/Google/Protobuf/OneofDescriptor.php index 92b4e279da..9717da8a77 100644 --- a/php/src/Google/Protobuf/OneofDescriptor.php +++ b/php/src/Google/Protobuf/OneofDescriptor.php @@ -38,6 +38,7 @@ class OneofDescriptor { use GetPublicDescriptorTrait; + /** @var \Google\Protobuf\Internal\OneofDescriptor $internal_desc */ private $internal_desc; /** @@ -75,6 +76,6 @@ class OneofDescriptor public function isSynthetic() { - return $this->internal_desc->isSynthetic(); + return $this->internal_desc->isSynthetic(); } } From 238331b35995f410766a9041e72d5b839e3d9fae Mon Sep 17 00:00:00 2001 From: "Thanet (Knack) Praneenararat" Date: Fri, 3 Jun 2022 17:19:23 +0900 Subject: [PATCH 2/4] Added support for getRealContainingOneof() and getContainingOneof() --- php/src/Google/Protobuf/FieldDescriptor.php | 22 +++++++++++-- .../Google/Protobuf/Internal/Descriptor.php | 2 +- .../Protobuf/Internal/FieldDescriptor.php | 33 ++++++++++++++++--- 3 files changed, 50 insertions(+), 7 deletions(-) diff --git a/php/src/Google/Protobuf/FieldDescriptor.php b/php/src/Google/Protobuf/FieldDescriptor.php index 128f0f08bd..6e5eeca9ff 100644 --- a/php/src/Google/Protobuf/FieldDescriptor.php +++ b/php/src/Google/Protobuf/FieldDescriptor.php @@ -90,12 +90,30 @@ class FieldDescriptor return $this->internal_desc->getOneofIndex(); } + /** + * @return OneofDescriptor + */ + public function getContainingOneof() + { + return $this->getPublicDescriptor($this->internal_desc->getContainingOneof()); + } + + /** + * Gets the field's containing oneof, only if non-synthetic. + * + * @return null|OneofDescriptor + */ + public function getRealContainingOneof() + { + return $this->getPublicDescriptor($this->internal_desc->getRealContainingOneof()); + } + /** * @return boolean */ - public function getProto3Optional() + public function hasOptionalKeyword() { - return $this->internal_desc->getProto3Optional(); + return $this->internal_desc->hasOptionalKeyword(); } /** diff --git a/php/src/Google/Protobuf/Internal/Descriptor.php b/php/src/Google/Protobuf/Internal/Descriptor.php index a7f80d534e..a965158ebe 100644 --- a/php/src/Google/Protobuf/Internal/Descriptor.php +++ b/php/src/Google/Protobuf/Internal/Descriptor.php @@ -194,7 +194,7 @@ class Descriptor $desc->setOptions($proto->getOptions()); foreach ($proto->getField() as $field_proto) { - $desc->addField(FieldDescriptor::buildFromProto($field_proto)); + $desc->addField(FieldDescriptor::buildFromProto($field_proto, $desc)); } // Handle nested types. diff --git a/php/src/Google/Protobuf/Internal/FieldDescriptor.php b/php/src/Google/Protobuf/Internal/FieldDescriptor.php index 368797b340..7ab30dd1c0 100644 --- a/php/src/Google/Protobuf/Internal/FieldDescriptor.php +++ b/php/src/Google/Protobuf/Internal/FieldDescriptor.php @@ -49,6 +49,11 @@ class FieldDescriptor private $oneof_index = -1; private $proto3_optional; + /** @var Descriptor $containing_type */ + private $containing_type; + /** @var OneofDescriptor $containing_oneof */ + private $containing_oneof; + public function __construct() { $this->public_desc = new \Google\Protobuf\FieldDescriptor($this); @@ -179,6 +184,17 @@ class FieldDescriptor $this->proto3_optional = $proto3_optional; } + public function getContainingOneof() + { + return $this->containing_oneof; + } + + public function getRealContainingOneof() + { + return !is_null($this->containing_oneof) && !$this->containing_oneof->isSynthetic() + ? $this->containing_oneof : null; + } + public function isPackable() { return $this->isRepeated() && self::isTypePackable($this->type); @@ -226,9 +242,10 @@ class FieldDescriptor /** * @param FieldDescriptorProto $proto + * @param Descriptor $parent_desc * @return FieldDescriptor */ - public static function getFieldDescriptor($proto) + public static function getFieldDescriptor($proto, $parent_desc) { $type_name = null; $type = $proto->getType(); @@ -242,7 +259,13 @@ class FieldDescriptor break; } - $oneof_index = $proto->hasOneofIndex() ? $proto->getOneofIndex() : -1; + if ($proto->hasOneofIndex()) { + $oneof_index = $proto->getOneofIndex(); + $containing_oneof = $parent_desc->getOneofDecl()[$oneof_index]; + } else { + $containing_oneof = null; + $oneof_index = -1; + } // TODO: once proto2 is supported, this default should be false // for proto2. if ($proto->getLabel() === GPBLabel::REPEATED && @@ -261,6 +284,8 @@ class FieldDescriptor $field = new FieldDescriptor(); $field->setName($proto->getName()); + $field->containing_type = $parent_desc; + $field->containing_oneof = $containing_oneof; $json_name = $proto->hasJsonName() ? $proto->getJsonName() : lcfirst(implode('', array_map('ucwords', explode('_', $proto->getName())))); @@ -302,8 +327,8 @@ class FieldDescriptor return $field; } - public static function buildFromProto($proto) + public static function buildFromProto($proto, $parent_desc) { - return FieldDescriptor::getFieldDescriptor($proto); + return FieldDescriptor::getFieldDescriptor($proto, $parent_desc); } } From 594f2a9b0d33f83c619828c745d9d413428e1a72 Mon Sep 17 00:00:00 2001 From: "Thanet (Knack) Praneenararat" Date: Sat, 4 Jun 2022 01:40:22 +0900 Subject: [PATCH 3/4] Fixes bugs of isSynthetic and makes containing_oneof work --- php/src/Google/Protobuf/FieldDescriptor.php | 8 -------- php/src/Google/Protobuf/Internal/Descriptor.php | 9 +++++---- php/src/Google/Protobuf/Internal/FieldDescriptor.php | 11 ++++------- php/src/Google/Protobuf/Internal/OneofDescriptor.php | 3 ++- 4 files changed, 11 insertions(+), 20 deletions(-) diff --git a/php/src/Google/Protobuf/FieldDescriptor.php b/php/src/Google/Protobuf/FieldDescriptor.php index 6e5eeca9ff..ac919a24a9 100644 --- a/php/src/Google/Protobuf/FieldDescriptor.php +++ b/php/src/Google/Protobuf/FieldDescriptor.php @@ -82,14 +82,6 @@ class FieldDescriptor return $this->internal_desc->getType(); } - /** - * @return int - */ - public function getOneofIndex() - { - return $this->internal_desc->getOneofIndex(); - } - /** * @return OneofDescriptor */ diff --git a/php/src/Google/Protobuf/Internal/Descriptor.php b/php/src/Google/Protobuf/Internal/Descriptor.php index a965158ebe..02b5433290 100644 --- a/php/src/Google/Protobuf/Internal/Descriptor.php +++ b/php/src/Google/Protobuf/Internal/Descriptor.php @@ -193,10 +193,6 @@ class Descriptor $desc->setLegacyClass($legacy_classname); $desc->setOptions($proto->getOptions()); - foreach ($proto->getField() as $field_proto) { - $desc->addField(FieldDescriptor::buildFromProto($field_proto, $desc)); - } - // Handle nested types. foreach ($proto->getNestedType() as $nested_proto) { $desc->addNestedType(Descriptor::buildFromProto( @@ -217,6 +213,11 @@ class Descriptor $index++; } + // Pass the descriptor to build FieldDescriptor after the OneofDescriptors are populated. + foreach ($proto->getField() as $field_proto) { + $desc->addField(FieldDescriptor::buildFromProto($field_proto, $desc)); + } + return $desc; } } diff --git a/php/src/Google/Protobuf/Internal/FieldDescriptor.php b/php/src/Google/Protobuf/Internal/FieldDescriptor.php index 7ab30dd1c0..875280b75c 100644 --- a/php/src/Google/Protobuf/Internal/FieldDescriptor.php +++ b/php/src/Google/Protobuf/Internal/FieldDescriptor.php @@ -49,8 +49,6 @@ class FieldDescriptor private $oneof_index = -1; private $proto3_optional; - /** @var Descriptor $containing_type */ - private $containing_type; /** @var OneofDescriptor $containing_oneof */ private $containing_oneof; @@ -242,10 +240,10 @@ class FieldDescriptor /** * @param FieldDescriptorProto $proto - * @param Descriptor $parent_desc + * @param Descriptor $desc * @return FieldDescriptor */ - public static function getFieldDescriptor($proto, $parent_desc) + public static function getFieldDescriptor($proto, $desc) { $type_name = null; $type = $proto->getType(); @@ -261,10 +259,10 @@ class FieldDescriptor if ($proto->hasOneofIndex()) { $oneof_index = $proto->getOneofIndex(); - $containing_oneof = $parent_desc->getOneofDecl()[$oneof_index]; + $containing_oneof = $desc->getOneofDecl()[$oneof_index]; } else { - $containing_oneof = null; $oneof_index = -1; + $containing_oneof = null; } // TODO: once proto2 is supported, this default should be false // for proto2. @@ -284,7 +282,6 @@ class FieldDescriptor $field = new FieldDescriptor(); $field->setName($proto->getName()); - $field->containing_type = $parent_desc; $field->containing_oneof = $containing_oneof; $json_name = $proto->hasJsonName() ? $proto->getJsonName() : diff --git a/php/src/Google/Protobuf/Internal/OneofDescriptor.php b/php/src/Google/Protobuf/Internal/OneofDescriptor.php index e685b26701..a74be1e585 100644 --- a/php/src/Google/Protobuf/Internal/OneofDescriptor.php +++ b/php/src/Google/Protobuf/Internal/OneofDescriptor.php @@ -67,7 +67,8 @@ class OneofDescriptor public function isSynthetic() { - return count($this->fields) === 1 && $this->fields[0]->getProto3Optional(); + return !is_null($this->fields) && count($this->fields) === 1 + && $this->fields[0]->getProto3Optional(); } public static function buildFromProto($oneof_proto, $desc, $index) From 0f1574aae26613b19e55c8812694fda3d79814ae Mon Sep 17 00:00:00 2001 From: "Thanet (Knack) Praneenararat" Date: Thu, 9 Jun 2022 16:53:27 +0900 Subject: [PATCH 4/4] Fixed bugs of OneofDescriptor. --- .../Google/Protobuf/Internal/Descriptor.php | 9 ++++---- .../Protobuf/Internal/FieldDescriptor.php | 23 ++++++++----------- .../Protobuf/Internal/OneofDescriptor.php | 2 ++ php/src/Google/Protobuf/OneofDescriptor.php | 6 +++++ 4 files changed, 21 insertions(+), 19 deletions(-) diff --git a/php/src/Google/Protobuf/Internal/Descriptor.php b/php/src/Google/Protobuf/Internal/Descriptor.php index 02b5433290..a7f80d534e 100644 --- a/php/src/Google/Protobuf/Internal/Descriptor.php +++ b/php/src/Google/Protobuf/Internal/Descriptor.php @@ -193,6 +193,10 @@ class Descriptor $desc->setLegacyClass($legacy_classname); $desc->setOptions($proto->getOptions()); + foreach ($proto->getField() as $field_proto) { + $desc->addField(FieldDescriptor::buildFromProto($field_proto)); + } + // Handle nested types. foreach ($proto->getNestedType() as $nested_proto) { $desc->addNestedType(Descriptor::buildFromProto( @@ -213,11 +217,6 @@ class Descriptor $index++; } - // Pass the descriptor to build FieldDescriptor after the OneofDescriptors are populated. - foreach ($proto->getField() as $field_proto) { - $desc->addField(FieldDescriptor::buildFromProto($field_proto, $desc)); - } - return $desc; } } diff --git a/php/src/Google/Protobuf/Internal/FieldDescriptor.php b/php/src/Google/Protobuf/Internal/FieldDescriptor.php index 875280b75c..3a9a73b729 100644 --- a/php/src/Google/Protobuf/Internal/FieldDescriptor.php +++ b/php/src/Google/Protobuf/Internal/FieldDescriptor.php @@ -187,6 +187,11 @@ class FieldDescriptor return $this->containing_oneof; } + public function setContainingOneof($containing_oneof) + { + $this->containing_oneof = $containing_oneof; + } + public function getRealContainingOneof() { return !is_null($this->containing_oneof) && !$this->containing_oneof->isSynthetic() @@ -240,10 +245,9 @@ class FieldDescriptor /** * @param FieldDescriptorProto $proto - * @param Descriptor $desc * @return FieldDescriptor */ - public static function getFieldDescriptor($proto, $desc) + public static function getFieldDescriptor($proto) { $type_name = null; $type = $proto->getType(); @@ -257,13 +261,7 @@ class FieldDescriptor break; } - if ($proto->hasOneofIndex()) { - $oneof_index = $proto->getOneofIndex(); - $containing_oneof = $desc->getOneofDecl()[$oneof_index]; - } else { - $oneof_index = -1; - $containing_oneof = null; - } + $oneof_index = $proto->hasOneofIndex() ? $proto->getOneofIndex() : -1; // TODO: once proto2 is supported, this default should be false // for proto2. if ($proto->getLabel() === GPBLabel::REPEATED && @@ -282,10 +280,7 @@ class FieldDescriptor $field = new FieldDescriptor(); $field->setName($proto->getName()); - $field->containing_oneof = $containing_oneof; - $json_name = $proto->hasJsonName() ? $proto->getJsonName() : - lcfirst(implode('', array_map('ucwords', explode('_', $proto->getName())))); if ($proto->hasJsonName()) { $json_name = $proto->getJsonName(); } else { @@ -324,8 +319,8 @@ class FieldDescriptor return $field; } - public static function buildFromProto($proto, $parent_desc) + public static function buildFromProto($proto) { - return FieldDescriptor::getFieldDescriptor($proto, $parent_desc); + return FieldDescriptor::getFieldDescriptor($proto); } } diff --git a/php/src/Google/Protobuf/Internal/OneofDescriptor.php b/php/src/Google/Protobuf/Internal/OneofDescriptor.php index a74be1e585..4323685710 100644 --- a/php/src/Google/Protobuf/Internal/OneofDescriptor.php +++ b/php/src/Google/Protobuf/Internal/OneofDescriptor.php @@ -76,8 +76,10 @@ class OneofDescriptor $oneof = new OneofDescriptor(); $oneof->setName($oneof_proto->getName()); foreach ($desc->getField() as $field) { + /** @var FieldDescriptor $field */ if ($field->getOneofIndex() == $index) { $oneof->addField($field); + $field->setContainingOneof($oneof); } } return $oneof; diff --git a/php/src/Google/Protobuf/OneofDescriptor.php b/php/src/Google/Protobuf/OneofDescriptor.php index 9717da8a77..66ffbd5caf 100644 --- a/php/src/Google/Protobuf/OneofDescriptor.php +++ b/php/src/Google/Protobuf/OneofDescriptor.php @@ -63,6 +63,12 @@ class OneofDescriptor */ public function getField($index) { + if ( + is_null($this->internal_desc->getFields()) + || !isset($this->internal_desc->getFields()[$index]) + ) { + return null; + } return $this->getPublicDescriptor($this->internal_desc->getFields()[$index]); }