diff options
Diffstat (limited to 'php/ext/google/protobuf/storage.c')
-rw-r--r-- | php/ext/google/protobuf/storage.c | 35 |
1 files changed, 32 insertions, 3 deletions
diff --git a/php/ext/google/protobuf/storage.c b/php/ext/google/protobuf/storage.c index cc34dcf6..a0488ecb 100644 --- a/php/ext/google/protobuf/storage.c +++ b/php/ext/google/protobuf/storage.c @@ -856,12 +856,41 @@ void layout_set(MessageLayout* layout, MessageHeader* header, zval* property_ptr = CACHED_PTR_TO_ZVAL_PTR((CACHED_VALUE*)memory); if (EXPECTED(property_ptr != val)) { + zend_class_entry *subce = NULL; + zval converted_value; + + if (upb_fielddef_ismap(field)) { + const upb_msgdef* mapmsg = upb_fielddef_msgsubdef(field); + const upb_fielddef* keyfield = upb_msgdef_ntof(mapmsg, "key", 3); + const upb_fielddef* valuefield = upb_msgdef_ntof(mapmsg, "value", 5); + if (upb_fielddef_descriptortype(valuefield) == + UPB_DESCRIPTOR_TYPE_MESSAGE) { + const upb_msgdef* submsg = upb_fielddef_msgsubdef(valuefield); + Descriptor* subdesc = + UNBOX_HASHTABLE_VALUE(Descriptor, get_def_obj(submsg)); + subce = subdesc->klass; + } + check_map_field(subce, upb_fielddef_descriptortype(keyfield), + upb_fielddef_descriptortype(valuefield), val, + &converted_value); + } else { + if (upb_fielddef_type(field) == UPB_TYPE_MESSAGE) { + const upb_msgdef* submsg = upb_fielddef_msgsubdef(field); + Descriptor* subdesc = + UNBOX_HASHTABLE_VALUE(Descriptor, get_def_obj(submsg)); + subce = subdesc->klass; + } + + check_repeated_field(subce, upb_fielddef_descriptortype(field), val, + &converted_value); + } #if PHP_MAJOR_VERSION < 7 - REPLACE_ZVAL_VALUE((zval**)memory, val, 1); + REPLACE_ZVAL_VALUE((zval**)memory, &converted_value, 1); #else - php_proto_zval_ptr_dtor(property_ptr); - ZVAL_ZVAL(property_ptr, val, 1, 0); + php_proto_zval_ptr_dtor(property_ptr); + ZVAL_ZVAL(property_ptr, &converted_value, 1, 0); #endif + zval_dtor(&converted_value); } } else { upb_fieldtype_t type = upb_fielddef_type(field); |