@@ -205,7 +205,7 @@ public void generate(
205205 bodyContent += "\n " ;
206206
207207 // record style getters
208- bodyContent += generateRecordStyleGetters (fieldsNoPrecomputed );
208+ bodyContent += generateRecordStyleGetters (fieldsNoPrecomputed , false );
209209 bodyContent += "\n " ;
210210
211211 bodyContent +=
@@ -356,11 +356,17 @@ private void generateClass(
356356
357357 /**
358358 * Generating method that generates getters for the record style accessors. Needed now we use class not record.
359+ * <p>
360+ * We generate the getters in both the model itself and in its builder. The builder already has a no-arg build()
361+ * method defined. If a protobuf model defines a field named "build", then the getter method name would clash
362+ * with it. So we use the `guardBuildFieldName` argument to help prefix such getter method name with "_"
363+ * to avoid a clash.
359364 *
360365 * @param fields the fields to use for the code generation
366+ * @param guardBuildFieldName if true and the field name is "build", then prefix the getter with "_"
361367 * @return the generated code
362368 */
363- private static String generateRecordStyleGetters (final List <Field > fields ) {
369+ private static String generateRecordStyleGetters (final List <Field > fields , final boolean guardBuildFieldName ) {
364370 return fields .stream ()
365371 .map (field -> {
366372 String fieldComment = field .comment ();
@@ -372,11 +378,15 @@ private static String generateRecordStyleGetters(final List<Field> fields) {
372378 *
373379 * @return the value of the $fieldName field
374380 */
375- public $fieldType $fieldName () {
381+ public $fieldType $methodName () {
376382 return $fieldName;
377383 }
378384 """
379385 .replace ("$fieldCommentLowerFirst" , fieldCommentLowerFirst )
386+ .replace (
387+ "$methodName" ,
388+ (guardBuildFieldName && "build" .equals (field .nameCamelFirstLower ()) ? "_" : "" )
389+ + field .nameCamelFirstLower ())
380390 .replace ("$fieldName" , field .nameCamelFirstLower ())
381391 .replace ("$fieldType" , field .javaFieldType ())
382392 .indent (DEFAULT_INDENT );
@@ -1154,7 +1164,19 @@ public static final class Builder {
11541164 return new $javaRecordName($recordParams);
11551165 }
11561166
1157- $builderMethods}"""
1167+ $builderMethods
1168+
1169+
1170+ // Generated record-style getters for the current state of the builder follow below.
1171+ // NOTE: for performance reasons, repeated fields are initialized with unmodifiable lists. Similarly,
1172+ // Builder.repeatedField(Type... values) methods would wrap the values into unmodifiable lists.
1173+ // If an application needs to dynamically modify repeated fields in builders, then it must first call
1174+ // the Builder.repeatedField(List<Type> list) method and supply a modifiable list, such as an ArrayList
1175+ // instance. After that, the application must only use the getter method to access the list.
1176+ // If the application wants to finalize the list after the building is finished, then it may call
1177+ // Builder.repeatedField(builder.repeatedField().toArray(new Type[0])) as one last final step.
1178+
1179+ $getterMethods}"""
11581180 .replace ("$fields" , fields .stream ().map (field ->
11591181 getFieldAnnotations (field )
11601182 + "private " + field .javaFieldType ()
@@ -1166,6 +1188,7 @@ public static final class Builder {
11661188 .replace ("$javaRecordName" ,javaRecordName )
11671189 .replace ("$recordParams" ,fields .stream ().map (Field ::nameCamelFirstLower ).collect (Collectors .joining (", " )))
11681190 .replace ("$builderMethods" , String .join ("\n " , builderMethods ))
1191+ .replace ("$getterMethods" , generateRecordStyleGetters (fields , true ))
11691192 .indent (DEFAULT_INDENT );
11701193 // spotless:on
11711194 }
0 commit comments