public static String getDescriptorForInvoke(int offset,
			AbstractConstantPoolInfoJava[] constantPool, JavaInvocationType type) {
		String descriptor = null;
		int name_and_type_index = 0;
		switch (type) {
			case INVOKE_DYNAMIC:
				ConstantPoolInvokeDynamicInfo dynamicInfo =
					(ConstantPoolInvokeDynamicInfo) constantPool[offset];
				name_and_type_index = dynamicInfo.getNameAndTypeIndex();
				break;
			case INVOKE_INTERFACE:
				ConstantPoolInterfaceMethodReferenceInfo interfaceInfo =
					(ConstantPoolInterfaceMethodReferenceInfo) constantPool[offset];
				name_and_type_index = interfaceInfo.getNameAndTypeIndex();
				break;
			case INVOKE_STATIC:
				AbstractConstantPoolInfoJava poolElem = constantPool[offset];
				if (poolElem instanceof ConstantPoolInterfaceMethodReferenceInfo) {
					interfaceInfo = (ConstantPoolInterfaceMethodReferenceInfo) constantPool[offset];
					name_and_type_index = interfaceInfo.getNameAndTypeIndex();
					break;
				}
				if (poolElem instanceof ConstantPoolMethodReferenceInfo) {
					ConstantPoolMethodReferenceInfo methodReferenceInfo =
						(ConstantPoolMethodReferenceInfo) constantPool[offset];
					name_and_type_index = methodReferenceInfo.getNameAndTypeIndex();
					break;
				}
				throw new IllegalArgumentException(
					"Unsupported type for invokestatic at constant pool element " + offset);
			case INVOKE_SPECIAL:
			case INVOKE_VIRTUAL:
				ConstantPoolMethodReferenceInfo methodReferenceInfo =
					(ConstantPoolMethodReferenceInfo) constantPool[offset];
				name_and_type_index = methodReferenceInfo.getNameAndTypeIndex();
				break;
			default:
				throw new IllegalArgumentException("unimplemented method type: " + type.name());
		}
		ConstantPoolNameAndTypeInfo methodNameAndType =
			(ConstantPoolNameAndTypeInfo) constantPool[name_and_type_index];
		int descriptor_index = methodNameAndType.getDescriptorIndex();
		ConstantPoolUtf8Info descriptorInfo = (ConstantPoolUtf8Info) constantPool[descriptor_index];
		descriptor = descriptorInfo.getString();
		return descriptor;
	}
Given an invocation type and an element in the constant pool, follows references in the constant
pool and returns the appropriate method descriptor.
@param offset
@param constantPool
@param type
@return
Ghidra/Processors/JVM/src/main/java/ghidra/javaclass/format/DescriptorDecoder.java