def _generate_struct_deserializer(self, struct):
        """Emits the deserialize method for the serialization object for the given struct."""
        struct_name = fmt_class_prefix(struct)

        with self.block_func(
                func='deserialize',
                args=fmt_func_args_declaration([('valueDict',
                                                 'NSDictionary<NSString *, id> *')]),
                return_type='{} *'.format(struct_name),
                class_func=True):
            if not struct.all_fields and not struct.has_enumerated_subtypes():
                self.emit('#pragma unused(valueDict)')

            def emit_struct_deserialize_logic(struct):
                for field in struct.all_fields:
                    data_type, nullable = unwrap_nullable(field.data_type)
                    input_value = 'valueDict[@"{}"]'.format(field.name)

                    if is_primitive_type(data_type):
                        deserialize_call = input_value
                    else:
                        deserialize_call = self._fmt_serialization_call(
                            field.data_type, input_value, False)

                    if nullable or field.has_default:
                        default_value = fmt_default_value(
                            field) if field.has_default else 'nil'
                        if is_primitive_type(data_type):
                            deserialize_call = '{} ?: {}'.format(
                                input_value, default_value)
                        else:
                            deserialize_call = '{} ? {} : {}'.format(
                                input_value, deserialize_call, default_value)

                    self.emit('{}{} = {};'.format(
                        fmt_type(field.data_type),
                        fmt_var(field.name), deserialize_call))

                self.emit()

                deserialized_obj_args = [(fmt_var(f.name), fmt_var(f.name))
                                         for f in struct.all_fields]
                init_call = fmt_func_call(
                    caller=fmt_alloc_call(caller=struct_name),
                    callee=self._cstor_name_from_fields(struct.all_fields),
                    args=fmt_func_args(deserialized_obj_args))
                self.emit('return {};'.format(init_call))

            if not struct.has_enumerated_subtypes():
                emit_struct_deserialize_logic(struct)
            else:
                for tags, subtype in struct.get_all_subtypes_with_tags():
                    assert len(tags) == 1, tags
                    tag = tags[0]

                    base_string = 'if ([valueDict[@".tag"] isEqualToString:@"{}"])'
                    with self.block(base_string.format(tag)):
                        caller = fmt_serial_class(fmt_class_prefix(subtype))
                        args = fmt_func_args([('value', 'valueDict')])
                        deserialize_call = fmt_func_call(
                            caller=caller, callee='deserialize', args=args)
                        self.emit('return {};'.format(deserialize_call))

                self.emit()

                if struct.is_catch_all():
                    emit_struct_deserialize_logic(struct)
                else:
                    description_str = (
                        '[NSString stringWithFormat:@"Tag has an invalid '
                        'value: \\\"%@\\\".", valueDict[@".tag"]]')
                    self._generate_throw_error('InvalidTag', description_str)
        self.emit()
Emits the deserialize method for the serialization object for the given struct.