or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

code-generation.mdcore-plugin.mdgenerated-code.mdindex.mdruntime-libraries.mdvalidation-rules.md

runtime-libraries.mddocs/

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