Protobuf serialization for pre-existing objects with runtime schema generation and polymorphic type handling
—
Low-level field access optimization and reflection utilities for high-performance field operations. The field access system provides efficient mechanisms for reading and writing object fields during serialization, with optimized implementations for different runtime environments.
Core abstraction representing a field within a schema, containing metadata and access methods for serialization operations.
/**
* Abstract base class representing a field in a schema
*/
public abstract class Field<T> {
/**
* The protobuf wire format field type
*/
public final WireFormat.FieldType type;
/**
* The field number used in the wire format
*/
public final int number;
/**
* The field name from the Java class
*/
public final String name;
/**
* Whether this field represents a repeated/collection value
*/
public final boolean repeated;
/**
* Group filter for conditional field processing
*/
public final int groupFilter;
/**
* Constructor for field with tag information
* @param type The wire format field type
* @param number The field number
* @param name The field name
* @param repeated Whether field is repeated
* @param tag Tag annotation information
*/
protected Field(WireFormat.FieldType type, int number, String name, boolean repeated, Tag tag);
/**
* Constructor for non-repeated field with tag information
* @param type The wire format field type
* @param number The field number
* @param name The field name
* @param tag Tag annotation information
*/
protected Field(WireFormat.FieldType type, int number, String name, Tag tag);
/**
* Write field value to output stream
* @param output Output stream to write to
* @param message Object containing the field value
* @throws IOException if writing fails
*/
protected abstract void writeTo(Output output, T message) throws IOException;
/**
* Read field value from input stream and merge into message
* @param input Input stream to read from
* @param message Object to merge field value into
* @throws IOException if reading fails
*/
protected abstract void mergeFrom(Input input, T message) throws IOException;
/**
* Transfer field value through a pipe
* @param pipe Pipe for transfer operations
* @param input Input stream
* @param output Output stream
* @param repeated Whether this is a repeated field
* @throws IOException if transfer fails
*/
protected abstract void transfer(Pipe pipe, Input input, Output output, boolean repeated) throws IOException;
}Optimized field value access abstraction providing efficient get/set operations for object fields.
/**
* Abstract base class for optimized field value access
*/
public abstract class Accessor {
/**
* The Java reflection field this accessor operates on
*/
public final java.lang.reflect.Field f;
/**
* Constructor
* @param f Java reflection field
*/
protected Accessor(java.lang.reflect.Field f);
/**
* Set field value on an object
* @param owner Object to set field on
* @param value Value to set
*/
public abstract void set(Object owner, Object value);
/**
* Get field value from an object
* @param owner Object to get field from
* @return Field value
*/
public abstract <T> T get(Object owner);
/**
* Factory interface for creating accessor instances
*/
public interface Factory {
/**
* Create accessor for the specified field
* @param f Java reflection field
* @return Accessor instance
*/
Accessor create(java.lang.reflect.Field f);
}
}Standard accessor implementation using Java reflection for field access.
/**
* Accessor implementation using Java reflection
*/
public final class ReflectAccessor extends Accessor {
/**
* Constructor
* @param f Java reflection field
*/
public ReflectAccessor(java.lang.reflect.Field f);
/**
* Set field value using reflection
* @param owner Object to set field on
* @param value Value to set
*/
public void set(Object owner, Object value);
/**
* Get field value using reflection
* @param owner Object to get field from
* @return Field value
*/
public <T> T get(Object owner);
/**
* Factory for creating reflection-based accessors
*/
public static final Accessor.Factory FACTORY;
}High-performance accessor implementation using sun.misc.Unsafe for direct memory access.
/**
* High-performance accessor implementation using sun.misc.Unsafe
* Available when USE_SUN_MISC_UNSAFE is enabled
*/
public final class UnsafeAccessor extends Accessor {
/**
* Constructor
* @param f Java reflection field
*/
public UnsafeAccessor(java.lang.reflect.Field f);
/**
* Set field value using unsafe direct memory access
* @param owner Object to set field on
* @param value Value to set
*/
public void set(Object owner, Object value);
/**
* Get field value using unsafe direct memory access
* @param owner Object to get field from
* @return Field value
*/
public <T> T get(Object owner);
/**
* Factory for creating unsafe-based accessors
*/
public static final Accessor.Factory FACTORY;
}Base class for field factories that create field instances based on Java reflection information.
/**
* Abstract base class for runtime field factories
* Extends Delegate to provide custom serialization logic
*/
public abstract class RuntimeFieldFactory<V> extends Delegate<V> {
/**
* The Java reflection field this factory operates on
*/
public final java.lang.reflect.Field f;
/**
* The field number assigned to this field
*/
public final int number;
/**
* The field name
*/
public final String name;
/**
* Tag information for this field
*/
public final Tag tag;
/**
* Constructor
* @param number Field number
* @param name Field name
* @param f Java reflection field
* @param messageFactory Message factory for creation
* @param tag Tag annotation information
*/
protected RuntimeFieldFactory(int number, String name, java.lang.reflect.Field f,
MessageFactory messageFactory, Tag tag);
}Concrete implementations for different runtime environments and optimization levels.
/**
* Reflection-based field factory implementation
*/
public final class RuntimeReflectionFieldFactory<V> extends RuntimeFieldFactory<V> {
// Implementation uses standard Java reflection
}
/**
* Unsafe-based field factory implementation
* Available when USE_SUN_MISC_UNSAFE is enabled
*/
public final class RuntimeUnsafeFieldFactory<V> extends RuntimeFieldFactory<V> {
// Implementation uses sun.misc.Unsafe for performance
}import io.protostuff.runtime.RuntimeSchema;
import io.protostuff.runtime.Field;
// Get schema and access fields
RuntimeSchema<User> schema = RuntimeSchema.createFrom(User.class);
// Access field by number
Field<User> nameField = schema.getFieldByNumber(1);
Field<User> ageField = schema.getFieldByNumber(2);
// Access field by name
Field<User> emailField = schema.getFieldByName("email");
// Get field metadata
System.out.println("Field name: " + nameField.name);
System.out.println("Field number: " + nameField.number);
System.out.println("Field type: " + nameField.type);
System.out.println("Is repeated: " + nameField.repeated);import io.protostuff.runtime.Accessor;
import io.protostuff.runtime.ReflectAccessor;
// Create accessor for a field
java.lang.reflect.Field javaField = User.class.getDeclaredField("name");
Accessor accessor = new ReflectAccessor(javaField);
// Use accessor for field operations
User user = new User();
accessor.set(user, "Alice"); // Set field value
String name = accessor.get(user); // Get field value
// Factory-based accessor creation
Accessor.Factory factory = ReflectAccessor.FACTORY;
Accessor factoryAccessor = factory.create(javaField);import io.protostuff.runtime.RuntimeEnv;
import io.protostuff.runtime.UnsafeAccessor;
// Check if unsafe is available
if (RuntimeEnv.USE_SUN_MISC_UNSAFE) {
// Use high-performance unsafe accessor
Accessor unsafeAccessor = new UnsafeAccessor(javaField);
// Perform high-speed field operations
unsafeAccessor.set(user, "FastValue");
String value = unsafeAccessor.get(user);
} else {
// Fall back to reflection accessor
Accessor reflectAccessor = new ReflectAccessor(javaField);
reflectAccessor.set(user, "SafeValue");
}import java.util.List;
// Get all fields from schema
RuntimeSchema<User> schema = RuntimeSchema.createFrom(User.class);
List<Field<User>> allFields = schema.getFields();
// Process each field
for (Field<User> field : allFields) {
System.out.printf("Field: %s (number=%d, type=%s, repeated=%s)%n",
field.name, field.number, field.type, field.repeated);
// Access field properties
if (field.groupFilter != 0) {
System.out.println(" Has group filter: " + field.groupFilter);
}
}
// Get field count
int fieldCount = schema.getFieldCount();
System.out.println("Total fields: " + fieldCount);// Create custom field processor
public class FieldAnalyzer {
public void analyzeSchema(RuntimeSchema<?> schema) {
for (Field<?> field : schema.getFields()) {
analyzeField(field);
}
}
private void analyzeField(Field<?> field) {
System.out.println("Analyzing field: " + field.name);
// Check field characteristics
if (field.repeated) {
System.out.println(" - Collection/repeated field");
}
if (field.groupFilter != 0) {
System.out.println(" - Has group filter: " + field.groupFilter);
}
// Check wire format type
switch (field.type) {
case STRING:
System.out.println(" - String field");
break;
case INT32:
System.out.println(" - Integer field");
break;
case MESSAGE:
System.out.println(" - Complex object field");
break;
default:
System.out.println(" - Other type: " + field.type);
}
}
}UnsafeAccessor when available for best performanceField instances to avoid repeated lookupsCommon exceptions when working with field access:
IllegalAccessException - Field access violations with reflectionSecurityException - Security manager restrictions on field accessNoSuchFieldException - Field not found during reflectionIllegalArgumentException - Invalid field values or null parametersInstall with Tessl CLI
npx tessl i tessl/maven-io-protostuff--protostuff-runtime