public static String getTypeStrFromProto(Descriptors.FieldDescriptor desc) {
    switch (desc.getJavaType()) {
      case INT:
        return "Integer";
      case LONG:
        return "Long";
      case STRING:
        return "String";
      case FLOAT:
        return "Float";
      case DOUBLE:
        return "Double";
      case BYTE_STRING:
        return "ByteString";
      case BOOLEAN:
        return "Boolean";
      case ENUM:
        return getFullJavaNameForEnum(desc.getEnumType());
      case MESSAGE:
        if (desc.isMapField()) {
          // map
          final Descriptors.FieldDescriptor key = desc.getMessageType().findFieldByName("key");
          final Descriptors.FieldDescriptor value = desc.getMessageType().findFieldByName("value");
          // key and value cannot be repeated
          String keyTypeStr = getTypeStrFromProto(key);
          String valueTypeStr = getTypeStrFromProto(value);
          return "Map<" + keyTypeStr + "," + valueTypeStr + ">";
        } else {
          // simple message
          return getFullJavaName(desc.getMessageType());
        }
      default:
        throw new RuntimeException("do not support field type: " + desc.getJavaType());
    }
  }
@Test(dataProvider = "typeCases")
  public void testGetTypeStrFromProto(String fieldName, String javaType) {
    Descriptors.FieldDescriptor fd = ComplexTypes.TestMessage.getDescriptor().findFieldByName(fieldName);
    Assert.assertEquals(ProtoBufUtils.getTypeStrFromProto(fd), javaType);
  }