Merge pull request #8003 from anight/php_extension_add_has_oneof_field_method
add missing hasOneof method to check presence of oneof fields
diff --git a/php/ext/google/protobuf/message.c b/php/ext/google/protobuf/message.c
index a4ae3d4..f15b8ac 100644
--- a/php/ext/google/protobuf/message.c
+++ b/php/ext/google/protobuf/message.c
@@ -905,6 +905,39 @@
}
/**
+ * Message::hasOneof()
+ *
+ * Returns the presence of the given oneof field, given a field number. Called
+ * from generated code methods such as:
+ *
+ * public function hasDoubleValueOneof()
+ * {
+ * return $this->hasOneof(10);
+ * }
+ *
+ * @return boolean
+ */
+PHP_METHOD(Message, hasOneof) {
+ Message* intern = (Message*)Z_OBJ_P(getThis());
+ zend_long field_num;
+ const upb_fielddef* f;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &field_num) == FAILURE) {
+ return;
+ }
+
+ f = upb_msgdef_itof(intern->desc->msgdef, field_num);
+
+ if (!f || !upb_fielddef_realcontainingoneof(f)) {
+ php_error_docref(NULL, E_USER_ERROR,
+ "Internal error, no such oneof field %d\n",
+ (int)field_num);
+ }
+
+ RETVAL_BOOL(upb_msg_has(intern->msg, f));
+}
+
+/**
* Message::readOneof()
*
* Returns the contents of the given oneof field, given a field number. Called
@@ -1014,6 +1047,7 @@
PHP_ME(Message, mergeFrom, arginfo_mergeFrom, ZEND_ACC_PUBLIC)
PHP_ME(Message, readWrapperValue, arginfo_read, ZEND_ACC_PROTECTED)
PHP_ME(Message, writeWrapperValue, arginfo_write, ZEND_ACC_PROTECTED)
+ PHP_ME(Message, hasOneof, arginfo_read, ZEND_ACC_PROTECTED)
PHP_ME(Message, readOneof, arginfo_read, ZEND_ACC_PROTECTED)
PHP_ME(Message, writeOneof, arginfo_write, ZEND_ACC_PROTECTED)
PHP_ME(Message, whichOneof, arginfo_read, ZEND_ACC_PROTECTED)
diff --git a/php/phpunit.xml b/php/phpunit.xml
index 8e75835..f00d4a3 100644
--- a/php/phpunit.xml
+++ b/php/phpunit.xml
@@ -13,6 +13,7 @@
<file>tests/DescriptorsTest.php</file>
<file>tests/GeneratedServiceTest.php</file>
<file>tests/WrapperTypeSettersTest.php</file>
+ <file>tests/HasOneofTest.php</file>
</testsuite>
</testsuites>
</phpunit>
diff --git a/php/tests/HasOneofTest.php b/php/tests/HasOneofTest.php
new file mode 100644
index 0000000..e7f8954
--- /dev/null
+++ b/php/tests/HasOneofTest.php
@@ -0,0 +1,26 @@
+<?php
+
+require_once('test_util.php');
+
+use Foo\TestMessage;
+
+class HasOneofTest extends \PHPUnit\Framework\TestCase {
+
+ #########################################################
+ # Test hasOneof<Field> methods exists and working
+ #########################################################
+
+ public function testHasOneof() {
+ $m = new TestMessage();
+ $this->assertFalse($m->hasOneofInt32());
+ $m->setOneofInt32(42);
+ $this->assertTrue($m->hasOneofInt32());
+ $m->setOneofString("bar");
+ $this->assertFalse($m->hasOneofInt32());
+ $this->assertTrue($m->hasOneofString());
+ $m->clear();
+ $this->assertFalse($m->hasOneofInt32());
+ $this->assertFalse($m->hasOneofString());
+ }
+
+}
diff --git a/php/tests/test.sh b/php/tests/test.sh
index 91ea56e..f693fe6 100755
--- a/php/tests/test.sh
+++ b/php/tests/test.sh
@@ -29,7 +29,7 @@
[ -f $PHPUNIT ] || wget https://phar.phpunit.de/$PHPUNIT
-tests=( ArrayTest.php EncodeDecodeTest.php GeneratedClassTest.php MapFieldTest.php WellKnownTest.php DescriptorsTest.php WrapperTypeSettersTest.php)
+tests=( ArrayTest.php EncodeDecodeTest.php GeneratedClassTest.php MapFieldTest.php WellKnownTest.php DescriptorsTest.php WrapperTypeSettersTest.php HasOneofTest.php)
for t in "${tests[@]}"
do