#pragma once

#include <saas/protos/rtyserver.pb.h>
#include <util/generic/vector.h>
#include <library/cpp/charset/doccodes.h>

#define PROTOBUF_FIELD_GETTER(Type, Propertie, Protobuf, Field) \
    inline Type Get ## Propertie() const { return Protobuf.Get ## Field(); }

#define PROTOBUF_FIELD_GETTER_OVERRIDE(Type, Propertie, Protobuf, Field) \
    inline Type Get ## Propertie() const override { return Protobuf.Get ## Field(); }

#define PROTOBUF_FIELD_SETTER(Type, Propertie, Protobuf, Field) \
    inline TThis& Set ## Propertie(const Type& value) { Protobuf.Set ## Field(value); return *this; }

#define PROTOBUF_PBFIELD_SETTER(Type, Propertie, Protobuf, Field) \
    inline TThis& Set ## Propertie(const Type& value) { *(Protobuf.Mutable ## Field()) = value; return *this; }

#define PROTOBUF_PBFIELD_MUTABLE(Type, Propertie, Protobuf, Field) \
    inline Type * Mutable ## Propertie() { return Protobuf.Mutable ## Field(); }

#define PROTOBUF_FIELD_EXISTS(Type, Propertie, Protobuf, Field) \
    inline bool Has ## Propertie() const { return Protobuf.Has ## Field(); }

#define PROTOBUF_FIELD_CLEAR(Type, Propertie, Protobuf, Field) \
    inline TThis& Clear ## Propertie() { Protobuf.Clear ## Field(); return *this; }

#define PROTOBUF_FIELD_ACCESSORS(Type, Propertie, Protobuf, Field) \
    PROTOBUF_FIELD_GETTER(Type, Propertie, Protobuf, Field) \
    PROTOBUF_FIELD_SETTER(Type, Propertie, Protobuf, Field) \
    PROTOBUF_FIELD_EXISTS(Type, Propertie, Protobuf, Field) \
    PROTOBUF_FIELD_CLEAR(Type, Propertie, Protobuf, Field)

#define PROTOBUF_PBFIELD_ACCESSORS(Type, Propertie, Protobuf, Field) \
    PROTOBUF_FIELD_GETTER(const Type&, Propertie, Protobuf, Field) \
    PROTOBUF_PBFIELD_SETTER(Type, Propertie, Protobuf, Field) \
    PROTOBUF_FIELD_EXISTS(Type, Propertie, Protobuf, Field) \
    PROTOBUF_PBFIELD_MUTABLE(Type, Propertie, Protobuf, Field) \
    PROTOBUF_FIELD_CLEAR(Type, Propertie, Protobuf, Field)

#define PROTOBUF_FIELD_ACCESSORS_REF(Type, Propertie, Protobuf, Field) \
    PROTOBUF_FIELD_GETTER(const Type&, Propertie, Protobuf, Field) \
    PROTOBUF_FIELD_SETTER(Type, Propertie, Protobuf, Field) \
    PROTOBUF_FIELD_EXISTS(Type, Propertie, Protobuf, Field) \
    PROTOBUF_FIELD_CLEAR(Type, Propertie, Protobuf, Field)

#define PROTOBUF_FIELD_ACCESSORS_REF_OVERRIDE(Type, Propertie, Protobuf, Field) \
    PROTOBUF_FIELD_GETTER_OVERRIDE(const Type&, Propertie, Protobuf, Field) \
    PROTOBUF_FIELD_SETTER(Type, Propertie, Protobuf, Field) \
    PROTOBUF_FIELD_EXISTS(Type, Propertie, Protobuf, Field) \
    PROTOBUF_FIELD_CLEAR(Type, Propertie, Protobuf, Field)

namespace NRTYServer {
    using TPositionValue = ui64;
}

struct TToJsonContext {
    enum TFormat {COMMON_JSON, JSON_REF};

    explicit TToJsonContext(TFormat format)
        : Format(format)
        , Encoding(CODES_UNKNOWN)
    {}

    TFormat Format;
    TVector <std::pair<TString, TString> > Parts;
    ECharset Encoding;
};
