or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

core-message-api.mddescriptors-reflection.mdextensions.mdindex.mdjson-format.mdserialization-io.mdwell-known-types.md
tile.json

descriptors-reflection.mddocs/

Descriptors and Reflection

Runtime reflection API for dynamically working with protocol buffer message types, fields, and schemas without generated code. This enables generic message processing and dynamic schema operations in the shaded akka.protobufv3.internal package.

Capabilities

Descriptors Class

Contains nested classes that represent protocol buffer descriptors for messages, fields, enums, services, and files. Provides the foundation for runtime reflection.

/**
 * Container class for protocol buffer descriptor types.
 * Descriptors provide runtime metadata about message structure and schema.
 */
class Descriptors {
    /** Exception thrown when descriptor validation fails */
    static class DescriptorValidationException extends Exception {
        /** Get the problem descriptor */
        FileDescriptor getProblemProto();
        
        /** Get the problem symbol name */
        String getProblemSymbolName();
        
        /** Get the problem description */
        String getDescription();
    }
}

FileDescriptor Class

Describes a .proto file including all its message types, enums, services, and dependencies.

/**
 * Describes a .proto file and all the types defined within it.
 * Represents the top-level container for protocol buffer definitions.
 */
static class Descriptors.FileDescriptor {
    /** Get the file name */
    String getName();
    
    /** Get the full file name including package */
    String getFullName();
    
    /** Get the package name */
    String getPackage();
    
    /** Get protocol buffer syntax version */
    Syntax getSyntax();
    
    /** Get all message types defined in this file */
    List<Descriptor> getMessageTypes();
    
    /** Get all enum types defined in this file */
    List<EnumDescriptor> getEnumTypes();
    
    /** Get all service types defined in this file */
    List<ServiceDescriptor> getServices();
    
    /** Get all extensions defined in this file */
    List<FieldDescriptor> getExtensions();
    
    /** Get file dependencies */
    List<FileDescriptor> getDependencies();
    
    /** Get public file dependencies */
    List<FileDescriptor> getPublicDependencies();
    
    /** Find message type by name */
    Descriptor findMessageTypeByName(String name);
    
    /** Find enum type by name */
    EnumDescriptor findEnumTypeByName(String name);
    
    /** Find service by name */
    ServiceDescriptor findServiceByName(String name);
    
    /** Find extension by name */
    FieldDescriptor findExtensionByName(String name);
    
    /** Build FileDescriptor from proto */
    static FileDescriptor buildFrom(DescriptorProtos.FileDescriptorProto proto,
                                   FileDescriptor[] dependencies)
        throws DescriptorValidationException;
}

Descriptor Class (Message Descriptor)

Describes a message type including all its fields, nested types, and extensions.

/**
 * Describes a protocol buffer message type.
 * Provides metadata about message structure, fields, and nested types.
 */
static class Descriptors.Descriptor {
    /** Get the message name */
    String getName();
    
    /** Get the full name including package and containing types */
    String getFullName();
    
    /** Get the file this message is defined in */
    FileDescriptor getFile();
    
    /** Get the containing type if this is a nested message */
    Descriptor getContainingType();
    
    /** Get all fields in this message */
    List<FieldDescriptor> getFields();
    
    /** Get all oneofs in this message */
    List<OneofDescriptor> getOneofs();
    
    /** Get all nested message types */
    List<Descriptor> getNestedTypes();
    
    /** Get all nested enum types */
    List<EnumDescriptor> getEnumTypes();
    
    /** Get all extensions defined in this message */
    List<FieldDescriptor> getExtensions();
    
    /** Find field by name */
    FieldDescriptor findFieldByName(String name);
    
    /** Find field by field number */
    FieldDescriptor findFieldByNumber(int number);
    
    /** Find nested type by name */
    Descriptor findNestedTypeByName(String name);
    
    /** Find nested enum by name */
    EnumDescriptor findEnumTypeByName(String name);
    
    /** Check if this is a map entry message */
    boolean isMapEntry();
    
    /** Get message options */
    DescriptorProtos.MessageOptions getOptions();
}

FieldDescriptor Class

Describes a field within a message including its type, number, label, and options.

/**
 * Describes a field within a protocol buffer message.
 * Provides metadata about field type, constraints, and options.
 */
static class Descriptors.FieldDescriptor {
    /** Get the field name */
    String getName();
    
    /** Get the full name including containing message */
    String getFullName();
    
    /** Get the field number */
    int getNumber();
    
    /** Get the field type */
    Type getType();
    
    /** Get the Java type for this field */
    JavaType getJavaType();
    
    /** Get the field label (optional/required/repeated) */
    Label getLabel();
    
    /** Check if field is required */
    boolean isRequired();
    
    /** Check if field is optional */
    boolean isOptional();
    
    /** Check if field is repeated */
    boolean isRepeated();
    
    /** Check if field is packed */
    boolean isPacked();
    
    /** Check if field has default value */
    boolean hasDefaultValue();
    
    /** Get the default value */
    Object getDefaultValue();
    
    /** Get the containing message type */
    Descriptor getContainingType();
    
    /** Get the oneof containing this field (if any) */
    OneofDescriptor getContainingOneof();
    
    /** Get the file this field is defined in */
    FileDescriptor getFile();
    
    /** For message/enum fields, get the type descriptor */
    Descriptor getMessageType();
    EnumDescriptor getEnumType();
    
    /** Get field options */
    DescriptorProtos.FieldOptions getOptions();
    
    /** Field type enumeration */
    enum Type {
        DOUBLE, FLOAT, INT64, UINT64, INT32, FIXED64, FIXED32,
        BOOL, STRING, GROUP, MESSAGE, BYTES, UINT32, ENUM,
        SFIXED32, SFIXED64, SINT32, SINT64;
        
        /** Get the Java type for this field type */
        JavaType getJavaType();
    }
    
    /** Java type enumeration */
    enum JavaType {
        INT, LONG, FLOAT, DOUBLE, BOOLEAN, STRING, BYTE_STRING, ENUM, MESSAGE;
        
        /** Get the default value for this Java type */
        Object getDefaultValue();
    }
    
    /** Field label enumeration */
    enum Label {
        OPTIONAL, REQUIRED, REPEATED;
    }
}

EnumDescriptor Class

Describes an enum type including all its values and options.

/**
 * Describes a protocol buffer enum type.
 * Provides metadata about enum values and options.
 */
static class Descriptors.EnumDescriptor {
    /** Get the enum name */
    String getName();
    
    /** Get the full name including package and containing types */
    String getFullName();
    
    /** Get the file this enum is defined in */
    FileDescriptor getFile();
    
    /** Get the containing message type if nested */
    Descriptor getContainingType();
    
    /** Get all enum values */
    List<EnumValueDescriptor> getValues();
    
    /** Find enum value by name */
    EnumValueDescriptor findValueByName(String name);
    
    /** Find enum value by number */
    EnumValueDescriptor findValueByNumber(int number);
    
    /** Get enum options */
    DescriptorProtos.EnumOptions getOptions();
}

EnumValueDescriptor Class

Describes a value within an enum type.

/**
 * Describes a value within a protocol buffer enum.
 * Provides metadata about enum value number and options.
 */
static class Descriptors.EnumValueDescriptor {
    /** Get the value name */
    String getName();
    
    /** Get the full name including enum and package */
    String getFullName();
    
    /** Get the numeric value */
    int getNumber();
    
    /** Get the enum type containing this value */
    EnumDescriptor getType();
    
    /** Get the file this value is defined in */
    FileDescriptor getFile();
    
    /** Get value options */
    DescriptorProtos.EnumValueOptions getOptions();
}

OneofDescriptor Class

Describes a oneof field group within a message.

/**
 * Describes a oneof field group within a protocol buffer message.
 * Represents mutually exclusive field choices.
 */
static class Descriptors.OneofDescriptor {
    /** Get the oneof name */
    String getName();
    
    /** Get the full name including containing message */
    String getFullName();
    
    /** Get the containing message type */
    Descriptor getContainingType();
    
    /** Get all fields in this oneof */
    List<FieldDescriptor> getFields();
    
    /** Get the file this oneof is defined in */
    FileDescriptor getFile();
    
    /** Get oneof options */
    DescriptorProtos.OneofOptions getOptions();
}

ServiceDescriptor Class

Describes a service definition including all its methods.

/**
 * Describes a protocol buffer service definition.
 * Provides metadata about service methods and options.
 */
static class Descriptors.ServiceDescriptor {
    /** Get the service name */
    String getName();
    
    /** Get the full name including package */
    String getFullName();
    
    /** Get the file this service is defined in */
    FileDescriptor getFile();
    
    /** Get all methods in this service */
    List<MethodDescriptor> getMethods();
    
    /** Find method by name */
    MethodDescriptor findMethodByName(String name);
    
    /** Get service options */
    DescriptorProtos.ServiceOptions getOptions();
}

MethodDescriptor Class

Describes a method within a service definition.

/**
 * Describes a method within a protocol buffer service.
 * Provides metadata about input/output types and streaming options.
 */
static class Descriptors.MethodDescriptor {
    /** Get the method name */
    String getName();
    
    /** Get the full name including service and package */
    String getFullName();
    
    /** Get the service containing this method */
    ServiceDescriptor getService();
    
    /** Get the input message type */
    Descriptor getInputType();
    
    /** Get the output message type */
    Descriptor getOutputType();
    
    /** Check if client streaming */
    boolean isClientStreaming();
    
    /** Check if server streaming */
    boolean isServerStreaming();
    
    /** Get the file this method is defined in */
    FileDescriptor getFile();
    
    /** Get method options */
    DescriptorProtos.MethodOptions getOptions();
}

DynamicMessage Class

Can represent arbitrary message types given a Descriptor. Enables working with messages without generated classes.

/**
 * Dynamically represents any protocol buffer message type.
 * Allows working with messages using only runtime descriptors.
 */
class DynamicMessage implements Message {
    /** Create a new builder for the given message type */
    static DynamicMessage.Builder newBuilder(Descriptor type);
    
    /** Create a builder initialized with a message */
    static DynamicMessage.Builder newBuilder(Message prototype);
    
    /** Parse from bytes using the given descriptor */
    static DynamicMessage parseFrom(Descriptor type, ByteString data)
        throws InvalidProtocolBufferException;
    
    /** Parse from bytes with extension registry */
    static DynamicMessage parseFrom(Descriptor type, ByteString data,
                                   ExtensionRegistry extensionRegistry)
        throws InvalidProtocolBufferException;
    
    /** Parse from CodedInputStream */
    static DynamicMessage parseFrom(Descriptor type, CodedInputStream input)
        throws IOException;
    
    /** Parse from CodedInputStream with extension registry */
    static DynamicMessage parseFrom(Descriptor type, CodedInputStream input,
                                   ExtensionRegistry extensionRegistry)
        throws IOException;
    
    /** Get the message descriptor */
    Descriptor getDescriptorForType();
    
    /** Get all set fields */
    Map<FieldDescriptor, Object> getAllFields();
    
    /** Check if field is set */
    boolean hasField(FieldDescriptor field);
    
    /** Get field value */
    Object getField(FieldDescriptor field);
    
    /** Get repeated field count */
    int getRepeatedFieldCount(FieldDescriptor field);
    
    /** Get repeated field element */
    Object getRepeatedField(FieldDescriptor field, int index);
    
    /** Create builder for this type */
    DynamicMessage.Builder newBuilderForType();
    
    /** Create builder with this message's contents */
    DynamicMessage.Builder toBuilder();
    
    /** Dynamic message builder */
    static class Builder implements Message.Builder {
        /** Build the dynamic message */
        DynamicMessage build();
        
        /** Build partial message */
        DynamicMessage buildPartial();
        
        /** Clone this builder */
        DynamicMessage.Builder clone();
        
        /** Clear all fields */
        DynamicMessage.Builder clear();
        
        /** Merge from another message */
        DynamicMessage.Builder mergeFrom(Message other);
        
        /** Set field value */
        DynamicMessage.Builder setField(FieldDescriptor field, Object value);
        
        /** Add to repeated field */
        DynamicMessage.Builder addRepeatedField(FieldDescriptor field, Object value);
        
        /** Clear field */
        DynamicMessage.Builder clearField(FieldDescriptor field);
        
        /** Clear oneof */
        DynamicMessage.Builder clearOneof(OneofDescriptor oneof);
        
        /** Get which field is set in oneof */
        FieldDescriptor getOneofFieldDescriptor(OneofDescriptor oneof);
    }
}

Usage Examples

Working with Descriptors

import akka.protobufv3.internal.*;

// Get descriptor from a message (assumes MyMessage exists)
// Descriptor descriptor = MyMessage.getDescriptor();

// Explore message structure
// System.out.println("Message name: " + descriptor.getName());
// System.out.println("Full name: " + descriptor.getFullName());

// List all fields
// for (Descriptors.FieldDescriptor field : descriptor.getFields()) {
//     System.out.println("Field: " + field.getName() + 
//                       " (type: " + field.getType() + 
//                       ", number: " + field.getNumber() + ")");
// }

// Find specific field
// Descriptors.FieldDescriptor nameField = descriptor.findFieldByName("name");
// if (nameField != null) {
//     System.out.println("Name field type: " + nameField.getJavaType());
// }

Dynamic Message Creation

import akka.protobufv3.internal.*;

// Create dynamic message using descriptor
// Descriptor messageType = MyMessage.getDescriptor();
DynamicMessage.Builder builder = DynamicMessage.newBuilder(messageType);

// Set fields dynamically
// Descriptors.FieldDescriptor nameField = messageType.findFieldByName("name");
// Descriptors.FieldDescriptor idField = messageType.findFieldByName("id");

// builder.setField(nameField, "Dynamic Name");
// builder.setField(idField, 42);

// Build the message
DynamicMessage message = builder.build();

// Read fields dynamically
// Object name = message.getField(nameField);
// Object id = message.getField(idField);
// System.out.println("Name: " + name + ", ID: " + id);

Working with Enums

import akka.protobufv3.internal.*;

// Get enum descriptor (assumes MyEnum exists)
// Descriptors.EnumDescriptor enumType = MyEnum.getDescriptor();

// List all values
// for (Descriptors.EnumValueDescriptor value : enumType.getValues()) {
//     System.out.println("Enum value: " + value.getName() + 
//                       " = " + value.getNumber());
// }

// Find specific value
// Descriptors.EnumValueDescriptor value = enumType.findValueByName("ACTIVE");
// if (value != null) {
//     System.out.println("ACTIVE = " + value.getNumber());
// }

File Descriptor Operations

import akka.protobufv3.internal.*;

// Get file descriptor
// FileDescriptor file = MyMessage.getDescriptor().getFile();

// Explore file contents
// System.out.println("File name: " + file.getName());
// System.out.println("Package: " + file.getPackage());

// List all message types in file
// for (Descriptors.Descriptor messageType : file.getMessageTypes()) {
//     System.out.println("Message type: " + messageType.getName());
// }

// List all enum types in file
// for (Descriptors.EnumDescriptor enumType : file.getEnumTypes()) {
//     System.out.println("Enum type: " + enumType.getName());
// }

// Check dependencies
// for (FileDescriptor dependency : file.getDependencies()) {
//     System.out.println("Depends on: " + dependency.getName());
// }

Generic Message Processing

import akka.protobufv3.internal.*;

public void processMessage(Message message) {
    Descriptors.Descriptor descriptor = message.getDescriptorForType();
    System.out.println("Processing message: " + descriptor.getName());
    
    // Process all set fields
    Map<Descriptors.FieldDescriptor, Object> fields = message.getAllFields();
    for (Map.Entry<Descriptors.FieldDescriptor, Object> entry : fields.entrySet()) {
        Descriptors.FieldDescriptor field = entry.getKey();
        Object value = entry.getValue();
        
        System.out.println("Field " + field.getName() + ": " + value);
        
        // Handle different field types
        switch (field.getJavaType()) {
            case STRING:
                System.out.println("  String value: " + value);
                break;
            case INT:
                System.out.println("  Integer value: " + value);
                break;
            case MESSAGE:
                if (value instanceof Message) {
                    processMessage((Message) value); // Recursive processing
                }
                break;
            // Handle other types...
        }
    }
}