or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

advanced-features.mdattributes.mdcore-immutable.mdindex.mdstyle-configuration.mdvalidation.md

style-configuration.mddocs/

0

# Style and Configuration

1

2

Comprehensive styling system for customizing naming conventions, generation behavior, validation methods, and code structure. The `@Value.Style` annotation provides extensive configuration options for tailoring generated code to specific project requirements.

3

4

## Capabilities

5

6

### Value.Style Annotation

7

8

Central configuration annotation for customizing all aspects of code generation.

9

10

```java { .api }

11

/**

12

* Naming and structural style configuration for generated immutable

13

* implementations and companion classes. Can be placed on class, package,

14

* or used as meta-annotation.

15

*/

16

@interface Value.Style {

17

// Naming templates for method recognition and generation

18

String[] get() default "get*";

19

String init() default "*";

20

String with() default "with*";

21

String withUnaryOperator() default "";

22

String add() default "add*";

23

String addAll() default "addAll*";

24

String put() default "put*";

25

String putAll() default "putAll*";

26

String copyOf() default "copyOf";

27

String of() default "of";

28

String instance() default "of";

29

String builder() default "builder";

30

String newBuilder() default "new";

31

String from() default "from";

32

String build() default "build";

33

String buildOrThrow() default "";

34

String canBuild() default "";

35

String toBuilder() default "";

36

String set() default "set*";

37

String unset() default "unset*";

38

String clear() default "clear";

39

String create() default "create";

40

String toImmutable() default "toImmutable";

41

String isInitialized() default "isInitialized";

42

String isSet() default "*IsSet";

43

44

// Type naming templates

45

String typeImmutable() default "Immutable*";

46

String typeBuilder() default "Builder";

47

String typeInnerBuilder() default "Builder";

48

String[] typeAbstract() default "Abstract*";

49

String typeImmutableEnclosing() default "Immutable*";

50

String typeImmutableNested() default "*";

51

String typeModifiable() default "Modifiable*";

52

String typeInnerModifiable() default "Modifiable";

53

String typeWith() default "With*";

54

String packageGenerated() default "*";

55

56

// Behavioral configuration flags

57

boolean strictBuilder() default false;

58

boolean strictModifiable() default true;

59

boolean allParameters() default false;

60

boolean jdkOnly() default false;

61

boolean jdk9Collections() default false;

62

ValidationMethod validationMethod() default ValidationMethod.SIMPLE;

63

ImplementationVisibility visibility() default ImplementationVisibility.SAME;

64

BuilderVisibility builderVisibility() default BuilderVisibility.PUBLIC;

65

String visibilityString() default "";

66

String builderVisibilityString() default "";

67

68

// Advanced configuration options

69

boolean depluralize() default false;

70

String[] depluralizeDictionary() default {};

71

boolean deepImmutablesDetection() default false;

72

boolean stagedBuilder() default false;

73

boolean optionalAcceptNullable() default false;

74

boolean generateSuppressAllWarnings() default true;

75

boolean privateNoargConstructor() default false;

76

boolean protectedNoargConstructor() default false;

77

boolean attributelessSingleton() default false;

78

boolean unsafeDefaultAndDerived() default false;

79

boolean clearBuilder() default false;

80

boolean deferCollectionAllocation() default false;

81

boolean overshadowImplementation() default false;

82

boolean implementationNestedInBuilder() default false;

83

boolean forceJacksonPropertyNames() default true;

84

boolean forceJacksonIgnoreFields() default false;

85

boolean forceEqualsInWithers() default false;

86

boolean jacksonIntegration() default true;

87

boolean weakInterning() default false;

88

boolean alwaysPublicInitializers() default true;

89

boolean builtinContainerAttributes() default true;

90

boolean beanFriendlyModifiables() default false;

91

boolean allMandatoryParameters() default false;

92

boolean transientDerivedFields() default true;

93

boolean finalInstanceFields() default true;

94

boolean attributeBuilderDetection() default false;

95

String redactedMask() default "";

96

String nullableAnnotation() default "Nullable";

97

String[] attributeBuilder() default {"Builder", "*Builder", "builder", "from", "build", "*Build", "new"};

98

String getBuilder() default "*Builder";

99

String setBuilder() default "*Builder";

100

String addBuilder() default "add*Builder";

101

String addAllBuilder() default "addAll*Builders";

102

String getBuilders() default "*Builders";

103

Class<? extends RuntimeException> throwForInvalidImmutableState() default IllegalStateException.class;

104

Class<? extends RuntimeException> throwForNullPointer() default NullPointerException.class;

105

Class<? extends Annotation>[] passAnnotations() default {};

106

Class<? extends Annotation>[] additionalJsonAnnotations() default {};

107

Class<?>[] immutableCopyOfRoutines() default {};

108

Class<? extends Annotation>[] allowedClasspathAnnotations() default {};

109

Class<? extends Annotation> fallbackNullableAnnotation() default Inherited.class;

110

int limitStringLengthInToString() default 0;

111

boolean headerComments() default false;

112

boolean defaultAsDefault() default false;

113

boolean jakarta() default false;

114

}

115

```

116

117

### Naming Template Customization

118

119

Control method and type naming conventions throughout generated code.

120

121

**Usage Examples:**

122

123

```java

124

// Custom naming style

125

@Value.Style(

126

typeImmutable = "*Impl", // Generate PersonImpl instead of ImmutablePerson

127

typeBuilder = "*Builder", // Generate PersonBuilder

128

get = {"get*", "is*"}, // Recognize both get* and is* prefixes

129

with = "set*", // Use set* instead of with* for copy methods

130

init = "set*" // Use set* for builder methods

131

)

132

@Value.Immutable

133

public interface Person {

134

String getName();

135

boolean isActive();

136

}

137

138

// Generated class: PersonImpl with PersonBuilder

139

PersonImpl person = PersonImpl.builder()

140

.setName("John")

141

.setActive(true)

142

.build();

143

144

PersonImpl updated = person.setName("Jane"); // Copy method

145

146

// Bean-style naming

147

@Value.Style(

148

get = {"get*", "is*"},

149

init = "set*",

150

with = "set*",

151

typeImmutable = "*Bean"

152

)

153

@Value.Immutable

154

public interface UserBean {

155

String getName();

156

boolean isEnabled();

157

}

158

159

// Usage follows JavaBean conventions

160

UserBeanBean user = UserBeanBean.builder()

161

.setName("Alice")

162

.setEnabled(true)

163

.build();

164

```

165

166

### Builder Behavior Configuration

167

168

Control builder generation and behavior patterns.

169

170

```java { .api }

171

/**

172

* Builder behavior configuration options

173

*/

174

boolean strictBuilder() default false; // Forward-only builders

175

boolean stagedBuilder() default false; // Telescopic/staged builders

176

boolean clearBuilder() default false; // Generate clear() method

177

String canBuild() default ""; // Generate canBuild() method

178

String buildOrThrow() default ""; // Generate buildOrThrow() method

179

```

180

181

**Usage Examples:**

182

183

```java

184

// Strict builders - forward-only, no reset

185

@Value.Style(strictBuilder = true)

186

@Value.Immutable

187

public interface Config {

188

String name();

189

int value();

190

List<String> tags();

191

}

192

193

// Strict builder prevents re-initialization

194

ImmutableConfig.Builder builder = ImmutableConfig.builder();

195

builder.name("test");

196

// builder.name("other"); // Would throw exception

197

builder.addTags("tag1", "tag2");

198

// builder.tags(List.of("different")); // No reset method generated

199

200

// Staged/telescopic builders - compile-time safety

201

@Value.Style(stagedBuilder = true)

202

@Value.Immutable

203

public interface Connection {

204

String host();

205

int port();

206

@Value.Default

207

default int timeout() { return 30; }

208

}

209

210

// Staged builder enforces mandatory attributes first

211

ImmutableConnection connection = ImmutableConnection.builder()

212

.host("localhost") // Must set host first

213

.port(8080) // Then port

214

.timeout(60) // Optional attributes can be set in any order

215

.build();

216

217

// Enhanced builder methods

218

@Value.Style(

219

canBuild = "isReady",

220

buildOrThrow = "buildOrThrow"

221

)

222

@Value.Immutable

223

public interface Request {

224

String method();

225

String url();

226

}

227

228

ImmutableRequest.Builder builder = ImmutableRequest.builder();

229

builder.method("GET");

230

231

if (builder.isReady()) { // Check if can build

232

Request req = builder.build();

233

} else {

234

Request req = builder.buildOrThrow(() ->

235

new IllegalStateException("Missing required fields"));

236

}

237

```

238

239

### Validation Method Configuration

240

241

Configure validation behavior for generated objects.

242

243

```java { .api }

244

/**

245

* Validation method options for generated immutable objects

246

*/

247

enum ValidationMethod {

248

NONE, // No validation, allow nulls and missing required fields

249

MANDATORY_ONLY, // Check required fields provided (even if null)

250

SIMPLE, // Standard null-hostile validation (default)

251

VALIDATION_API // Use JSR 303 Bean Validation API

252

}

253

```

254

255

**Usage Examples:**

256

257

```java

258

// Disable validation completely

259

@Value.Style(validationMethod = ValidationMethod.NONE)

260

@Value.Immutable

261

public interface Lenient {

262

String name(); // Can be null

263

int count(); // Will be 0 if not provided

264

}

265

266

// Lenient validation allows nulls and missing fields

267

Lenient lenient = ImmutableLenient.builder().build(); // No errors

268

269

// Mandatory-only validation

270

@Value.Style(validationMethod = ValidationMethod.MANDATORY_ONLY)

271

@Value.Immutable

272

public interface MandatoryCheck {

273

String name();

274

@Value.Default

275

default int count() { return 0; }

276

}

277

278

// Must provide name (even if null), count is optional

279

MandatoryCheck obj1 = ImmutableMandatoryCheck.builder()

280

.name(null) // Allowed - null is provided

281

.build();

282

283

// MandatoryCheck obj2 = ImmutableMandatoryCheck.builder().build(); // Error - name not provided

284

285

// JSR 303 Bean Validation

286

@Value.Style(validationMethod = ValidationMethod.VALIDATION_API)

287

@Value.Immutable

288

public interface ValidatedUser {

289

@NotNull @Size(min = 2)

290

String name();

291

292

@NotNull @Email

293

String email();

294

295

@Min(0) @Max(120)

296

int age();

297

}

298

299

// Uses Bean Validation annotations for validation

300

ValidatedUser user = ImmutableValidatedUser.builder()

301

.name("John")

302

.email("john@example.com")

303

.age(25)

304

.build(); // Validates constraints

305

```

306

307

### Visibility and Access Control

308

309

Control the visibility of generated classes and methods.

310

311

```java { .api }

312

/**

313

* Implementation visibility options

314

*/

315

enum ImplementationVisibility {

316

PUBLIC, // Generated class forced to be public

317

SAME, // Same visibility as abstract type

318

SAME_NON_RETURNED, // Same visibility, abstract type returned from factories

319

PACKAGE, // Package visibility

320

PRIVATE // Private visibility (requires builder or enclosing)

321

}

322

323

enum BuilderVisibility {

324

PUBLIC, // Builder forced to be public

325

SAME, // Same visibility as abstract type

326

PACKAGE // Package visibility

327

}

328

```

329

330

**Usage Examples:**

331

332

```java

333

// Private implementation with public builder

334

@Value.Style(

335

visibility = ImplementationVisibility.PRIVATE,

336

builderVisibility = BuilderVisibility.PUBLIC

337

)

338

@Value.Immutable

339

public interface PrivateImpl {

340

String value();

341

}

342

343

// Implementation class is private, only accessible via builder

344

// PrivateImpl obj = ImmutablePrivateImpl.of("test"); // Not accessible

345

PrivateImpl obj = ImmutablePrivateImpl.builder().value("test").build(); // OK

346

347

// Package-private implementation

348

@Value.Style(visibility = ImplementationVisibility.PACKAGE)

349

@Value.Immutable

350

public interface PackagePrivate {

351

String data();

352

}

353

354

// Generated ImmutablePackagePrivate has package visibility

355

```

356

357

### Advanced Configuration Options

358

359

Specialized configuration for complex scenarios and performance optimization.

360

361

```java { .api }

362

/**

363

* Advanced configuration options

364

*/

365

boolean allParameters() default false; // All attributes become parameters

366

boolean deepImmutablesDetection() default false; // Enhanced type analysis

367

boolean jdkOnly() default false; // Use only JDK collections

368

boolean jdk9Collections() default false; // Use JDK 9+ immutable collections

369

boolean depluralize() default false; // Depluralize collection method names

370

boolean weakInterning() default false; // Use weak references for interning

371

boolean forceJacksonPropertyNames() default true; // Force Jackson property names

372

```

373

374

**Usage Examples:**

375

376

```java

377

// All parameters style for tuple-like objects

378

@Value.Style(

379

allParameters = true,

380

typeImmutable = "*Tuple",

381

defaults = @Value.Immutable(builder = false)

382

)

383

@Value.Immutable

384

public interface Point {

385

double x();

386

double y();

387

388

@Value.Parameter(false) // Exclude from parameters

389

@Value.Derived

390

default double magnitude() {

391

return Math.sqrt(x() * x() + y() * y());

392

}

393

}

394

395

// Only constructor available: ImmutablePointTuple.of(x, y)

396

Point point = ImmutablePointTuple.of(3.0, 4.0);

397

398

// Deep immutables detection for enhanced builder methods

399

@Value.Style(deepImmutablesDetection = true)

400

@Value.Immutable

401

public interface Container {

402

Point location();

403

List<Point> waypoints();

404

}

405

406

// Enhanced builder with shortcut methods

407

Container container = ImmutableContainer.builder()

408

.location(3.0, 4.0) // Shortcut for ImmutablePoint.of(3.0, 4.0)

409

.addWaypoints(1.0, 1.0) // Shortcut for waypoints list

410

.addWaypoints(2.0, 2.0)

411

.build();

412

413

// Collection method depluralization

414

@Value.Style(

415

depluralize = true,

416

depluralizeDictionary = {"person:people", "child:children"}

417

)

418

@Value.Immutable

419

public interface Family {

420

List<String> people(); // addPerson(), addAllPeople()

421

List<String> children(); // addChild(), addAllChildren()

422

List<String> items(); // addItem(), addAllItems()

423

}

424

425

ImmutableFamily family = ImmutableFamily.builder()

426

.addPerson("Alice") // Singular form

427

.addChild("Bob") // Custom depluralization

428

.addItem("laptop") // Standard depluralization

429

.build();

430

```