class ValidationError(BadRequest):
    def __init__(self, message, path=None):
        super().__init__(message)
        self.path = path or []

    def format(self) -> ErrorResponse:
        msg = super().format()
        msg.description = self.description
        if self.path:
            msg.path = '.'.join(self.path)
        return msg class String(Field[str]):
    def __init__(self, **kwargs) -> None:
        super().__init__(str, **kwargs) class Int32(Field[int]):
    def __init__(self, **kwargs) -> None:
        super().__init__(int, **kwargs) class Int64(Field[int]):
    def __init__(self, **kwargs) -> None:
        super().__init__(int, **kwargs) class Bool(Field[bool]):
    def __init__(self, **kwargs) -> None:
        super().__init__(bool, **kwargs) class Float32(Field[float]):
    def __init__(self, **kwargs) -> None:
        super().__init__(float, **kwargs) class Float64(Field[float]):
    def __init__(self, **kwargs) -> None:
        super().__init__(float, **kwargs) def repeated(field: Union[FieldDescriptor, type, str], name: str = None) -> RepeatField:
    if isinstance(field, type) and issubclass(field, Field):
        field = field()
    elif not isinstance(field, FieldDescriptor):
        field = Field(field)

    if field.repeated:
        raise ValueError('Repeated fields cannot be embedded by another repeated field')

    return RepeatField(field._type,
                       name,
                       json_name=field.json_name,
                       schema=field.schema,
                       options=field.options) class Bytes(Field[bytes]):
    def __init__(self, **kwargs) -> None:
        super().__init__(bytes, **kwargs) class Field(Generic[_VT], FieldDescriptor):
    def __init__(self,
                 type_: Union[Type[_VT], str],
                 name: str = None,
                 *,
                 default: Any = None,
                 json_name: str = None,
                 schema: 'venom.validation.Schema' = None,
                 **options) -> None:
        super(Field, self).__init__(type_, name, json_name=json_name, schema=schema, options=options)
        self._default = default

    def default(self):
        if self._default is None:
            return self.type()
        return self._default

    @cached_property
    def type(self) -> Type[_VT]:
        if isinstance(self._type, str):
            if '.' in self._type:
                module_name, class_name = self._type.rsplit('.', 1)
                module = import_module(module_name)
                return getattr(module, class_name)

            raise RuntimeError('Unable to resolve: {} in {}'.format(self._type, repr(self)))
        return self._type

    def __eq__(self, other):
        if not isinstance(other, Field):
            return False
        return self.type == other.type and self.options == other.options

    def __hash__(self):
        return hash(repr(self)) class MapField(FieldDescriptor[_VT], Generic[_KT, _VT]):
    repeated: bool = True
    key_type: Type[_KT]

    def __init__(self,
                 type_: Union[Type[_VT], str],
                 key_type: Type[_KT] = str,
                 name: str = None,
                 *,
                 json_name: str = None,
                 schema: 'venom.validation.Schema' = None,
                 **options) -> None:
        super(MapField, self).__init__(type_, name, json_name=json_name, schema=schema, options=options)
        self.key_type = key_type

    @overload
    def __get__(self, instance: None, owner) -> 'MapField[_VT]':
        pass

    @overload
    def __get__(self, instance: 'venom.message.Message', owner) -> Map[_KT, _VT]:
        pass

    def __get__(self, instance, owner):
        if instance is None:
            return self
        return Map(instance, self.name) class Repeat(Generic[_VT], MutableSequence[_VT]):
    def __init__(self, message: 'venom.message.Message', name: str):
        self.message = message
        self.name = name

    @property
    def _sequence(self) -> list:
        try:
            return self.message[self.name]
        except KeyError:
            return []

    def __len__(self):
        return len(self._sequence)

    def __getitem__(self, index):
        return self._sequence[index]

    def insert(self, index, value):
        self.message[self.name] = sequence = self._sequence
        sequence.insert(index, value)

    def __delitem__(self, index):
        self.message[self.name] = sequence = self._sequence
        del sequence[index]

    def __setitem__(self, index, value):
        self.message[self.name] = sequence = self._sequence
        sequence[index] = value

    def __iter__(self):
        return iter(self._sequence)

    def items(self) -> Iterable[Tuple[int, Any]]:
        return enumerate(self._sequence)

    def __repr__(self):
        return f'Repeat({repr(self._sequence)})' class Message(Mapping, metaclass=MessageMeta):
    __slots__ = ('_values',)  # TODO slot message fields directly.
    # TODO change to tuple (FieldDescriptor would need FieldDescriptor.attribute attribute.)
    __fields__: ClassVar[Dict[str, FieldDescriptor]] = None
    __meta__: ClassVar[Dict[str, Any]] = None

    class Meta:
        name = None
        one_of_groups = ()
        protocols = None
        validators = None

    def __init__(self, *args, **kwargs):
        self._values = {}
        if args:
            for value, field in zip(args, self.__fields__.values()):
                if value is not None:
                    field.__set__(self, value)
        for key, value in kwargs.items():
            if value is not None:
                self.__fields__[key].__set__(self, value)

    def get(self, key, default=None):
        try:
            return self._values[key]
        except KeyError:
            if default is None and key in self.__fields__:
                return self.__fields__[key].default()
            return default

    def __getitem__(self, key):
        return self._values[key]

    def __setitem__(self, key, value):
        if value is None:
            try:
                del self._values[key]
            except KeyError:
                pass
        else:
            self._values[key] = value

    def __delitem__(self, key):
        del self._values[key]

    def __contains__(self, key):
        return key in self._values

    def __iter__(self):
        return iter(self._values)

    def __len__(self):
        return len(self._values)

    def __repr__(self):
        parts = []
        for key in self.__fields__.keys():
            if key in self._values and self._values[key] is not None:
                parts.append('{}={}'.format(key, repr(self._values[key])))
        return '{}({})'.format(self.__meta__.name, ', '.join(parts))

    def __eq__(self, other):
        if not isinstance(other, (Message, Mapping)):
            return NotImplemented
        return dict(ItemsView(self)) == dict(ItemsView(other)) def one_of(*choices):
    """

    Usage:::

        class SearchRequest(Message):
            query = one_of('name', 'id')

        s = SearchRequest(id=123)
        s.query.which()  # 'id'


    """
    return OneOf(choices)
import calendar
import enum
import json
import datetime
from typing import Iterable, Any, Tuple
from venom.exceptions import ValidationError
from venom.fields import String, Int32, Int64, Bool, Float32, Float64, repeated, Bytes, Field, MapField, Repeat
from venom.message import Message, one_of




class StringValue(Message):
    value = String()

    class Meta:
        proto_package = 'google.protobuf'


class BytesValue(Message):
    value = Bytes()

    class Meta:
        proto_package = 'google.protobuf'


class BoolValue(Message):
    value = Bool()

    class Meta:
        proto_package = 'google.protobuf'


class Int32Value(Message):
    value = Int32()

    class Meta:
        proto_package = 'google.protobuf'


class Int64Value(Message):
    value = Int64()

    class Meta:
        proto_package = 'google.protobuf'


IntegerValue = Int64Value


class Float32Value(Message):
    value = Float32()

    class Meta:
        proto_package = 'google.protobuf'


class Float64Value(Message):
    value = Float64()

    class Meta:
        proto_package = 'google.protobuf'


NumberValue = Float64Value


class NullValue(enum.Enum):
    NULL_VALUE = None


class Struct(Message):
    fields = MapField('venom.common.messages.Value')


class ListValue(Message):
    values = repeated('venom.common.messages.Value')


class Value(Message):
    # null_value = Field(NullValue)
    number_value = Field(NumberValue)
    string_value = Field(StringValue)
    bool_value = Field(BoolValue)
    struct_value = Field(Struct)
    list_value = Field(ListValue)

    value = one_of(  # null_value,
        number_value,
        string_value,
        bool_value,
        struct_value,
        list_value)


class JSONValue(Message):
    value = String()

    def __init__(self, value):
        super().__init__(json.dumps(value))


class FieldMask(Message):
    paths: Repeat[str]

    class Meta:
        proto_package = 'google.protobuf'

    # TODO needs tests
    def match_path(self, *path: Tuple[str]) -> bool:
        for level in range(len(path)):
            match_path = '.'.join(path[:level + 1])
            for path_ in self.paths:
                if match_path in path_:
                    return True
        return False


class Timestamp(Message):
    seconds = Int64()

    nanos = Int32()