Permalink
Browse files

PHP: Add support for primitive types in setters (#5126)

* Add support for primitive types in setters

* Update to address PR feedback

* Add tests and fixes for repeated fields

* Remove repeated field code, add getters

* Cleanup, test getters and oneofs

* Move boxing logic into separate class

* Add tests for wrapper type constructor args

* Update to add new setXXXValue methods

* Fix tests for invalid values

* Fix c extension for wrapper accessors

* Fix the bug that well known types didn't call Message_construct

* Address PR comments

* Refactoring init message with array logic

* Add include path to protoc

* Add missing TSRM_LS defintion

* Fix TSRM_LS

* Fix dist check
  • Loading branch information...
michaelbausor authored and TeBoring committed Oct 7, 2018
1 parent 9e69594 commit 6a51c03823448a9229c50795ae0d984ac0fe4fbd
View
@@ -194,3 +194,7 @@ cmake/cmake-build-debug/
# Visual Studio 2017
.vs
# IntelliJ
.idea
*.iml
View
@@ -749,11 +749,13 @@ php_EXTRA_DIST= \
php/tests/proto/test_reserved_message_upper.proto \
php/tests/proto/test_service.proto \
php/tests/proto/test_service_namespace.proto \
php/tests/proto/test_wrapper_type_setters.proto \
php/tests/test.sh \
php/tests/test_base.php \
php/tests/test_util.php \
php/tests/undefined_test.php \
php/tests/well_known_test.php
php/tests/well_known_test.php \
php/tests/wrapper_type_setters_test.php
python_EXTRA_DIST= \
python/MANIFEST.in \
View
@@ -23,6 +23,6 @@
}
},
"scripts": {
"test": "(cd tests && rm -rf generated && mkdir -p generated && ../../src/protoc --php_out=generated proto/empty/echo.proto proto/test.proto proto/test_include.proto proto/test_no_namespace.proto proto/test_prefix.proto proto/test_php_namespace.proto proto/test_empty_php_namespace.proto proto/test_reserved_enum_lower.proto proto/test_reserved_enum_upper.proto proto/test_reserved_enum_value_lower.proto proto/test_reserved_enum_value_upper.proto proto/test_reserved_message_lower.proto proto/test_reserved_message_upper.proto proto/test_service.proto proto/test_service_namespace.proto proto/test_descriptors.proto) && (cd ../src && ./protoc --php_out=../php/tests/generated -I../php/tests -I. ../php/tests/proto/test_import_descriptor_proto.proto) && vendor/bin/phpunit"
"test": "(cd tests && rm -rf generated && mkdir -p generated && ../../src/protoc --php_out=generated -I../../src -I. proto/empty/echo.proto proto/test.proto proto/test_include.proto proto/test_no_namespace.proto proto/test_prefix.proto proto/test_php_namespace.proto proto/test_empty_php_namespace.proto proto/test_reserved_enum_lower.proto proto/test_reserved_enum_upper.proto proto/test_reserved_enum_value_lower.proto proto/test_reserved_enum_value_upper.proto proto/test_reserved_message_lower.proto proto/test_reserved_message_upper.proto proto/test_service.proto proto/test_service_namespace.proto proto/test_wrapper_type_setters.proto proto/test_descriptors.proto) && (cd ../src && ./protoc --php_out=../php/tests/generated -I../php/tests -I. ../php/tests/proto/test_import_descriptor_proto.proto) && vendor/bin/phpunit"
}
}
@@ -254,6 +254,16 @@ void custom_data_init(const zend_class_entry* ce,
&intern->std PHP_PROTO_TSRMLS_CC);
}
#define INIT_MESSAGE_WITH_ARRAY \
{ \
zval* array_wrapper = NULL; \
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, \
"|a!", &array_wrapper) == FAILURE) { \
return; \
} \
Message_construct(getThis(), array_wrapper); \
}
void build_class_from_descriptor(
PHP_PROTO_HASHTABLE_VALUE php_descriptor TSRMLS_DC) {
Descriptor* desc = UNBOX_HASHTABLE_VALUE(Descriptor, php_descriptor);
@@ -361,15 +371,26 @@ void Message_construct(zval* msg, zval* array_wrapper) {
zval* submsg = CACHED_PTR_TO_ZVAL_PTR(cached);
ZVAL_OBJ(submsg, desc->klass->create_object(desc->klass TSRMLS_CC));
Message_construct(submsg, NULL);
MessageHeader* from = UNBOX(MessageHeader,
CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)value));
MessageHeader* to = UNBOX(MessageHeader, submsg);
if(from->descriptor != to->descriptor) {
zend_error(E_USER_ERROR, "Cannot merge messages with different class.");
return;
const upb_filedef *file = upb_def_file(upb_msgdef_upcast(submsgdef));
if (!strcmp(upb_filedef_name(file), "google/protobuf/wrappers.proto") &&
Z_TYPE_P(CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)value)) != IS_OBJECT) {
const upb_fielddef *value_field = upb_msgdef_itof(submsgdef, 1);
layout_set(to->descriptor->layout, to,
value_field, CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)value)
TSRMLS_CC);
} else {
MessageHeader* from =
UNBOX(MessageHeader,
CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)value));
if(from->descriptor != to->descriptor) {
zend_error(E_USER_ERROR,
"Cannot merge messages with different class.");
return;
}
layout_merge(from->descriptor->layout, from, to TSRMLS_CC);
}
layout_merge(from->descriptor->layout, from, to TSRMLS_CC);
} else {
message_set_property_internal(msg, &key,
CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)value) TSRMLS_CC);
@@ -382,14 +403,7 @@ void Message_construct(zval* msg, zval* array_wrapper) {
// modified. As a result, the first created instance will be a normal zend
// object. Here, we manually modify it to our message in such a case.
PHP_METHOD(Message, __construct) {
// Init message with array
zval* array_wrapper = NULL;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,
"|a!", &array_wrapper) == FAILURE) {
return;
}
Message_construct(getThis(), array_wrapper);
INIT_MESSAGE_WITH_ARRAY;
}
PHP_METHOD(Message, clear) {
@@ -1024,7 +1038,7 @@ static void hex_to_binary(const char* hex, char** binary, int* binary_len) {
PHP_METHOD(Any, __construct) {
init_file_any(TSRMLS_C);
MessageHeader* intern = UNBOX(MessageHeader, getThis());
custom_data_init(any_type, intern PHP_PROTO_TSRMLS_CC);
INIT_MESSAGE_WITH_ARRAY;
}
PHP_PROTO_FIELD_ACCESSORS(Any, any, TypeUrl, "type_url")
@@ -1193,7 +1207,7 @@ PHP_PROTO_INIT_SUBMSGCLASS_END
PHP_METHOD(Duration, __construct) {
init_file_duration(TSRMLS_C);
MessageHeader* intern = UNBOX(MessageHeader, getThis());
custom_data_init(duration_type, intern PHP_PROTO_TSRMLS_CC);
INIT_MESSAGE_WITH_ARRAY;
}
PHP_PROTO_FIELD_ACCESSORS(Duration, duration, Seconds, "seconds")
@@ -1229,7 +1243,7 @@ PHP_PROTO_INIT_SUBMSGCLASS_END
PHP_METHOD(Timestamp, __construct) {
init_file_timestamp(TSRMLS_C);
MessageHeader* intern = UNBOX(MessageHeader, getThis());
custom_data_init(timestamp_type, intern PHP_PROTO_TSRMLS_CC);
INIT_MESSAGE_WITH_ARRAY;
}
PHP_PROTO_FIELD_ACCESSORS(Timestamp, timestamp, Seconds, "seconds")
@@ -1432,7 +1446,7 @@ PHP_PROTO_INIT_SUBMSGCLASS_END
PHP_METHOD(Api, __construct) {
init_file_api(TSRMLS_C);
MessageHeader* intern = UNBOX(MessageHeader, getThis());
custom_data_init(api_type, intern PHP_PROTO_TSRMLS_CC);
INIT_MESSAGE_WITH_ARRAY;
}
PHP_PROTO_FIELD_ACCESSORS(Api, api, Name, "name")
@@ -1467,7 +1481,7 @@ PHP_PROTO_INIT_SUBMSGCLASS_END
PHP_METHOD(BoolValue, __construct) {
init_file_wrappers(TSRMLS_C);
MessageHeader* intern = UNBOX(MessageHeader, getThis());
custom_data_init(bool_value_type, intern PHP_PROTO_TSRMLS_CC);
INIT_MESSAGE_WITH_ARRAY;
}
PHP_PROTO_FIELD_ACCESSORS(BoolValue, bool_value, Value, "value")
@@ -1496,7 +1510,7 @@ PHP_PROTO_INIT_SUBMSGCLASS_END
PHP_METHOD(BytesValue, __construct) {
init_file_wrappers(TSRMLS_C);
MessageHeader* intern = UNBOX(MessageHeader, getThis());
custom_data_init(bytes_value_type, intern PHP_PROTO_TSRMLS_CC);
INIT_MESSAGE_WITH_ARRAY;
}
PHP_PROTO_FIELD_ACCESSORS(BytesValue, bytes_value, Value, "value")
@@ -1525,7 +1539,7 @@ PHP_PROTO_INIT_SUBMSGCLASS_END
PHP_METHOD(DoubleValue, __construct) {
init_file_wrappers(TSRMLS_C);
MessageHeader* intern = UNBOX(MessageHeader, getThis());
custom_data_init(double_value_type, intern PHP_PROTO_TSRMLS_CC);
INIT_MESSAGE_WITH_ARRAY;
}
PHP_PROTO_FIELD_ACCESSORS(DoubleValue, double_value, Value, "value")
@@ -1570,7 +1584,7 @@ PHP_PROTO_INIT_SUBMSGCLASS_END
PHP_METHOD(Enum, __construct) {
init_file_type(TSRMLS_C);
MessageHeader* intern = UNBOX(MessageHeader, getThis());
custom_data_init(enum_type, intern PHP_PROTO_TSRMLS_CC);
INIT_MESSAGE_WITH_ARRAY;
}
PHP_PROTO_FIELD_ACCESSORS(Enum, enum, Name, "name")
@@ -1611,7 +1625,7 @@ PHP_PROTO_INIT_SUBMSGCLASS_END
PHP_METHOD(EnumValue, __construct) {
init_file_type(TSRMLS_C);
MessageHeader* intern = UNBOX(MessageHeader, getThis());
custom_data_init(enum_value_type, intern PHP_PROTO_TSRMLS_CC);
INIT_MESSAGE_WITH_ARRAY;
}
PHP_PROTO_FIELD_ACCESSORS(EnumValue, enum_value, Name, "name")
@@ -1642,7 +1656,7 @@ PHP_PROTO_INIT_SUBMSGCLASS_END
PHP_METHOD(FieldMask, __construct) {
init_file_field_mask(TSRMLS_C);
MessageHeader* intern = UNBOX(MessageHeader, getThis());
custom_data_init(field_mask_type, intern PHP_PROTO_TSRMLS_CC);
INIT_MESSAGE_WITH_ARRAY;
}
PHP_PROTO_FIELD_ACCESSORS(FieldMask, field_mask, Paths, "paths")
@@ -1707,7 +1721,7 @@ PHP_PROTO_INIT_SUBMSGCLASS_END
PHP_METHOD(Field, __construct) {
init_file_type(TSRMLS_C);
MessageHeader* intern = UNBOX(MessageHeader, getThis());
custom_data_init(field_type, intern PHP_PROTO_TSRMLS_CC);
INIT_MESSAGE_WITH_ARRAY;
}
PHP_PROTO_FIELD_ACCESSORS(Field, field, Kind, "kind")
@@ -1745,7 +1759,7 @@ PHP_PROTO_INIT_SUBMSGCLASS_END
PHP_METHOD(FloatValue, __construct) {
init_file_wrappers(TSRMLS_C);
MessageHeader* intern = UNBOX(MessageHeader, getThis());
custom_data_init(float_value_type, intern PHP_PROTO_TSRMLS_CC);
INIT_MESSAGE_WITH_ARRAY;
}
PHP_PROTO_FIELD_ACCESSORS(FloatValue, float_value, Value, "value")
@@ -1770,7 +1784,7 @@ PHP_PROTO_INIT_SUBMSGCLASS_END
PHP_METHOD(GPBEmpty, __construct) {
init_file_empty(TSRMLS_C);
MessageHeader* intern = UNBOX(MessageHeader, getThis());
custom_data_init(empty_type, intern PHP_PROTO_TSRMLS_CC);
INIT_MESSAGE_WITH_ARRAY;
}
@@ -1798,7 +1812,7 @@ PHP_PROTO_INIT_SUBMSGCLASS_END
PHP_METHOD(Int32Value, __construct) {
init_file_wrappers(TSRMLS_C);
MessageHeader* intern = UNBOX(MessageHeader, getThis());
custom_data_init(int32_value_type, intern PHP_PROTO_TSRMLS_CC);
INIT_MESSAGE_WITH_ARRAY;
}
PHP_PROTO_FIELD_ACCESSORS(Int32Value, int32_value, Value, "value")
@@ -1827,7 +1841,7 @@ PHP_PROTO_INIT_SUBMSGCLASS_END
PHP_METHOD(Int64Value, __construct) {
init_file_wrappers(TSRMLS_C);
MessageHeader* intern = UNBOX(MessageHeader, getThis());
custom_data_init(int64_value_type, intern PHP_PROTO_TSRMLS_CC);
INIT_MESSAGE_WITH_ARRAY;
}
PHP_PROTO_FIELD_ACCESSORS(Int64Value, int64_value, Value, "value")
@@ -1856,7 +1870,7 @@ PHP_PROTO_INIT_SUBMSGCLASS_END
PHP_METHOD(ListValue, __construct) {
init_file_struct(TSRMLS_C);
MessageHeader* intern = UNBOX(MessageHeader, getThis());
custom_data_init(list_value_type, intern PHP_PROTO_TSRMLS_CC);
INIT_MESSAGE_WITH_ARRAY;
}
PHP_PROTO_FIELD_ACCESSORS(ListValue, list_value, Values, "values")
@@ -1909,7 +1923,7 @@ PHP_PROTO_INIT_SUBMSGCLASS_END
PHP_METHOD(Method, __construct) {
init_file_api(TSRMLS_C);
MessageHeader* intern = UNBOX(MessageHeader, getThis());
custom_data_init(method_type, intern PHP_PROTO_TSRMLS_CC);
INIT_MESSAGE_WITH_ARRAY;
}
PHP_PROTO_FIELD_ACCESSORS(Method, method, Name, "name")
@@ -1948,7 +1962,7 @@ PHP_PROTO_INIT_SUBMSGCLASS_END
PHP_METHOD(Mixin, __construct) {
init_file_api(TSRMLS_C);
MessageHeader* intern = UNBOX(MessageHeader, getThis());
custom_data_init(mixin_type, intern PHP_PROTO_TSRMLS_CC);
INIT_MESSAGE_WITH_ARRAY;
}
PHP_PROTO_FIELD_ACCESSORS(Mixin, mixin, Name, "name")
@@ -1982,7 +1996,7 @@ PHP_PROTO_INIT_SUBMSGCLASS_END
PHP_METHOD(Option, __construct) {
init_file_type(TSRMLS_C);
MessageHeader* intern = UNBOX(MessageHeader, getThis());
custom_data_init(option_type, intern PHP_PROTO_TSRMLS_CC);
INIT_MESSAGE_WITH_ARRAY;
}
PHP_PROTO_FIELD_ACCESSORS(Option, option, Name, "name")
@@ -2012,7 +2026,7 @@ PHP_PROTO_INIT_SUBMSGCLASS_END
PHP_METHOD(SourceContext, __construct) {
init_file_source_context(TSRMLS_C);
MessageHeader* intern = UNBOX(MessageHeader, getThis());
custom_data_init(source_context_type, intern PHP_PROTO_TSRMLS_CC);
INIT_MESSAGE_WITH_ARRAY;
}
PHP_PROTO_FIELD_ACCESSORS(SourceContext, source_context, FileName, "file_name")
@@ -2041,7 +2055,7 @@ PHP_PROTO_INIT_SUBMSGCLASS_END
PHP_METHOD(StringValue, __construct) {
init_file_wrappers(TSRMLS_C);
MessageHeader* intern = UNBOX(MessageHeader, getThis());
custom_data_init(string_value_type, intern PHP_PROTO_TSRMLS_CC);
INIT_MESSAGE_WITH_ARRAY;
}
PHP_PROTO_FIELD_ACCESSORS(StringValue, string_value, Value, "value")
@@ -2070,7 +2084,7 @@ PHP_PROTO_INIT_SUBMSGCLASS_END
PHP_METHOD(Struct, __construct) {
init_file_struct(TSRMLS_C);
MessageHeader* intern = UNBOX(MessageHeader, getThis());
custom_data_init(struct_type, intern PHP_PROTO_TSRMLS_CC);
INIT_MESSAGE_WITH_ARRAY;
}
PHP_PROTO_FIELD_ACCESSORS(Struct, struct, Fields, "fields")
@@ -2119,7 +2133,7 @@ PHP_PROTO_INIT_SUBMSGCLASS_END
PHP_METHOD(Type, __construct) {
init_file_type(TSRMLS_C);
MessageHeader* intern = UNBOX(MessageHeader, getThis());
custom_data_init(type_type, intern PHP_PROTO_TSRMLS_CC);
INIT_MESSAGE_WITH_ARRAY;
}
PHP_PROTO_FIELD_ACCESSORS(Type, type, Name, "name")
@@ -2153,7 +2167,7 @@ PHP_PROTO_INIT_SUBMSGCLASS_END
PHP_METHOD(UInt32Value, __construct) {
init_file_wrappers(TSRMLS_C);
MessageHeader* intern = UNBOX(MessageHeader, getThis());
custom_data_init(u_int32_value_type, intern PHP_PROTO_TSRMLS_CC);
INIT_MESSAGE_WITH_ARRAY;
}
PHP_PROTO_FIELD_ACCESSORS(UInt32Value, u_int32_value, Value, "value")
@@ -2182,7 +2196,7 @@ PHP_PROTO_INIT_SUBMSGCLASS_END
PHP_METHOD(UInt64Value, __construct) {
init_file_wrappers(TSRMLS_C);
MessageHeader* intern = UNBOX(MessageHeader, getThis());
custom_data_init(u_int64_value_type, intern PHP_PROTO_TSRMLS_CC);
INIT_MESSAGE_WITH_ARRAY;
}
PHP_PROTO_FIELD_ACCESSORS(UInt64Value, u_int64_value, Value, "value")
@@ -2222,7 +2236,7 @@ PHP_PROTO_INIT_SUBMSGCLASS_END
PHP_METHOD(Value, __construct) {
init_file_struct(TSRMLS_C);
MessageHeader* intern = UNBOX(MessageHeader, getThis());
custom_data_init(value_type, intern PHP_PROTO_TSRMLS_CC);
INIT_MESSAGE_WITH_ARRAY;
}
PHP_PROTO_ONEOF_FIELD_ACCESSORS(Value, value, NullValue, "null_value")
Oops, something went wrong.

0 comments on commit 6a51c03

Please sign in to comment.