content: package com.alibaba.fastjson2.util;
  
  import com.alibaba.fastjson2.codec.BeanInfo;
  import kotlin.jvm.internal.DefaultConstructorMarker;
  import kotlin.jvm.internal.Reflection;
  import kotlin.reflect.KClass;
  import kotlin.reflect.KFunction;
  import kotlin.reflect.KParameter;
  
  import java.lang.reflect.Constructor;
  import java.lang.reflect.Method;
  import java.util.*;
  
  /**
   * @author kraity
   * @since 2.0.39
   */
  public class KotlinUtils {
      public static final int STATE;
      private static volatile Class kotlin_metadata;
      private static volatile boolean kotlin_metadata_error;
      private static volatile boolean kotlin_class_klass_error;
      private static volatile Constructor kotlin_kclass_constructor;
      private static volatile Method kotlin_kclass_getConstructors;
      private static volatile Method kotlin_kfunction_getParameters;
      private static volatile Method kotlin_kparameter_getName;
      private static volatile boolean kotlin_error;
      private static volatile Map<Class, String[]> kotlinIgnores;
      private static volatile boolean kotlinIgnores_error;
  
      static {
          int state = 0;
          try {
              Class.forName("kotlin.Metadata");
              state++;
              Class.forName("kotlin.reflect.jvm.ReflectJvmMapping");
              state++;
          } catch (Throwable e) {
              // Nothing
          }
          STATE = state;
      }
  
      private KotlinUtils() {
          throw new IllegalStateException();
      }
  
      /**
       * Gets the target constructor and its
       * parameter names of the specified {@code clazz}
       *
       * @param clazz the specified class for search
       */
      public static void getConstructor(Class<?> clazz, BeanInfo beanInfo) {
          int creatorParams = 0;
          Constructor<?> creatorConstructor = null;
  
          String[] paramNames = beanInfo.createParameterNames;
          Constructor<?>[] constructors = BeanUtils.getConstructor(clazz);
  
          for (Constructor<?> constructor : constructors) {
              int paramCount = constructor.getParameterCount();
              if (paramNames != null && paramCount != paramNames.length) {
                  continue;
              }
  
              if (paramCount > 2) {
                  Class<?>[] parameterTypes = constructor.getParameterTypes();
                  if (parameterTypes[paramCount - 2] == int.class &&
                          parameterTypes[paramCount - 1] == DefaultConstructorMarker.class
                  ) {
                      beanInfo.markerConstructor = constructor;
                      continue;
                  }
              }
  
              if (creatorConstructor == null || creatorParams < paramCount) {
                  creatorParams = paramCount;
                  creatorConstructor = constructor;
              }
          }
  
          if (creatorParams != 0 && STATE == 2) {
              try {
                  List<KParameter> params = null;
                  KClass<?> kClass = Reflection.getOrCreateKotlinClass(clazz);
  
                  for (KFunction<?> function : kClass.getConstructors()) {
                      List<KParameter> parameters = function.getParameters();
                      if (params == null || creatorParams == parameters.size()) {
                          params = parameters;
                      }
                  }
  
                  if (params != null) {
                      String[] names = new String[params.size()];
                      for (int i = 0, m = names.length; i < m; i++) {
                          names[i] = params.get(i).getName();
                      }
                      beanInfo.createParameterNames = names;
                  }
              } catch (Throwable e) {
                  // Ignore this exception
              }
          }
  
          beanInfo.creatorConstructor = creatorConstructor;
      }
  
      public static boolean isKotlin(Class clazz) {
          if (kotlin_metadata == null && !kotlin_metadata_error) {
              try {
                  kotlin_metadata = Class.forName("kotlin.Metadata");
              } catch (Throwable e) {
                  kotlin_metadata_error = true;
              }
          }
          return kotlin_metadata != null && clazz.isAnnotationPresent(kotlin_metadata);
      }
  
      public static Constructor getKotlinConstructor(Constructor[] constructors) {
          return getKotlinConstructor(constructors, null);
      }
  
      public static Constructor getKotlinConstructor(Constructor[] constructors, String[] paramNames) {
          Constructor creatorConstructor = null;
          for (Constructor<?> constructor : constructors) {
              Class<?>[] parameterTypes = constructor.getParameterTypes();
              if (paramNames != null && parameterTypes.length != paramNames.length) {
                  continue;
              }
              // String equals to Class will always return false !
              if (parameterTypes.length > 0 && "kotlin.jvm.internal.DefaultConstructorMarker".equals(parameterTypes[parameterTypes.length - 1].getName())) {
                  continue;
              }
              if (creatorConstructor != null && creatorConstructor.getParameterTypes().length >= parameterTypes.length) {
                  continue;
              }
              creatorConstructor = constructor;
          }
          return creatorConstructor;
      }
  
      public static String[] getKoltinConstructorParameters(Class clazz) {
          if (kotlin_kclass_constructor == null && !kotlin_class_klass_error) {
              try {
                  Class class_kotlin_kclass = Class.forName("kotlin.reflect.jvm.internal.KClassImpl");
                  kotlin_kclass_constructor = class_kotlin_kclass.getConstructor(Class.class);
              } catch (Throwable e) {
                  kotlin_class_klass_error = true;
              }
          }
          if (kotlin_kclass_constructor == null) {
              return null;
          }
  
          if (kotlin_kclass_getConstructors == null && !kotlin_class_klass_error) {
              try {
                  Class class_kotlin_kclass = Class.forName("kotlin.reflect.jvm.internal.KClassImpl");
                  kotlin_kclass_getConstructors = class_kotlin_kclass.getMethod("getConstructors");
              } catch (Throwable e) {
                  kotlin_class_klass_error = true;
              }
          }
  
          if (kotlin_kfunction_getParameters == null && !kotlin_class_klass_error) {
              try {
                  Class class_kotlin_kfunction = Class.forName("kotlin.reflect.KFunction");
                  kotlin_kfunction_getParameters = class_kotlin_kfunction.getMethod("getParameters");
              } catch (Throwable e) {
                  kotlin_class_klass_error = true;
              }
          }
  
          if (kotlin_kparameter_getName == null && !kotlin_class_klass_error) {
              try {
                  Class class_kotlinn_kparameter = Class.forName("kotlin.reflect.KParameter");
                  kotlin_kparameter_getName = class_kotlinn_kparameter.getMethod("getName");
              } catch (Throwable e) {
                  kotlin_class_klass_error = true;
              }
          }
  
          if (kotlin_error) {
              return null;
          }
  
          try {
              Object constructor = null;
              Object kclassImpl = kotlin_kclass_constructor.newInstance(clazz);
              Iterable it = (Iterable) kotlin_kclass_getConstructors.invoke(kclassImpl);
              for (Iterator iterator = it.iterator(); iterator.hasNext();) {
                  Object item = iterator.next();
                  List parameters = (List) kotlin_kfunction_getParameters.invoke(item);
                  if (constructor != null && parameters.size() == 0) {
                      continue;
                  }
                  constructor = item;
              }
  
              if (constructor == null) {
                  return null;
              }
  
              List parameters = (List) kotlin_kfunction_getParameters.invoke(constructor);
              String[] names = new String[parameters.size()];
              for (int i = 0; i < parameters.size(); i++) {
                  Object param = parameters.get(i);
                  names[i] = (String) kotlin_kparameter_getName.invoke(param);
              }
              return names;
          } catch (Throwable e) {
              e.printStackTrace();
              kotlin_error = true;
          }
          return null;
      }
  
      public static boolean isKotlinIgnore(Class clazz, String methodName) {
          if (kotlinIgnores == null && !kotlinIgnores_error) {
              try {
                  Map<Class, String[]> map = new HashMap<>();
                  Class charRangeClass = Class.forName("kotlin.ranges.CharRange");
                  map.put(charRangeClass, new String[]{"getEndInclusive", "isEmpty"});
                  Class intRangeClass = Class.forName("kotlin.ranges.IntRange");
                  map.put(intRangeClass, new String[]{"getEndInclusive", "isEmpty"});
                  Class longRangeClass = Class.forName("kotlin.ranges.LongRange");
                  map.put(longRangeClass, new String[]{"getEndInclusive", "isEmpty"});
                  Class floatRangeClass = Class.forName("kotlin.ranges.ClosedFloatRange");
                  map.put(floatRangeClass, new String[]{"getEndInclusive", "isEmpty"});
                  Class doubleRangeClass = Class.forName("kotlin.ranges.ClosedDoubleRange");
                  map.put(doubleRangeClass, new String[]{"getEndInclusive", "isEmpty"});
                  kotlinIgnores = map;
              } catch (Throwable error) {
                  kotlinIgnores_error = true;
              }
          }
          if (kotlinIgnores == null) {
              return false;
          }
          String[] ignores = kotlinIgnores.get(clazz);
          return ignores != null && Arrays.binarySearch(ignores, methodName) >= 0;
      }
  }
  