1# How do I... (Builder edition) 2 3 4This page answers common how-to questions that may come up when using AutoValue 5**with the builder option**. You should read and understand [AutoValue with 6builders](builders.md) first. 7 8If you are not using a builder, see [Introduction](index.md) and 9[How do I...](howto.md) instead. 10 11## Contents 12 13How do I... 14 15* ... [use (or not use) `set` **prefixes**?](#beans) 16* ... [use different **names** besides 17 `builder()`/`Builder`/`build()`?](#build_names) 18* ... [specify a **default** value for a property?](#default) 19* ... [initialize a builder to the same property values as an **existing** 20 value instance](#to_builder) 21* ... [include `with-` methods on my value class for creating slightly 22 **altered** instances?](#withers) 23* ... [**validate** property values?](#validate) 24* ... [**normalize** (modify) a property value at `build` time?](#normalize) 25* ... [expose **both** a builder and a factory method?](#both) 26* ... [handle `Optional` properties?](#optional) 27* ... [use a **collection**-valued property?](#collection) 28 * ... [let my builder **accumulate** values for a collection-valued 29 property (not require them all at once)?](#accumulate) 30 * ... [accumulate values for a collection-valued property, without 31 **"breaking the chain"**?](#add) 32 * ... [offer **both** accumulation and set-at-once methods for the same 33 collection-valued property?](#collection_both) 34* ... [access nested builders while building?](#nested_builders) 35* ... [create a "step builder"?](#step) 36* ... [create a builder for something other than an `@AutoValue`?](#autobuilder) 37* ... [use a different build method for a 38 property?](#build_method) 39 40## <a name="beans"></a>... use (or not use) `set` prefixes? 41 42Just as you can choose whether to use JavaBeans-style names for property getters 43(`getFoo()` or just `foo()`) in your value class, you have the same choice for 44setters in builders too (`setFoo(value)` or just `foo(value)`). As with getters, 45you must use these prefixes consistently or not at all. 46 47Using `get`/`is` prefixes for getters and using the `set` prefix for setters are 48independent choices. For example, it is fine to use the `set` prefixes on all 49your builder methods, but omit the `get`/`is` prefixes from all your accessors. 50 51Here is the `Animal` example using `get` prefixes but not `set` prefixes: 52 53```java 54@AutoValue 55abstract class Animal { 56 abstract String getName(); 57 abstract int getNumberOfLegs(); 58 59 static Builder builder() { 60 return new AutoValue_Animal.Builder(); 61 } 62 63 @AutoValue.Builder 64 abstract static class Builder { 65 abstract Builder name(String value); 66 abstract Builder numberOfLegs(int value); 67 abstract Animal build(); 68 } 69} 70``` 71 72## <a name="build_names"></a>... use different names besides `builder()`/`Builder`/`build()`? 73 74Use whichever names you like; AutoValue doesn't actually care. 75 76(We would gently recommend these names as conventional.) 77 78## <a name="default"></a>... specify a default value for a property? 79 80What should happen when a caller does not supply a value for a property before 81calling `build()`? If the property in question is [nullable](howto.md#nullable), 82it will simply default to `null` as you would expect. And if it is 83[Optional](#optional) it will default to an empty `Optional` as you might also 84expect. But if it isn't either of those things (including if it is a 85primitive-valued property, which *can't* be null), then `build()` will throw an 86unchecked exception. This includes collection properties, which must be given a 87value. They don't default to empty unless there is a 88[collection builder](#accumulate). 89 90But this requirement to supply a value presents a problem, since one of the main 91*advantages* of a builder in the first place is that callers can specify only 92the properties they care about! 93 94The solution is to provide a default value for such properties. Fortunately this 95is easy: just set it on the newly-constructed builder instance before returning 96it from the `builder()` method. 97 98Here is the `Animal` example with the default number of legs being 4: 99 100```java 101@AutoValue 102abstract class Animal { 103 abstract String name(); 104 abstract int numberOfLegs(); 105 106 static Builder builder() { 107 return new AutoValue_Animal.Builder() 108 .setNumberOfLegs(4); 109 } 110 111 @AutoValue.Builder 112 abstract static class Builder { 113 abstract Builder setName(String value); 114 abstract Builder setNumberOfLegs(int value); 115 abstract Animal build(); 116 } 117} 118``` 119 120Occasionally you may want to supply a default value, but only if the property is 121not set explicitly. This is covered in the section on 122[normalization](#normalize). 123 124## <a name="to_builder"></a>... initialize a builder to the same property values as an existing value instance 125 126Suppose your caller has an existing instance of your value class, and wants to 127change only one or two of its properties. Of course, it's immutable, but it 128would be convenient if they could easily get a `Builder` instance representing 129the same property values, which they could then modify and use to create a new 130value instance. 131 132To give them this ability, just add an abstract `toBuilder` method, returning 133your abstract builder type, to your value class. AutoValue will implement it. 134 135```java 136 public abstract Builder toBuilder(); 137``` 138 139## <a name="withers"></a>... include `with-` methods on my value class for creating slightly altered instances? 140 141This is a somewhat common pattern among immutable classes. You can't have 142setters, but you can have methods that act similarly to setters by returning a 143new immutable instance that has one property changed. 144 145If you're already using the builder option, you can add these methods by hand: 146 147```java 148@AutoValue 149public abstract class Animal { 150 public abstract String name(); 151 public abstract int numberOfLegs(); 152 153 public static Builder builder() { 154 return new AutoValue_Animal.Builder(); 155 } 156 157 abstract Builder toBuilder(); 158 159 public final Animal withName(String name) { 160 return toBuilder().setName(name).build(); 161 } 162 163 @AutoValue.Builder 164 public abstract static class Builder { 165 public abstract Builder setName(String value); 166 public abstract Builder setNumberOfLegs(int value); 167 public abstract Animal build(); 168 } 169} 170``` 171 172Note that it's your free choice what to make public (`toBuilder`, `withName`, 173neither, or both). 174 175## <a name="validate"></a>... validate property values? 176 177Validating properties is a little less straightforward than it is in the 178[non-builder case](howto.md#validate). 179 180What you need to do is *split* your "build" method into two methods: 181 182* the non-visible, abstract method that AutoValue implements 183* and the visible, *concrete* method you provide, which calls the generated 184 method and performs validation. 185 186We recommend naming these methods `autoBuild` and `build`, but any names will 187work. It ends up looking like this: 188 189```java 190@AutoValue 191public abstract class Animal { 192 public abstract String name(); 193 public abstract int numberOfLegs(); 194 195 public static Builder builder() { 196 return new AutoValue_Animal.Builder(); 197 } 198 199 @AutoValue.Builder 200 public abstract static class Builder { 201 public abstract Builder setName(String value); 202 public abstract Builder setNumberOfLegs(int value); 203 204 abstract Animal autoBuild(); // not public 205 206 public final Animal build() { 207 Animal animal = autoBuild(); 208 Preconditions.checkState(animal.numberOfLegs() >= 0, "Negative legs"); 209 return animal; 210 } 211 } 212} 213``` 214 215## <a name="normalize"></a>... normalize (modify) a property value at `build` time? 216 217Suppose you want to convert the animal's name to lower case. 218 219You'll need to add a *getter* to your builder, as shown: 220 221```java 222@AutoValue 223public abstract class Animal { 224 public abstract String name(); 225 public abstract int numberOfLegs(); 226 227 public static Builder builder() { 228 return new AutoValue_Animal.Builder(); 229 } 230 231 @AutoValue.Builder 232 public abstract static class Builder { 233 public abstract Builder setName(String value); 234 public abstract Builder setNumberOfLegs(int value); 235 236 abstract String name(); // must match method name in Animal 237 238 abstract Animal autoBuild(); // not public 239 240 public final Animal build() { 241 setName(name().toLowerCase()); 242 return autoBuild(); 243 } 244 } 245} 246``` 247 248The getter in your builder must have the same signature as the abstract property 249accessor method in the value class. It will return the value that has been set 250on the `Builder`. If no value has been set for a 251non-[nullable](howto.md#nullable) property, `IllegalStateException` is thrown. 252 253Getters should generally only be used within the `Builder` as shown, so they are 254not public. 255 256<p id="optional-getter">As an alternative to returning the same type as the 257property accessor method, the builder getter can return an Optional wrapping of 258that type. This can be used if you want to supply a default, but only if the 259property has not been set. (The [usual way](#default) of supplying defaults 260means that the property always appears to have been set.) For example, suppose 261you wanted the default name of your Animal to be something like "4-legged 262creature", where 4 is the `numberOfLegs()` property. You might write this: 263 264```java 265@AutoValue 266public abstract class Animal { 267 public abstract String name(); 268 public abstract int numberOfLegs(); 269 270 public static Builder builder() { 271 return new AutoValue_Animal.Builder(); 272 } 273 274 @AutoValue.Builder 275 public abstract static class Builder { 276 public abstract Builder setName(String value); 277 public abstract Builder setNumberOfLegs(int value); 278 279 abstract Optional<String> name(); 280 abstract int numberOfLegs(); 281 282 abstract Animal autoBuild(); // not public 283 284 public final Animal build() { 285 if (name().isEmpty()) { 286 setName(numberOfLegs() + "-legged creature"); 287 } 288 return autoBuild(); 289 } 290 } 291} 292``` 293 294Notice that this will throw `IllegalStateException` if the `numberOfLegs` 295property hasn't been set either. 296 297The Optional wrapping can be any of the Optional types mentioned in the 298[section](#optional) on `Optional` properties. If your property has type `int` 299it can be wrapped as either `Optional<Integer>` or `OptionalInt`, and likewise 300for `long` and `double`. 301 302## <a name="both"></a>... expose *both* a builder *and* a factory method? 303 304If you use the builder option, AutoValue will not generate a visible constructor 305for the generated concrete value class. If it's important to offer your caller 306the choice of a factory method as well as the builder, then your factory method 307implementation will have to invoke the builder itself. 308 309## <a name="optional"></a>... handle `Optional` properties? 310 311Properties of type `Optional` benefit from special treatment. If you have a 312property of type `Optional<String>`, say, then it will default to an empty 313`Optional` without needing to [specify](#default) a default explicitly. And, 314instead of or as well as the normal `setFoo(Optional<String>)` method, you can 315have `setFoo(String)`. Then `setFoo(s)` is equivalent to 316`setFoo(Optional.of(s))`. (If it is `setFoo(@Nullable String)`, then `setFoo(s)` 317is equivalent to `setFoo(Optional.ofNullable(s))`.) 318 319Here, `Optional` means either [`java.util.Optional`] from Java (Java 8 or 320later), or [`com.google.common.base.Optional`] from Guava. Java 8 also 321introduced related classes in `java.util` called [`OptionalInt`], 322[`OptionalLong`], and [`OptionalDouble`]. You can use those in the same way. For 323example a property of type `OptionalInt` will default to `OptionalInt.empty()` 324and you can set it with either `setFoo(OptionalInt)` or `setFoo(int)`. 325 326```java 327@AutoValue 328public abstract class Animal { 329 public abstract Optional<String> name(); 330 331 public static Builder builder() { 332 return new AutoValue_Animal.Builder(); 333 } 334 335 @AutoValue.Builder 336 public abstract static class Builder { 337 // You can have either or both of these two methods: 338 public abstract Builder setName(Optional<String> value); 339 public abstract Builder setName(String value); 340 public abstract Animal build(); 341 } 342} 343``` 344 345[`java.util.Optional`]: https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html 346[`com.google.common.base.Optional`]: https://guava.dev/releases/snapshot/api/docs/com/google/common/base/Optional.html 347[`OptionalDouble`]: https://docs.oracle.com/javase/8/docs/api/java/util/OptionalDouble.html 348[`OptionalInt`]: https://docs.oracle.com/javase/8/docs/api/java/util/OptionalInt.html 349[`OptionalLong`]: https://docs.oracle.com/javase/8/docs/api/java/util/OptionalLong.html 350 351## <a name="collection"></a>... use a collection-valued property? 352 353Value objects should be immutable, so if a property of one is a collection then 354that collection should be immutable too. We recommend using Guava's [immutable 355collections] to make that explicit. AutoValue's builder support includes a few 356special arrangements to make this more convenient. 357 358In the examples here we use `ImmutableSet`, but the same principles apply to all 359of Guava's immutable collection types, like `ImmutableList`, 360`ImmutableMultimap`, and so on. 361 362We recommend using the immutable type (like `ImmutableSet<String>`) as your 363actual property type. However, it can be a pain for callers to always have to 364construct `ImmutableSet` instances to pass into your builder. So AutoValue 365allows your builder method to accept an argument of any type that 366`ImmutableSet.copyOf` accepts. 367 368If our `Animal` acquires an `ImmutableSet<String>` that is the countries it 369lives in, that can be set from a `Set<String>` or a `Collection<String>` or an 370`Iterable<String>` or a `String[]` or any other compatible type. You can even 371offer multiple choices, as in this example: 372 373```java 374@AutoValue 375public abstract class Animal { 376 public abstract String name(); 377 public abstract int numberOfLegs(); 378 public abstract ImmutableSet<String> countries(); 379 380 public static Builder builder() { 381 return new AutoValue_Animal.Builder(); 382 } 383 384 @AutoValue.Builder 385 public abstract static class Builder { 386 public abstract Builder setName(String value); 387 public abstract Builder setNumberOfLegs(int value); 388 public abstract Builder setCountries(Set<String> value); 389 public abstract Builder setCountries(String... value); 390 public abstract Animal build(); 391 } 392} 393``` 394 395[immutable collections]: https://github.com/google/guava/wiki/ImmutableCollectionsExplained 396 397### <a name="accumulate"></a>... let my builder *accumulate* values for a collection-valued property (not require them all at once)? 398 399Instead of defining a setter for an immutable collection `foos`, you can define 400a method `foosBuilder()` that returns the associated builder type for that 401collection. In this example, we have an `ImmutableSet<String>` which can be 402built using the `countriesBuilder()` method: 403 404```java 405@AutoValue 406public abstract class Animal { 407 public abstract String name(); 408 public abstract int numberOfLegs(); 409 public abstract ImmutableSet<String> countries(); 410 411 public static Builder builder() { 412 return new AutoValue_Animal.Builder(); 413 } 414 415 @AutoValue.Builder 416 public abstract static class Builder { 417 public abstract Builder setName(String value); 418 public abstract Builder setNumberOfLegs(int value); 419 public abstract ImmutableSet.Builder<String> countriesBuilder(); 420 public abstract Animal build(); 421 } 422} 423``` 424 425The name of this method must be exactly the property name (`countries` here) 426followed by the string `Builder`. Even if the properties follow the 427`getCountries()` convention, the builder method must be `countriesBuilder()` 428and not `getCountriesBuilder()`. 429 430It's also possible to have a method like `countriesBuilder` with a single 431argument, provided that the `Builder` class has a public constructor or a 432static `builder` method, with one parameter that the argument can be assigned 433to. For example, if `countries()` were an `ImmutableSortedSet<String>` and you 434wanted to supply a `Comparator` to `ImmutableSortedSet.Builder`, you could 435write: 436 437```java 438 public abstract ImmutableSortedSet.Builder<String> 439 countriesBuilder(Comparator<String> comparator); 440``` 441 442That works because `ImmutableSortedSet.Builder` has a constructor that 443accepts a `Comparator` parameter. 444 445You may notice a small problem with these examples: the caller can no longer 446create their instance in a single chained statement: 447 448```java 449 // This DOES NOT work! 450 Animal dog = Animal.builder() 451 .setName("dog") 452 .setNumberOfLegs(4) 453 .countriesBuilder() 454 .add("Guam") 455 .add("Laos") 456 .build(); 457``` 458 459Instead they are forced to hold the builder itself in a temporary variable: 460 461```java 462 // This DOES work... but we have to "break the chain"! 463 Animal.Builder builder = Animal.builder() 464 .setName("dog") 465 .setNumberOfLegs(4); 466 builder.countriesBuilder() 467 .add("Guam") 468 .add("Laos"); 469 Animal dog = builder.build(); 470``` 471 472One solution for this problem is just below. 473 474### <a name="add"></a>... accumulate values for a collection-valued property, without "breaking the chain"? 475 476Another option is to keep `countriesBuilder()` itself non-public, and only use 477it to implement a public `addCountry` method: 478 479```java 480@AutoValue 481public abstract class Animal { 482 public abstract String name(); 483 public abstract int numberOfLegs(); 484 public abstract ImmutableSet<String> countries(); 485 486 public static Builder builder() { 487 return new AutoValue_Animal.Builder(); 488 } 489 490 @AutoValue.Builder 491 public abstract static class Builder { 492 public abstract Builder setName(String value); 493 public abstract Builder setNumberOfLegs(int value); 494 495 abstract ImmutableSet.Builder<String> countriesBuilder(); 496 public final Builder addCountry(String value) { 497 countriesBuilder().add(value); 498 return this; 499 } 500 501 public abstract Animal build(); 502 } 503} 504``` 505 506Now the caller can do this: 507 508```java 509 // This DOES work! 510 Animal dog = Animal.builder() 511 .setName("dog") 512 .setNumberOfLegs(4) 513 .addCountry("Guam") 514 .addCountry("Laos") // however many times needed 515 .build(); 516``` 517 518### <a name="collection_both"></a>... offer both accumulation and set-at-once methods for the same collection-valued property? 519 520Yes, you can provide both methods, letting your caller choose the style they 521prefer. 522 523The same caller can mix the two styles only in limited ways; once `foosBuilder` 524has been called, any subsequent call to `setFoos` will throw an unchecked 525exception. On the other hand, calling `setFoos` first is okay; a later call to 526`foosBuilder` will return a builder already populated with the 527previously-supplied elements. 528 529## <a name="nested_builders"></a>... access nested builders while building? 530 531Often a property of an `@AutoValue` class is itself an immutable class, 532perhaps another `@AutoValue`. In such cases your builder can expose a builder 533for that nested class. This is very similar to exposing a builder for a 534collection property, as described [earlier](#accumulate). 535 536Suppose the `Animal` class has a property of type `Species`: 537 538```java 539@AutoValue 540public abstract class Animal { 541 public abstract String name(); 542 public abstract Species species(); 543 544 public static Builder builder() { 545 return new AutoValue_Animal.Builder(); 546 } 547 548 @AutoValue.Builder 549 public abstract static class Builder { 550 public abstract Builder setName(String name); 551 public abstract Species.Builder speciesBuilder(); 552 public abstract Animal build(); 553 } 554} 555 556@AutoValue 557public abstract class Species { 558 public abstract String genus(); 559 public abstract String epithet(); 560 561 public static Builder builder() { 562 return new AutoValue_Species.Builder(); 563 } 564 565 @AutoValue.Builder 566 public abstract static class Builder { 567 public abstract Builder setGenus(String genus); 568 public abstract Builder setEpithet(String epithet); 569 public abstract Species build(); 570 } 571} 572``` 573 574Now you can access the builder of the nested `Species` while you are building 575the `Animal`: 576 577```java 578 Animal.Builder catBuilder = Animal.builder() 579 .setName("cat"); 580 catBuilder.speciesBuilder() 581 .setGenus("Felis") 582 .setEpithet("catus"); 583 Animal cat = catBuilder.build(); 584``` 585 586Although the nested class in the example (`Species`) is also an `@AutoValue` 587class, it does not have to be. For example, it could be a [protobuf]. The 588requirements are: 589 590* The nested class must have a way to make a new builder. This can be 591 `new Species.Builder()`, or `Species.builder()`, or `Species.newBuilder()`. 592 593* There must be a way to build an instance from the builder: `Species.Builder` 594 must have a method `Species build()`. 595 596* If there is a need to convert `Species` back into its builder, then `Species` 597 must have a method `Species.Builder toBuilder()`. 598 599 In the example, if `Animal` has an abstract [`toBuilder()`](#to_builder) 600 method then `Species` must also have a `toBuilder()` method. That also applies 601 if there is an abstract `setSpecies` method in addition to the 602 `speciesBuilder` method. 603 604 As an alternative to having a method `Species.Builder toBuilder()` in 605 `Species`, `Species.Builder` can have a method called `addAll` or `putAll` 606 that accepts an argument of type `Species`. This is how AutoValue handles 607 `ImmutableSet` for example. `ImmutableSet` does not have a `toBuilder()` 608 method, but `ImmutableSet.Builder` does have an `addAll` method that accepts 609 an `ImmutableSet`. So given `ImmutableSet<String> strings`, we can achieve the 610 effect of `strings.toBuilder()` by doing: 611 612 ``` 613 ImmutableSet.Builder<String> builder = ImmutableSet.builder(); 614 builder.addAll(strings); 615 ``` 616 617There are no requirements on the name of the builder class. Instead of 618`Species.Builder`, it could be `Species.Factory` or `SpeciesBuilder`. 619 620If `speciesBuilder()` is never called then the final `species()` property will 621be set as if by `speciesBuilder().build()`. In the example, that would result 622in an exception because the required properties of `Species` have not been set. 623 624## <a name="step"></a>... create a "step builder"? 625 626A [_step builder_](http://rdafbn.blogspot.com/2012/07/step-builder-pattern_28.html) 627is a collection of builder interfaces that take you step by step through the 628setting of each of a list of required properties. This means you can be sure at 629compile time that all the properties are set before you build, at the expense of 630some extra code and a bit less flexibility. 631 632Here is an example: 633 634```java 635@AutoValue 636public abstract class Stepped { 637 public abstract String foo(); 638 public abstract String bar(); 639 public abstract int baz(); 640 641 public static FooStep builder() { 642 return new AutoValue_Stepped.Builder(); 643 } 644 645 public interface FooStep { 646 BarStep setFoo(String foo); 647 } 648 649 public interface BarStep { 650 BazStep setBar(String bar); 651 } 652 653 public interface BazStep { 654 Build setBaz(int baz); 655 } 656 657 public interface Build { 658 Stepped build(); 659 } 660 661 @AutoValue.Builder 662 abstract static class Builder implements FooStep, BarStep, BazStep, Build {} 663} 664``` 665 666It might be used like this: 667 668```java 669Stepped stepped = Stepped.builder().setFoo("foo").setBar("bar").setBaz(3).build(); 670``` 671 672The idea is that the only way to build an instance of `Stepped` 673is to go through the steps imposed by the `FooStep`, `BarStep`, and 674`BazStep` interfaces to set the properties in order, with a final build step. 675 676Once you have set the `baz` property there is nothing else to do except build, 677so you could also combine the `setBaz` and `build` methods like this: 678 679```java 680 ... 681 682 public interface BazStep { 683 Stepped setBazAndBuild(int baz); 684 } 685 686 @AutoValue.Builder 687 abstract static class Builder implements FooStep, BarStep, BazStep { 688 abstract Builder setBaz(int baz); 689 abstract Stepped build(); 690 691 @Override 692 public Stepped setBazAndBuild(int baz) { 693 return setBaz(baz).build(); 694 } 695 } 696``` 697 698## <a name="autobuilder"></a> ... create a builder for something other than an `@AutoValue`? 699 700Sometimes you want to make a builder like the kind described here, but have it 701build something other than an `@AutoValue` class, or even call a static method. 702In that case you can use `@AutoBuilder`. See 703[its documentation](autobuilder.md). 704 705Sometimes you want to use a different build method for your property. This is 706especially applicable for `ImmutableMap`, which has two different build methods. 707`builder.buildOrThrow()` is used as the default build method for AutoValue. You 708might prefer to use `builder.buildKeepingLast()` instead, so if the same key is 709put more than once then the last value is retained rather than throwing an 710exception. AutoValue doesn't currently have a way to request this, but here is a 711workaround if you need it. Let's say you have a class like this: 712 713```java 714 @AutoValue 715 public abstract class Foo { 716 public abstract ImmutableMap<Integer, String> map(); 717 ... 718 719 @AutoValue.Builder 720 public abstract static class Builder { 721 public abstract ImmutableMap.Builder<Integer, String> mapBuilder(); 722 public abstract Foo build(); 723 } 724 } 725``` 726 727Instead, you could write this: 728 729```java 730 @AutoValue 731 public abstract class Foo { 732 public abstract ImmutableMap<Integer, String> map(); 733 734 // #start 735 // Needed only if your class has toBuilder() method 736 public Builder toBuilder() { 737 Builder builder = autoToBuilder(); 738 builder.mapBuilder().putAll(map()); 739 return builder; 740 } 741 742 abstract Builder autoToBuilder(); // not public 743 // #end 744 745 @AutoValue.Builder 746 public abstract static class Builder { 747 748 private final ImmutableMap.Builder<Integer, String> mapBuilder = ImmutableMap.builder(); 749 750 public ImmutableMap.Builder<Integer, String> mapBuilder() { 751 return mapBuilder; 752 } 753 754 abstract Builder setMap(ImmutableMap<Integer, String> map); // not public 755 756 abstract Foo autoBuild(); // not public 757 758 public Foo build() { 759 setMap(mapBuilder.buildKeepingLast()); 760 return autoBuild(); 761 } 762 } 763 } 764``` 765 766[protobuf]: https://developers.google.com/protocol-buffers/docs/reference/java-generated#builders 767