// Copyright (c) 2019, the R8 project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.kotlin;

import static com.android.tools.r8.kotlin.Kotlin.NAME;
import static com.android.tools.r8.kotlin.KotlinMetadataJvmExtensionUtils.toJvmFieldSignature;
import static com.android.tools.r8.kotlin.KotlinMetadataJvmExtensionUtils.toJvmMethodSignature;
import static com.android.tools.r8.utils.DescriptorUtils.descriptorToKotlinClassifier;
import static com.android.tools.r8.utils.DescriptorUtils.getBinaryNameFromDescriptor;
import static com.android.tools.r8.utils.DescriptorUtils.getDescriptorFromKmType;
import static kotlinx.metadata.Flag.Property.IS_VAR;
import static kotlinx.metadata.FlagsKt.flagsOf;

import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DebugLocalInfo;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexEncodedField;
import com.android.tools.r8.graph.DexEncodedMethod;
import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexProto;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.graph.GenericSignature;
import com.android.tools.r8.graph.GenericSignature.ClassTypeSignature;
import com.android.tools.r8.graph.GenericSignature.FieldTypeSignature;
import com.android.tools.r8.graph.GenericSignature.MethodTypeSignature;
import com.android.tools.r8.graph.GenericSignature.TypeSignature;
import com.android.tools.r8.kotlin.KotlinMemberInfo.KotlinFunctionInfo;
import com.android.tools.r8.naming.NamingLens;
import com.android.tools.r8.shaking.AppInfoWithLiveness;
import java.util.List;
import java.util.function.Consumer;
import kotlinx.metadata.KmConstructor;
import kotlinx.metadata.KmFunction;
import kotlinx.metadata.KmProperty;
import kotlinx.metadata.KmType;
import kotlinx.metadata.KmTypeProjection;
import kotlinx.metadata.KmValueParameter;
import kotlinx.metadata.KmVariance;
import kotlinx.metadata.jvm.JvmExtensionsKt;

class KotlinMetadataSynthesizer {

  static boolean isExtension(KmFunction kmFunction) {
    return kmFunction.getReceiverParameterType() != null;
  }

  static boolean isExtension(KmProperty kmProperty) {
    return kmProperty.getReceiverParameterType() != null;
  }

  static KmType toKmType(String descriptor) {
    KmType kmType = new KmType(flagsOf());
    kmType.visitClass(descriptorToKotlinClassifier(descriptor));
    return kmType;
  }

  static DexType toRenamedType(
      DexType type, AppView<AppInfoWithLiveness> appView, NamingLens lens) {
    // For library or classpath class, synthesize @Metadata always.
    // For a program class, make sure it is live.
    if (!appView.appInfo().isNonProgramTypeOrLiveProgramType(type)) {
      return null;
    }
    DexType renamedType = lens.lookupType(type, appView.dexItemFactory());
    // For library or classpath class, we should not have renamed it.
    DexClass clazz = appView.definitionFor(type);
    assert clazz == null || clazz.isProgramClass() || renamedType == type
        : type.toSourceString() + " -> " + renamedType.toSourceString();
    return renamedType;
  }

  static String toRenamedBinaryName(
      DexType type, AppView<AppInfoWithLiveness> appView, NamingLens lens) {
    DexType renamedType = toRenamedType(type, appView, lens);
    if (renamedType == null) {
      return null;
    }
    return getBinaryNameFromDescriptor(renamedType.toDescriptorString());
  }

  static String toRenamedClassifier(
      DexType type, AppView<AppInfoWithLiveness> appView, NamingLens lens) {
    // E.g., V -> kotlin/Unit, J -> kotlin/Long, [J -> kotlin/LongArray
    if (appView.dexItemFactory().kotlin.knownTypeConversion.containsKey(type)) {
      DexType convertedType = appView.dexItemFactory().kotlin.knownTypeConversion.get(type);
      assert convertedType != null;
      return descriptorToKotlinClassifier(convertedType.toDescriptorString());
    }
    // E.g., [Ljava/lang/String; -> kotlin/Array
    if (type.isArrayType()) {
      return NAME + "/Array";
    }
    DexType renamedType = toRenamedType(type, appView, lens);
    if (renamedType == null) {
      return null;
    }
    return descriptorToKotlinClassifier(renamedType.toDescriptorString());
  }

  // TODO(b/148654451): Canonicalization?
  static KmType toRenamedKmType(
      DexType type,
      TypeSignature typeSignature,
      AppView<AppInfoWithLiveness> appView,
      NamingLens lens) {
    if (typeSignature != null
        && typeSignature.isFieldTypeSignature()
        && typeSignature.asFieldTypeSignature().isClassTypeSignature()
        && typeSignature.asFieldTypeSignature().asClassTypeSignature().type() == type) {
      return toRenamedKmType(
          typeSignature.asFieldTypeSignature().asClassTypeSignature(), appView, lens);
    }

    String classifier = toRenamedClassifier(type, appView, lens);
    if (classifier == null) {
      return null;
    }
    // TODO(b/151194869): Mysterious, why attempts to properly set flags bothers kotlinc?
    //   and/or why wiping out flags works for KmType but not KmFunction?!
    KmType kmType = new KmType(flagsOf());
    kmType.visitClass(classifier);
    // TODO(b/151194164): Can be generalized too, like ArrayTypeSignature.Converter ?
    // E.g., java.lang.String[] -> KmType(kotlin/Array, KmTypeProjection(OUT, kotlin/String))
    if (type.isArrayType() && !type.isPrimitiveArrayType()) {
      DexType elementType = type.toArrayElementType(appView.dexItemFactory());
      KmType argumentType = toRenamedKmType(elementType, null, appView, lens);
      kmType.getArguments().add(new KmTypeProjection(KmVariance.OUT, argumentType));
    }
    return kmType;
  }

  static KmType toRenamedKmType(
      ClassTypeSignature classTypeSignature,
      AppView<AppInfoWithLiveness> appView,
      NamingLens lens) {
    return classTypeSignature.convert(
        new ClassTypeSignatureToRenamedKmTypeConverter(appView, lens));
  }

  static class ClassTypeSignatureToRenamedKmTypeConverter
      implements ClassTypeSignature.Converter<KmType> {

    private final AppView<AppInfoWithLiveness> appView;
    private final NamingLens lens;

    ClassTypeSignatureToRenamedKmTypeConverter(
        AppView<AppInfoWithLiveness> appView, NamingLens lens) {
      this.appView = appView;
      this.lens = lens;
    }

    @Override
    public KmType init() {
      return new KmType(flagsOf());
    }

    @Override
    public KmType visitType(DexType type, KmType result) {
      if (result == null) {
        return result;
      }
      String classifier = toRenamedClassifier(type, appView, lens);
      if (classifier == null) {
        return null;
      }
      result.visitClass(classifier);
      return result;
    }

    @Override
    public KmType visitTypeArgument(FieldTypeSignature typeArgument, KmType result) {
      if (result == null) {
        return result;
      }
      if (typeArgument.isClassTypeSignature()) {
        KmType argumentType = typeArgument.asClassTypeSignature().convert(this);
        result.getArguments().add(new KmTypeProjection(KmVariance.INVARIANT, argumentType));
      }
      // TODO(b/151194164): for TypeVariableSignature, there is KmType::visitTypeParameter.
      return result;
    }

    @Override
    public KmType visitInnerTypeSignature(ClassTypeSignature innerTypeSignature, KmType result) {
      // Do nothing
      return result;
    }
  }

  private static KmType setRenamedKmType(
      DexType type,
      TypeSignature signature,
      AppView<AppInfoWithLiveness> appView,
      NamingLens lens,
      Consumer<KmType> consumer) {
    KmType renamedKmType = toRenamedKmType(type, signature, appView, lens);
    if (renamedKmType != null) {
      consumer.accept(renamedKmType);
    }
    return renamedKmType;
  }

  static KmConstructor toRenamedKmConstructor(
      DexEncodedMethod method,
      AppView<AppInfoWithLiveness> appView,
      NamingLens lens) {
    // Make sure it is an instance initializer and live.
    if (!method.isInstanceInitializer()
        || !appView.appInfo().liveMethods.contains(method.method)) {
      return null;
    }
    KmConstructor kmConstructor = new KmConstructor(method.accessFlags.getAsKotlinFlags());
    JvmExtensionsKt.setSignature(kmConstructor, toJvmMethodSignature(method.method));
    MethodTypeSignature signature = GenericSignature.Parser.toMethodTypeSignature(method, appView);
    List<KmValueParameter> parameters = kmConstructor.getValueParameters();
    if (!populateKmValueParameters(parameters, method, signature, appView, lens)) {
      return null;
    }
    return kmConstructor;
  }

  static KmFunction toRenamedKmFunction(
      DexEncodedMethod method,
      AppView<AppInfoWithLiveness> appView,
      NamingLens lens) {
    // For library overrides, synthesize @Metadata always.
    // For regular methods, make sure it is live or pinned.
    if (!method.isLibraryMethodOverride().isTrue()
        && !appView.appInfo().isPinned(method.method)
        && !appView.appInfo().liveMethods.contains(method.method)) {
      return null;
    }
    DexMethod renamedMethod = lens.lookupMethod(method.method, appView.dexItemFactory());
    // For a library method override, we should not have renamed it.
    assert !method.isLibraryMethodOverride().isTrue() || renamedMethod.name == method.method.name
        : method.toSourceString() + " -> " + renamedMethod.toSourceString();
    // TODO(b/151194869): Should we keep kotlin-specific flags only while synthesizing the base
    //  value from general JVM flags?
    int flag =
        appView.appInfo().isPinned(method.method) && method.getKotlinMemberInfo() != null
            ? method.getKotlinMemberInfo().flags
            : method.accessFlags.getAsKotlinFlags();
    KmFunction kmFunction = new KmFunction(flag, renamedMethod.name.toString());
    JvmExtensionsKt.setSignature(kmFunction, toJvmMethodSignature(renamedMethod));

    // TODO(b/129925954): Should this be integrated as part of DexDefinition instead of parsing it
    //  on demand? That may require utils to map internal encoding of signature back to
    //  corresponding backend definitions, like DexAnnotation (DEX) or Signature attribute (CF).
    MethodTypeSignature signature = GenericSignature.Parser.toMethodTypeSignature(method, appView);

    DexProto proto = method.method.proto;
    DexType returnType = proto.returnType;
    TypeSignature returnSignature = signature.returnType().typeSignature();
    KmType kmReturnType = setRenamedKmType(
        returnType, returnSignature, appView, lens, kmFunction::setReturnType);
    if (kmReturnType == null) {
      return null;
    }

    if (method.isKotlinExtensionFunction()) {
      assert proto.parameters.values.length > 0
          : method.method.toSourceString();
      DexType receiverType = proto.parameters.values[0];
      TypeSignature receiverSignature = signature.getParameterTypeSignature(0);
      KmType kmReceiverType = setRenamedKmType(
          receiverType, receiverSignature, appView, lens, kmFunction::setReceiverParameterType);
      if (kmReceiverType == null) {
        return null;
      }
    }

    List<KmValueParameter> parameters = kmFunction.getValueParameters();
    if (!populateKmValueParameters(parameters, method, signature, appView, lens)) {
      return null;
    }
    return kmFunction;
  }

  private static boolean populateKmValueParameters(
      List<KmValueParameter> parameters,
      DexEncodedMethod method,
      MethodTypeSignature signature,
      AppView<AppInfoWithLiveness> appView,
      NamingLens lens) {
    KotlinFunctionInfo kotlinFunctionInfo = method.getKotlinMemberInfo().asFunctionInfo();
    if (kotlinFunctionInfo == null) {
      return false;
    }
    boolean isExtension = method.isKotlinExtensionFunction();
    for (int i = isExtension ? 1 : 0; i < method.method.proto.parameters.values.length; i++) {
      DexType parameterType = method.method.proto.parameters.values[i];
      DebugLocalInfo debugLocalInfo = method.getParameterInfo().get(i);
      String parameterName = debugLocalInfo != null ? debugLocalInfo.name.toString() : ("p" + i);
      KotlinValueParameterInfo valueParameterInfo =
          kotlinFunctionInfo.getValueParameterInfo(isExtension ? i - 1 : i);
      TypeSignature parameterTypeSignature = signature.getParameterTypeSignature(i);
      KmValueParameter kmValueParameter =
          toRewrittenKmValueParameter(
              valueParameterInfo,
              parameterType,
              parameterTypeSignature,
              parameterName,
              appView,
              lens);
      if (kmValueParameter == null) {
        return false;
      }
      parameters.add(kmValueParameter);
    }
    return true;
  }

  private static KmValueParameter toRewrittenKmValueParameter(
      KotlinValueParameterInfo valueParameterInfo,
      DexType parameterType,
      TypeSignature parameterTypeSignature,
      String candidateParameterName,
      AppView<AppInfoWithLiveness> appView,
      NamingLens lens) {
    int flag = valueParameterInfo != null ? valueParameterInfo.flag : flagsOf();
    String name = valueParameterInfo != null ? valueParameterInfo.name : candidateParameterName;
    KmValueParameter kmValueParameter = new KmValueParameter(flag, name);
    KmType kmParamType = setRenamedKmType(
        parameterType, parameterTypeSignature, appView, lens, kmValueParameter::setType);
    if (kmParamType == null) {
      return null;
    }
    if (valueParameterInfo != null) {
      JvmExtensionsKt.getAnnotations(kmParamType).addAll(valueParameterInfo.annotations);
    }

    if (valueParameterInfo != null && valueParameterInfo.isVararg) {
      if (!parameterType.isArrayType()) {
        return null;
      }
      DexType elementType = parameterType.toArrayElementType(appView.dexItemFactory());
      TypeSignature elementSignature =
          parameterTypeSignature != null
              ? parameterTypeSignature.toArrayElementTypeSignature(appView) : null;
      KmType kmElementType = setRenamedKmType(
          elementType, elementSignature, appView, lens, kmValueParameter::setVarargElementType);
      if (kmElementType == null) {
        return null;
      }
    }

    return kmValueParameter;
  }

  /**
   * A group of a field, and methods that correspond to a Kotlin property.
   *
   * <p>
   * va(l|r) prop: T
   *
   * is converted to a backing field with signature `T prop` if necessary. If the property is a pure
   * computation, e.g., return `this` or access to the status of other properties, a field is not
   * needed for the property.
   * <p>
   * Depending on property visibility, getter is defined with signature `T getProp()` (or `isProp`
   * for boolean property).
   * <p>
   * If it's editable, i.e., declared as `var`, setter is defined with signature `void setProp(T)`.
   * <p>
   * Yet another addition, `void prop$annotations()`, seems(?) to be used to store associated
   * annotations.
   *
   * <p>
   * Currently, it's unclear how users can selectively keep each. Assuming every piece is kept by
   * more general rules, such as keeping non-private members, we expect to find those as a whole.
   * When rewriting a corresponding property, each information is used to update corresponding part,
   * e.g., field to update the return type of the property, getter to update jvmMethodSignature of
   * getter, and so on.
   */
  static class KmPropertyGroup {
    final int flags;
    final String name;
    final DexEncodedField field;
    final DexEncodedMethod getter;
    final int getterFlags;
    final DexEncodedMethod setter;
    final int setterFlags;
    final DexEncodedMethod annotations;
    final boolean isExtension;

    private KmPropertyGroup(
        int flags,
        String name,
        DexEncodedField field,
        DexEncodedMethod getter,
        int getterFlags,
        DexEncodedMethod setter,
        int setterFlags,
        DexEncodedMethod annotations,
        boolean isExtension) {
      this.flags = flags;
      this.name = name;
      this.field = field;
      this.getter = getter;
      this.getterFlags = getterFlags;
      this.setter = setter;
      this.setterFlags = setterFlags;
      this.annotations = annotations;
      this.isExtension = isExtension;
    }

    static Builder builder(int flags, String name) {
      return new Builder(flags, name);
    }

    static class Builder {
      private final int flags;
      private final String name;
      private DexEncodedField field;
      private DexEncodedMethod getter;
      private int getterFlags;
      private DexEncodedMethod setter;
      private int setterFlags;
      private DexEncodedMethod annotations;

      private boolean isExtensionGetter;
      private boolean isExtensionSetter;
      private boolean isExtensionAnnotations;

      private Builder(int flags, String name) {
        this.flags = flags;
        this.name = name;
      }

      Builder foundBackingField(DexEncodedField field) {
        this.field = field;
        return this;
      }

      Builder foundGetter(DexEncodedMethod getter, int flags) {
        this.getter = getter;
        this.getterFlags = flags;
        return this;
      }

      Builder foundSetter(DexEncodedMethod setter, int flags) {
        this.setter = setter;
        this.setterFlags = flags;
        return this;
      }

      Builder foundAnnotations(DexEncodedMethod annotations) {
        this.annotations = annotations;
        return this;
      }

      Builder isExtensionGetter() {
        this.isExtensionGetter = true;
        return this;
      }

      Builder isExtensionSetter() {
        this.isExtensionSetter = true;
        return this;
      }

      Builder isExtensionAnnotations() {
        this.isExtensionAnnotations = true;
        return this;
      }

      KmPropertyGroup build() {
        boolean isExtension = isExtensionGetter || isExtensionSetter || isExtensionAnnotations;
        // If this is an extension property, everything should be an extension.
        if (isExtension) {
          if (getter != null && !isExtensionGetter) {
            return null;
          }
          if (setter != null && !isExtensionSetter) {
            return null;
          }
          if (annotations != null && !isExtensionAnnotations) {
            return null;
          }
        }
        return new KmPropertyGroup(
            flags, name, field, getter, getterFlags, setter, setterFlags, annotations, isExtension);
      }
    }

    KmProperty toRenamedKmProperty(AppView<AppInfoWithLiveness> appView, NamingLens lens) {
      KmProperty kmProperty = new KmProperty(flags, name, flagsOf(), flagsOf());
      KmType kmPropertyType = null;
      KmType kmReceiverType = null;

      // A flag to indicate we can rename the property name. This will become false if any member
      // is pinned. Then, we conservatively assume that users want the property to be pinned too.
      // That is, we won't rename the property even though some other members could be renamed.
      boolean canChangePropertyName = true;
      // A candidate property name. Not overwritten by the following members, hence the order of
      // preference: a backing field, getter, and setter.
      String renamedPropertyName = name;
      if (field != null) {
        if (appView.appInfo().isPinned(field.field)) {
          canChangePropertyName = false;
        }
        DexField renamedField = lens.lookupField(field.field, appView.dexItemFactory());
        if (canChangePropertyName && renamedField.name != field.field.name) {
          renamedPropertyName = renamedField.name.toString();
        }
        FieldTypeSignature signature =
            GenericSignature.Parser.toFieldTypeSignature(field, appView);
        kmPropertyType =
            setRenamedKmType(field.field.type, signature, appView, lens, kmProperty::setReturnType);
        JvmExtensionsKt.setFieldSignature(kmProperty, toJvmFieldSignature(renamedField));
      }

      GetterSetterCriteria criteria = checkGetterCriteria();
      if (criteria == GetterSetterCriteria.VIOLATE) {
        return null;
      }

      if (criteria == GetterSetterCriteria.MET) {
        assert getter != null && getter.method.proto.parameters.size() == (isExtension ? 1 : 0)
            : "checkGetterCriteria: " + this.toString();
        MethodTypeSignature signature =
            GenericSignature.Parser.toMethodTypeSignature(getter, appView);
        if (isExtension) {
          TypeSignature receiverSignature = signature.getParameterTypeSignature(0);
          kmReceiverType =
              setRenamedKmType(
                  getter.method.proto.parameters.values[0],
                  receiverSignature,
                  appView,
                  lens,
                  kmProperty::setReceiverParameterType);
        }

        DexType returnType = getter.method.proto.returnType;
        TypeSignature returnSignature = signature.returnType().typeSignature();
        if (kmPropertyType == null) {
          // The property type is not set yet.
          kmPropertyType = setRenamedKmType(
              returnType, returnSignature, appView, lens, kmProperty::setReturnType);
        } else {
          // If property type is set already (via backing field), make sure it's consistent.
          KmType kmPropertyTypeFromGetter =
              toRenamedKmType(returnType, returnSignature, appView, lens);
          if (!getDescriptorFromKmType(kmPropertyType)
              .equals(getDescriptorFromKmType(kmPropertyTypeFromGetter))) {
            return null;
          }
        }
        if (appView.appInfo().isPinned(getter.method)) {
          canChangePropertyName = false;
        }
        DexMethod renamedGetter = lens.lookupMethod(getter.method, appView.dexItemFactory());
        if (canChangePropertyName
            && renamedGetter.name != getter.method.name
            && renamedPropertyName.equals(name)) {
          renamedPropertyName = renamedGetter.name.toString();
        }
        kmProperty.setGetterFlags(getterFlags);
        JvmExtensionsKt.setGetterSignature(kmProperty, toJvmMethodSignature(renamedGetter));
      } else if (field != null) {
        // Property without getter.
        // Even though a getter does not exist, `kotlinc` still set getter flags and use them to
        // determine when to direct field access v.s. getter calls for property resolution.
        kmProperty.setGetterFlags(field.accessFlags.getAsKotlinFlags());
      }

      criteria = checkSetterCriteria();
      if (criteria == GetterSetterCriteria.VIOLATE) {
        return null;
      }

      if (criteria == GetterSetterCriteria.MET) {
        assert setter != null && setter.method.proto.parameters.size() == (isExtension ? 2 : 1)
            : "checkSetterCriteria: " + this.toString();
        MethodTypeSignature signature =
            GenericSignature.Parser.toMethodTypeSignature(setter, appView);
        if (isExtension) {
          DexType receiverType = setter.method.proto.parameters.values[0];
          TypeSignature receiverSignature = signature.getParameterTypeSignature(0);
          if (kmReceiverType == null) {
            kmReceiverType =
                setRenamedKmType(
                    receiverType,
                    receiverSignature,
                    appView,
                    lens,
                    kmProperty::setReceiverParameterType);
          } else {
            // If the receiver type for the extension property is set already (via getter),
            // make sure it's consistent.
            KmType kmReceiverTypeFromSetter =
                toRenamedKmType(receiverType, receiverSignature, appView, lens);
            if (!getDescriptorFromKmType(kmReceiverType)
                .equals(getDescriptorFromKmType(kmReceiverTypeFromSetter))) {
              return null;
            }
          }
        }

        int valueIndex = isExtension ? 1 : 0;
        DexType valueType = setter.method.proto.parameters.values[valueIndex];
        TypeSignature valueSignature = signature.getParameterTypeSignature(valueIndex);
        if (kmPropertyType == null) {
          // The property type is not set yet.
          kmPropertyType =
              setRenamedKmType(valueType, valueSignature, appView, lens, kmProperty::setReturnType);
        } else {
          // If property type is set already (via either backing field or getter),
          // make sure it's consistent.
          KmType kmPropertyTypeFromSetter =
              toRenamedKmType(valueType, valueSignature, appView, lens);
          if (!getDescriptorFromKmType(kmPropertyType)
              .equals(getDescriptorFromKmType(kmPropertyTypeFromSetter))) {
            return null;
          }
        }
        assert setter.getKotlinMemberInfo().isPropertyInfo();
        KotlinValueParameterInfo valueParameterInfo =
            setter.getKotlinMemberInfo().asPropertyInfo().valueParameterInfo;
        KmValueParameter kmValueParameter = toRewrittenKmValueParameter(
            valueParameterInfo, valueType, valueSignature, "value", appView, lens);
        if (kmValueParameter != null) {
          kmProperty.setSetterParameter(kmValueParameter);
        }
        if (appView.appInfo().isPinned(setter.method)) {
          canChangePropertyName = false;
        }
        DexMethod renamedSetter = lens.lookupMethod(setter.method, appView.dexItemFactory());
        if (canChangePropertyName
            && renamedSetter.name != setter.method.name
            && renamedPropertyName.equals(name)) {
          renamedPropertyName = renamedSetter.name.toString();
        }
        kmProperty.setSetterFlags(setterFlags);
        JvmExtensionsKt.setSetterSignature(kmProperty, toJvmMethodSignature(renamedSetter));
      } else if (field != null && IS_VAR.invoke(flags)) {
        // Editable property without setter.
        // Even though a setter does not exist, `kotlinc` still set setter flags and use them to
        // determine when to direct field access v.s. setter calls for property resolution.
        kmProperty.setGetterFlags(field.accessFlags.getAsKotlinFlags());
      }

      // If the property type remains null at the end, bail out to synthesize this property.
      if (kmPropertyType == null) {
        return null;
      }
      // For extension property, if the receiver type remains null at the end, bail out too.
      if (isExtension && kmReceiverType == null) {
        return null;
      }
      // Rename the property name if and only if none of participating members is pinned, and
      // any of them is indeed renamed (to a new name).
      if (canChangePropertyName && !renamedPropertyName.equals(name)) {
        kmProperty.setName(renamedPropertyName);
      }
      return kmProperty;
    }

    enum GetterSetterCriteria {
      NOT_AVAILABLE,
      MET,
      VIOLATE
    }

    // Getter should look like:
    //   1) T getProp(); for regular property, or
    //   2) T getProp(R); for extension property, where
    // T is a property type, and R is a receiver type.
    private GetterSetterCriteria checkGetterCriteria() {
      if (getter == null) {
        return GetterSetterCriteria.NOT_AVAILABLE;
      }
      // Property type will be checked against a backing field type if any.
      // And if they're different, we won't synthesize KmProperty for that.
      // Checking parameter size.
      if (isExtension) {
        return getter.method.proto.parameters.size() == 1
            ? GetterSetterCriteria.MET : GetterSetterCriteria.VIOLATE;
      } else {
        return getter.method.proto.parameters.size() == 0
            ? GetterSetterCriteria.MET : GetterSetterCriteria.VIOLATE;
      }
    }

    // Setter should look like:
    //   1) void setProp(T); for regular property, or
    //   2) void setProp(R, T); for extension property, where
    // T is a property type, and R is a receiver type.
    private GetterSetterCriteria checkSetterCriteria() {
      if (setter == null) {
        return GetterSetterCriteria.NOT_AVAILABLE;
      }
      if (!setter.method.proto.returnType.isVoidType()) {
        return GetterSetterCriteria.VIOLATE;
      }
      // Property type will be checked against a backing field type if any.
      // And if they're different, we won't synthesize KmProperty for that.
      // Plus, receiver type will be checked, too, against a getter.
      if (isExtension) {
        return setter.method.proto.parameters.size() == 2
            ? GetterSetterCriteria.MET : GetterSetterCriteria.VIOLATE;
      } else {
        return setter.method.proto.parameters.size() == 1
            ? GetterSetterCriteria.MET : GetterSetterCriteria.VIOLATE;
      }
    }

    @Override
    public String toString() {
      StringBuilder builder = new StringBuilder();
      builder.append("KmPropertyGroup {").append(System.lineSeparator());
      builder.append("  name: ").append(name).append(System.lineSeparator());
      builder.append("  isExtension: ").append(isExtension).append(System.lineSeparator());
      if (field != null) {
        builder.append("  field: ")
            .append(field.toSourceString())
            .append(System.lineSeparator());
      }
      if (getter != null) {
        builder
            .append("  getter: ")
            .append(getter.toSourceString())
            .append(System.lineSeparator());
      }
      if (setter != null) {
        builder
            .append("  setter: ")
            .append(setter.toSourceString())
            .append(System.lineSeparator());
      }
      if (annotations != null) {
        builder
            .append("  annotations: ")
            .append(annotations.toSourceString())
            .append(System.lineSeparator());
      }
      builder.append("}");
      return builder.toString();
    }
  }
}
