package jetbrains.mps.baseLanguage.javastub;

/*Generated by MPS */

import jetbrains.mps.annotations.GeneratedClass;
import org.jetbrains.mps.openapi.model.SNodeId;
import jetbrains.mps.util.NameUtil;
import jetbrains.mps.baseLanguage.javastub.asm.ASMClass;
import jetbrains.mps.baseLanguage.javastub.asm.ASMField;
import jetbrains.mps.baseLanguage.javastub.asm.ASMMethod;
import jetbrains.mps.smodel.StringBasedIdForJavaStubMethods;
import jetbrains.mps.baseLanguage.javastub.asm.ASMType;
import jetbrains.mps.baseLanguage.javastub.asm.ASMParameterizedType;
import jetbrains.mps.baseLanguage.javastub.asm.ASMClassType;
import jetbrains.mps.baseLanguage.javastub.asm.ASMArrayType;
import jetbrains.mps.baseLanguage.javastub.asm.ASMVarArgType;
import jetbrains.mps.baseLanguage.javastub.asm.ASMPrimitiveType;
import jetbrains.mps.baseLanguage.javastub.asm.ASMTypeVariable;
import jetbrains.mps.baseLanguage.javastub.asm.ASMExtendsType;
import jetbrains.mps.baseLanguage.javastub.asm.ASMSuperType;
import jetbrains.mps.baseLanguage.javastub.asm.ASMUnboundedType;
import java.util.List;
import java.util.Iterator;

@GeneratedClass(node = "r:aa7e8178-3b66-4295-bcce-165c85d78006(jetbrains.mps.baseLanguage.javastub)/7241381882860008238", model = "r:aa7e8178-3b66-4295-bcce-165c85d78006(jetbrains.mps.baseLanguage.javastub)")
public class ASMNodeId {
  public ASMNodeId() {
  }
  public static SNodeId createId(String fqClassName) {
    return new jetbrains.mps.smodel.SNodeId.Foreign(jetbrains.mps.smodel.SNodeId.Foreign.ID_PREFIX + NameUtil.shortNameFromLongName(fqClassName));
  }
  public static SNodeId createId(ASMClass cls, ASMField field) {
    return new jetbrains.mps.smodel.SNodeId.Foreign(jetbrains.mps.smodel.SNodeId.Foreign.ID_PREFIX + ASMNodeId.shortNameFromSlashedLongName(cls.getName()) + "." + field.getName());
  }
  public static SNodeId createFieldId(String fqClassName, String fieldName) {
    return new jetbrains.mps.smodel.SNodeId.Foreign(jetbrains.mps.smodel.SNodeId.Foreign.ID_PREFIX + NameUtil.shortNameFromLongName(fqClassName) + "." + fieldName);
  }
  public static SNodeId createId(ASMClass cls, ASMMethod method) {
    StringBuilder sb = new StringBuilder();
    sb.append(ASMNodeId.shortNameFromSlashedLongName(cls.getName()));
    sb.append('.');
    if (method.isConstructor()) {
      sb.append("<init>");
    } else {
      sb.append(method.getName());
    }
    sb.append('(');
    ASMNodeId.appendList(sb, method.getParameterTypes());
    sb.append(')');
    if (!(method.isConstructor())) {
      sb.append(':');
      sb.append(ASMNodeId.asString(method.getReturnType()));
      return new StringBasedIdForJavaStubMethods(StringBasedIdForJavaStubMethods.ID_PREFIX + sb.toString());
    }
    return new jetbrains.mps.smodel.SNodeId.Foreign(jetbrains.mps.smodel.SNodeId.Foreign.ID_PREFIX + sb.toString());
  }
  public static SNodeId createAnnotationMethodId(String fqClassName, String methodName) {
    StringBuilder sb = new StringBuilder();
    sb.append(NameUtil.shortNameFromLongName(fqClassName));
    sb.append('.');
    sb.append(methodName);
    sb.append("()");
    return new jetbrains.mps.smodel.SNodeId.Foreign(jetbrains.mps.smodel.SNodeId.Foreign.ID_PREFIX + sb.toString());
  }
  private static String shortNameFromSlashedLongName(String slashedLongName) {
    int offset = slashedLongName.lastIndexOf('/');
    if (offset < 0) {
      return slashedLongName;
    }
    return slashedLongName.substring(offset + 1);
  }
  private static String asString(ASMType type) {
    if (type instanceof ASMParameterizedType) {
      StringBuilder sb = new StringBuilder();
      sb.append(ASMNodeId.asString(((ASMParameterizedType) type).getRawType()));
      sb.append('<');
      ASMNodeId.appendList(sb, ((ASMParameterizedType) type).getActualTypeArguments());
      sb.append('>');
      return sb.toString();
    }
    if (type instanceof ASMClassType) {
      return ((ASMClassType) type).getName();
    }
    if (type instanceof ASMArrayType) {
      return ASMNodeId.asString(((ASMArrayType) type).getElementType()) + "[]";
    }
    if (type instanceof ASMVarArgType) {
      return ASMNodeId.asString(((ASMVarArgType) type).getElementType()) + "...";
    }
    if (type instanceof ASMPrimitiveType) {
      return ((ASMPrimitiveType) type).getName();
    }
    if (type instanceof ASMTypeVariable) {
      return ((ASMTypeVariable) type).getName();
    }
    if (type instanceof ASMExtendsType) {
      return "? extends " + ASMNodeId.asString(((ASMExtendsType) type).getBound());
    }
    if (type instanceof ASMSuperType) {
      return "? super " + ASMNodeId.asString(((ASMSuperType) type).getBound());
    }
    if (type instanceof ASMUnboundedType) {
      return "?";
    }
    throw new RuntimeException("unexpected type: " + type);
  }
  private static void appendList(StringBuilder sb, List<ASMType> types) {
    Iterator<ASMType> iterator = types.iterator();
    while (iterator.hasNext()) {
      sb.append(ASMNodeId.asString(iterator.next()));
      if (iterator.hasNext()) {
        sb.append(',');
      }
    }
  }
}
