static char *dex_resolve_proto_id(RzBinDex *dex, const char *name, ut32 proto_idx, bool varargs) {
	if (proto_idx >= rz_pvector_len(dex->proto_ids)) {
		RZ_LOG_INFO("cannot find proto_id with index %u\n", proto_idx);
		return NULL;
	}

	DexProtoId *proto_id = (DexProtoId *)rz_pvector_at(dex->proto_ids, proto_idx);
	if (proto_id->return_type_idx >= dex->type_ids_size) {
		RZ_LOG_INFO("cannot find return type id with index %u\n", proto_id->return_type_idx);
		return NULL;
	}

	RzStrBuf *sb = rz_strbuf_new(name);
	if (!sb) {
		return NULL;
	}

	const DexString *return_type = dex_resolve_string_id_native(dex, dex->types[proto_id->return_type_idx]);
	if (!return_type) {
		RZ_LOG_INFO("cannot find return type string with index %u\n", proto_id->return_type_idx);
		rz_strbuf_free(sb);
		return NULL;
	}

	rz_strbuf_append(sb, "(");
	for (ut32 i = 0; i < proto_id->type_list_size; ++i) {
		ut32 type_idx = proto_id->type_list[i];
		if (type_idx >= dex->type_ids_size) {
			continue;
		}

		const DexString *param = dex_resolve_string_id_native(dex, dex->types[type_idx]);
		if (!param) {
			RZ_LOG_INFO("cannot find param string with index %d\n", dex->types[type_idx]);
			rz_strbuf_free(sb);
			return NULL;
		}
		if (varargs && (i + 1) >= proto_id->type_list_size) {
			rz_strbuf_append(sb, "...");
		}
		rz_strbuf_append_n(sb, param->data, param->size);
	}
	rz_strbuf_append(sb, ")");
	rz_strbuf_append_n(sb, return_type->data, return_type->size);
	return rz_strbuf_drain(sb);
}
static char *dex_resolve_proto_id(RzBinDex *dex, const char *name, ut32 proto_idx, bool varargs) {
	if (proto_idx >= rz_pvector_len(dex->proto_ids)) {
		RZ_LOG_INFO("cannot find proto_id with index %u\n", proto_idx);
		return NULL;
	}

	DexProtoId *proto_id = (DexProtoId *)rz_pvector_at(dex->proto_ids, proto_idx);
	if (proto_id->return_type_idx >= dex->type_ids_size) {
		RZ_LOG_INFO("cannot find return type id with index %u\n", proto_id->return_type_idx);
		return NULL;
	}

	RzStrBuf *sb = rz_strbuf_new(name);
	if (!sb) {
		return NULL;
	}

	const DexString *return_type = dex_resolve_string_id_native(dex, dex->types[proto_id->return_type_idx]);
	if (!return_type) {
		RZ_LOG_INFO("cannot find return type string with index %u\n", proto_id->return_type_idx);
		rz_strbuf_free(sb);
		return NULL;
	}

	rz_strbuf_append(sb, "(");
	for (ut32 i = 0; i < proto_id->type_list_size; ++i) {
		ut32 type_idx = proto_id->type_list[i];
		if (type_idx >= dex->type_ids_size) {
			continue;
		}

		const DexString *param = dex_resolve_string_id_native(dex, dex->types[type_idx]);
		if (!param) {
			RZ_LOG_INFO("cannot find param string with index %d\n", dex->types[type_idx]);
			rz_strbuf_free(sb);
			return NULL;
		}
		if (varargs && (i + 1) >= proto_id->type_list_size) {
			rz_strbuf_append(sb, "...");
		}
		rz_strbuf_append_n(sb, param->data, param->size);
	}
	rz_strbuf_append(sb, ")");
	rz_strbuf_append_n(sb, return_type->data, return_type->size);
	return rz_strbuf_drain(sb);
}