Google's Protocol Buffers implementation for Java, providing comprehensive serialization of structured data with efficient encoding and extensive API coverage
—
Utility classes for working with protocol buffer well-known types including timestamps, durations, field masks, and Google's common structured data types.
Comprehensive utilities for working with google.protobuf.Timestamp messages, providing conversion between different time representations and validation.
/**
* Utilities for working with Timestamp messages
*/
public final class Timestamps {
// Constants for common timestamp values
/** Minimum valid timestamp (0001-01-01T00:00:00Z) */
public static final Timestamp MIN_VALUE;
/** Maximum valid timestamp (9999-12-31T23:59:59.999999999Z) */
public static final Timestamp MAX_VALUE;
/** Epoch timestamp (1970-01-01T00:00:00.000000000Z) */
public static final Timestamp EPOCH;
// Comparison utilities
/** Returns timestamp comparator for sorting */
public static Comparator<Timestamp> comparator();
/** Compares two timestamps (-1, 0, or 1) */
public static int compare(Timestamp x, Timestamp y);
// Validation methods
/** Validates timestamp is within valid range */
public static boolean isValid(Timestamp timestamp);
/** Validates and returns timestamp, throws exception if invalid */
public static Timestamp checkValid(Timestamp timestamp) throws IllegalArgumentException;
// Conversion from time units to Timestamp
/** Creates timestamp from milliseconds since Unix epoch */
public static Timestamp fromMillis(long millis);
/** Creates timestamp from microseconds since Unix epoch */
public static Timestamp fromMicros(long micros);
/** Creates timestamp from nanoseconds since Unix epoch */
public static Timestamp fromNanos(long nanos);
// Conversion from Timestamp to time units
/** Converts timestamp to milliseconds since Unix epoch */
public static long toMillis(Timestamp timestamp);
/** Converts timestamp to microseconds since Unix epoch */
public static long toMicros(Timestamp timestamp);
/** Converts timestamp to nanoseconds since Unix epoch */
public static long toNanos(Timestamp timestamp);
// Arithmetic operations
/** Adds duration to timestamp */
public static Timestamp add(Timestamp timestamp, Duration duration);
/** Subtracts duration from timestamp */
public static Timestamp subtract(Timestamp timestamp, Duration duration);
/** Calculates duration between two timestamps */
public static Duration between(Timestamp from, Timestamp to);
// String representation
/** Converts timestamp to RFC 3339 string format */
public static String toString(Timestamp timestamp);
/** Parses RFC 3339 timestamp string */
public static Timestamp parseTimestamp(String value) throws ParseException;
}Utilities for working with google.protobuf.Duration messages, supporting time span calculations and conversions.
/**
* Utilities for working with Duration messages
*/
public final class Durations {
// Constants for common duration values
/** Minimum valid duration (approximately -10,000 years) */
public static final Duration MIN_VALUE;
/** Maximum valid duration (approximately +10,000 years) */
public static final Duration MAX_VALUE;
/** Duration of zero */
public static final Duration ZERO;
// Comparison utilities
/** Returns duration comparator for sorting */
public static Comparator<Duration> comparator();
/** Compares two durations (-1, 0, or 1) */
public static int compare(Duration x, Duration y);
// Validation methods
/** Validates duration is within valid range */
public static boolean isValid(Duration duration);
/** Validates and returns duration, throws exception if invalid */
public static Duration checkValid(Duration duration) throws IllegalArgumentException;
// Conversion from time units to Duration
/** Creates duration from milliseconds */
public static Duration fromMillis(long millis);
/** Creates duration from microseconds */
public static Duration fromMicros(long micros);
/** Creates duration from nanoseconds */
public static Duration fromNanos(long nanos);
/** Creates duration from seconds */
public static Duration fromSeconds(long seconds);
/** Creates duration from minutes */
public static Duration fromMinutes(long minutes);
/** Creates duration from hours */
public static Duration fromHours(long hours);
/** Creates duration from days */
public static Duration fromDays(long days);
// Conversion from Duration to time units
/** Converts duration to total milliseconds */
public static long toMillis(Duration duration);
/** Converts duration to total microseconds */
public static long toMicros(Duration duration);
/** Converts duration to total nanoseconds */
public static long toNanos(Duration duration);
/** Converts duration to total seconds */
public static long toSeconds(Duration duration);
/** Converts duration to total minutes */
public static long toMinutes(Duration duration);
/** Converts duration to total hours */
public static long toHours(Duration duration);
/** Converts duration to total days */
public static long toDays(Duration duration);
// Arithmetic operations
/** Adds two durations */
public static Duration add(Duration d1, Duration d2);
/** Subtracts second duration from first */
public static Duration subtract(Duration d1, Duration d2);
/** Multiplies duration by scalar */
public static Duration multiply(Duration duration, long times);
/** Multiplies duration by double scalar */
public static Duration multiply(Duration duration, double times);
/** Divides duration by scalar */
public static Duration divide(Duration duration, long times);
/** Divides duration by double scalar */
public static Duration divide(Duration duration, double times);
/** Returns absolute value of duration */
public static Duration abs(Duration duration);
/** Negates duration */
public static Duration negate(Duration duration);
// String representation
/** Converts duration to string representation (e.g., "1.500s", "2m30s") */
public static String toString(Duration duration);
/** Parses duration string (e.g., "1s", "2.5s", "1m30s") */
public static Duration parseDuration(String value) throws ParseException;
}Utilities for working with google.protobuf.FieldMask messages, enabling selective field operations and updates.
/**
* Utilities for working with FieldMask messages
*/
public final class FieldMaskUtil {
// String conversion methods
/** Converts FieldMask to comma-separated string */
public static String toString(FieldMask fieldMask);
/** Parses FieldMask from comma-separated string */
public static FieldMask fromString(String value);
/** Parses and validates FieldMask for specific message type */
public static FieldMask fromString(Class<? extends Message> type, String value);
// List-based creation methods
/** Creates FieldMask from field path strings with type validation */
public static FieldMask fromStringList(Class<? extends Message> type, Iterable<String> paths);
/** Creates FieldMask from field paths using message descriptor */
public static FieldMask fromStringList(Descriptor descriptor, Iterable<String> paths);
/** Creates FieldMask from field paths without validation */
public static FieldMask fromStringList(Iterable<String> paths);
/** Creates FieldMask from field numbers */
public static FieldMask fromFieldNumbers(Class<? extends Message> type, int... fieldNumbers);
// Set operations on field masks
/** Computes union of multiple field masks */
public static FieldMask union(FieldMask mask1, FieldMask mask2, FieldMask... otherMasks);
/** Computes intersection of two field masks */
public static FieldMask intersection(FieldMask mask1, FieldMask mask2);
/** Subtracts second mask from first mask */
public static FieldMask subtract(FieldMask mask1, FieldMask mask2);
// Validation methods
/** Validates FieldMask paths for message type */
public static boolean isValid(Class<? extends Message> type, FieldMask fieldMask);
/** Validates FieldMask paths using message descriptor */
public static boolean isValid(Descriptor descriptor, FieldMask fieldMask);
// Field mask operations
/** Merges fields specified by mask from source to destination */
public static void merge(FieldMask mask, Message source, Message.Builder destination);
/** Merges fields specified by mask with merge options */
public static void merge(FieldMask mask, Message source, Message.Builder destination, MergeOptions options);
/** Copies fields specified by mask from source to destination builder */
public static void copy(FieldMask mask, Message source, Message.Builder destination);
// Utility methods
/** Checks if field mask is valid for given message type */
public static void normalize(FieldMask.Builder maskBuilder);
/** Gets all field paths that would be affected by the mask */
public static Set<String> getFieldPathSet(FieldMask fieldMask);
/**
* Options for field mask merge operations
*/
public static class MergeOptions {
/** Whether to replace repeated fields entirely or merge them */
public MergeOptions setReplaceRepeatedFields(boolean replaceRepeatedFields);
/** Whether to replace message fields entirely or merge them */
public MergeOptions setReplaceMessageFields(boolean replaceMessageFields);
/** Whether to replace primitive fields */
public MergeOptions setReplacePrimitiveFields(boolean replacePrimitiveFields);
}
}Utilities for working with google.protobuf.Struct, google.protobuf.Value, and google.protobuf.ListValue for representing arbitrary JSON-like data.
/**
* Utilities for creating Struct messages
*/
public final class Structs {
/** Creates struct with one key-value pair */
public static Struct of(String k1, Value v1);
/** Creates struct with two key-value pairs */
public static Struct of(String k1, Value v1, String k2, Value v2);
/** Creates struct with three key-value pairs */
public static Struct of(String k1, Value v1, String k2, Value v2, String k3, Value v3);
/** Creates struct with four key-value pairs */
public static Struct of(String k1, Value v1, String k2, Value v2, String k3, Value v3, String k4, Value v4);
/** Creates struct with five key-value pairs */
public static Struct of(String k1, Value v1, String k2, Value v2, String k3, Value v3, String k4, Value v4, String k5, Value v5);
}
/**
* Utilities for creating Value messages
*/
public final class Values {
/** Creates null value */
public static Value ofNull();
/** Creates boolean value */
public static Value of(boolean value);
/** Creates number value from double */
public static Value of(double value);
/** Creates number value from int */
public static Value of(int value);
/** Creates number value from long */
public static Value of(long value);
/** Creates string value */
public static Value of(String value);
/** Creates struct value */
public static Value of(Struct value);
/** Creates list value */
public static Value of(ListValue value);
/** Creates list value from Value iterable */
public static Value of(Iterable<Value> values);
/** Creates list value from mixed objects (converted to Values) */
public static Value ofList(Object... values);
}Utilities for working with google.protobuf.Any messages for type-safe storage of arbitrary message types.
/**
* Utilities for working with Any messages
*/
public final class Any {
/** Packs message into Any */
public static Any pack(Message message);
/** Packs message into Any with custom type URL prefix */
public static Any pack(Message message, String typeUrlPrefix);
/** Unpacks Any to specific message type */
public static <T extends Message> T unpack(Any any, Class<T> clazz) throws InvalidProtocolBufferException;
/** Checks if Any contains message of specific type */
public static <T extends Message> boolean is(Any any, Class<T> clazz);
/** Gets type URL from Any */
public static String getTypeUrl(Any any);
/** Gets type name from type URL */
public static String getTypeName(String typeUrl);
/** Creates type URL from type name */
public static String getTypeUrl(String typeUrlPrefix, Descriptor descriptor);
}Usage Examples:
import com.google.protobuf.util.*;
import com.google.protobuf.*;
import java.time.Instant;
// Working with timestamps
Timestamp now = Timestamps.fromMillis(System.currentTimeMillis());
Timestamp epoch = Timestamps.EPOCH;
Timestamp future = Timestamps.add(now, Durations.fromHours(24));
// Timestamp comparisons and validation
if (Timestamps.compare(now, future) < 0) {
System.out.println("Now is before future");
}
if (Timestamps.isValid(now)) {
String rfc3339 = Timestamps.toString(now);
System.out.println("Timestamp: " + rfc3339);
}
// Working with durations
Duration oneHour = Durations.fromHours(1);
Duration thirtyMinutes = Durations.fromMinutes(30);
Duration totalTime = Durations.add(oneHour, thirtyMinutes);
long totalSeconds = Durations.toSeconds(totalTime);
System.out.println("Total seconds: " + totalSeconds);
// Working with field masks
FieldMask mask = FieldMaskUtil.fromString("name,email,profile.age");
FieldMask nameMask = FieldMaskUtil.fromStringList(Arrays.asList("name", "email"));
// Merge specific fields from one message to another
MyMessage source = MyMessage.newBuilder()
.setName("John")
.setEmail("john@example.com")
.setAge(30)
.build();
MyMessage.Builder target = MyMessage.newBuilder();
FieldMaskUtil.merge(nameMask, source, target);
MyMessage result = target.build(); // Only has name and email fields
// Working with Struct and Value
Struct jsonStruct = Structs.of(
"name", Values.of("John Doe"),
"age", Values.of(30),
"active", Values.of(true)
);
Value listValue = Values.of(Arrays.asList(
Values.of("item1"),
Values.of("item2"),
Values.of(42)
));
// Working with Any messages
MyMessage originalMessage = MyMessage.newBuilder()
.setName("Test")
.build();
Any packedMessage = Any.pack(originalMessage);
System.out.println("Type URL: " + Any.getTypeUrl(packedMessage));
if (Any.is(packedMessage, MyMessage.class)) {
MyMessage unpacked = Any.unpack(packedMessage, MyMessage.class);
System.out.println("Unpacked name: " + unpacked.getName());
}Field mask paths use dot notation to specify nested fields:
// Field mask path examples:
// "name" - selects top-level name field
// "user.name" - selects name field within user message
// "user.address.street" - selects street field within nested address
// "items" - selects entire repeated field
// "user.phone_numbers" - selects repeated phone_numbers field
// "map_field" - selects entire map field
// "map_field.key" - selects specific map entry (not standard, use with caution)
// Complex field mask examples:
FieldMask complexMask = FieldMaskUtil.fromString(
"user.name,user.email,user.profile.age,settings.notifications,items"
);
// Field mask operations:
FieldMask mask1 = FieldMaskUtil.fromString("name,email");
FieldMask mask2 = FieldMaskUtil.fromString("email,age");
FieldMask union = FieldMaskUtil.union(mask1, mask2); // "name,email,age"
FieldMask intersection = FieldMaskUtil.intersection(mask1, mask2); // "email"
FieldMask difference = FieldMaskUtil.subtract(mask1, mask2); // "name"Common patterns for converting between well-known types and Java types:
// Timestamp conversions
Instant javaInstant = Instant.ofEpochMilli(Timestamps.toMillis(timestamp));
Timestamp fromInstant = Timestamps.fromMillis(javaInstant.toEpochMilli());
// Duration conversions
java.time.Duration javaDuration = java.time.Duration.ofMillis(Durations.toMillis(protoDuration));
Duration fromJavaDuration = Durations.fromMillis(javaDuration.toMillis());
// Struct/Value to JSON-like operations
Map<String, Object> javaMap = convertStructToMap(struct);
Object javaValue = convertValueToObject(value);
List<Object> javaList = convertListValueToList(listValue);
// Helper methods for conversions (not part of API, but common patterns)
public static Map<String, Object> convertStructToMap(Struct struct) {
Map<String, Object> map = new HashMap<>();
for (Map.Entry<String, Value> entry : struct.getFieldsMap().entrySet()) {
map.put(entry.getKey(), convertValueToObject(entry.getValue()));
}
return map;
}
public static Object convertValueToObject(Value value) {
switch (value.getKindCase()) {
case NULL_VALUE: return null;
case BOOL_VALUE: return value.getBoolValue();
case NUMBER_VALUE: return value.getNumberValue();
case STRING_VALUE: return value.getStringValue();
case STRUCT_VALUE: return convertStructToMap(value.getStructValue());
case LIST_VALUE: return convertListValueToList(value.getListValue());
default: throw new IllegalArgumentException("Unknown value type");
}
}Common exceptions when working with utility classes:
// Timestamp/Duration validation errors
try {
Timestamp invalid = Timestamps.checkValid(someTimestamp);
} catch (IllegalArgumentException e) {
// Handle invalid timestamp (out of range, invalid seconds/nanos)
}
// Parse exceptions for string formats
try {
Timestamp parsed = Timestamps.parseTimestamp("invalid-format");
} catch (ParseException e) {
// Handle invalid RFC 3339 format
}
try {
Duration parsed = Durations.parseDuration("invalid-duration");
} catch (ParseException e) {
// Handle invalid duration format
}
// Field mask validation errors
try {
FieldMask mask = FieldMaskUtil.fromString(MyMessage.class, "invalid.field.path");
} catch (IllegalArgumentException e) {
// Handle invalid field path for message type
}
// Any message unpacking errors
try {
MyMessage unpacked = Any.unpack(anyMessage, MyMessage.class);
} catch (InvalidProtocolBufferException e) {
// Handle type mismatch or malformed Any message
}// Exception types for parsing
public class ParseException extends Exception {
public ParseException(String message);
public ParseException(String message, Throwable cause);
}
// Well-known type message classes (defined in well-known type .proto files)
public final class Timestamp extends GeneratedMessage { /* ... */ }
public final class Duration extends GeneratedMessage { /* ... */ }
public final class FieldMask extends GeneratedMessage { /* ... */ }
public final class Struct extends GeneratedMessage { /* ... */ }
public final class Value extends GeneratedMessage { /* ... */ }
public final class ListValue extends GeneratedMessage { /* ... */ }
public final class Any extends GeneratedMessage { /* ... */ }
public final class NullValue extends GeneratedMessage { /* ... */ }
// Utility helper classes (internal)
public final class FieldMaskTree {
// Internal tree structure for efficient field mask operations
}Install with Tessl CLI
npx tessl i tessl/maven-com-google-protobuf--protobuf-java