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

advanced-features.mddocs/

0

# Advanced Features

1

2

Specialized features including modifiable companions, collection ordering, inclusion patterns, enclosing type organization, and extended generation capabilities for complex scenarios.

3

4

## Capabilities

5

6

### Modifiable Companions

7

8

Generate mutable companion classes that can be converted to and from immutable instances.

9

10

```java { .api }

11

/**

12

* Generate modifiable implementation of abstract value class.

13

* Provides over-flexible builder or partially built representation.

14

* Generated with "Modifiable" prefix by default.

15

*/

16

@interface Value.Modifiable { }

17

```

18

19

**Usage Examples:**

20

21

```java

22

@Value.Immutable

23

@Value.Modifiable

24

public interface Person {

25

String name();

26

int age();

27

List<String> hobbies();

28

Optional<String> email();

29

}

30

31

// Both immutable and modifiable implementations generated

32

// ImmutablePerson - immutable implementation

33

// ModifiablePerson - mutable implementation

34

35

// Create modifiable instance

36

ModifiablePerson modifiable = ModifiablePerson.create()

37

.setName("Alice")

38

.setAge(25)

39

.addHobbies("reading")

40

.setEmail("alice@example.com");

41

42

// Modify values

43

modifiable.setAge(26);

44

modifiable.addHobbies("swimming", "hiking");

45

modifiable.getHobbies().add("cooking"); // Direct collection access

46

47

// Convert to immutable

48

Person immutable = modifiable.toImmutable();

49

50

// Convert back to modifiable for further changes

51

ModifiablePerson anotherModifiable = ModifiablePerson.copyOf(immutable);

52

53

// Modifiable from builder pattern

54

ModifiablePerson fromBuilder = ModifiablePerson.create()

55

.from(immutable) // Initialize from existing instance

56

.setAge(27);

57

```

58

59

### Collection Ordering

60

61

Control the ordering behavior of generated collection implementations.

62

63

```java { .api }

64

/**

65

* Specify natural ordering for implemented SortedSet, NavigableSet,

66

* SortedMap, or NavigableMap. Elements must implement Comparable.

67

*/

68

@interface Value.NaturalOrder { }

69

70

/**

71

* Specify reversed natural ordering for sorted collections.

72

* Elements must implement Comparable.

73

*/

74

@interface Value.ReverseOrder { }

75

```

76

77

**Usage Examples:**

78

79

```java

80

@Value.Immutable

81

public interface SortedData {

82

// Natural ordering - ascending

83

@Value.NaturalOrder

84

SortedSet<String> names();

85

86

// Reverse ordering - descending

87

@Value.ReverseOrder

88

SortedSet<Integer> scores();

89

90

// Natural ordering for map

91

@Value.NaturalOrder

92

SortedMap<String, Integer> rankings();

93

94

// Regular collections (no special ordering)

95

List<String> tags();

96

Set<String> categories();

97

}

98

99

// Usage with automatic ordering

100

SortedData data = ImmutableSortedData.builder()

101

.addNames("Charlie", "Alice", "Bob") // Stored as: Alice, Bob, Charlie

102

.addScores(85, 92, 78) // Stored as: 92, 85, 78 (descending)

103

.putRankings("Alice", 1)

104

.putRankings("Bob", 2) // Stored by key order: Alice, Bob

105

.addTags("urgent", "review", "feature") // Insertion order preserved

106

.build();

107

108

// Accessing ordered collections

109

SortedSet<String> orderedNames = data.names(); // [Alice, Bob, Charlie]

110

SortedSet<Integer> orderedScores = data.scores(); // [92, 85, 78]

111

```

112

113

### Inclusion Patterns

114

115

Include external types in generation without modifying their source code.

116

117

```java { .api }

118

/**

119

* Includes specified abstract value types into generation processing.

120

* Used to generate immutable implementations of classes from different

121

* packages where source code cannot be changed.

122

*/

123

@interface Value.Include {

124

Class<?>[] value();

125

}

126

```

127

128

**Usage Examples:**

129

130

```java

131

// External interface that cannot be modified

132

package com.external.library;

133

public interface ExternalConfig {

134

String getHost();

135

int getPort();

136

boolean isSecure();

137

}

138

139

// Include external types for generation

140

package com.myapp.config;

141

142

@Value.Include({

143

com.external.library.ExternalConfig.class,

144

com.external.library.DatabaseSettings.class

145

})

146

@Value.Immutable

147

public interface MyConfig extends ExternalConfig {

148

@Override

149

default String getHost() { return "localhost"; }

150

151

@Override

152

default int getPort() { return 8080; }

153

154

@Override

155

default boolean isSecure() { return false; }

156

157

// Additional attributes specific to MyConfig

158

String applicationName();

159

List<String> allowedOrigins();

160

}

161

162

// Generated: ImmutableMyConfig implementing both interfaces

163

MyConfig config = ImmutableMyConfig.builder()

164

.host("production.example.com")

165

.port(443)

166

.secure(true)

167

.applicationName("MyApp")

168

.addAllowedOrigins("https://app.example.com", "https://admin.example.com")

169

.build();

170

171

// Works with external interface type

172

ExternalConfig external = config; // Upcasting works

173

String host = external.getHost();

174

```

175

176

### Enclosing Type Organization

177

178

Organize generated classes under umbrella top-level classes for better namespace management.

179

180

```java { .api }

181

/**

182

* Applied to top level class containing nested abstract value types

183

* to provide namespacing. Generated implementation classes will be

184

* nested under "Immutable" prefixed umbrella class.

185

*/

186

@interface Value.Enclosing { }

187

```

188

189

**Usage Examples:**

190

191

```java

192

@Value.Enclosing

193

public class GraphPrimitives {

194

195

@Value.Immutable

196

public interface Vertex {

197

String id();

198

double x();

199

double y();

200

@Value.Default

201

default String label() { return id(); }

202

}

203

204

@Value.Immutable

205

public interface Edge {

206

String id();

207

Vertex source();

208

Vertex target();

209

@Value.Default

210

default double weight() { return 1.0; }

211

}

212

213

@Value.Immutable

214

public interface Graph {

215

Set<Vertex> vertices();

216

Set<Edge> edges();

217

218

@Value.Check

219

protected void validateGraph() {

220

// Ensure all edge endpoints exist in vertex set

221

Set<String> vertexIds = vertices().stream()

222

.map(Vertex::id)

223

.collect(Collectors.toSet());

224

225

for (Edge edge : edges()) {

226

if (!vertexIds.contains(edge.source().id()) ||

227

!vertexIds.contains(edge.target().id())) {

228

throw new IllegalStateException(

229

"Edge " + edge.id() + " references non-existent vertex"

230

);

231

}

232

}

233

}

234

}

235

}

236

237

// Generated umbrella class: ImmutableGraphPrimitives

238

// Generated nested classes:

239

// - ImmutableGraphPrimitives.Vertex

240

// - ImmutableGraphPrimitives.Edge

241

// - ImmutableGraphPrimitives.Graph

242

243

// Usage with clean imports

244

import static com.example.ImmutableGraphPrimitives.*;

245

246

// Simple class names without "Immutable" prefix

247

Vertex v1 = Vertex.builder().id("v1").x(0).y(0).build();

248

Vertex v2 = Vertex.builder().id("v2").x(1).y(1).build();

249

250

Edge edge = Edge.builder()

251

.id("e1")

252

.source(v1)

253

.target(v2)

254

.weight(2.5)

255

.build();

256

257

Graph graph = Graph.builder()

258

.addVertices(v1, v2)

259

.addEdges(edge)

260

.build();

261

```

262

263

### Advanced Builder Features

264

265

Enhanced builder functionality for complex construction scenarios.

266

267

```java { .api }

268

/**

269

* Style configuration for advanced builder features

270

*/

271

@interface Value.Style {

272

/**

273

* Generate attribute builder methods for discoverable nested builders.

274

* Enables fluent construction of nested immutable objects.

275

*/

276

boolean attributeBuilderDetection() default false;

277

278

/**

279

* Patterns for detecting builder methods on attribute types.

280

*/

281

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

282

283

/**

284

* Generate toBuilder() method on immutable instances.

285

*/

286

String toBuilder() default "";

287

}

288

```

289

290

**Usage Examples:**

291

292

```java

293

// Nested builders with attribute builder detection

294

@Value.Style(

295

attributeBuilderDetection = true,

296

toBuilder = "toBuilder"

297

)

298

@Value.Immutable

299

public interface Order {

300

Customer customer();

301

List<OrderItem> items();

302

Address shippingAddress();

303

}

304

305

@Value.Immutable

306

public interface Customer {

307

String name();

308

String email();

309

310

static Builder builder() { return ImmutableCustomer.builder(); }

311

}

312

313

@Value.Immutable

314

public interface OrderItem {

315

String productId();

316

int quantity();

317

BigDecimal price();

318

319

static Builder builder() { return ImmutableOrderItem.builder(); }

320

}

321

322

// Enhanced builder with nested builder methods

323

Order order = ImmutableOrder.builder()

324

.customerBuilder() // Returns Customer.Builder

325

.name("John Doe")

326

.email("john@example.com")

327

.addItemsBuilder() // Returns OrderItem.Builder for collection

328

.productId("LAPTOP-001")

329

.quantity(1)

330

.price(new BigDecimal("999.99"))

331

.addItemsBuilder() // Another item builder

332

.productId("MOUSE-001")

333

.quantity(2)

334

.price(new BigDecimal("25.99"))

335

.shippingAddressBuilder() // Returns Address.Builder

336

.street("123 Main St")

337

.city("Springfield")

338

.zipCode("12345")

339

.build();

340

341

// toBuilder() for creating modified copies

342

Order.Builder orderBuilder = order.toBuilder();

343

Order updatedOrder = orderBuilder

344

.customerBuilder()

345

.email("john.doe@example.com") // Update customer email

346

.build();

347

```

348

349

### Serialization Support

350

351

Built-in support for various serialization frameworks and custom serialization patterns.

352

353

**Usage Examples:**

354

355

```java

356

// Jackson JSON serialization

357

@Value.Immutable

358

@JsonSerialize(as = ImmutableUser.class)

359

@JsonDeserialize(as = ImmutableUser.class)

360

public interface User {

361

@JsonProperty("user_name")

362

String name();

363

364

@JsonProperty("user_age")

365

int age();

366

367

@JsonIgnore

368

@Value.Auxiliary

369

long internalId();

370

}

371

372

// Java serialization

373

@Value.Immutable

374

public interface SerializableData implements Serializable {

375

String data();

376

int version();

377

378

@Value.Auxiliary // Excluded from serialization

379

transient long timestamp();

380

}

381

382

// Custom serialization with Style

383

@Value.Style(

384

forceJacksonPropertyNames = false, // Use custom naming strategy

385

forceJacksonIgnoreFields = true // Add @JsonIgnore to fields

386

)

387

@Value.Immutable

388

public interface CustomSerialization {

389

String publicData();

390

391

@Value.Redacted

392

String sensitiveData();

393

}

394

```