/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.apache.ignite.internal.binary;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Proxy;
import java.math.BigDecimal;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.UUID;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.binary.BinaryObjectException;
import org.apache.ignite.binary.BinaryReflectiveSerializer;
import org.apache.ignite.binary.BinarySerializer;
import org.apache.ignite.binary.Binarylizable;
import org.apache.ignite.internal.UnregisteredClassException;
import org.apache.ignite.internal.UnregisteredBinaryTypeException;
import org.apache.ignite.internal.marshaller.optimized.OptimizedMarshaller;
import org.apache.ignite.internal.processors.cache.CacheObjectImpl;
import org.apache.ignite.internal.processors.query.QueryUtils;
import org.apache.ignite.internal.util.GridUnsafe;
import org.apache.ignite.internal.util.tostring.GridToStringExclude;
import org.apache.ignite.internal.util.typedef.F;
import org.apache.ignite.internal.util.typedef.internal.S;
import org.apache.ignite.internal.util.typedef.internal.U;
import org.apache.ignite.marshaller.MarshallerExclusions;
import org.jetbrains.annotations.Nullable;

import static org.apache.ignite.internal.processors.query.QueryUtils.isGeometryClass;

/**
 * Binary class descriptor.
 */
public class BinaryClassDescriptor {
    /** */
    @GridToStringExclude
    private final BinaryContext ctx;

    /** */
    private final Class<?> cls;

    /** Configured serializer. */
    private final BinarySerializer serializer;

    /** Serializer that is passed during BinaryClassDescriptor construction. Can differ from {@link #serializer}. */
    private final BinarySerializer initialSerializer;

    /** ID mapper. */
    private final BinaryInternalMapper mapper;

    /** */
    private final BinaryWriteMode mode;

    /** */
    private final boolean userType;

    /** */
    private final int typeId;

    /** */
    private final String typeName;

    /** Affinity key field name. */
    private final String affKeyFieldName;

    /** */
    private final Constructor<?> ctor;

    /** */
    private final BinaryFieldAccessor[] fields;

    /** Write replacer. */
    private final BinaryWriteReplacer writeReplacer;

    /** */
    private final Method readResolveMtd;

    /** */
    private final Map<String, BinaryFieldMetadata> stableFieldsMeta;

    /** Object schemas. Initialized only for serializable classes and contains only 1 entry. */
    private final BinarySchema stableSchema;

    /** Schema registry. */
    private final BinarySchemaRegistry schemaReg;

    /** */
    private final boolean registered;

    /** */
    private final boolean useOptMarshaller;

    /** */
    private final boolean excluded;

    /** */
    private final Class<?>[] intfs;

    /** Whether stable schema was published. */
    private volatile boolean stableSchemaPublished;

    /**
     * @param ctx Context.
     * @param cls Class.
     * @param userType User type flag.
     * @param typeId Type ID.
     * @param typeName Type name.
     * @param affKeyFieldName Affinity key field name.
     * @param mapper Mapper.
     * @param serializer Serializer.
     * @param metaDataEnabled Metadata enabled flag.
     * @param registered Whether typeId has been successfully registered by MarshallerContext or not.
     * @throws BinaryObjectException In case of error.
     */
    BinaryClassDescriptor(
        BinaryContext ctx,
        Class<?> cls,
        boolean userType,
        int typeId,
        String typeName,
        @Nullable String affKeyFieldName,
        @Nullable BinaryInternalMapper mapper,
        @Nullable BinarySerializer serializer,
        boolean metaDataEnabled,
        boolean registered
    ) throws BinaryObjectException {
        assert ctx != null;
        assert cls != null;
        assert mapper != null;

        initialSerializer = serializer;

        // If serializer is not defined at this point, then we have to use OptimizedMarshaller.
        useOptMarshaller = serializer == null || isGeometryClass(cls);

        // Reset reflective serializer so that we rely on existing reflection-based serialization.
        if (serializer instanceof BinaryReflectiveSerializer)
            serializer = null;

        this.ctx = ctx;
        this.cls = cls;
        this.typeId = typeId;
        this.userType = userType;
        this.typeName = typeName;
        this.affKeyFieldName = affKeyFieldName;
        this.serializer = serializer;
        this.mapper = mapper;
        this.registered = registered;

        schemaReg = ctx.schemaRegistry(typeId);

        excluded = MarshallerExclusions.isExcluded(cls);

        if (excluded)
            mode = BinaryWriteMode.EXCLUSION;
        else if (useOptMarshaller)
            mode = BinaryWriteMode.OPTIMIZED; // Will not be used anywhere.
        else {
            if (cls == BinaryEnumObjectImpl.class)
                mode = BinaryWriteMode.BINARY_ENUM;
            else
                mode = serializer != null ? BinaryWriteMode.BINARY : BinaryUtils.mode(cls);
        }

        if (useOptMarshaller && userType && !U.isIgnite(cls) && !U.isJdk(cls) && !QueryUtils.isGeometryClass(cls)) {
            U.warnDevOnly(ctx.log(), "Class \"" + cls.getName() + "\" cannot be serialized using " +
                BinaryMarshaller.class.getSimpleName() + " because it either implements Externalizable interface " +
                "or have writeObject/readObject methods. " + OptimizedMarshaller.class.getSimpleName() + " will be " +
                "used instead and class instances will be deserialized on the server. Please ensure that all nodes " +
                "have this class in classpath. To enable binary serialization either implement " +
                Binarylizable.class.getSimpleName() + " interface or set explicit serializer using " +
                "BinaryTypeConfiguration.setSerializer() method.");
        }

        switch (mode) {
            case P_BYTE:
            case P_BOOLEAN:
            case P_SHORT:
            case P_CHAR:
            case P_INT:
            case P_LONG:
            case P_FLOAT:
            case P_DOUBLE:
            case BYTE:
            case SHORT:
            case INT:
            case LONG:
            case FLOAT:
            case DOUBLE:
            case CHAR:
            case BOOLEAN:
            case DECIMAL:
            case STRING:
            case UUID:
            case DATE:
            case TIMESTAMP:
            case TIME:
            case BYTE_ARR:
            case SHORT_ARR:
            case INT_ARR:
            case LONG_ARR:
            case FLOAT_ARR:
            case DOUBLE_ARR:
            case CHAR_ARR:
            case BOOLEAN_ARR:
            case DECIMAL_ARR:
            case STRING_ARR:
            case UUID_ARR:
            case DATE_ARR:
            case TIMESTAMP_ARR:
            case TIME_ARR:
            case OBJECT_ARR:
            case COL:
            case MAP:
            case BINARY_OBJ:
            case ENUM:
            case BINARY_ENUM:
            case ENUM_ARR:
            case CLASS:
            case OPTIMIZED:
            case EXCLUSION:
                ctor = null;
                fields = null;
                stableFieldsMeta = null;
                stableSchema = null;
                intfs = null;

                break;

            case PROXY:
                ctor = null;
                fields = null;
                stableFieldsMeta = null;
                stableSchema = null;
                intfs = cls.getInterfaces();

                break;

            case BINARY:
                ctor = constructor(cls);
                fields = null;
                stableFieldsMeta = null;
                stableSchema = null;
                intfs = null;

                break;

            case OBJECT:
                // Must not use constructor to honor transient fields semantics.
                ctor = null;

                Map<Object, BinaryFieldAccessor> fields0;

                if (BinaryUtils.FIELDS_SORTED_ORDER) {
                    fields0 = new TreeMap<>();

                    stableFieldsMeta = metaDataEnabled ? new TreeMap<String, BinaryFieldMetadata>() : null;
                }
                else {
                    fields0 = new LinkedHashMap<>();

                    stableFieldsMeta = metaDataEnabled ? new LinkedHashMap<String, BinaryFieldMetadata>() : null;
                }

                Set<String> duplicates = duplicateFields(cls);

                Collection<String> names = new HashSet<>();
                Collection<Integer> ids = new HashSet<>();

                for (Class<?> c = cls; c != null && !c.equals(Object.class); c = c.getSuperclass()) {
                    for (Field f : c.getDeclaredFields()) {
                        if (serializeField(f)) {
                            f.setAccessible(true);

                            String name = f.getName();

                            if (duplicates.contains(name))
                                name = BinaryUtils.qualifiedFieldName(c, name);

                            boolean added = names.add(name);

                            assert added : name;

                            int fieldId = this.mapper.fieldId(typeId, name);

                            if (!ids.add(fieldId))
                                throw new BinaryObjectException("Duplicate field ID: " + name);

                            BinaryFieldAccessor fieldInfo = BinaryFieldAccessor.create(f, fieldId);

                            fields0.put(name, fieldInfo);

                            if (metaDataEnabled)
                                stableFieldsMeta.put(name, new BinaryFieldMetadata(fieldInfo));
                        }
                    }
                }

                fields = fields0.values().toArray(new BinaryFieldAccessor[fields0.size()]);

                BinarySchema.Builder schemaBuilder = BinarySchema.Builder.newBuilder();

                for (BinaryFieldAccessor field : fields)
                    schemaBuilder.addField(field.id);

                stableSchema = schemaBuilder.build();

                intfs = null;

                break;

            default:
                // Should never happen.
                throw new BinaryObjectException("Invalid mode: " + mode);
        }

        BinaryWriteReplacer writeReplacer0 = BinaryUtils.writeReplacer(cls);

        Method writeReplaceMthd;

        if (mode == BinaryWriteMode.BINARY || mode == BinaryWriteMode.OBJECT) {
            readResolveMtd = U.findInheritableMethod(cls, "readResolve");

            writeReplaceMthd = U.findInheritableMethod(cls, "writeReplace");
        }
        else {
            readResolveMtd = null;
            writeReplaceMthd = null;
        }

        if (writeReplaceMthd != null && writeReplacer0 == null)
            writeReplacer0 = new BinaryMethodWriteReplacer(writeReplaceMthd);

        writeReplacer = writeReplacer0;
    }

    /**
     * Find all fields with duplicate names in the class.
     *
     * @param cls Class.
     * @return Fields with duplicate names.
     */
    private static Set<String> duplicateFields(Class cls) {
        Set<String> all = new HashSet<>();
        Set<String> duplicates = new HashSet<>();

        for (Class<?> c = cls; c != null && !c.equals(Object.class); c = c.getSuperclass()) {
            for (Field f : c.getDeclaredFields()) {
                if (serializeField(f)) {
                    String name = f.getName();

                    if (!all.add(name))
                        duplicates.add(name);
                }
            }
        }

        return duplicates;
    }

    /**
     * Whether the field must be serialized.
     *
     * @param f Field.
     * @return {@code True} if must be serialized.
     */
    private static boolean serializeField(Field f) {
        int mod = f.getModifiers();

        return !Modifier.isStatic(mod) && !Modifier.isTransient(mod);
    }

    /**
     * @return {@code True} if enum.
     */
    boolean isEnum() {
        return mode == BinaryWriteMode.ENUM;
    }

    /**
     * @return Described class.
     */
    Class<?> describedClass() {
        return cls;
    }

    /**
     * @return Type ID.
     */
    public int typeId() {
        return typeId;
    }

    /**
     * @return Type name.
     */
    String typeName() {
        return typeName;
    }

    /**
     * @return Type mapper.
     */
    BinaryInternalMapper mapper() {
        return mapper;
    }

    /**
     * @return Serializer.
     */
    BinarySerializer serializer() {
        return serializer;
    }

    /**
     * @return Initial serializer that is passed during BinaryClassDescriptor construction.
     * Can differ from {@link #serializer}.
     */
    BinarySerializer initialSerializer() {
        return initialSerializer;
    }

    /**
     * @return Affinity field key name.
     */
    String affFieldKeyName() {
        return affKeyFieldName;
    }

    /**
     * @return User type flag.
     */
    boolean userType() {
        return userType;
    }

    /**
     * @return Fields meta data.
     */
    Map<String, BinaryFieldMetadata> fieldsMeta() {
        return stableFieldsMeta;
    }

    /**
     * @return Schema.
     */
    BinarySchema schema() {
        return stableSchema;
    }

    /**
     * @return Whether typeId has been successfully registered by MarshallerContext or not.
     */
    public boolean registered() {
        return registered;
    }

    /**
     * @return {@code true} if {@link OptimizedMarshaller} must be used instead of {@link BinaryMarshaller}
     * for object serialization and deserialization.
     */
    public boolean useOptimizedMarshaller() {
        return useOptMarshaller;
    }

    /**
     * Checks whether the class values are explicitly excluded from marshalling.
     *
     * @return {@code true} if excluded, {@code false} otherwise.
     */
    public boolean excluded() {
        return excluded;
    }

    /**
     * @return {@code True} if write-replace should be performed for class.
     */
    public boolean isWriteReplace() {
        return writeReplacer != null;
    }

    /**
     * Perform write replace.
     *
     * @param obj Original object.
     * @return Replaced object.
     */
    public Object writeReplace(Object obj) {
        assert isWriteReplace();

        return writeReplacer.replace(obj);
    }

    /**
     * Register current stable schema if applicable.
     */
    public void registerStableSchema() {
        if (schemaReg != null && stableSchema != null) {
            int schemaId = stableSchema.schemaId();

            if (schemaReg.schema(schemaId) == null)
                schemaReg.addSchema(stableSchema.schemaId(), stableSchema);
        }
    }

    /**
     * @return binaryReadResolve() method
     */
    @SuppressWarnings("UnusedDeclaration")
    @Nullable Method getReadResolveMethod() {
        return readResolveMtd;
    }

    /**
     * @param obj Object.
     * @param writer Writer.
     * @throws BinaryObjectException In case of error.
     */
    void write(Object obj, BinaryWriterExImpl writer) throws BinaryObjectException {
        try {
            assert obj != null;
            assert writer != null;
            assert mode != BinaryWriteMode.OPTIMIZED : "OptimizedMarshaller should not be used here: " + cls.getName();

            writer.typeId(typeId);

            switch (mode) {
                case P_BYTE:
                case BYTE:
                    writer.writeByteFieldPrimitive((byte)obj);

                    break;

                case P_SHORT:
                case SHORT:
                    writer.writeShortFieldPrimitive((short)obj);

                    break;

                case P_INT:
                case INT:
                    writer.writeIntFieldPrimitive((int)obj);

                    break;

                case P_LONG:
                case LONG:
                    writer.writeLongFieldPrimitive((long)obj);

                    break;

                case P_FLOAT:
                case FLOAT:
                    writer.writeFloatFieldPrimitive((float)obj);

                    break;

                case P_DOUBLE:
                case DOUBLE:
                    writer.writeDoubleFieldPrimitive((double)obj);

                    break;

                case P_CHAR:
                case CHAR:
                    writer.writeCharFieldPrimitive((char)obj);

                    break;

                case P_BOOLEAN:
                case BOOLEAN:
                    writer.writeBooleanFieldPrimitive((boolean)obj);

                    break;

                case DECIMAL:
                    writer.doWriteDecimal((BigDecimal)obj);

                    break;

                case STRING:
                    writer.doWriteString((String)obj);

                    break;

                case UUID:
                    writer.doWriteUuid((UUID)obj);

                    break;

                case DATE:
                    writer.doWriteDate((Date)obj);

                    break;

                case TIMESTAMP:
                    writer.doWriteTimestamp((Timestamp)obj);

                    break;

                case TIME:
                    writer.doWriteTime((Time)obj);

                    break;

                case BYTE_ARR:
                    writer.doWriteByteArray((byte[])obj);

                    break;

                case SHORT_ARR:
                    writer.doWriteShortArray((short[])obj);

                    break;

                case INT_ARR:
                    writer.doWriteIntArray((int[])obj);

                    break;

                case LONG_ARR:
                    writer.doWriteLongArray((long[])obj);

                    break;

                case FLOAT_ARR:
                    writer.doWriteFloatArray((float[])obj);

                    break;

                case DOUBLE_ARR:
                    writer.doWriteDoubleArray((double[])obj);

                    break;

                case CHAR_ARR:
                    writer.doWriteCharArray((char[])obj);

                    break;

                case BOOLEAN_ARR:
                    writer.doWriteBooleanArray((boolean[])obj);

                    break;

                case DECIMAL_ARR:
                    writer.doWriteDecimalArray((BigDecimal[])obj);

                    break;

                case STRING_ARR:
                    writer.doWriteStringArray((String[])obj);

                    break;

                case UUID_ARR:
                    writer.doWriteUuidArray((UUID[])obj);

                    break;

                case DATE_ARR:
                    writer.doWriteDateArray((Date[])obj);

                    break;

                case TIMESTAMP_ARR:
                    writer.doWriteTimestampArray((Timestamp[])obj);

                    break;

                case TIME_ARR:
                    writer.doWriteTimeArray((Time[])obj);

                    break;

                case OBJECT_ARR:
                    writer.doWriteObjectArray((Object[])obj);

                    break;

                case COL:
                    writer.doWriteCollection((Collection<?>)obj);

                    break;

                case MAP:
                    writer.doWriteMap((Map<?, ?>)obj);

                    break;

                case ENUM:
                    writer.doWriteEnum((Enum<?>)obj);

                    break;

                case BINARY_ENUM:
                    writer.doWriteBinaryEnum((BinaryEnumObjectImpl)obj);

                    break;

                case ENUM_ARR:
                    writer.doWriteEnumArray((Object[])obj);

                    break;

                case CLASS:
                    writer.doWriteClass((Class)obj);

                    break;

                case PROXY:
                    writer.doWriteProxy((Proxy)obj, intfs);

                    break;

                case BINARY_OBJ:
                    writer.doWriteBinaryObject((BinaryObjectImpl)obj);

                    break;

                case BINARY:
                    if (preWrite(writer, obj)) {
                        try {
                            if (serializer != null)
                                serializer.writeBinary(obj, writer);
                            else
                                ((Binarylizable)obj).writeBinary(writer);

                            postWrite(writer);

                            // Check whether we need to update metadata.
                            // The reason for this check is described in https://issues.apache.org/jira/browse/IGNITE-7138.
                            if (obj.getClass() != BinaryMetadata.class && obj.getClass() != BinaryTreeMap.class) {
                                int schemaId = writer.schemaId();

                                if (schemaReg.schema(schemaId) == null) {
                                    // This is new schema, let's update metadata.
                                    BinaryMetadataCollector collector =
                                        new BinaryMetadataCollector(typeId, typeName, mapper);

                                    if (serializer != null)
                                        serializer.writeBinary(obj, collector);
                                    else
                                        ((Binarylizable)obj).writeBinary(collector);

                                    BinarySchema newSchema = collector.schema();

                                    BinaryMetadata meta = new BinaryMetadata(typeId, typeName, collector.meta(),
                                        affKeyFieldName, Collections.singleton(newSchema), false, null);

                                    ctx.updateMetadata(typeId, meta, writer.failIfUnregistered());

                                    schemaReg.addSchema(newSchema.schemaId(), newSchema);
                                }
                            }

                            postWriteHashCode(writer, obj);
                        }
                        finally {
                            writer.popSchema();
                        }
                    }

                    break;

                case OBJECT:
                    if (userType && !stableSchemaPublished) {
                        // Update meta before write object with new schema
                        BinaryMetadata meta = new BinaryMetadata(typeId, typeName, stableFieldsMeta,
                            affKeyFieldName, Collections.singleton(stableSchema), false, null);

                        ctx.updateMetadata(typeId, meta, writer.failIfUnregistered());

                        schemaReg.addSchema(stableSchema.schemaId(), stableSchema);

                        stableSchemaPublished = true;
                    }

                    if (preWrite(writer, obj)) {
                        try {
                            for (BinaryFieldAccessor info : fields)
                                info.write(obj, writer);

                            writer.schemaId(stableSchema.schemaId());

                            postWrite(writer);
                            postWriteHashCode(writer, obj);
                        }
                        finally {
                            writer.popSchema();
                        }
                    }

                    break;

                default:
                    assert false : "Invalid mode: " + mode;
            }
        }
        catch (Exception e) {
            if (e instanceof UnregisteredBinaryTypeException || e instanceof UnregisteredClassException)
                throw e;

            String msg;

            if (S.INCLUDE_SENSITIVE && !F.isEmpty(typeName))
                msg = "Failed to serialize object [typeName=" + typeName + ']';
            else
                msg = "Failed to serialize object [typeId=" + typeId + ']';

            U.error(ctx.log(), msg, e);

            throw new BinaryObjectException(msg, e);
        }
    }

    /**
     * @param reader Reader.
     * @return Object.
     * @throws BinaryObjectException If failed.
     */
    Object read(BinaryReaderExImpl reader) throws BinaryObjectException {
        try {
            assert reader != null;
            assert mode != BinaryWriteMode.OPTIMIZED : "OptimizedMarshaller should not be used here: " + cls.getName();

            Object res;

            switch (mode) {
                case BINARY:
                    res = newInstance();

                    reader.setHandle(res);

                    if (serializer != null)
                        serializer.readBinary(res, reader);
                    else
                        ((Binarylizable)res).readBinary(reader);

                    break;

                case OBJECT:
                    res = newInstance();

                    reader.setHandle(res);

                    for (BinaryFieldAccessor info : fields)
                        info.read(res, reader);

                    break;

                default:
                    assert false : "Invalid mode: " + mode;

                    return null;
            }

            if (readResolveMtd != null) {
                try {
                    res = readResolveMtd.invoke(res);

                    reader.setHandle(res);
                }
                catch (IllegalAccessException e) {
                    throw new RuntimeException(e);
                }
                catch (InvocationTargetException e) {
                    if (e.getTargetException() instanceof BinaryObjectException)
                        throw (BinaryObjectException)e.getTargetException();

                    throw new BinaryObjectException("Failed to execute readResolve() method on " + res, e);
                }
            }

            return res;
        }
        catch (Exception e) {
            String msg;

            if (S.INCLUDE_SENSITIVE && !F.isEmpty(typeName))
                msg = "Failed to deserialize object [typeName=" + typeName + ']';
            else
                msg = "Failed to deserialize object [typeId=" + typeId + ']';

            U.error(ctx.log(), msg, e);

            throw new BinaryObjectException(msg, e);
        }
    }

    /**
     * Pre-write phase.
     *
     * @param writer Writer.
     * @param obj Object.
     * @return Whether further write is needed.
     */
    private boolean preWrite(BinaryWriterExImpl writer, Object obj) {
        if (writer.tryWriteAsHandle(obj))
            return false;

        writer.preWrite(registered ? null : cls.getName());

        return true;
    }

    /**
     * Post-write phase.
     *
     * @param writer Writer.
     */
    private void postWrite(BinaryWriterExImpl writer) {
        writer.postWrite(userType, registered);
    }

    /**
     * Post-write routine for hash code.
     *
     * @param writer Writer.
     * @param obj Object.
     */
    private void postWriteHashCode(BinaryWriterExImpl writer, Object obj) {
        // No need to call "postWriteHashCode" here because we do not care about hash code.
        if (!(obj instanceof CacheObjectImpl))
            writer.postWriteHashCode(registered ? null : cls.getName());
    }

    /**
     * @return Instance.
     * @throws BinaryObjectException In case of error.
     */
    private Object newInstance() throws BinaryObjectException {
        try {
            return ctor != null ? ctor.newInstance() : GridUnsafe.allocateInstance(cls);
        }
        catch (InstantiationException | InvocationTargetException | IllegalAccessException e) {
            throw new BinaryObjectException("Failed to instantiate instance: " + cls, e);
        }
    }

    /**
     * @param cls Class.
     * @return Constructor.
     * @throws BinaryObjectException If constructor doesn't exist.
     */
    @SuppressWarnings("ConstantConditions")
    @Nullable private static Constructor<?> constructor(Class<?> cls) throws BinaryObjectException {
        assert cls != null;

        try {
            Constructor<?> ctor = U.forceEmptyConstructor(cls);

            if (ctor == null)
                throw new BinaryObjectException("Failed to find empty constructor for class: " + cls.getName());

            ctor.setAccessible(true);

            return ctor;
        }
        catch (IgniteCheckedException e) {
            throw new BinaryObjectException("Failed to get constructor for class: " + cls.getName(), e);
        }
    }

    /** {@inheritDoc} */
    @Override public String toString() {
        return S.toString(BinaryClassDescriptor.class, this);
    }
}
