0
# Runtime Libraries
1
2
Runtime libraries provide language-specific utilities, validation support, and integration helpers for protoc-gen-validate generated code. Each target language has different runtime requirements and capabilities.
3
4
## Go Runtime
5
6
Go generated code has **zero runtime dependencies** and integrates directly with existing protobuf Go libraries.
7
8
### Generated Code Integration
9
10
Generated validation methods are added directly to protobuf message types:
11
12
```go { .api }
13
// No additional runtime library required
14
// Methods are generated directly on message types
15
func (m *Message) Validate() error
16
func (m *Message) ValidateAll() error
17
```
18
19
### Error Handling
20
21
Uses standard Go error interface with contextual error messages:
22
23
```go
24
// Example error patterns generated in validation code
25
return fmt.Errorf("invalid %s.%s: %s", messageType, fieldName, constraint)
26
```
27
28
### Integration Utilities
29
30
While no runtime library is required, common integration patterns include:
31
32
```go
33
// HTTP middleware example (user-implemented)
34
func ValidateRequest(next http.Handler) http.Handler {
35
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
36
var req proto.Message
37
// ... decode request
38
if err := req.(interface{ Validate() error }).Validate(); err != nil {
39
http.Error(w, err.Error(), http.StatusBadRequest)
40
return
41
}
42
next.ServeHTTP(w, r)
43
})
44
}
45
```
46
47
## Java Runtime
48
49
Java runtime provides validator discovery, caching, and gRPC integration through the pgv-java-stub library.
50
51
### Core Runtime Classes
52
53
```java { .api }
54
class ReflectiveValidatorIndex implements ValidatorIndex {
55
public Validator validatorFor(Class<?> clazz);
56
}
57
```
58
59
Reflection-based validator discovery and caching.
60
61
**Methods:**
62
- `validatorFor(Class<?> clazz)`: Returns cached validator for message class
63
64
**Usage:**
65
```java
66
ValidatorIndex index = new ReflectiveValidatorIndex();
67
Validator<UserProto> validator = index.validatorFor(UserProto.class);
68
validator.assertValid(user);
69
```
70
71
### Validator Interface
72
73
```java { .api }
74
interface Validator<T> {
75
void assertValid(T message) throws ValidationException;
76
}
77
```
78
79
Base interface implemented by all generated validators.
80
81
### Exception Types
82
83
```java { .api }
84
class ValidationException extends Exception {
85
public ValidationException(String message);
86
public String getFieldPath();
87
public Object getInvalidValue();
88
}
89
```
90
91
Exception thrown by validators on validation failure.
92
93
### gRPC Integration
94
95
```java { .api }
96
class ValidatingClientInterceptor implements ClientInterceptor {
97
public ValidatingClientInterceptor(ValidatorIndex index);
98
}
99
```
100
101
Client-side gRPC interceptor for automatic request/response validation.
102
103
```java { .api }
104
class ValidatingServerInterceptor implements ServerInterceptor {
105
public ValidatingServerInterceptor(ValidatorIndex index);
106
}
107
```
108
109
Server-side gRPC interceptor for automatic request/response validation.
110
111
**Usage:**
112
```java
113
// Client setup
114
ValidatorIndex index = new ReflectiveValidatorIndex();
115
ManagedChannel channel = NettyChannelBuilder.forAddress("localhost", 8080)
116
.usePlaintext()
117
.build();
118
UserServiceGrpc.UserServiceBlockingStub stub = UserServiceGrpc.newBlockingStub(channel)
119
.withInterceptors(new ValidatingClientInterceptor(index));
120
121
// Server setup
122
Server server = ServerBuilder.forPort(8080)
123
.addService(ServerInterceptors.intercept(
124
new UserServiceImpl(),
125
new ValidatingServerInterceptor(index)
126
))
127
.build();
128
```
129
130
### Maven Integration
131
132
```xml
133
<dependency>
134
<groupId>build.buf.protoc-gen-validate</groupId>
135
<artifactId>pgv-java-stub</artifactId>
136
<version>${pgv.version}</version>
137
</dependency>
138
```
139
140
## Python Runtime
141
142
Python provides a full runtime library for JIT validation function generation and caching.
143
144
### Core Runtime Module
145
146
```python { .api }
147
# protoc_gen_validate.validator module
148
```
149
150
Main module containing validation functionality.
151
152
### Validation Functions
153
154
```python { .api }
155
def validate(proto_message: Message)
156
```
157
158
Main validation function that dynamically generates and executes validation code.
159
160
**Parameters:**
161
- `msg`: Protobuf message instance to validate
162
163
**Raises:** `ValidationFailed` when validation fails
164
165
**Implementation:**
166
- Generates validation function code dynamically based on message descriptor
167
- Uses `exec()` to compile and execute validation logic
168
- Caches compiled functions using LRU cache for performance
169
170
```python { .api }
171
def validate_all(proto_message: Message)
172
```
173
174
Validates message and returns all validation errors instead of raising exception on first error.
175
176
**Parameters:**
177
- `proto_message: Message`: Protocol buffer message to validate
178
179
**Raises:** `ValidationFailed` with all validation error messages
180
181
```python { .api }
182
def print_validate(msg) -> None
183
```
184
185
Debug utility that prints generated validation code.
186
187
**Parameters:**
188
- `msg`: Protobuf message instance
189
190
**Behavior:**
191
- Generates the same validation code as `validate()`
192
- Prints Python code to stdout for debugging
193
- Useful for understanding validation logic
194
195
### Exception Types
196
197
```python { .api }
198
class ValidatingMessage(object):
199
"""Wrap a proto message to cache validate functions"""
200
def __init__(self, proto_message: Message)
201
def __hash__(self) -> int
202
def __eq__(self, other) -> bool
203
204
class ValidationFailed(Exception):
205
"""Raised when message validation fails"""
206
pass
207
```
208
209
Exception raised when validation fails.
210
211
**Usage:**
212
```python
213
from protoc_gen_validate.validator import validate, ValidationFailed
214
215
try:
216
validate(message)
217
except ValidationFailed as e:
218
logger.error(f"Validation failed: {e}")
219
```
220
221
### Performance Features
222
223
```python { .api }
224
# Internal caching mechanism (implementation detail)
225
@lru_cache(maxsize=128)
226
def _get_validator_func(descriptor_name):
227
# Returns cached validation function
228
pass
229
```
230
231
Performance optimizations:
232
- **LRU Cache**: Validation functions cached by message descriptor
233
- **JIT Compilation**: Functions compiled on first use
234
- **Code Reuse**: Shared validation logic across similar message types
235
236
### Installation
237
238
```bash
239
pip install protoc-gen-validate
240
```
241
242
## C++ Runtime
243
244
C++ generated code has minimal runtime dependencies and uses standard library types.
245
246
### Generated Function Pattern
247
248
```cpp { .api }
249
namespace validate {
250
bool Validate(const Message& msg, std::string* error = nullptr);
251
}
252
```
253
254
Generated validation functions follow consistent pattern:
255
- Return `bool` for validation result
256
- Optional `std::string*` parameter for error details
257
- Const reference parameter for message
258
259
### Dependencies
260
261
C++ runtime requires only standard library and protobuf headers:
262
263
```cpp
264
#include <string>
265
#include <google/protobuf/message.h>
266
// Generated validation headers
267
```
268
269
### Error Handling
270
271
```cpp
272
// Error handling pattern
273
std::string error;
274
if (!validate::Validate(message, &error)) {
275
// Handle validation failure
276
std::cerr << "Validation failed: " << error << std::endl;
277
}
278
```
279
280
### Integration Examples
281
282
```cpp
283
// Service layer integration
284
class UserService {
285
public:
286
Status CreateUser(const CreateUserRequest& request) {
287
std::string validation_error;
288
if (!validate::Validate(request, &validation_error)) {
289
return Status(StatusCode::kInvalidArgument, validation_error);
290
}
291
// Process valid request
292
return Status::OK;
293
}
294
};
295
```
296
297
## Cross-Language Runtime Comparison
298
299
### Feature Matrix
300
301
| Feature | Go | Java | C++ | Python |
302
|---------|----|----- |-----|--------|
303
| Runtime Dependencies | None | pgv-java-stub | Standard library | protoc-gen-validate |
304
| Error Types | error interface | ValidationException | std::string | ValidationFailed |
305
| Performance | Zero allocation | Reflection cache | Static validation | JIT with cache |
306
| gRPC Integration | Manual | Built-in interceptors | Manual | Manual |
307
| Framework Integration | Manual | Spring/JAX-RS ready | Manual | Django/Flask ready |
308
309
### Consistency Guarantees
310
311
All runtimes maintain:
312
- **Identical validation logic** for the same proto rules
313
- **Consistent error detection** across languages
314
- **Similar performance characteristics** relative to language capabilities
315
- **Compatible error messaging** for debugging
316
317
### Installation Methods
318
319
**Go:**
320
```bash
321
# No runtime installation needed
322
# Generated code has zero dependencies
323
```
324
325
**Java:**
326
```xml
327
<!-- Maven -->
328
<dependency>
329
<groupId>build.buf.protoc-gen-validate</groupId>
330
<artifactId>pgv-java-stub</artifactId>
331
<version>${pgv.version}</version>
332
</dependency>
333
```
334
335
**C++:**
336
```bash
337
# No runtime installation needed
338
# Generated code uses standard library
339
```
340
341
**Python:**
342
```bash
343
pip install protoc-gen-validate
344
```
345
346
## Performance Considerations
347
348
### Go Performance
349
- Zero heap allocations for valid messages
350
- Compile-time optimized validation logic
351
- Direct method calls, no reflection
352
353
### Java Performance
354
- Reflection-based but with caching
355
- Validator instances cached by class
356
- gRPC interceptor overhead minimal
357
358
### C++ Performance
359
- Compile-time optimized validation
360
- Stack-based error handling
361
- Minimal function call overhead
362
363
### Python Performance
364
- JIT compilation overhead on first use
365
- LRU cache eliminates repeated compilation
366
- Dynamic execution with `exec()` overhead
367
368
## Testing and Development
369
370
### Runtime Testing Support
371
372
All runtimes support:
373
- Unit testing of validation logic
374
- Mock validation for testing
375
- Performance benchmarking
376
- Integration testing utilities
377
378
### Development Tools
379
380
Language-specific development aids:
381
- **Go**: Built-in testing framework integration
382
- **Java**: JUnit integration examples
383
- **C++**: GoogleTest integration patterns
384
- **Python**: pytest integration and debug utilities