@staticmethod<EOL><INDENT>def parse_field(data, field_cfg, target, is_optional=False):<DEDENT>
field_type = field_cfg[Field.FIELD_TYPE]<EOL>field_key = field_cfg[Field.FIELD_KEY] if Field.FIELD_KEY in field_cfg else None<EOL>field_ext_id = field_cfg[Field.FIELD_EXT_ID] if Field.FIELD_EXT_ID in field_cfg else field_key<EOL>if field_type == Types.TYPE_ARRAY:<EOL><INDENT>if isinstance(target, dict):  <EOL><INDENT>target.update({field_ext_id: []})<EOL>field_value = data[field_key]<EOL><DEDENT>elif not field_key:  <EOL><INDENT>field_value = data<EOL><DEDENT>else:<EOL><INDENT>raise NotImplementedError('<STR_LIT>')<EOL><DEDENT>field_pattern = field_cfg[Field.FIELD_MATCH] if Field.FIELD_MATCH in field_cfg else None<EOL>if Field.FIELD_SUBITEMS in field_cfg:<EOL><INDENT>subfield = next(iter(field_cfg[Field.FIELD_SUBITEMS].values()))  <EOL>for item in field_value:<EOL><INDENT>if Field.is_match(field_pattern, item):<EOL><INDENT>Field.parse_field(item, subfield, target[field_ext_id] if field_ext_id else target)<EOL><DEDENT><DEDENT><DEDENT>else:<EOL><INDENT>target[field_ext_id] = field_value<EOL><DEDENT><DEDENT>elif field_type == Types.TYPE_OBJECT:<EOL><INDENT>is_explicit = bool(field_cfg[Field.FIELD_EXPLICIT]) if Field.FIELD_EXPLICIT in field_cfg else False<EOL>is_optional = bool(field_cfg[Field.FIELD_OPTIONAL]) if Field.FIELD_OPTIONAL in field_cfg else False<EOL>if field_key:<EOL><INDENT>try:<EOL><INDENT>field_value = data[field_key]<EOL><DEDENT>except KeyError:<EOL><INDENT>if is_optional:<EOL><INDENT>field_value = None<EOL><DEDENT>else:<EOL><INDENT>raise<EOL><DEDENT><DEDENT><DEDENT>else: <EOL><INDENT>field_value = data  <EOL><DEDENT>if is_explicit:<EOL><INDENT>obj_exp = {}<EOL>if isinstance(target, dict):  <EOL><INDENT>target.update({field_ext_id: obj_exp})<EOL><DEDENT>else:  <EOL><INDENT>target.append(obj_exp)<EOL><DEDENT><DEDENT>for subfield in field_cfg[Field.FIELD_SUBITEMS]:<EOL><INDENT>Field.parse_field(field_value, field_cfg[Field.FIELD_SUBITEMS][subfield],<EOL>obj_exp if is_explicit else target, is_optional)<EOL><DEDENT><DEDENT>else:  <EOL><INDENT>try:<EOL><INDENT>field_value = data[field_key]<EOL><DEDENT>except TypeError:<EOL><INDENT>if is_optional:<EOL><INDENT>field_value = None<EOL><DEDENT>else:<EOL><INDENT>raise<EOL><DEDENT><DEDENT>casted_value = Converter.convert(field_value, field_type)<EOL>if isinstance(target, dict):  <EOL><INDENT>target.update({field_ext_id: casted_value})<EOL><DEDENT>else:  <EOL><INDENT>target.append(casted_value)<EOL><DEDENT><DEDENT>
Recursively parses response according to configuration
:param data: response or its part
:param field_cfg: field configuration
:param target: target object for parsed data
:param is_optional: optional sign