33
33
import java .util .Map .Entry ;
34
34
import java .util .Objects ;
35
35
import java .util .TreeMap ;
36
+ import javax .annotation .Nonnull ;
36
37
import javax .annotation .Nullable ;
37
38
import javax .annotation .concurrent .Immutable ;
38
39
@@ -71,6 +72,10 @@ public final class Type implements Serializable {
71
72
private static final int AMBIGUOUS_FIELD = -1 ;
72
73
private static final long serialVersionUID = -3076152125004114582L ;
73
74
75
+ static Type unrecognized (com .google .spanner .v1 .Type proto ) {
76
+ return new Type (proto );
77
+ }
78
+
74
79
/** Returns the descriptor for the {@code BOOL type}. */
75
80
public static Type bool () {
76
81
return TYPE_BOOL ;
@@ -190,6 +195,7 @@ public static Type struct(StructField... fields) {
190
195
return new Type (Code .STRUCT , null , ImmutableList .copyOf (fields ));
191
196
}
192
197
198
+ private final com .google .spanner .v1 .Type proto ;
193
199
private final Code code ;
194
200
private final Type arrayElementType ;
195
201
private final ImmutableList <StructField > structFields ;
@@ -204,13 +210,23 @@ private Type(
204
210
Code code ,
205
211
@ Nullable Type arrayElementType ,
206
212
@ Nullable ImmutableList <StructField > structFields ) {
213
+ this .proto = null ;
207
214
this .code = code ;
208
215
this .arrayElementType = arrayElementType ;
209
216
this .structFields = structFields ;
210
217
}
211
218
219
+ private Type (@ Nonnull com .google .spanner .v1 .Type proto ) {
220
+ this .proto = proto ;
221
+ this .code = Code .UNRECOGNIZED ;
222
+ this .arrayElementType =
223
+ proto .hasArrayElementType () ? new Type (proto .getArrayElementType ()) : null ;
224
+ this .structFields = null ;
225
+ }
226
+
212
227
/** Enumerates the categories of types. */
213
228
public enum Code {
229
+ UNRECOGNIZED (TypeCode .UNRECOGNIZED ),
214
230
BOOL (TypeCode .BOOL ),
215
231
INT64 (TypeCode .INT64 ),
216
232
NUMERIC (TypeCode .NUMERIC ),
@@ -258,8 +274,7 @@ TypeAnnotationCode getTypeAnnotationCode() {
258
274
259
275
static Code fromProto (TypeCode typeCode , TypeAnnotationCode typeAnnotationCode ) {
260
276
Code code = protoToCode .get (new SimpleEntry <>(typeCode , typeAnnotationCode ));
261
- checkArgument (code != null , "Invalid code: %s<%s>" , typeCode , typeAnnotationCode );
262
- return code ;
277
+ return code == null ? Code .UNRECOGNIZED : code ;
263
278
}
264
279
265
280
@ Override
@@ -325,7 +340,7 @@ public Code getCode() {
325
340
* @throws IllegalStateException if {@code code() != Code.ARRAY}
326
341
*/
327
342
public Type getArrayElementType () {
328
- Preconditions .checkState (code == Code . ARRAY , "Illegal call for non-ARRAY type" );
343
+ Preconditions .checkState (arrayElementType != null , "Illegal call for non-ARRAY type" );
329
344
return arrayElementType ;
330
345
}
331
346
@@ -378,7 +393,7 @@ public int getFieldIndex(String fieldName) {
378
393
}
379
394
380
395
void toString (StringBuilder b ) {
381
- if (code == Code .ARRAY ) {
396
+ if (code == Code .ARRAY || ( proto != null && proto . hasArrayElementType ()) ) {
382
397
b .append ("ARRAY<" );
383
398
arrayElementType .toString (b );
384
399
b .append ('>' );
@@ -393,6 +408,11 @@ void toString(StringBuilder b) {
393
408
f .getType ().toString (b );
394
409
}
395
410
b .append ('>' );
411
+ } else if (proto != null ) {
412
+ b .append (proto .getCode ().name ());
413
+ if (proto .getTypeAnnotation () != TYPE_ANNOTATION_CODE_UNSPECIFIED ) {
414
+ b .append ("<" ).append (proto .getTypeAnnotation ().name ()).append (">" );
415
+ }
396
416
} else {
397
417
b .append (code .toString ());
398
418
}
@@ -414,17 +434,26 @@ public boolean equals(Object o) {
414
434
return false ;
415
435
}
416
436
Type that = (Type ) o ;
437
+ if (proto != null ) {
438
+ return Objects .equals (proto , that .proto );
439
+ }
417
440
return code == that .code
418
441
&& Objects .equals (arrayElementType , that .arrayElementType )
419
442
&& Objects .equals (structFields , that .structFields );
420
443
}
421
444
422
445
@ Override
423
446
public int hashCode () {
447
+ if (proto != null ) {
448
+ return proto .hashCode ();
449
+ }
424
450
return Objects .hash (code , arrayElementType , structFields );
425
451
}
426
452
427
453
com .google .spanner .v1 .Type toProto () {
454
+ if (proto != null ) {
455
+ return proto ;
456
+ }
428
457
com .google .spanner .v1 .Type .Builder proto = com .google .spanner .v1 .Type .newBuilder ();
429
458
proto .setCode (code .getTypeCode ());
430
459
proto .setTypeAnnotation (code .getTypeAnnotationCode ());
@@ -490,8 +519,9 @@ static Type fromProto(com.google.spanner.v1.Type proto) {
490
519
fields .add (StructField .of (name , fromProto (field .getType ())));
491
520
}
492
521
return struct (fields );
522
+ case UNRECOGNIZED :
493
523
default :
494
- throw new AssertionError ( "Unimplemented case: " + type );
524
+ return unrecognized ( proto );
495
525
}
496
526
}
497
527
}
0 commit comments