aboutsummaryrefslogtreecommitdiff
path: root/php
diff options
context:
space:
mode:
authormichaelbausor <michaelbausor@google.com>2018-11-28 16:44:53 -0800
committerPaul Yang <TeBoring@users.noreply.github.com>2018-11-28 16:44:53 -0800
commit0b9af83daeac04a6e8afa17343f7717c09239add (patch)
treee254dc6bcf0bdcb7f7340331e6cf58a0da7bfdec /php
parentbfdc2ba0ee776db8fb502d9efa42cd696f765496 (diff)
downloadprotobuf-0b9af83daeac04a6e8afa17343f7717c09239add.tar.gz
PHP: Add Enum methods for converting to/from strings (#5342)
* adds string-to-int and int-to-string methods to enums * remove check for valueToName property in EnumTrait * Remove unused imports * Update to avoid using EnumTrait * Remove EnumTrait * Update enum types * Move name and value methods into generated classes * Remove functions from GPBUtil * Test well known enums * Implement enum value to/from name in c extension * Only generate use statement when namespace is present
Diffstat (limited to 'php')
-rw-r--r--php/ext/google/protobuf/message.c224
-rw-r--r--php/ext/google/protobuf/protobuf.h12
-rw-r--r--php/src/Google/Protobuf/Field/Cardinality.php28
-rw-r--r--php/src/Google/Protobuf/Field/Kind.php43
-rw-r--r--php/src/Google/Protobuf/Internal/FieldDescriptorProto/Label.php27
-rw-r--r--php/src/Google/Protobuf/Internal/FieldDescriptorProto/Type.php42
-rw-r--r--php/src/Google/Protobuf/Internal/FieldOptions/CType.php27
-rw-r--r--php/src/Google/Protobuf/Internal/FieldOptions/JSType.php27
-rw-r--r--php/src/Google/Protobuf/Internal/FileOptions/OptimizeMode.php27
-rw-r--r--php/src/Google/Protobuf/Internal/MethodOptions/IdempotencyLevel.php27
-rw-r--r--php/src/Google/Protobuf/NullValue.php25
-rw-r--r--php/src/Google/Protobuf/Syntax.php26
-rw-r--r--php/tests/generated_class_test.php22
-rw-r--r--php/tests/well_known_test.php23
14 files changed, 580 insertions, 0 deletions
diff --git a/php/ext/google/protobuf/message.c b/php/ext/google/protobuf/message.c
index b99ca5b79..284332164 100644
--- a/php/ext/google/protobuf/message.c
+++ b/php/ext/google/protobuf/message.c
@@ -862,6 +862,8 @@ static void init_file_wrappers(TSRMLS_D) {
// -----------------------------------------------------------------------------
static zend_function_entry field_cardinality_methods[] = {
+ PHP_ME(Field_Cardinality, name, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
+ PHP_ME(Field_Cardinality, value, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
{NULL, NULL, NULL}
};
@@ -886,11 +888,60 @@ PHP_PROTO_INIT_ENUMCLASS_START("Google\\Protobuf\\Field\\Cardinality",
#endif
PHP_PROTO_INIT_ENUMCLASS_END
+PHP_METHOD(Field_Cardinality, name) {
+ PHP_PROTO_LONG value;
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &value) ==
+ FAILURE) {
+ return;
+ }
+ switch (value) {
+ case 0:
+ PHP_PROTO_RETURN_STRING("CARDINALITY_UNKNOWN", 1);
+ case 1:
+ PHP_PROTO_RETURN_STRING("CARDINALITY_OPTIONAL", 1);
+ case 2:
+ PHP_PROTO_RETURN_STRING("CARDINALITY_REQUIRED", 1);
+ case 3:
+ PHP_PROTO_RETURN_STRING("CARDINALITY_REPEATED", 1);
+ default:
+ zend_throw_exception(
+ NULL,
+ "Enum Google\\Protobuf\\Field_Cardinality has no name "
+ "defined for value %d.",
+ value,
+ 0 TSRMLS_CC);
+ }
+}
+
+PHP_METHOD(Field_Cardinality, value) {
+ char *name = NULL;
+ PHP_PROTO_SIZE name_len;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) ==
+ FAILURE) {
+ return;
+ }
+
+ if (strncmp(name, "CARDINALITY_UNKNOWN", name_len) == 0) RETURN_LONG(0);
+ if (strncmp(name, "CARDINALITY_OPTIONAL", name_len) == 0) RETURN_LONG(1);
+ if (strncmp(name, "CARDINALITY_REQUIRED", name_len) == 0) RETURN_LONG(2);
+ if (strncmp(name, "CARDINALITY_REPEATED", name_len) == 0) RETURN_LONG(3);
+
+ zend_throw_exception(
+ NULL,
+ "Enum Google\\Protobuf\\Field_Cardinality has no value "
+ "defined for name %s.",
+ name,
+ 0 TSRMLS_CC);
+}
+
// -----------------------------------------------------------------------------
// Field_Kind
// -----------------------------------------------------------------------------
static zend_function_entry field_kind_methods[] = {
+ PHP_ME(Field_Kind, name, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
+ PHP_ME(Field_Kind, value, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
{NULL, NULL, NULL}
};
@@ -945,11 +996,105 @@ PHP_PROTO_INIT_ENUMCLASS_START("Google\\Protobuf\\Field\\Kind",
#endif
PHP_PROTO_INIT_ENUMCLASS_END
+PHP_METHOD(Field_Kind, name) {
+ PHP_PROTO_LONG value;
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &value) ==
+ FAILURE) {
+ return;
+ }
+ switch (value) {
+ case 0:
+ PHP_PROTO_RETURN_STRING("TYPE_UNKNOWN", 1);
+ case 1:
+ PHP_PROTO_RETURN_STRING("TYPE_DOUBLE", 1);
+ case 2:
+ PHP_PROTO_RETURN_STRING("TYPE_FLOAT", 1);
+ case 3:
+ PHP_PROTO_RETURN_STRING("TYPE_INT64", 1);
+ case 4:
+ PHP_PROTO_RETURN_STRING("TYPE_UINT64", 1);
+ case 5:
+ PHP_PROTO_RETURN_STRING("TYPE_INT32", 1);
+ case 6:
+ PHP_PROTO_RETURN_STRING("TYPE_FIXED64", 1);
+ case 7:
+ PHP_PROTO_RETURN_STRING("TYPE_FIXED32", 1);
+ case 8:
+ PHP_PROTO_RETURN_STRING("TYPE_BOOL", 1);
+ case 9:
+ PHP_PROTO_RETURN_STRING("TYPE_STRING", 1);
+ case 10:
+ PHP_PROTO_RETURN_STRING("TYPE_GROUP", 1);
+ case 11:
+ PHP_PROTO_RETURN_STRING("TYPE_MESSAGE", 1);
+ case 12:
+ PHP_PROTO_RETURN_STRING("TYPE_BYTES", 1);
+ case 13:
+ PHP_PROTO_RETURN_STRING("TYPE_UINT32", 1);
+ case 14:
+ PHP_PROTO_RETURN_STRING("TYPE_ENUM", 1);
+ case 15:
+ PHP_PROTO_RETURN_STRING("TYPE_SFIXED32", 1);
+ case 16:
+ PHP_PROTO_RETURN_STRING("TYPE_SFIXED64", 1);
+ case 17:
+ PHP_PROTO_RETURN_STRING("TYPE_SINT32", 1);
+ case 18:
+ PHP_PROTO_RETURN_STRING("TYPE_SINT64", 1);
+ default:
+ zend_throw_exception(
+ NULL,
+ "Enum Google\\Protobuf\\Field_Kind has no name "
+ "defined for value %d.",
+ value,
+ 0 TSRMLS_CC);
+ }
+}
+
+PHP_METHOD(Field_Kind, value) {
+ char *name = NULL;
+ PHP_PROTO_SIZE name_len;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) ==
+ FAILURE) {
+ return;
+ }
+
+ if (strncmp(name, "TYPE_UNKNOWN", name_len) == 0) RETURN_LONG(0);
+ if (strncmp(name, "TYPE_DOUBLE", name_len) == 0) RETURN_LONG(1);
+ if (strncmp(name, "TYPE_FLOAT", name_len) == 0) RETURN_LONG(2);
+ if (strncmp(name, "TYPE_INT64", name_len) == 0) RETURN_LONG(3);
+ if (strncmp(name, "TYPE_UINT64", name_len) == 0) RETURN_LONG(4);
+ if (strncmp(name, "TYPE_INT32", name_len) == 0) RETURN_LONG(5);
+ if (strncmp(name, "TYPE_FIXED64", name_len) == 0) RETURN_LONG(6);
+ if (strncmp(name, "TYPE_FIXED32", name_len) == 0) RETURN_LONG(7);
+ if (strncmp(name, "TYPE_BOOL", name_len) == 0) RETURN_LONG(8);
+ if (strncmp(name, "TYPE_STRING", name_len) == 0) RETURN_LONG(9);
+ if (strncmp(name, "TYPE_GROUP", name_len) == 0) RETURN_LONG(10);
+ if (strncmp(name, "TYPE_MESSAGE", name_len) == 0) RETURN_LONG(11);
+ if (strncmp(name, "TYPE_BYTES", name_len) == 0) RETURN_LONG(12);
+ if (strncmp(name, "TYPE_UINT32", name_len) == 0) RETURN_LONG(13);
+ if (strncmp(name, "TYPE_ENUM", name_len) == 0) RETURN_LONG(14);
+ if (strncmp(name, "TYPE_SFIXED32", name_len) == 0) RETURN_LONG(15);
+ if (strncmp(name, "TYPE_SFIXED64", name_len) == 0) RETURN_LONG(16);
+ if (strncmp(name, "TYPE_SINT32", name_len) == 0) RETURN_LONG(17);
+ if (strncmp(name, "TYPE_SINT64", name_len) == 0) RETURN_LONG(18);
+
+ zend_throw_exception(
+ NULL,
+ "Enum Google\\Protobuf\\Field_Kind has no value "
+ "defined for name %s.",
+ name,
+ 0 TSRMLS_CC);
+}
+
// -----------------------------------------------------------------------------
// NullValue
// -----------------------------------------------------------------------------
static zend_function_entry null_value_methods[] = {
+ PHP_ME(NullValue, name, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
+ PHP_ME(NullValue, value, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
{NULL, NULL, NULL}
};
@@ -962,11 +1107,51 @@ PHP_PROTO_INIT_ENUMCLASS_START("Google\\Protobuf\\NullValue",
"NULL_VALUE", 10, 0 TSRMLS_CC);
PHP_PROTO_INIT_ENUMCLASS_END
+PHP_METHOD(NullValue, name) {
+ PHP_PROTO_LONG value;
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &value) ==
+ FAILURE) {
+ return;
+ }
+ switch (value) {
+ case 0:
+ PHP_PROTO_RETURN_STRING("NULL_VALUE", 1);
+ default:
+ zend_throw_exception(
+ NULL,
+ "Enum Google\\Protobuf\\NullValue has no name "
+ "defined for value %d.",
+ value,
+ 0 TSRMLS_CC);
+ }
+}
+
+PHP_METHOD(NullValue, value) {
+ char *name = NULL;
+ PHP_PROTO_SIZE name_len;
+
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) ==
+ FAILURE) {
+ return;
+ }
+
+ if (strncmp(name, "NULL_VALUE", name_len) == 0) RETURN_LONG(0);
+
+ zend_throw_exception(
+ NULL,
+ "Enum Google\\Protobuf\\NullValue has no value "
+ "defined for name %s.",
+ name,
+ 0 TSRMLS_CC);
+}
+
// -----------------------------------------------------------------------------
// Syntax
// -----------------------------------------------------------------------------
static zend_function_entry syntax_methods[] = {
+ PHP_ME(Syntax, name, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
+ PHP_ME(Syntax, value, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
{NULL, NULL, NULL}
};
@@ -981,7 +1166,46 @@ PHP_PROTO_INIT_ENUMCLASS_START("Google\\Protobuf\\Syntax",
"SYNTAX_PROTO3", 13, 1 TSRMLS_CC);
PHP_PROTO_INIT_ENUMCLASS_END
+PHP_METHOD(Syntax, name) {
+ PHP_PROTO_LONG value;
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &value) ==
+ FAILURE) {
+ return;
+ }
+ switch (value) {
+ case 0:
+ PHP_PROTO_RETURN_STRING("SYNTAX_PROTO2", 1);
+ case 1:
+ PHP_PROTO_RETURN_STRING("SYNTAX_PROTO3", 1);
+ default:
+ zend_throw_exception(
+ NULL,
+ "Enum Google\\Protobuf\\Syntax has no name "
+ "defined for value %d.",
+ value,
+ 0 TSRMLS_CC);
+ }
+}
+
+PHP_METHOD(Syntax, value) {
+ char *name = NULL;
+ PHP_PROTO_SIZE name_len;
+ if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name, &name_len) ==
+ FAILURE) {
+ return;
+ }
+
+ if (strncmp(name, "SYNTAX_PROTO2", name_len) == 0) RETURN_LONG(0);
+ if (strncmp(name, "SYNTAX_PROTO3", name_len) == 0) RETURN_LONG(1);
+
+ zend_throw_exception(
+ NULL,
+ "Enum Google\\Protobuf\\Syntax has no value "
+ "defined for name %s.",
+ name,
+ 0 TSRMLS_CC);
+}
// -----------------------------------------------------------------------------
// Define message
diff --git a/php/ext/google/protobuf/protobuf.h b/php/ext/google/protobuf/protobuf.h
index a84feec66..0045358a4 100644
--- a/php/ext/google/protobuf/protobuf.h
+++ b/php/ext/google/protobuf/protobuf.h
@@ -1301,6 +1301,12 @@ PHP_METHOD(Field, setJsonName);
PHP_METHOD(Field, getDefaultValue);
PHP_METHOD(Field, setDefaultValue);
+PHP_METHOD(Field_Cardinality, name);
+PHP_METHOD(Field_Cardinality, value);
+
+PHP_METHOD(Field_Kind, name);
+PHP_METHOD(Field_Kind, value);
+
PHP_METHOD(FloatValue, __construct);
PHP_METHOD(FloatValue, getValue);
PHP_METHOD(FloatValue, setValue);
@@ -1341,6 +1347,9 @@ PHP_METHOD(Mixin, setName);
PHP_METHOD(Mixin, getRoot);
PHP_METHOD(Mixin, setRoot);
+PHP_METHOD(NullValue, name);
+PHP_METHOD(NullValue, value);
+
PHP_METHOD(Option, __construct);
PHP_METHOD(Option, getName);
PHP_METHOD(Option, setName);
@@ -1359,6 +1368,9 @@ PHP_METHOD(Struct, __construct);
PHP_METHOD(Struct, getFields);
PHP_METHOD(Struct, setFields);
+PHP_METHOD(Syntax, name);
+PHP_METHOD(Syntax, value);
+
PHP_METHOD(Type, __construct);
PHP_METHOD(Type, getName);
PHP_METHOD(Type, setName);
diff --git a/php/src/Google/Protobuf/Field/Cardinality.php b/php/src/Google/Protobuf/Field/Cardinality.php
index c887f6d31..479dc0bfc 100644
--- a/php/src/Google/Protobuf/Field/Cardinality.php
+++ b/php/src/Google/Protobuf/Field/Cardinality.php
@@ -4,6 +4,8 @@
namespace Google\Protobuf\Field;
+use UnexpectedValueException;
+
/**
* Whether a field is optional, required, or repeated.
*
@@ -35,6 +37,32 @@ class Cardinality
* Generated from protobuf enum <code>CARDINALITY_REPEATED = 3;</code>
*/
const CARDINALITY_REPEATED = 3;
+
+ private static $valueToName = [
+ self::CARDINALITY_UNKNOWN => 'CARDINALITY_UNKNOWN',
+ self::CARDINALITY_OPTIONAL => 'CARDINALITY_OPTIONAL',
+ self::CARDINALITY_REQUIRED => 'CARDINALITY_REQUIRED',
+ self::CARDINALITY_REPEATED => 'CARDINALITY_REPEATED',
+ ];
+
+ public static function name($value)
+ {
+ if (!isset(self::$valueToName[$value])) {
+ throw new UnexpectedValueException(sprintf(
+ 'Enum %s has no name defined for value %s', __CLASS__, $value));
+ }
+ return self::$valueToName[$value];
+ }
+
+ public static function value($name)
+ {
+ $const = __CLASS__ . '::' . strtoupper($name);
+ if (!defined($const)) {
+ throw new UnexpectedValueException(sprintf(
+ 'Enum %s has no value defined for name %s', __CLASS__, $name));
+ }
+ return constant($const);
+ }
}
// Adding a class alias for backwards compatibility with the previous class name.
diff --git a/php/src/Google/Protobuf/Field/Kind.php b/php/src/Google/Protobuf/Field/Kind.php
index a2bbbdebb..f30bd2f59 100644
--- a/php/src/Google/Protobuf/Field/Kind.php
+++ b/php/src/Google/Protobuf/Field/Kind.php
@@ -4,6 +4,8 @@
namespace Google\Protobuf\Field;
+use UnexpectedValueException;
+
/**
* Basic field types.
*
@@ -125,6 +127,47 @@ class Kind
* Generated from protobuf enum <code>TYPE_SINT64 = 18;</code>
*/
const TYPE_SINT64 = 18;
+
+ private static $valueToName = [
+ self::TYPE_UNKNOWN => 'TYPE_UNKNOWN',
+ self::TYPE_DOUBLE => 'TYPE_DOUBLE',
+ self::TYPE_FLOAT => 'TYPE_FLOAT',
+ self::TYPE_INT64 => 'TYPE_INT64',
+ self::TYPE_UINT64 => 'TYPE_UINT64',
+ self::TYPE_INT32 => 'TYPE_INT32',
+ self::TYPE_FIXED64 => 'TYPE_FIXED64',
+ self::TYPE_FIXED32 => 'TYPE_FIXED32',
+ self::TYPE_BOOL => 'TYPE_BOOL',
+ self::TYPE_STRING => 'TYPE_STRING',
+ self::TYPE_GROUP => 'TYPE_GROUP',
+ self::TYPE_MESSAGE => 'TYPE_MESSAGE',
+ self::TYPE_BYTES => 'TYPE_BYTES',
+ self::TYPE_UINT32 => 'TYPE_UINT32',
+ self::TYPE_ENUM => 'TYPE_ENUM',
+ self::TYPE_SFIXED32 => 'TYPE_SFIXED32',
+ self::TYPE_SFIXED64 => 'TYPE_SFIXED64',
+ self::TYPE_SINT32 => 'TYPE_SINT32',
+ self::TYPE_SINT64 => 'TYPE_SINT64',
+ ];
+
+ public static function name($value)
+ {
+ if (!isset(self::$valueToName[$value])) {
+ throw new UnexpectedValueException(sprintf(
+ 'Enum %s has no name defined for value %s', __CLASS__, $value));
+ }
+ return self::$valueToName[$value];
+ }
+
+ public static function value($name)
+ {
+ $const = __CLASS__ . '::' . strtoupper($name);
+ if (!defined($const)) {
+ throw new UnexpectedValueException(sprintf(
+ 'Enum %s has no value defined for name %s', __CLASS__, $name));
+ }
+ return constant($const);
+ }
}
// Adding a class alias for backwards compatibility with the previous class name.
diff --git a/php/src/Google/Protobuf/Internal/FieldDescriptorProto/Label.php b/php/src/Google/Protobuf/Internal/FieldDescriptorProto/Label.php
index b105088e6..f10505724 100644
--- a/php/src/Google/Protobuf/Internal/FieldDescriptorProto/Label.php
+++ b/php/src/Google/Protobuf/Internal/FieldDescriptorProto/Label.php
@@ -4,6 +4,8 @@
namespace Google\Protobuf\Internal\FieldDescriptorProto;
+use UnexpectedValueException;
+
/**
* Protobuf type <code>google.protobuf.FieldDescriptorProto.Label</code>
*/
@@ -23,6 +25,31 @@ class Label
* Generated from protobuf enum <code>LABEL_REPEATED = 3;</code>
*/
const LABEL_REPEATED = 3;
+
+ private static $valueToName = [
+ self::LABEL_OPTIONAL => 'LABEL_OPTIONAL',
+ self::LABEL_REQUIRED => 'LABEL_REQUIRED',
+ self::LABEL_REPEATED => 'LABEL_REPEATED',
+ ];
+
+ public static function name($value)
+ {
+ if (!isset(self::$valueToName[$value])) {
+ throw new UnexpectedValueException(sprintf(
+ 'Enum %s has no name defined for value %s', __CLASS__, $value));
+ }
+ return self::$valueToName[$value];
+ }
+
+ public static function value($name)
+ {
+ $const = __CLASS__ . '::' . strtoupper($name);
+ if (!defined($const)) {
+ throw new UnexpectedValueException(sprintf(
+ 'Enum %s has no value defined for name %s', __CLASS__, $name));
+ }
+ return constant($const);
+ }
}
// Adding a class alias for backwards compatibility with the previous class name.
diff --git a/php/src/Google/Protobuf/Internal/FieldDescriptorProto/Type.php b/php/src/Google/Protobuf/Internal/FieldDescriptorProto/Type.php
index ea228a77f..74559978a 100644
--- a/php/src/Google/Protobuf/Internal/FieldDescriptorProto/Type.php
+++ b/php/src/Google/Protobuf/Internal/FieldDescriptorProto/Type.php
@@ -4,6 +4,8 @@
namespace Google\Protobuf\Internal\FieldDescriptorProto;
+use UnexpectedValueException;
+
/**
* Protobuf type <code>google.protobuf.FieldDescriptorProto.Type</code>
*/
@@ -103,6 +105,46 @@ class Type
* Generated from protobuf enum <code>TYPE_SINT64 = 18;</code>
*/
const TYPE_SINT64 = 18;
+
+ private static $valueToName = [
+ self::TYPE_DOUBLE => 'TYPE_DOUBLE',
+ self::TYPE_FLOAT => 'TYPE_FLOAT',
+ self::TYPE_INT64 => 'TYPE_INT64',
+ self::TYPE_UINT64 => 'TYPE_UINT64',
+ self::TYPE_INT32 => 'TYPE_INT32',
+ self::TYPE_FIXED64 => 'TYPE_FIXED64',
+ self::TYPE_FIXED32 => 'TYPE_FIXED32',
+ self::TYPE_BOOL => 'TYPE_BOOL',
+ self::TYPE_STRING => 'TYPE_STRING',
+ self::TYPE_GROUP => 'TYPE_GROUP',
+ self::TYPE_MESSAGE => 'TYPE_MESSAGE',
+ self::TYPE_BYTES => 'TYPE_BYTES',
+ self::TYPE_UINT32 => 'TYPE_UINT32',
+ self::TYPE_ENUM => 'TYPE_ENUM',
+ self::TYPE_SFIXED32 => 'TYPE_SFIXED32',
+ self::TYPE_SFIXED64 => 'TYPE_SFIXED64',
+ self::TYPE_SINT32 => 'TYPE_SINT32',
+ self::TYPE_SINT64 => 'TYPE_SINT64',
+ ];
+
+ public static function name($value)
+ {
+ if (!isset(self::$valueToName[$value])) {
+ throw new UnexpectedValueException(sprintf(
+ 'Enum %s has no name defined for value %s', __CLASS__, $value));
+ }
+ return self::$valueToName[$value];
+ }
+
+ public static function value($name)
+ {
+ $const = __CLASS__ . '::' . strtoupper($name);
+ if (!defined($const)) {
+ throw new UnexpectedValueException(sprintf(
+ 'Enum %s has no value defined for name %s', __CLASS__, $name));
+ }
+ return constant($const);
+ }
}
// Adding a class alias for backwards compatibility with the previous class name.
diff --git a/php/src/Google/Protobuf/Internal/FieldOptions/CType.php b/php/src/Google/Protobuf/Internal/FieldOptions/CType.php
index 016197acb..9043640cb 100644
--- a/php/src/Google/Protobuf/Internal/FieldOptions/CType.php
+++ b/php/src/Google/Protobuf/Internal/FieldOptions/CType.php
@@ -4,6 +4,8 @@
namespace Google\Protobuf\Internal\FieldOptions;
+use UnexpectedValueException;
+
/**
* Protobuf type <code>google.protobuf.FieldOptions.CType</code>
*/
@@ -23,6 +25,31 @@ class CType
* Generated from protobuf enum <code>STRING_PIECE = 2;</code>
*/
const STRING_PIECE = 2;
+
+ private static $valueToName = [
+ self::STRING => 'STRING',
+ self::CORD => 'CORD',
+ self::STRING_PIECE => 'STRING_PIECE',
+ ];
+
+ public static function name($value)
+ {
+ if (!isset(self::$valueToName[$value])) {
+ throw new UnexpectedValueException(sprintf(
+ 'Enum %s has no name defined for value %s', __CLASS__, $value));
+ }
+ return self::$valueToName[$value];
+ }
+
+ public static function value($name)
+ {
+ $const = __CLASS__ . '::' . strtoupper($name);
+ if (!defined($const)) {
+ throw new UnexpectedValueException(sprintf(
+ 'Enum %s has no value defined for name %s', __CLASS__, $name));
+ }
+ return constant($const);
+ }
}
// Adding a class alias for backwards compatibility with the previous class name.
diff --git a/php/src/Google/Protobuf/Internal/FieldOptions/JSType.php b/php/src/Google/Protobuf/Internal/FieldOptions/JSType.php
index f7b78a1b3..5ff81620e 100644
--- a/php/src/Google/Protobuf/Internal/FieldOptions/JSType.php
+++ b/php/src/Google/Protobuf/Internal/FieldOptions/JSType.php
@@ -4,6 +4,8 @@
namespace Google\Protobuf\Internal\FieldOptions;
+use UnexpectedValueException;
+
/**
* Protobuf type <code>google.protobuf.FieldOptions.JSType</code>
*/
@@ -27,6 +29,31 @@ class JSType
* Generated from protobuf enum <code>JS_NUMBER = 2;</code>
*/
const JS_NUMBER = 2;
+
+ private static $valueToName = [
+ self::JS_NORMAL => 'JS_NORMAL',
+ self::JS_STRING => 'JS_STRING',
+ self::JS_NUMBER => 'JS_NUMBER',
+ ];
+
+ public static function name($value)
+ {
+ if (!isset(self::$valueToName[$value])) {
+ throw new UnexpectedValueException(sprintf(
+ 'Enum %s has no name defined for value %s', __CLASS__, $value));
+ }
+ return self::$valueToName[$value];
+ }
+
+ public static function value($name)
+ {
+ $const = __CLASS__ . '::' . strtoupper($name);
+ if (!defined($const)) {
+ throw new UnexpectedValueException(sprintf(
+ 'Enum %s has no value defined for name %s', __CLASS__, $name));
+ }
+ return constant($const);
+ }
}
// Adding a class alias for backwards compatibility with the previous class name.
diff --git a/php/src/Google/Protobuf/Internal/FileOptions/OptimizeMode.php b/php/src/Google/Protobuf/Internal/FileOptions/OptimizeMode.php
index 3dd60bf6e..119b23a90 100644
--- a/php/src/Google/Protobuf/Internal/FileOptions/OptimizeMode.php
+++ b/php/src/Google/Protobuf/Internal/FileOptions/OptimizeMode.php
@@ -4,6 +4,8 @@
namespace Google\Protobuf\Internal\FileOptions;
+use UnexpectedValueException;
+
/**
* Generated classes can be optimized for speed or code size.
*
@@ -29,6 +31,31 @@ class OptimizeMode
* Generated from protobuf enum <code>LITE_RUNTIME = 3;</code>
*/
const LITE_RUNTIME = 3;
+
+ private static $valueToName = [
+ self::SPEED => 'SPEED',
+ self::CODE_SIZE => 'CODE_SIZE',
+ self::LITE_RUNTIME => 'LITE_RUNTIME',
+ ];
+
+ public static function name($value)
+ {
+ if (!isset(self::$valueToName[$value])) {
+ throw new UnexpectedValueException(sprintf(
+ 'Enum %s has no name defined for value %s', __CLASS__, $value));
+ }
+ return self::$valueToName[$value];
+ }
+
+ public static function value($name)
+ {
+ $const = __CLASS__ . '::' . strtoupper($name);
+ if (!defined($const)) {
+ throw new UnexpectedValueException(sprintf(
+ 'Enum %s has no value defined for name %s', __CLASS__, $name));
+ }
+ return constant($const);
+ }
}
// Adding a class alias for backwards compatibility with the previous class name.
diff --git a/php/src/Google/Protobuf/Internal/MethodOptions/IdempotencyLevel.php b/php/src/Google/Protobuf/Internal/MethodOptions/IdempotencyLevel.php
index dcc30e271..ab94458f7 100644
--- a/php/src/Google/Protobuf/Internal/MethodOptions/IdempotencyLevel.php
+++ b/php/src/Google/Protobuf/Internal/MethodOptions/IdempotencyLevel.php
@@ -4,6 +4,8 @@
namespace Google\Protobuf\Internal\MethodOptions;
+use UnexpectedValueException;
+
/**
* Is this method side-effect-free (or safe in HTTP parlance), or idempotent,
* or neither? HTTP based RPC implementation may choose GET verb for safe
@@ -29,6 +31,31 @@ class IdempotencyLevel
* Generated from protobuf enum <code>IDEMPOTENT = 2;</code>
*/
const IDEMPOTENT = 2;
+
+ private static $valueToName = [
+ self::IDEMPOTENCY_UNKNOWN => 'IDEMPOTENCY_UNKNOWN',
+ self::NO_SIDE_EFFECTS => 'NO_SIDE_EFFECTS',
+ self::IDEMPOTENT => 'IDEMPOTENT',
+ ];
+
+ public static function name($value)
+ {
+ if (!isset(self::$valueToName[$value])) {
+ throw new UnexpectedValueException(sprintf(
+ 'Enum %s has no name defined for value %s', __CLASS__, $value));
+ }
+ return self::$valueToName[$value];
+ }
+
+ public static function value($name)
+ {
+ $const = __CLASS__ . '::' . strtoupper($name);
+ if (!defined($const)) {
+ throw new UnexpectedValueException(sprintf(
+ 'Enum %s has no value defined for name %s', __CLASS__, $name));
+ }
+ return constant($const);
+ }
}
// Adding a class alias for backwards compatibility with the previous class name.
diff --git a/php/src/Google/Protobuf/NullValue.php b/php/src/Google/Protobuf/NullValue.php
index 482b80dde..a72cbb2ed 100644
--- a/php/src/Google/Protobuf/NullValue.php
+++ b/php/src/Google/Protobuf/NullValue.php
@@ -4,6 +4,8 @@
namespace Google\Protobuf;
+use UnexpectedValueException;
+
/**
* `NullValue` is a singleton enumeration to represent the null value for the
* `Value` type union.
@@ -19,5 +21,28 @@ class NullValue
* Generated from protobuf enum <code>NULL_VALUE = 0;</code>
*/
const NULL_VALUE = 0;
+
+ private static $valueToName = [
+ self::NULL_VALUE => 'NULL_VALUE',
+ ];
+
+ public static function name($value)
+ {
+ if (!isset(self::$valueToName[$value])) {
+ throw new UnexpectedValueException(sprintf(
+ 'Enum %s has no name defined for value %s', __CLASS__, $value));
+ }
+ return self::$valueToName[$value];
+ }
+
+ public static function value($name)
+ {
+ $const = __CLASS__ . '::' . strtoupper($name);
+ if (!defined($const)) {
+ throw new UnexpectedValueException(sprintf(
+ 'Enum %s has no value defined for name %s', __CLASS__, $name));
+ }
+ return constant($const);
+ }
}
diff --git a/php/src/Google/Protobuf/Syntax.php b/php/src/Google/Protobuf/Syntax.php
index 3a52dc9e1..9812669da 100644
--- a/php/src/Google/Protobuf/Syntax.php
+++ b/php/src/Google/Protobuf/Syntax.php
@@ -4,6 +4,8 @@
namespace Google\Protobuf;
+use UnexpectedValueException;
+
/**
* The syntax in which a protocol buffer element is defined.
*
@@ -23,5 +25,29 @@ class Syntax
* Generated from protobuf enum <code>SYNTAX_PROTO3 = 1;</code>
*/
const SYNTAX_PROTO3 = 1;
+
+ private static $valueToName = [
+ self::SYNTAX_PROTO2 => 'SYNTAX_PROTO2',
+ self::SYNTAX_PROTO3 => 'SYNTAX_PROTO3',
+ ];
+
+ public static function name($value)
+ {
+ if (!isset(self::$valueToName[$value])) {
+ throw new UnexpectedValueException(sprintf(
+ 'Enum %s has no name defined for value %s', __CLASS__, $value));
+ }
+ return self::$valueToName[$value];
+ }
+
+ public static function value($name)
+ {
+ $const = __CLASS__ . '::' . strtoupper($name);
+ if (!defined($const)) {
+ throw new UnexpectedValueException(sprintf(
+ 'Enum %s has no value defined for name %s', __CLASS__, $name));
+ }
+ return constant($const);
+ }
}
diff --git a/php/tests/generated_class_test.php b/php/tests/generated_class_test.php
index 8bac4e5eb..96dad228a 100644
--- a/php/tests/generated_class_test.php
+++ b/php/tests/generated_class_test.php
@@ -232,6 +232,28 @@ class GeneratedClassTest extends TestBase
// Set string.
$m->setOptionalEnum("1");
$this->assertEquals(TestEnum::ONE, $m->getOptionalEnum());
+
+ // Test Enum methods
+ $this->assertEquals('ONE', TestEnum::name(1));
+ $this->assertEquals(1, TestEnum::value('ONE'));
+ }
+
+ /**
+ * @expectedException UnexpectedValueException
+ * @expectedExceptionMessage Enum Foo\TestEnum has no name defined for value -1
+ */
+ public function testInvalidEnumValueThrowsException()
+ {
+ TestEnum::name(-1);
+ }
+
+ /**
+ * @expectedException UnexpectedValueException
+ * @expectedExceptionMessage Enum Foo\TestEnum has no value defined for name DOES_NOT_EXIST
+ */
+ public function testInvalidEnumNameThrowsException()
+ {
+ TestEnum::value('DOES_NOT_EXIST');
}
public function testNestedEnum()
diff --git a/php/tests/well_known_test.php b/php/tests/well_known_test.php
index 6a788df29..db5d5a7a0 100644
--- a/php/tests/well_known_test.php
+++ b/php/tests/well_known_test.php
@@ -392,4 +392,27 @@ class WellKnownTest extends TestBase {
$m->setValue("a");
$this->assertSame("a", $m->getValue());
}
+
+ /**
+ * @dataProvider enumNameValueConversionDataProvider
+ */
+ public function testEnumNameValueConversion($class)
+ {
+ $reflectionClass = new ReflectionClass($class);
+ $constants = $reflectionClass->getConstants();
+ foreach ($constants as $k => $v) {
+ $this->assertSame($k, $class::name($v));
+ $this->assertSame($v, $class::value($k));
+ }
+ }
+
+ public function enumNameValueConversionDataProvider()
+ {
+ return [
+ ['\Google\Protobuf\Field\Cardinality'],
+ ['\Google\Protobuf\Field\Kind'],
+ ['\Google\Protobuf\NullValue'],
+ ['\Google\Protobuf\Syntax'],
+ ];
+ }
}