# Path: aiohttp_json_api/abc/processors.py
# class MetaProcessors:
#     def _resolve_processors(cls):
#         """
#         Add in the decorated processors
#         By doing this after constructing the class, we let standard inheritance
#         do all the hard work.
# 
#         Almost the same as https://github.com/marshmallow-code/marshmallow/blob/dev/marshmallow/schema.py#L139-L174
#         """
#         mro = inspect.getmro(cls)
#         cls._has_processors = False
#         cls.__processors__ = defaultdict(list)
#         for attr_name in dir(cls):
#             # Need to look up the actual descriptor, not whatever might be
#             # bound to the class. This needs to come from the __dict__ of the
#             # declaring class.
#             for parent in mro:
#                 try:
#                     attr = parent.__dict__[attr_name]
#                 except KeyError:
#                     continue
#                 else:
#                     break
#             else:
#                 # In case we didn't find the attribute and didn't break above.
#                 # We should never hit this - it's just here for completeness
#                 # to exclude the possibility of attr being undefined.
#                 continue
# 
#             try:
#                 processor_tags = attr.__processing_tags__
#             except AttributeError:
#                 continue
# 
#             cls._has_processors = bool(processor_tags)
#             for tag in processor_tags:
#                 # Use name here so we can get the bound method later, in case
#                 # the processor was a descriptor or something.
#                 cls.__processors__[tag].append(attr_name)
# 
# Path: aiohttp_json_api/abc/field.py
# class FieldABC(abc.ABC):
#     @property
#     @abc.abstractmethod
#     def key(self) -> str:
#         raise NotImplementedError
# 
#     @property
#     @abc.abstractmethod
#     def sp(self) -> JSONPointer:
#         raise NotImplementedError
# 
#     @property
#     @abc.abstractmethod
#     def name(self) -> Optional[str]:
#         raise NotImplementedError
# 
#     @name.setter
#     @abc.abstractmethod
#     def name(self, value: Optional[str]):
#         pass
# 
#     @property
#     @abc.abstractmethod
#     def mapped_key(self) -> Optional[str]:
#         raise NotImplementedError
# 
#     @mapped_key.setter
#     @abc.abstractmethod
#     def mapped_key(self, value: Optional[str]):
#         pass
# 
#     @abc.abstractmethod
#     def serialize(self, schema, data, **kwargs):
#         """
#         Serialize the passed *data*.
#         """
#         raise NotImplementedError
# 
#     @abc.abstractmethod
#     def deserialize(self, schema, data, sp, **kwargs):
#         """
#         Deserialize the raw *data* from the JSON API input document
#         and returns it.
#         """
#         raise NotImplementedError
# 
#     @abc.abstractmethod
#     def pre_validate(self, schema, data, sp):
#         """
#         Validates the raw JSON API input for this field. This method is
#         called before :meth:`deserialize`.
# 
#         :arg ~aiohttp_json_api.schema.BaseSchema schema:
#             The schema this field has been defined on.
#         :arg data:
#             The raw input data
#         :arg ~aiohttp_json_api.jsonpointer.JSONPointer sp:
#             A JSON pointer to the source of *data*.
#         :arg ~aiohttp_json_api.context.JSONAPIContext context:
#             A JSON API request context instance
#         """
#         raise NotImplementedError
# 
#     @abc.abstractmethod
#     def post_validate(self, schema, data, sp):
#         """
#         Validates the decoded input *data* for this field. This method is
#         called after :meth:`deserialize`.
# 
#         :arg ~aiohttp_json_api.schema.BaseSchema schema:
#             The schema this field has been defined on.
#         :arg data:
#             The decoded input data
#         :arg ~aiohttp_json_api.jsonpointer.JSONPointer sp:
#             A JSON pointer to the source of *data*.
#         :arg ~aiohttp_json_api.context.JSONAPIContext context:
#             A JSON API request context instance
#         """
#         raise NotImplementedError
# 
# Path: aiohttp_json_api/jsonpointer.py
# class JSONPointer(BaseJsonPointer):
#     def __truediv__(self,
#                     path: typing.Union['JSONPointer', str]) -> 'JSONPointer':
#         parts = self.parts.copy()
# 
#         if isinstance(path, int):
#             path = str(path)
# 
#         if isinstance(path, str):
#             if not path.startswith('/'):
#                 path = f'/{path}'
#             new_parts = JSONPointer(path).parts.pop(0)
#             parts.append(new_parts)
#         else:
#             new_parts = path.parts
#             parts.extend(new_parts)
#         return JSONPointer.from_parts(parts)


import abc
import inspect
import itertools
import inflection
from collections import OrderedDict
from types import MappingProxyType
from .processors import MetaProcessors
from .field import FieldABC
from ..jsonpointer import JSONPointer
        from aiohttp_json_api.fields.base import Relationship
        from aiohttp_json_api.fields.base import Relationship
        from aiohttp_json_api.fields.base import Relationship, Attribute, Link
            field._key = key
            field.name = (
                field.name or (klass.opts.inflect(key)
                               if callable(klass.opts.inflect)
                               else key)
            )
            field.mapped_key = field.mapped_key or key
            declared_fields[field.key] = field

        # Find nested fields (link_of, ...) and link them with
        # their parent.
        for key, field in declared_fields.items():
            if getattr(field, 'link_of', None):
                relationship = declared_fields[field.link_of]

                if not isinstance(relationship, Relationship):
                    raise TypeError('Links can be added only for '
                                    'relationships fields.')

                relationship.add_link(field)

        klass._id = declared_fields.pop('id', None)

        # Find the *top-level* attributes, relationships,
        # links and meta fields.
        attributes = OrderedDict(
            (key, field)
            for key, field in declared_fields.items()
            if isinstance(field, Attribute) and not field.meta
        )

# Path: aiohttp_json_api/abc/processors.py
# class MetaProcessors:
#     def _resolve_processors(cls):
#         """
#         Add in the decorated processors
#         By doing this after constructing the class, we let standard inheritance
#         do all the hard work.
# 
#         Almost the same as https://github.com/marshmallow-code/marshmallow/blob/dev/marshmallow/schema.py#L139-L174
#         """
#         mro = inspect.getmro(cls)
#         cls._has_processors = False
#         cls.__processors__ = defaultdict(list)
#         for attr_name in dir(cls):
#             # Need to look up the actual descriptor, not whatever might be
#             # bound to the class. This needs to come from the __dict__ of the
#             # declaring class.
#             for parent in mro:
#                 try:
#                     attr = parent.__dict__[attr_name]
#                 except KeyError:
#                     continue
#                 else:
#                     break
#             else:
#                 # In case we didn't find the attribute and didn't break above.
#                 # We should never hit this - it's just here for completeness
#                 # to exclude the possibility of attr being undefined.
#                 continue
# 
#             try:
#                 processor_tags = attr.__processing_tags__
#             except AttributeError:
#                 continue
# 
#             cls._has_processors = bool(processor_tags)
#             for tag in processor_tags:
#                 # Use name here so we can get the bound method later, in case
#                 # the processor was a descriptor or something.
#                 cls.__processors__[tag].append(attr_name)
# 
# Path: aiohttp_json_api/abc/field.py
# class FieldABC(abc.ABC):
#     @property
#     @abc.abstractmethod
#     def key(self) -> str:
#         raise NotImplementedError
# 
#     @property
#     @abc.abstractmethod
#     def sp(self) -> JSONPointer:
#         raise NotImplementedError
# 
#     @property
#     @abc.abstractmethod
#     def name(self) -> Optional[str]:
#         raise NotImplementedError
# 
#     @name.setter
#     @abc.abstractmethod
#     def name(self, value: Optional[str]):
#         pass
# 
#     @property
#     @abc.abstractmethod
#     def mapped_key(self) -> Optional[str]:
#         raise NotImplementedError
# 
#     @mapped_key.setter
#     @abc.abstractmethod
#     def mapped_key(self, value: Optional[str]):
#         pass
# 
#     @abc.abstractmethod
#     def serialize(self, schema, data, **kwargs):
#         """
#         Serialize the passed *data*.
#         """
#         raise NotImplementedError
# 
#     @abc.abstractmethod
#     def deserialize(self, schema, data, sp, **kwargs):
#         """
#         Deserialize the raw *data* from the JSON API input document
#         and returns it.
#         """
#         raise NotImplementedError
# 
#     @abc.abstractmethod
#     def pre_validate(self, schema, data, sp):
#         """
#         Validates the raw JSON API input for this field. This method is
#         called before :meth:`deserialize`.
# 
#         :arg ~aiohttp_json_api.schema.BaseSchema schema:
#             The schema this field has been defined on.
#         :arg data:
#             The raw input data
#         :arg ~aiohttp_json_api.jsonpointer.JSONPointer sp:
#             A JSON pointer to the source of *data*.
#         :arg ~aiohttp_json_api.context.JSONAPIContext context:
#             A JSON API request context instance
#         """
#         raise NotImplementedError
# 
#     @abc.abstractmethod
#     def post_validate(self, schema, data, sp):
#         """
#         Validates the decoded input *data* for this field. This method is
#         called after :meth:`deserialize`.
# 
#         :arg ~aiohttp_json_api.schema.BaseSchema schema:
#             The schema this field has been defined on.
#         :arg data:
#             The decoded input data
#         :arg ~aiohttp_json_api.jsonpointer.JSONPointer sp:
#             A JSON pointer to the source of *data*.
#         :arg ~aiohttp_json_api.context.JSONAPIContext context:
#             A JSON API request context instance
#         """
#         raise NotImplementedError
# 
# Path: aiohttp_json_api/jsonpointer.py
# class JSONPointer(BaseJsonPointer):
#     def __truediv__(self,
#                     path: typing.Union['JSONPointer', str]) -> 'JSONPointer':
#         parts = self.parts.copy()
# 
#         if isinstance(path, int):
#             path = str(path)
# 
#         if isinstance(path, str):
#             if not path.startswith('/'):
#                 path = f'/{path}'
#             new_parts = JSONPointer(path).parts.pop(0)
#             parts.append(new_parts)
#         else:
#             new_parts = path.parts
#             parts.extend(new_parts)
#         return JSONPointer.from_parts(parts)


# Path: aiohttp_json_api/abc/schema.py
import abc
import inspect
import itertools
import inflection
from collections import OrderedDict
from types import MappingProxyType
from .processors import MetaProcessors
from .field import FieldABC
from ..jsonpointer import JSONPointer
        from aiohttp_json_api.fields.base import Relationship
        from aiohttp_json_api.fields.base import Relationship
        from aiohttp_json_api.fields.base import Relationship, Attribute, Link

            field._key = key
            field.name = (
                field.name or (klass.opts.inflect(key)
                               if callable(klass.opts.inflect)
                               else key)
            )
            field.mapped_key = field.mapped_key or key
            declared_fields[field.key] = field

        # Find nested fields (link_of, ...) and link them with
        # their parent.
        for key, field in declared_fields.items():
            if getattr(field, 'link_of', None):
                relationship = declared_fields[field.link_of]

                if not isinstance(relationship, Relationship):
                    raise TypeError('Links can be added only for '
                                    'relationships fields.')

                relationship.add_link(field)

        klass._id = declared_fields.pop('id', None)

        # Find the *top-level* attributes, relationships,
        # links and meta fields.
        attributes = OrderedDict(
            (key, field)
            for key, field in declared_fields.items()
            if isinstance(field, Attribute) and not field.meta
        )

        mcs._assign_sp(attributes.values(), JSONPointer('/attributes'))