Skip to content

Commit

Permalink
fix: Numerics cast from strings (#1588)
Browse files Browse the repository at this point in the history
Signed-off-by: dark0dave <dark0dave@mykolab.com>
  • Loading branch information
dark0dave authored Mar 29, 2022
1 parent 0c62c85 commit 085768b
Show file tree
Hide file tree
Showing 3 changed files with 84 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
import com.google.api.pathtemplate.ValidationException;
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableMap;
import com.google.common.primitives.Doubles;
import com.google.common.primitives.Ints;
import com.google.common.primitives.Longs;
import com.google.protobuf.ByteString;
import com.google.protobuf.Descriptors.Descriptor;
import com.google.protobuf.Descriptors.FieldDescriptor;
Expand Down Expand Up @@ -226,6 +229,12 @@ private static void fillField(
protoMsg.setField(fieldDescriptor, (Boolean) val);
return;
}
if (val instanceof String
&& ("true".equals(((String) val).toLowerCase())
|| "false".equals(((String) val).toLowerCase()))) {
protoMsg.setField(fieldDescriptor, Boolean.parseBoolean((String) val));
return;
}
break;
case BYTES:
if (fieldSchema != null) {
Expand Down Expand Up @@ -312,6 +321,13 @@ private static void fillField(
protoMsg.setField(fieldDescriptor, (Long) val);
return;
}
if (val instanceof String) {
Long parsed = Longs.tryParse((String) val);
if (parsed != null) {
protoMsg.setField(fieldDescriptor, parsed);
return;
}
}
break;
case INT32:
if (fieldSchema != null && fieldSchema.getType() == TableFieldSchema.Type.DATE) {
Expand All @@ -327,6 +343,13 @@ private static void fillField(
protoMsg.setField(fieldDescriptor, (Integer) val);
return;
}
if (val instanceof String) {
Integer parsed = Ints.tryParse((String) val);
if (parsed != null) {
protoMsg.setField(fieldDescriptor, parsed);
return;
}
}
break;
case STRING:
if (val instanceof String) {
Expand All @@ -339,6 +362,13 @@ private static void fillField(
protoMsg.setField(fieldDescriptor, ((Number) val).doubleValue());
return;
}
if (val instanceof String) {
Double parsed = Doubles.tryParse((String) val);
if (parsed != null) {
protoMsg.setField(fieldDescriptor, parsed);
return;
}
}
break;
case MESSAGE:
if (val instanceof JSONObject) {
Expand Down Expand Up @@ -400,6 +430,10 @@ private static void fillRepeatedField(
case BOOL:
if (val instanceof Boolean) {
protoMsg.addRepeatedField(fieldDescriptor, (Boolean) val);
} else if (val instanceof String
&& ("true".equals(((String) val).toLowerCase())
|| "false".equals(((String) val).toLowerCase()))) {
protoMsg.addRepeatedField(fieldDescriptor, Boolean.parseBoolean((String) val));
} else {
fail = true;
}
Expand Down Expand Up @@ -491,6 +525,13 @@ private static void fillRepeatedField(
protoMsg.addRepeatedField(fieldDescriptor, new Long((Integer) val));
} else if (val instanceof Long) {
protoMsg.addRepeatedField(fieldDescriptor, (Long) val);
} else if (val instanceof String) {
Long parsed = Longs.tryParse((String) val);
if (parsed != null) {
protoMsg.addRepeatedField(fieldDescriptor, parsed);
} else {
fail = true;
}
} else {
fail = true;
}
Expand All @@ -507,6 +548,13 @@ private static void fillRepeatedField(
}
} else if (val instanceof Integer) {
protoMsg.addRepeatedField(fieldDescriptor, (Integer) val);
} else if (val instanceof String) {
Integer parsed = Ints.tryParse((String) val);
if (parsed != null) {
protoMsg.addRepeatedField(fieldDescriptor, parsed);
} else {
fail = true;
}
} else {
fail = true;
}
Expand All @@ -521,6 +569,13 @@ private static void fillRepeatedField(
case DOUBLE:
if (val instanceof Number) {
protoMsg.addRepeatedField(fieldDescriptor, ((Number) val).doubleValue());
} else if (val instanceof String) {
Double parsed = Doubles.tryParse((String) val);
if (parsed != null) {
protoMsg.addRepeatedField(fieldDescriptor, parsed);
} else {
fail = true;
}
} else {
fail = true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -473,27 +473,43 @@ public void testDifferentNameCasing() throws Exception {
assertEquals(expectedProto, protoMsg);
}

@Test
public void testBool() throws Exception {
TestBool expectedProto =
TestBool.newBuilder().setBool(true).setUppercase(true).setLowercase(false).build();
JSONObject json = new JSONObject();
json.put("bool", true);
json.put("uppercase", "TRUE");
json.put("lowercase", "false");
DynamicMessage protoMsg =
JsonToProtoMessage.convertJsonToProtoMessage(TestBool.getDescriptor(), json);
assertEquals(expectedProto, protoMsg);
}

@Test
public void testInt64() throws Exception {
TestInt64 expectedProto =
TestInt64.newBuilder().setByte(1).setShort(1).setInt(1).setLong(1).build();
TestInt64.newBuilder().setByte(1).setShort(1).setInt(1).setLong(1).setString(1).build();
JSONObject json = new JSONObject();
json.put("byte", (byte) 1);
json.put("short", (short) 1);
json.put("int", 1);
json.put("long", 1L);
json.put("string", "1");
DynamicMessage protoMsg =
JsonToProtoMessage.convertJsonToProtoMessage(TestInt64.getDescriptor(), json);
assertEquals(expectedProto, protoMsg);
}

@Test
public void testInt32() throws Exception {
TestInt32 expectedProto = TestInt32.newBuilder().setByte(1).setShort(1).setInt(1).build();
TestInt32 expectedProto =
TestInt32.newBuilder().setByte(1).setShort(1).setInt(1).setString(1).build();
JSONObject json = new JSONObject();
json.put("byte", (byte) 1);
json.put("short", (short) 1);
json.put("int", 1);
json.put("string", 1);
DynamicMessage protoMsg =
JsonToProtoMessage.convertJsonToProtoMessage(TestInt32.getDescriptor(), json);
assertEquals(expectedProto, protoMsg);
Expand Down Expand Up @@ -625,6 +641,7 @@ public void testDouble() throws Exception {
.setShort(6)
.setInt(7)
.setLong(8)
.setString(9.1)
.build();
JSONObject json = new JSONObject();
json.put("double", 1.2);
Expand All @@ -633,6 +650,7 @@ public void testDouble() throws Exception {
json.put("short", new Short((short) 6));
json.put("int", 7);
json.put("long", 8L);
json.put("string", "9.1");
DynamicMessage protoMsg =
JsonToProtoMessage.convertJsonToProtoMessage(TestDouble.getDescriptor(), json);
assertEquals(expectedProto, protoMsg);
Expand Down
9 changes: 9 additions & 0 deletions google-cloud-bigquerystorage/src/test/proto/jsonTest.proto
Original file line number Diff line number Diff line change
Expand Up @@ -103,17 +103,25 @@ message RepeatedObject {
repeated ComplexLvl2 test_repeated = 1;
}

message TestBool {
optional bool bool = 1;
optional bool lowercase = 2;
optional bool uppercase = 3;
}

message TestInt64 {
optional int64 byte = 1;
optional int64 short = 2;
optional int64 int = 3;
optional int64 long = 4;
optional int64 string = 5;
}

message TestInt32 {
optional int32 byte = 1;
optional int32 short = 2;
optional int32 int = 3;
optional int32 string = 4;
}

message TestDouble {
Expand All @@ -123,6 +131,7 @@ message TestDouble {
optional double short = 4;
optional double int = 5;
optional double long = 6;
optional double string = 7;
}

message TestDate {
Expand Down

0 comments on commit 085768b

Please sign in to comment.