0
# Utility Classes
1
2
Utility classes for working with protocol buffer well-known types including timestamps, durations, field masks, and Google's common structured data types.
3
4
## Capabilities
5
6
### Timestamp Utilities
7
8
Comprehensive utilities for working with `google.protobuf.Timestamp` messages, providing conversion between different time representations and validation.
9
10
```java { .api }
11
/**
12
* Utilities for working with Timestamp messages
13
*/
14
public final class Timestamps {
15
// Constants for common timestamp values
16
/** Minimum valid timestamp (0001-01-01T00:00:00Z) */
17
public static final Timestamp MIN_VALUE;
18
19
/** Maximum valid timestamp (9999-12-31T23:59:59.999999999Z) */
20
public static final Timestamp MAX_VALUE;
21
22
/** Epoch timestamp (1970-01-01T00:00:00.000000000Z) */
23
public static final Timestamp EPOCH;
24
25
// Comparison utilities
26
/** Returns timestamp comparator for sorting */
27
public static Comparator<Timestamp> comparator();
28
29
/** Compares two timestamps (-1, 0, or 1) */
30
public static int compare(Timestamp x, Timestamp y);
31
32
// Validation methods
33
/** Validates timestamp is within valid range */
34
public static boolean isValid(Timestamp timestamp);
35
36
/** Validates and returns timestamp, throws exception if invalid */
37
public static Timestamp checkValid(Timestamp timestamp) throws IllegalArgumentException;
38
39
// Conversion from time units to Timestamp
40
/** Creates timestamp from milliseconds since Unix epoch */
41
public static Timestamp fromMillis(long millis);
42
43
/** Creates timestamp from microseconds since Unix epoch */
44
public static Timestamp fromMicros(long micros);
45
46
/** Creates timestamp from nanoseconds since Unix epoch */
47
public static Timestamp fromNanos(long nanos);
48
49
// Conversion from Timestamp to time units
50
/** Converts timestamp to milliseconds since Unix epoch */
51
public static long toMillis(Timestamp timestamp);
52
53
/** Converts timestamp to microseconds since Unix epoch */
54
public static long toMicros(Timestamp timestamp);
55
56
/** Converts timestamp to nanoseconds since Unix epoch */
57
public static long toNanos(Timestamp timestamp);
58
59
// Arithmetic operations
60
/** Adds duration to timestamp */
61
public static Timestamp add(Timestamp timestamp, Duration duration);
62
63
/** Subtracts duration from timestamp */
64
public static Timestamp subtract(Timestamp timestamp, Duration duration);
65
66
/** Calculates duration between two timestamps */
67
public static Duration between(Timestamp from, Timestamp to);
68
69
// String representation
70
/** Converts timestamp to RFC 3339 string format */
71
public static String toString(Timestamp timestamp);
72
73
/** Parses RFC 3339 timestamp string */
74
public static Timestamp parseTimestamp(String value) throws ParseException;
75
}
76
```
77
78
### Duration Utilities
79
80
Utilities for working with `google.protobuf.Duration` messages, supporting time span calculations and conversions.
81
82
```java { .api }
83
/**
84
* Utilities for working with Duration messages
85
*/
86
public final class Durations {
87
// Constants for common duration values
88
/** Minimum valid duration (approximately -10,000 years) */
89
public static final Duration MIN_VALUE;
90
91
/** Maximum valid duration (approximately +10,000 years) */
92
public static final Duration MAX_VALUE;
93
94
/** Duration of zero */
95
public static final Duration ZERO;
96
97
// Comparison utilities
98
/** Returns duration comparator for sorting */
99
public static Comparator<Duration> comparator();
100
101
/** Compares two durations (-1, 0, or 1) */
102
public static int compare(Duration x, Duration y);
103
104
// Validation methods
105
/** Validates duration is within valid range */
106
public static boolean isValid(Duration duration);
107
108
/** Validates and returns duration, throws exception if invalid */
109
public static Duration checkValid(Duration duration) throws IllegalArgumentException;
110
111
// Conversion from time units to Duration
112
/** Creates duration from milliseconds */
113
public static Duration fromMillis(long millis);
114
115
/** Creates duration from microseconds */
116
public static Duration fromMicros(long micros);
117
118
/** Creates duration from nanoseconds */
119
public static Duration fromNanos(long nanos);
120
121
/** Creates duration from seconds */
122
public static Duration fromSeconds(long seconds);
123
124
/** Creates duration from minutes */
125
public static Duration fromMinutes(long minutes);
126
127
/** Creates duration from hours */
128
public static Duration fromHours(long hours);
129
130
/** Creates duration from days */
131
public static Duration fromDays(long days);
132
133
// Conversion from Duration to time units
134
/** Converts duration to total milliseconds */
135
public static long toMillis(Duration duration);
136
137
/** Converts duration to total microseconds */
138
public static long toMicros(Duration duration);
139
140
/** Converts duration to total nanoseconds */
141
public static long toNanos(Duration duration);
142
143
/** Converts duration to total seconds */
144
public static long toSeconds(Duration duration);
145
146
/** Converts duration to total minutes */
147
public static long toMinutes(Duration duration);
148
149
/** Converts duration to total hours */
150
public static long toHours(Duration duration);
151
152
/** Converts duration to total days */
153
public static long toDays(Duration duration);
154
155
// Arithmetic operations
156
/** Adds two durations */
157
public static Duration add(Duration d1, Duration d2);
158
159
/** Subtracts second duration from first */
160
public static Duration subtract(Duration d1, Duration d2);
161
162
/** Multiplies duration by scalar */
163
public static Duration multiply(Duration duration, long times);
164
165
/** Multiplies duration by double scalar */
166
public static Duration multiply(Duration duration, double times);
167
168
/** Divides duration by scalar */
169
public static Duration divide(Duration duration, long times);
170
171
/** Divides duration by double scalar */
172
public static Duration divide(Duration duration, double times);
173
174
/** Returns absolute value of duration */
175
public static Duration abs(Duration duration);
176
177
/** Negates duration */
178
public static Duration negate(Duration duration);
179
180
// String representation
181
/** Converts duration to string representation (e.g., "1.500s", "2m30s") */
182
public static String toString(Duration duration);
183
184
/** Parses duration string (e.g., "1s", "2.5s", "1m30s") */
185
public static Duration parseDuration(String value) throws ParseException;
186
}
187
```
188
189
### Field Mask Utilities
190
191
Utilities for working with `google.protobuf.FieldMask` messages, enabling selective field operations and updates.
192
193
```java { .api }
194
/**
195
* Utilities for working with FieldMask messages
196
*/
197
public final class FieldMaskUtil {
198
// String conversion methods
199
/** Converts FieldMask to comma-separated string */
200
public static String toString(FieldMask fieldMask);
201
202
/** Parses FieldMask from comma-separated string */
203
public static FieldMask fromString(String value);
204
205
/** Parses and validates FieldMask for specific message type */
206
public static FieldMask fromString(Class<? extends Message> type, String value);
207
208
// List-based creation methods
209
/** Creates FieldMask from field path strings with type validation */
210
public static FieldMask fromStringList(Class<? extends Message> type, Iterable<String> paths);
211
212
/** Creates FieldMask from field paths using message descriptor */
213
public static FieldMask fromStringList(Descriptor descriptor, Iterable<String> paths);
214
215
/** Creates FieldMask from field paths without validation */
216
public static FieldMask fromStringList(Iterable<String> paths);
217
218
/** Creates FieldMask from field numbers */
219
public static FieldMask fromFieldNumbers(Class<? extends Message> type, int... fieldNumbers);
220
221
// Set operations on field masks
222
/** Computes union of multiple field masks */
223
public static FieldMask union(FieldMask mask1, FieldMask mask2, FieldMask... otherMasks);
224
225
/** Computes intersection of two field masks */
226
public static FieldMask intersection(FieldMask mask1, FieldMask mask2);
227
228
/** Subtracts second mask from first mask */
229
public static FieldMask subtract(FieldMask mask1, FieldMask mask2);
230
231
// Validation methods
232
/** Validates FieldMask paths for message type */
233
public static boolean isValid(Class<? extends Message> type, FieldMask fieldMask);
234
235
/** Validates FieldMask paths using message descriptor */
236
public static boolean isValid(Descriptor descriptor, FieldMask fieldMask);
237
238
// Field mask operations
239
/** Merges fields specified by mask from source to destination */
240
public static void merge(FieldMask mask, Message source, Message.Builder destination);
241
242
/** Merges fields specified by mask with merge options */
243
public static void merge(FieldMask mask, Message source, Message.Builder destination, MergeOptions options);
244
245
/** Copies fields specified by mask from source to destination builder */
246
public static void copy(FieldMask mask, Message source, Message.Builder destination);
247
248
// Utility methods
249
/** Checks if field mask is valid for given message type */
250
public static void normalize(FieldMask.Builder maskBuilder);
251
252
/** Gets all field paths that would be affected by the mask */
253
public static Set<String> getFieldPathSet(FieldMask fieldMask);
254
255
/**
256
* Options for field mask merge operations
257
*/
258
public static class MergeOptions {
259
/** Whether to replace repeated fields entirely or merge them */
260
public MergeOptions setReplaceRepeatedFields(boolean replaceRepeatedFields);
261
262
/** Whether to replace message fields entirely or merge them */
263
public MergeOptions setReplaceMessageFields(boolean replaceMessageFields);
264
265
/** Whether to replace primitive fields */
266
public MergeOptions setReplacePrimitiveFields(boolean replacePrimitiveFields);
267
}
268
}
269
```
270
271
### Struct and Value Utilities
272
273
Utilities for working with `google.protobuf.Struct`, `google.protobuf.Value`, and `google.protobuf.ListValue` for representing arbitrary JSON-like data.
274
275
```java { .api }
276
/**
277
* Utilities for creating Struct messages
278
*/
279
public final class Structs {
280
/** Creates struct with one key-value pair */
281
public static Struct of(String k1, Value v1);
282
283
/** Creates struct with two key-value pairs */
284
public static Struct of(String k1, Value v1, String k2, Value v2);
285
286
/** Creates struct with three key-value pairs */
287
public static Struct of(String k1, Value v1, String k2, Value v2, String k3, Value v3);
288
289
/** Creates struct with four key-value pairs */
290
public static Struct of(String k1, Value v1, String k2, Value v2, String k3, Value v3, String k4, Value v4);
291
292
/** Creates struct with five key-value pairs */
293
public static Struct of(String k1, Value v1, String k2, Value v2, String k3, Value v3, String k4, Value v4, String k5, Value v5);
294
}
295
296
/**
297
* Utilities for creating Value messages
298
*/
299
public final class Values {
300
/** Creates null value */
301
public static Value ofNull();
302
303
/** Creates boolean value */
304
public static Value of(boolean value);
305
306
/** Creates number value from double */
307
public static Value of(double value);
308
309
/** Creates number value from int */
310
public static Value of(int value);
311
312
/** Creates number value from long */
313
public static Value of(long value);
314
315
/** Creates string value */
316
public static Value of(String value);
317
318
/** Creates struct value */
319
public static Value of(Struct value);
320
321
/** Creates list value */
322
public static Value of(ListValue value);
323
324
/** Creates list value from Value iterable */
325
public static Value of(Iterable<Value> values);
326
327
/** Creates list value from mixed objects (converted to Values) */
328
public static Value ofList(Object... values);
329
}
330
```
331
332
### Any Message Utilities
333
334
Utilities for working with `google.protobuf.Any` messages for type-safe storage of arbitrary message types.
335
336
```java { .api }
337
/**
338
* Utilities for working with Any messages
339
*/
340
public final class Any {
341
/** Packs message into Any */
342
public static Any pack(Message message);
343
344
/** Packs message into Any with custom type URL prefix */
345
public static Any pack(Message message, String typeUrlPrefix);
346
347
/** Unpacks Any to specific message type */
348
public static <T extends Message> T unpack(Any any, Class<T> clazz) throws InvalidProtocolBufferException;
349
350
/** Checks if Any contains message of specific type */
351
public static <T extends Message> boolean is(Any any, Class<T> clazz);
352
353
/** Gets type URL from Any */
354
public static String getTypeUrl(Any any);
355
356
/** Gets type name from type URL */
357
public static String getTypeName(String typeUrl);
358
359
/** Creates type URL from type name */
360
public static String getTypeUrl(String typeUrlPrefix, Descriptor descriptor);
361
}
362
```
363
364
**Usage Examples:**
365
366
```java
367
import com.google.protobuf.util.*;
368
import com.google.protobuf.*;
369
import java.time.Instant;
370
371
// Working with timestamps
372
Timestamp now = Timestamps.fromMillis(System.currentTimeMillis());
373
Timestamp epoch = Timestamps.EPOCH;
374
Timestamp future = Timestamps.add(now, Durations.fromHours(24));
375
376
// Timestamp comparisons and validation
377
if (Timestamps.compare(now, future) < 0) {
378
System.out.println("Now is before future");
379
}
380
381
if (Timestamps.isValid(now)) {
382
String rfc3339 = Timestamps.toString(now);
383
System.out.println("Timestamp: " + rfc3339);
384
}
385
386
// Working with durations
387
Duration oneHour = Durations.fromHours(1);
388
Duration thirtyMinutes = Durations.fromMinutes(30);
389
Duration totalTime = Durations.add(oneHour, thirtyMinutes);
390
391
long totalSeconds = Durations.toSeconds(totalTime);
392
System.out.println("Total seconds: " + totalSeconds);
393
394
// Working with field masks
395
FieldMask mask = FieldMaskUtil.fromString("name,email,profile.age");
396
FieldMask nameMask = FieldMaskUtil.fromStringList(Arrays.asList("name", "email"));
397
398
// Merge specific fields from one message to another
399
MyMessage source = MyMessage.newBuilder()
400
.setName("John")
401
.setEmail("john@example.com")
402
.setAge(30)
403
.build();
404
405
MyMessage.Builder target = MyMessage.newBuilder();
406
FieldMaskUtil.merge(nameMask, source, target);
407
MyMessage result = target.build(); // Only has name and email fields
408
409
// Working with Struct and Value
410
Struct jsonStruct = Structs.of(
411
"name", Values.of("John Doe"),
412
"age", Values.of(30),
413
"active", Values.of(true)
414
);
415
416
Value listValue = Values.of(Arrays.asList(
417
Values.of("item1"),
418
Values.of("item2"),
419
Values.of(42)
420
));
421
422
// Working with Any messages
423
MyMessage originalMessage = MyMessage.newBuilder()
424
.setName("Test")
425
.build();
426
427
Any packedMessage = Any.pack(originalMessage);
428
System.out.println("Type URL: " + Any.getTypeUrl(packedMessage));
429
430
if (Any.is(packedMessage, MyMessage.class)) {
431
MyMessage unpacked = Any.unpack(packedMessage, MyMessage.class);
432
System.out.println("Unpacked name: " + unpacked.getName());
433
}
434
```
435
436
### Field Mask Path Syntax
437
438
Field mask paths use dot notation to specify nested fields:
439
440
```java { .api }
441
// Field mask path examples:
442
// "name" - selects top-level name field
443
// "user.name" - selects name field within user message
444
// "user.address.street" - selects street field within nested address
445
// "items" - selects entire repeated field
446
// "user.phone_numbers" - selects repeated phone_numbers field
447
// "map_field" - selects entire map field
448
// "map_field.key" - selects specific map entry (not standard, use with caution)
449
450
// Complex field mask examples:
451
FieldMask complexMask = FieldMaskUtil.fromString(
452
"user.name,user.email,user.profile.age,settings.notifications,items"
453
);
454
455
// Field mask operations:
456
FieldMask mask1 = FieldMaskUtil.fromString("name,email");
457
FieldMask mask2 = FieldMaskUtil.fromString("email,age");
458
459
FieldMask union = FieldMaskUtil.union(mask1, mask2); // "name,email,age"
460
FieldMask intersection = FieldMaskUtil.intersection(mask1, mask2); // "email"
461
FieldMask difference = FieldMaskUtil.subtract(mask1, mask2); // "name"
462
```
463
464
### Well-Known Type Conversions
465
466
Common patterns for converting between well-known types and Java types:
467
468
```java { .api }
469
// Timestamp conversions
470
Instant javaInstant = Instant.ofEpochMilli(Timestamps.toMillis(timestamp));
471
Timestamp fromInstant = Timestamps.fromMillis(javaInstant.toEpochMilli());
472
473
// Duration conversions
474
java.time.Duration javaDuration = java.time.Duration.ofMillis(Durations.toMillis(protoDuration));
475
Duration fromJavaDuration = Durations.fromMillis(javaDuration.toMillis());
476
477
// Struct/Value to JSON-like operations
478
Map<String, Object> javaMap = convertStructToMap(struct);
479
Object javaValue = convertValueToObject(value);
480
List<Object> javaList = convertListValueToList(listValue);
481
482
// Helper methods for conversions (not part of API, but common patterns)
483
public static Map<String, Object> convertStructToMap(Struct struct) {
484
Map<String, Object> map = new HashMap<>();
485
for (Map.Entry<String, Value> entry : struct.getFieldsMap().entrySet()) {
486
map.put(entry.getKey(), convertValueToObject(entry.getValue()));
487
}
488
return map;
489
}
490
491
public static Object convertValueToObject(Value value) {
492
switch (value.getKindCase()) {
493
case NULL_VALUE: return null;
494
case BOOL_VALUE: return value.getBoolValue();
495
case NUMBER_VALUE: return value.getNumberValue();
496
case STRING_VALUE: return value.getStringValue();
497
case STRUCT_VALUE: return convertStructToMap(value.getStructValue());
498
case LIST_VALUE: return convertListValueToList(value.getListValue());
499
default: throw new IllegalArgumentException("Unknown value type");
500
}
501
}
502
```
503
504
## Exception Handling
505
506
Common exceptions when working with utility classes:
507
508
```java { .api }
509
// Timestamp/Duration validation errors
510
try {
511
Timestamp invalid = Timestamps.checkValid(someTimestamp);
512
} catch (IllegalArgumentException e) {
513
// Handle invalid timestamp (out of range, invalid seconds/nanos)
514
}
515
516
// Parse exceptions for string formats
517
try {
518
Timestamp parsed = Timestamps.parseTimestamp("invalid-format");
519
} catch (ParseException e) {
520
// Handle invalid RFC 3339 format
521
}
522
523
try {
524
Duration parsed = Durations.parseDuration("invalid-duration");
525
} catch (ParseException e) {
526
// Handle invalid duration format
527
}
528
529
// Field mask validation errors
530
try {
531
FieldMask mask = FieldMaskUtil.fromString(MyMessage.class, "invalid.field.path");
532
} catch (IllegalArgumentException e) {
533
// Handle invalid field path for message type
534
}
535
536
// Any message unpacking errors
537
try {
538
MyMessage unpacked = Any.unpack(anyMessage, MyMessage.class);
539
} catch (InvalidProtocolBufferException e) {
540
// Handle type mismatch or malformed Any message
541
}
542
```
543
544
## Types
545
546
```java { .api }
547
// Exception types for parsing
548
public class ParseException extends Exception {
549
public ParseException(String message);
550
public ParseException(String message, Throwable cause);
551
}
552
553
// Well-known type message classes (defined in well-known type .proto files)
554
public final class Timestamp extends GeneratedMessage { /* ... */ }
555
public final class Duration extends GeneratedMessage { /* ... */ }
556
public final class FieldMask extends GeneratedMessage { /* ... */ }
557
public final class Struct extends GeneratedMessage { /* ... */ }
558
public final class Value extends GeneratedMessage { /* ... */ }
559
public final class ListValue extends GeneratedMessage { /* ... */ }
560
public final class Any extends GeneratedMessage { /* ... */ }
561
public final class NullValue extends GeneratedMessage { /* ... */ }
562
563
// Utility helper classes (internal)
564
public final class FieldMaskTree {
565
// Internal tree structure for efficient field mask operations
566
}
567
```