0
# Schema Generation and Management
1
2
Core functionality for creating, registering, and managing runtime schemas for Java classes. The `RuntimeSchema` class serves as the main entry point for all schema operations and provides both creation and optimization capabilities.
3
4
## Capabilities
5
6
### Schema Creation and Retrieval
7
8
Primary methods for obtaining schemas for Java classes, with automatic caching and type safety.
9
10
```java { .api }
11
/**
12
* Get or create a cached schema for the specified class using the default ID strategy
13
* @param typeClass The class to create a schema for
14
* @return Schema instance for the class
15
*/
16
public static <T> Schema<T> getSchema(Class<T> typeClass);
17
18
/**
19
* Get or create a cached schema for the specified class with a custom ID strategy
20
* @param typeClass The class to create a schema for
21
* @param strategy Custom ID strategy for polymorphic type handling
22
* @return Schema instance for the class
23
*/
24
public static <T> Schema<T> getSchema(Class<T> typeClass, IdStrategy strategy);
25
26
/**
27
* Create a new RuntimeSchema instance for the specified class
28
* @param typeClass The class to create a schema for
29
* @return New RuntimeSchema instance
30
*/
31
public static <T> RuntimeSchema<T> createFrom(Class<T> typeClass);
32
33
/**
34
* Create a new RuntimeSchema instance with custom ID strategy
35
* @param typeClass The class to create a schema for
36
* @param strategy Custom ID strategy for polymorphic type handling
37
* @return New RuntimeSchema instance
38
*/
39
public static <T> RuntimeSchema<T> createFrom(Class<T> typeClass, IdStrategy strategy);
40
41
/**
42
* Create a new RuntimeSchema instance with field exclusions using String array
43
* @param typeClass The class to create a schema for
44
* @param exclusions Array of field names to exclude from the schema
45
* @param strategy Custom ID strategy for polymorphic type handling
46
* @return New RuntimeSchema instance
47
*/
48
public static <T> RuntimeSchema<T> createFrom(Class<T> typeClass, String[] exclusions, IdStrategy strategy);
49
50
/**
51
* Create a new RuntimeSchema instance with field exclusions
52
* @param typeClass The class to create a schema for
53
* @param exclusions Set of field names to exclude from the schema
54
* @param strategy Custom ID strategy for polymorphic type handling
55
* @return New RuntimeSchema instance
56
*/
57
public static <T> RuntimeSchema<T> createFrom(Class<T> typeClass, Set<String> exclusions, IdStrategy strategy);
58
59
/**
60
* Create a new RuntimeSchema instance with custom field mappings
61
* @param typeClass The class to create a schema for
62
* @param declaredFields Map of field names to custom field mappings
63
* @param strategy Custom ID strategy for polymorphic type handling
64
* @return New RuntimeSchema instance
65
*/
66
public static <T> RuntimeSchema<T> createFrom(Class<T> typeClass, Map<String, String> declaredFields, IdStrategy strategy);
67
```
68
69
### RuntimeSchema Constructors and Fields
70
71
Constructor methods and public fields available on RuntimeSchema instances.
72
73
```java { .api }
74
/**
75
* Constructor for RuntimeSchema with reflection-based constructor
76
* @param typeClass The class this schema represents
77
* @param fields Collection of field definitions
78
* @param constructor Java constructor for creating instances
79
*/
80
public RuntimeSchema(Class<T> typeClass, Collection<Field<T>> fields, Constructor<T> constructor);
81
82
/**
83
* Constructor for RuntimeSchema with custom instantiator
84
* @param typeClass The class this schema represents
85
* @param fields Collection of field definitions
86
* @param instantiator Custom instantiator for creating instances
87
*/
88
public RuntimeSchema(Class<T> typeClass, Collection<Field<T>> fields, Instantiator<T> instantiator);
89
90
/**
91
* Public field providing access to the instantiator
92
* Used for optimized object creation
93
*/
94
public final Instantiator<T> instantiator;
95
```
96
97
**Usage Examples:**
98
99
```java
100
import io.protostuff.runtime.RuntimeSchema;
101
import io.protostuff.runtime.DefaultIdStrategy;
102
import io.protostuff.Schema;
103
import java.util.Set;
104
105
// Basic schema creation
106
Schema<User> userSchema = RuntimeSchema.getSchema(User.class);
107
108
// Schema with custom strategy
109
IdStrategy strategy = new DefaultIdStrategy(IdStrategy.ENUMS_BY_NAME);
110
Schema<User> customSchema = RuntimeSchema.getSchema(User.class, strategy);
111
112
// Create schema instance directly
113
RuntimeSchema<User> runtimeSchema = RuntimeSchema.createFrom(User.class);
114
115
// Exclude sensitive fields using String array
116
String[] exclusionsArray = {"password", "ssn"};
117
RuntimeSchema<User> filteredSchema1 = RuntimeSchema.createFrom(
118
User.class, exclusionsArray, strategy
119
);
120
121
// Exclude sensitive fields using Set
122
Set<String> exclusionsSet = Set.of("password", "ssn");
123
RuntimeSchema<User> filteredSchema2 = RuntimeSchema.createFrom(
124
User.class, exclusionsSet, strategy
125
);
126
127
// Access instantiator for optimized object creation
128
RuntimeSchema<User> schema = RuntimeSchema.createFrom(User.class);
129
Instantiator<User> instantiator = schema.instantiator;
130
131
// Use instantiator for fast object creation
132
User user1 = instantiator.newInstance();
133
User user2 = instantiator.newInstance();
134
```
135
136
### Schema Registration and Optimization
137
138
Performance optimization methods for pre-registering schemas and mapping inheritance hierarchies.
139
140
```java { .api }
141
/**
142
* Pre-register a schema for the specified class for improved performance
143
* @param typeClass The class to register
144
* @return true if registration was successful, false if already registered
145
*/
146
public static <T> boolean register(Class<T> typeClass);
147
148
/**
149
* Register a custom schema for the specified class
150
* @param typeClass The class to register
151
* @param schema Custom schema implementation
152
* @return true if registration was successful, false if already registered
153
*/
154
public static <T> boolean register(Class<T> typeClass, Schema<T> schema);
155
156
/**
157
* Map a concrete class to its base class for inheritance handling
158
* @param baseClass The base/parent class
159
* @param typeClass The concrete/child class
160
* @return true if mapping was successful
161
*/
162
public static <T> boolean map(Class<? super T> baseClass, Class<T> typeClass);
163
164
/**
165
* Check if a class has been registered
166
* @param typeClass The class to check
167
* @return true if the class is registered
168
*/
169
public static boolean isRegistered(Class<?> typeClass);
170
171
/**
172
* Check if a class has been registered with a specific strategy
173
* @param typeClass The class to check
174
* @param strategy The ID strategy to check against
175
* @return true if the class is registered with the specified strategy
176
*/
177
public static boolean isRegistered(Class<?> typeClass, IdStrategy strategy);
178
```
179
180
**Usage Examples:**
181
182
```java
183
// Pre-register for performance
184
RuntimeSchema.register(User.class);
185
RuntimeSchema.register(Order.class);
186
RuntimeSchema.register(Product.class);
187
188
// Register custom schema
189
Schema<SpecialObject> customSchema = new MyCustomSchema();
190
RuntimeSchema.register(SpecialObject.class, customSchema);
191
192
// Map inheritance hierarchy
193
RuntimeSchema.map(Animal.class, Dog.class);
194
RuntimeSchema.map(Animal.class, Cat.class);
195
RuntimeSchema.map(Vehicle.class, Car.class);
196
197
// Check registration status
198
if (!RuntimeSchema.isRegistered(User.class)) {
199
RuntimeSchema.register(User.class);
200
}
201
```
202
203
### Schema Constants and Configuration
204
205
Important constants for field number validation and schema configuration.
206
207
```java { .api }
208
/**
209
* Minimum valid protobuf tag/field number
210
*/
211
public static final int MIN_TAG_VALUE = 1;
212
213
/**
214
* Maximum valid protobuf tag/field number (2^29 - 1)
215
*/
216
public static final int MAX_TAG_VALUE = 536870911;
217
218
/**
219
* Threshold for using hash-based field maps instead of array-based maps
220
*/
221
public static final int MIN_TAG_FOR_HASH_FIELD_MAP = 100;
222
```
223
224
### RuntimeSchema Instance Methods
225
226
Methods available on RuntimeSchema instances for field access and schema information.
227
228
```java { .api }
229
/**
230
* Get the Java class this schema represents
231
* @return The class type
232
*/
233
public Class<T> typeClass();
234
235
/**
236
* Get the message name for this schema
237
* @return Message name string
238
*/
239
public String messageName();
240
241
/**
242
* Get the full message name for this schema
243
* @return Full message name string
244
*/
245
public String messageFullName();
246
247
/**
248
* Get field by its protobuf field number
249
* @param number The field number
250
* @return Field instance or null if not found
251
*/
252
public Field<T> getFieldByNumber(int number);
253
254
/**
255
* Get field by its name
256
* @param fieldName The field name
257
* @return Field instance or null if not found
258
*/
259
public Field<T> getFieldByName(String fieldName);
260
261
/**
262
* Get the total number of fields in this schema
263
* @return Field count
264
*/
265
public int getFieldCount();
266
267
/**
268
* Get all fields as a list
269
* @return List of all fields
270
*/
271
public List<Field<T>> getFields();
272
273
/**
274
* Get the field name for a given field number
275
* @param number The field number
276
* @return Field name or null if not found
277
*/
278
public String getFieldName(int number);
279
280
/**
281
* Get the field number for a given field name
282
* @param name The field name
283
* @return Field number or 0 if not found
284
*/
285
public int getFieldNumber(String name);
286
287
/**
288
* Get the pipe schema for streaming operations
289
* @return Pipe schema instance
290
*/
291
public Pipe.Schema<T> getPipeSchema();
292
293
/**
294
* Create a new instance of the schema's type
295
* @return New instance of T
296
*/
297
public T newMessage();
298
299
/**
300
* Check if a message instance is fully initialized
301
* @param message The message to check
302
* @return true if initialized
303
*/
304
public boolean isInitialized(T message);
305
```
306
307
**Usage Examples:**
308
309
```java
310
RuntimeSchema<User> schema = RuntimeSchema.createFrom(User.class);
311
312
// Access schema information
313
Class<User> userClass = schema.typeClass();
314
String messageName = schema.messageName();
315
int fieldCount = schema.getFieldCount();
316
317
// Field access
318
Field<User> nameField = schema.getFieldByName("name");
319
Field<User> ageField = schema.getFieldByNumber(2);
320
List<Field<User>> allFields = schema.getFields();
321
322
// Create new instances
323
User newUser = schema.newMessage();
324
325
// Check field mappings
326
String fieldName = schema.getFieldName(1);
327
int fieldNumber = schema.getFieldNumber("email");
328
```
329
330
## Field Number Management
331
332
Protostuff Runtime automatically assigns field numbers based on field discovery order, but you can control this through:
333
334
1. **Field ordering**: Fields are processed in declaration order by default
335
2. **Custom field mappings**: Use `createFrom` with custom field mappings
336
3. **Field exclusions**: Use `createFrom` with exclusions to skip specific fields
337
4. **Annotations**: Use protostuff annotations to explicitly control field numbers (requires additional dependencies)
338
339
## Performance Considerations
340
341
- **Registration**: Pre-register frequently used classes with `register()` for better performance
342
- **Caching**: `getSchema()` automatically caches schemas, reuse the same Schema instances
343
- **Field Maps**: Large schemas (>100 fields) automatically use hash-based field maps for better lookup performance
344
- **Inheritance Mapping**: Use `map()` to establish inheritance relationships for polymorphic serialization
345
346
## Common Patterns
347
348
```java
349
// Application startup: register all schemas
350
public class SchemaRegistry {
351
static {
352
RuntimeSchema.register(User.class);
353
RuntimeSchema.register(Order.class);
354
RuntimeSchema.register(Product.class);
355
356
// Inheritance mappings
357
RuntimeSchema.map(BaseEntity.class, User.class);
358
RuntimeSchema.map(BaseEntity.class, Order.class);
359
}
360
}
361
362
// Service layer: use cached schemas
363
public class SerializationService {
364
private static final Schema<User> USER_SCHEMA = RuntimeSchema.getSchema(User.class);
365
366
public void processUser(User user) {
367
// Use USER_SCHEMA for serialization operations
368
}
369
}
370
371
// Dynamic schema creation with filtering
372
public <T> Schema<T> createFilteredSchema(Class<T> clazz, Set<String> sensitiveFields) {
373
return RuntimeSchema.createFrom(clazz, sensitiveFields, RuntimeEnv.ID_STRATEGY);
374
}
375
```