1// Protocol Buffers - Google's data interchange format
2// Copyright 2008 Google Inc. All rights reserved.
3// https://developers.google.com/protocol-buffers/
4//
5// Redistribution and use in source and binary forms, with or without
6// modification, are permitted provided that the following conditions are
7// met:
8//
9// * Redistributions of source code must retain the above copyright
10// notice, this list of conditions and the following disclaimer.
11// * Redistributions in binary form must reproduce the above
12// copyright notice, this list of conditions and the following disclaimer
13// in the documentation and/or other materials provided with the
14// distribution.
15// * Neither the name of Google Inc. nor the names of its
16// contributors may be used to endorse or promote products derived from
17// this software without specific prior written permission.
18//
19// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31// Author: kenton@google.com (Kenton Varda)
32// Based on original Protocol Buffers design by
33// Sanjay Ghemawat, Jeff Dean, and others.
34
35#include <google/protobuf/compiler/java/message_field.h>
36
37#include <map>
38#include <string>
39
40#include <google/protobuf/io/printer.h>
41#include <google/protobuf/wire_format.h>
42#include <google/protobuf/stubs/strutil.h>
43#include <google/protobuf/compiler/java/context.h>
44#include <google/protobuf/compiler/java/doc_comment.h>
45#include <google/protobuf/compiler/java/helpers.h>
46#include <google/protobuf/compiler/java/name_resolver.h>
47
48// Must be last.
49#include <google/protobuf/port_def.inc>
50
51namespace google {
52namespace protobuf {
53namespace compiler {
54namespace java {
55
56
57namespace {
58
59void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex,
60 int builderBitIndex, const FieldGeneratorInfo* info,
61 ClassNameResolver* name_resolver,
62 std::map<std::string, std::string>* variables) {
63 SetCommonFieldVariables(descriptor, info, variables);
64
65 (*variables)["type"] =
66 name_resolver->GetImmutableClassName(descriptor: descriptor->message_type());
67 (*variables)["kt_type"] = (*variables)["type"];
68 (*variables)["mutable_type"] =
69 name_resolver->GetMutableClassName(descriptor: descriptor->message_type());
70 (*variables)["group_or_message"] =
71 (GetType(field: descriptor) == FieldDescriptor::TYPE_GROUP) ? "Group"
72 : "Message";
73 // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
74 // by the proto compiler
75 (*variables)["deprecation"] =
76 descriptor->options().deprecated() ? "@java.lang.Deprecated " : "";
77 (*variables)["kt_deprecation"] =
78 descriptor->options().deprecated()
79 ? "@kotlin.Deprecated(message = \"Field " + (*variables)["name"] +
80 " is deprecated\") "
81 : "";
82 (*variables)["on_changed"] = "onChanged();";
83 (*variables)["ver"] = GeneratedCodeVersionSuffix();
84 (*variables)["get_parser"] =
85 ExposePublicParser(descriptor: descriptor->message_type()->file()) ? "PARSER"
86 : "parser()";
87
88 if (HasHasbit(descriptor)) {
89 // For singular messages and builders, one bit is used for the hasField bit.
90 (*variables)["get_has_field_bit_message"] = GenerateGetBit(bitIndex: messageBitIndex);
91 (*variables)["get_has_field_bit_builder"] = GenerateGetBit(bitIndex: builderBitIndex);
92
93 // Note that these have a trailing ";".
94 (*variables)["set_has_field_bit_message"] =
95 GenerateSetBit(bitIndex: messageBitIndex) + ";";
96 (*variables)["set_has_field_bit_builder"] =
97 GenerateSetBit(bitIndex: builderBitIndex) + ";";
98 (*variables)["clear_has_field_bit_builder"] =
99 GenerateClearBit(bitIndex: builderBitIndex) + ";";
100
101 (*variables)["is_field_present_message"] = GenerateGetBit(bitIndex: messageBitIndex);
102 } else {
103 (*variables)["set_has_field_bit_message"] = "";
104 (*variables)["set_has_field_bit_builder"] = "";
105 (*variables)["clear_has_field_bit_builder"] = "";
106
107 (*variables)["is_field_present_message"] =
108 (*variables)["name"] + "_ != null";
109 }
110
111 // For repeated builders, one bit is used for whether the array is immutable.
112 (*variables)["get_mutable_bit_builder"] = GenerateGetBit(bitIndex: builderBitIndex);
113 (*variables)["set_mutable_bit_builder"] = GenerateSetBit(bitIndex: builderBitIndex);
114 (*variables)["clear_mutable_bit_builder"] = GenerateClearBit(bitIndex: builderBitIndex);
115
116 // For repeated fields, one bit is used for whether the array is immutable
117 // in the parsing constructor.
118 (*variables)["get_mutable_bit_parser"] =
119 GenerateGetBitMutableLocal(bitIndex: builderBitIndex);
120 (*variables)["set_mutable_bit_parser"] =
121 GenerateSetBitMutableLocal(bitIndex: builderBitIndex);
122
123 (*variables)["get_has_field_bit_from_local"] =
124 GenerateGetBitFromLocal(bitIndex: builderBitIndex);
125 (*variables)["set_has_field_bit_to_local"] =
126 GenerateSetBitToLocal(bitIndex: messageBitIndex);
127}
128
129} // namespace
130
131// ===================================================================
132
133ImmutableMessageFieldGenerator::ImmutableMessageFieldGenerator(
134 const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex,
135 Context* context)
136 : descriptor_(descriptor), name_resolver_(context->GetNameResolver()) {
137 SetMessageVariables(descriptor, messageBitIndex, builderBitIndex,
138 info: context->GetFieldGeneratorInfo(field: descriptor),
139 name_resolver: name_resolver_, variables: &variables_);
140}
141
142ImmutableMessageFieldGenerator::~ImmutableMessageFieldGenerator() {}
143
144int ImmutableMessageFieldGenerator::GetNumBitsForMessage() const {
145 return HasHasbit(descriptor: descriptor_) ? 1 : 0;
146}
147
148int ImmutableMessageFieldGenerator::GetNumBitsForBuilder() const {
149 return GetNumBitsForMessage();
150}
151
152void ImmutableMessageFieldGenerator::GenerateInterfaceMembers(
153 io::Printer* printer) const {
154 // TODO(jonp): In the future, consider having a method specific to the
155 // interface so that builders can choose dynamically to either return a
156 // message or a nested builder, so that asking for the interface doesn't
157 // cause a message to ever be built.
158 WriteFieldAccessorDocComment(printer, field: descriptor_, type: HAZZER);
159 printer->Print(variables: variables_, text: "$deprecation$boolean has$capitalized_name$();\n");
160 WriteFieldAccessorDocComment(printer, field: descriptor_, type: GETTER);
161 printer->Print(variables: variables_, text: "$deprecation$$type$ get$capitalized_name$();\n");
162
163 WriteFieldDocComment(printer, field: descriptor_);
164 printer->Print(
165 variables: variables_,
166 text: "$deprecation$$type$OrBuilder get$capitalized_name$OrBuilder();\n");
167}
168
169void ImmutableMessageFieldGenerator::GenerateMembers(
170 io::Printer* printer) const {
171 printer->Print(variables: variables_, text: "private $type$ $name$_;\n");
172 PrintExtraFieldInfo(variables: variables_, printer);
173
174 if (HasHasbit(descriptor: descriptor_)) {
175 WriteFieldAccessorDocComment(printer, field: descriptor_, type: HAZZER);
176 printer->Print(
177 variables: variables_,
178 text: "@java.lang.Override\n"
179 "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
180 " return $get_has_field_bit_message$;\n"
181 "}\n");
182 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
183 WriteFieldAccessorDocComment(printer, field: descriptor_, type: GETTER);
184 printer->Print(
185 variables: variables_,
186 text: "@java.lang.Override\n"
187 "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
188 " return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n"
189 "}\n");
190 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
191
192 WriteFieldDocComment(printer, field: descriptor_);
193 printer->Print(
194 variables: variables_,
195 text: "@java.lang.Override\n"
196 "$deprecation$public $type$OrBuilder "
197 "${$get$capitalized_name$OrBuilder$}$() {\n"
198 " return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n"
199 "}\n");
200 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
201 } else {
202 WriteFieldAccessorDocComment(printer, field: descriptor_, type: HAZZER);
203 printer->Print(
204 variables: variables_,
205 text: "@java.lang.Override\n"
206 "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
207 " return $name$_ != null;\n"
208 "}\n");
209 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
210 WriteFieldAccessorDocComment(printer, field: descriptor_, type: GETTER);
211 printer->Print(
212 variables: variables_,
213 text: "@java.lang.Override\n"
214 "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
215 " return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n"
216 "}\n");
217 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
218
219 WriteFieldDocComment(printer, field: descriptor_);
220 printer->Print(variables: variables_,
221 text: "@java.lang.Override\n"
222 "$deprecation$public $type$OrBuilder "
223 "${$get$capitalized_name$OrBuilder$}$() {\n"
224 " return get$capitalized_name$();\n"
225 "}\n");
226 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
227 }
228}
229
230void ImmutableMessageFieldGenerator::PrintNestedBuilderCondition(
231 io::Printer* printer, const char* regular_case,
232 const char* nested_builder_case) const {
233 printer->Print(variables: variables_, text: "if ($name$Builder_ == null) {\n");
234 printer->Indent();
235 printer->Print(variables: variables_, text: regular_case);
236 printer->Outdent();
237 printer->Print(text: "} else {\n");
238 printer->Indent();
239 printer->Print(variables: variables_, text: nested_builder_case);
240 printer->Outdent();
241 printer->Print(text: "}\n");
242}
243
244void ImmutableMessageFieldGenerator::PrintNestedBuilderFunction(
245 io::Printer* printer, const char* method_prototype,
246 const char* regular_case, const char* nested_builder_case,
247 const char* trailing_code) const {
248 printer->Print(variables: variables_, text: method_prototype);
249 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
250 printer->Print(text: " {\n");
251 printer->Indent();
252 PrintNestedBuilderCondition(printer, regular_case, nested_builder_case);
253 if (trailing_code != NULL) {
254 printer->Print(variables: variables_, text: trailing_code);
255 }
256 printer->Outdent();
257 printer->Print(text: "}\n");
258}
259
260void ImmutableMessageFieldGenerator::GenerateBuilderMembers(
261 io::Printer* printer) const {
262 // When using nested-builders, the code initially works just like the
263 // non-nested builder case. It only creates a nested builder lazily on
264 // demand and then forever delegates to it after creation.
265
266 bool has_hasbit = HasHasbit(descriptor: descriptor_);
267
268 printer->Print(variables: variables_, text: "private $type$ $name$_;\n");
269
270 printer->Print(variables: variables_,
271 // If this builder is non-null, it is used and the other fields
272 // are ignored.
273 text: "private com.google.protobuf.SingleFieldBuilder$ver$<\n"
274 " $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;"
275 "\n");
276
277 // The comments above the methods below are based on a hypothetical
278 // field of type "Field" called "Field".
279
280 // boolean hasField()
281 WriteFieldAccessorDocComment(printer, field: descriptor_, type: HAZZER);
282 if (has_hasbit) {
283 printer->Print(
284 variables: variables_,
285 text: "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
286 " return $get_has_field_bit_builder$;\n"
287 "}\n");
288 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
289 } else {
290 printer->Print(
291 variables: variables_,
292 text: "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
293 " return $name$Builder_ != null || $name$_ != null;\n"
294 "}\n");
295 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
296 }
297
298 // Field getField()
299 WriteFieldAccessorDocComment(printer, field: descriptor_, type: GETTER);
300 PrintNestedBuilderFunction(
301 printer, method_prototype: "$deprecation$public $type$ ${$get$capitalized_name$$}$()",
302 regular_case: "return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n",
303 nested_builder_case: "return $name$Builder_.getMessage();\n", NULL);
304
305 // Field.Builder setField(Field value)
306 WriteFieldDocComment(printer, field: descriptor_);
307 PrintNestedBuilderFunction(
308 printer,
309 method_prototype: "$deprecation$public Builder ${$set$capitalized_name$$}$($type$ value)",
310
311 regular_case: "if (value == null) {\n"
312 " throw new NullPointerException();\n"
313 "}\n"
314 "$name$_ = value;\n"
315 "$on_changed$\n",
316
317 nested_builder_case: "$name$Builder_.setMessage(value);\n",
318
319 trailing_code: "$set_has_field_bit_builder$\n"
320 "return this;\n");
321
322 // Field.Builder setField(Field.Builder builderForValue)
323 WriteFieldDocComment(printer, field: descriptor_);
324 PrintNestedBuilderFunction(
325 printer,
326 method_prototype: "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
327 " $type$.Builder builderForValue)",
328
329 regular_case: "$name$_ = builderForValue.build();\n"
330 "$on_changed$\n",
331
332 nested_builder_case: "$name$Builder_.setMessage(builderForValue.build());\n",
333
334 trailing_code: "$set_has_field_bit_builder$\n"
335 "return this;\n");
336
337 // Field.Builder mergeField(Field value)
338 WriteFieldDocComment(printer, field: descriptor_);
339 PrintNestedBuilderFunction(
340 printer,
341 method_prototype: "$deprecation$public Builder ${$merge$capitalized_name$$}$($type$ value)",
342
343 regular_case: has_hasbit
344 ? "if ($get_has_field_bit_builder$ &&\n"
345 " $name$_ != null &&\n"
346 " $name$_ != $type$.getDefaultInstance()) {\n"
347 " $name$_ =\n"
348 " $type$.newBuilder($name$_).mergeFrom(value).buildPartial();\n"
349 "} else {\n"
350 " $name$_ = value;\n"
351 "}\n"
352 "$on_changed$\n"
353 : "if ($name$_ != null) {\n"
354 " $name$_ =\n"
355 " $type$.newBuilder($name$_).mergeFrom(value).buildPartial();\n"
356 "} else {\n"
357 " $name$_ = value;\n"
358 "}\n"
359 "$on_changed$\n",
360
361 nested_builder_case: "$name$Builder_.mergeFrom(value);\n",
362
363 trailing_code: "$set_has_field_bit_builder$\n"
364 "return this;\n");
365
366 // Field.Builder clearField()
367 WriteFieldDocComment(printer, field: descriptor_);
368 PrintNestedBuilderFunction(
369 printer, method_prototype: "$deprecation$public Builder ${$clear$capitalized_name$$}$()",
370
371 regular_case: "$name$_ = null;\n"
372 "$on_changed$\n",
373
374 nested_builder_case: has_hasbit ? "$name$Builder_.clear();\n"
375 : "$name$_ = null;\n"
376 "$name$Builder_ = null;\n",
377
378 trailing_code: "$clear_has_field_bit_builder$\n"
379 "return this;\n");
380
381 WriteFieldDocComment(printer, field: descriptor_);
382 printer->Print(variables: variables_,
383 text: "$deprecation$public $type$.Builder "
384 "${$get$capitalized_name$Builder$}$() {\n"
385 " $set_has_field_bit_builder$\n"
386 " $on_changed$\n"
387 " return get$capitalized_name$FieldBuilder().getBuilder();\n"
388 "}\n");
389 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
390 WriteFieldDocComment(printer, field: descriptor_);
391 printer->Print(variables: variables_,
392 text: "$deprecation$public $type$OrBuilder "
393 "${$get$capitalized_name$OrBuilder$}$() {\n"
394 " if ($name$Builder_ != null) {\n"
395 " return $name$Builder_.getMessageOrBuilder();\n"
396 " } else {\n"
397 " return $name$_ == null ?\n"
398 " $type$.getDefaultInstance() : $name$_;\n"
399 " }\n"
400 "}\n");
401 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
402 WriteFieldDocComment(printer, field: descriptor_);
403 printer->Print(
404 variables: variables_,
405 text: "private com.google.protobuf.SingleFieldBuilder$ver$<\n"
406 " $type$, $type$.Builder, $type$OrBuilder> \n"
407 " get$capitalized_name$FieldBuilder() {\n"
408 " if ($name$Builder_ == null) {\n"
409 " $name$Builder_ = new com.google.protobuf.SingleFieldBuilder$ver$<\n"
410 " $type$, $type$.Builder, $type$OrBuilder>(\n"
411 " get$capitalized_name$(),\n"
412 " getParentForChildren(),\n"
413 " isClean());\n"
414 " $name$_ = null;\n"
415 " }\n"
416 " return $name$Builder_;\n"
417 "}\n");
418}
419
420void ImmutableMessageFieldGenerator::GenerateKotlinDslMembers(
421 io::Printer* printer) const {
422 WriteFieldDocComment(printer, field: descriptor_);
423 printer->Print(variables: variables_,
424 text: "$kt_deprecation$var $kt_name$: $kt_type$\n"
425 " @JvmName(\"${$get$kt_capitalized_name$$}$\")\n"
426 " get() = $kt_dsl_builder$.${$get$capitalized_name$$}$()\n"
427 " @JvmName(\"${$set$kt_capitalized_name$$}$\")\n"
428 " set(value) {\n"
429 " $kt_dsl_builder$.${$set$capitalized_name$$}$(value)\n"
430 " }\n");
431
432 WriteFieldAccessorDocComment(printer, field: descriptor_, type: CLEARER,
433 /* builder */ false);
434 printer->Print(variables: variables_,
435 text: "fun ${$clear$kt_capitalized_name$$}$() {\n"
436 " $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n"
437 "}\n");
438
439 WriteFieldAccessorDocComment(printer, field: descriptor_, type: HAZZER);
440 printer->Print(
441 variables: variables_,
442 text: "fun ${$has$kt_capitalized_name$$}$(): kotlin.Boolean {\n"
443 " return $kt_dsl_builder$.${$has$capitalized_name$$}$()\n"
444 "}\n");
445
446 GenerateKotlinOrNull(printer);
447}
448
449void ImmutableMessageFieldGenerator::GenerateKotlinOrNull(io::Printer* printer) const {
450 if (descriptor_->has_optional_keyword()) {
451 printer->Print(variables: variables_,
452 text: "val $classname$Kt.Dsl.$name$OrNull: $kt_type$?\n"
453 " get() = $kt_dsl_builder$.$name$OrNull\n");
454 }
455}
456
457void ImmutableMessageFieldGenerator::GenerateFieldBuilderInitializationCode(
458 io::Printer* printer) const {
459 if (HasHasbit(descriptor: descriptor_)) {
460 printer->Print(variables: variables_, text: "get$capitalized_name$FieldBuilder();\n");
461 }
462}
463
464void ImmutableMessageFieldGenerator::GenerateInitializationCode(
465 io::Printer* printer) const {}
466
467void ImmutableMessageFieldGenerator::GenerateBuilderClearCode(
468 io::Printer* printer) const {
469 if (HasHasbit(descriptor: descriptor_)) {
470 PrintNestedBuilderCondition(printer, regular_case: "$name$_ = null;\n",
471
472 nested_builder_case: "$name$Builder_.clear();\n");
473 printer->Print(variables: variables_, text: "$clear_has_field_bit_builder$\n");
474 } else {
475 PrintNestedBuilderCondition(printer, regular_case: "$name$_ = null;\n",
476
477 nested_builder_case: "$name$_ = null;\n"
478 "$name$Builder_ = null;\n");
479 }
480}
481
482void ImmutableMessageFieldGenerator::GenerateMergingCode(
483 io::Printer* printer) const {
484 printer->Print(variables: variables_,
485 text: "if (other.has$capitalized_name$()) {\n"
486 " merge$capitalized_name$(other.get$capitalized_name$());\n"
487 "}\n");
488}
489
490void ImmutableMessageFieldGenerator::GenerateBuildingCode(
491 io::Printer* printer) const {
492 if (HasHasbit(descriptor: descriptor_)) {
493 printer->Print(variables: variables_, text: "if ($get_has_field_bit_from_local$) {\n");
494 printer->Indent();
495 PrintNestedBuilderCondition(printer, regular_case: "result.$name$_ = $name$_;\n",
496 nested_builder_case: "result.$name$_ = $name$Builder_.build();\n");
497 printer->Outdent();
498 printer->Print(variables: variables_,
499 text: " $set_has_field_bit_to_local$;\n"
500 "}\n");
501 } else {
502 PrintNestedBuilderCondition(printer, regular_case: "result.$name$_ = $name$_;\n",
503 nested_builder_case: "result.$name$_ = $name$Builder_.build();\n");
504 }
505}
506
507void ImmutableMessageFieldGenerator::GenerateParsingCode(
508 io::Printer* printer) const {
509 printer->Print(variables: variables_,
510 text: "$type$.Builder subBuilder = null;\n"
511 "if ($is_field_present_message$) {\n"
512 " subBuilder = $name$_.toBuilder();\n"
513 "}\n");
514
515 if (GetType(field: descriptor_) == FieldDescriptor::TYPE_GROUP) {
516 printer->Print(variables: variables_,
517 text: "$name$_ = input.readGroup($number$, $type$.$get_parser$,\n"
518 " extensionRegistry);\n");
519 } else {
520 printer->Print(variables: variables_,
521 text: "$name$_ = input.readMessage($type$.$get_parser$, "
522 "extensionRegistry);\n");
523 }
524
525 printer->Print(variables: variables_,
526 text: "if (subBuilder != null) {\n"
527 " subBuilder.mergeFrom($name$_);\n"
528 " $name$_ = subBuilder.buildPartial();\n"
529 "}\n"
530 "$set_has_field_bit_message$\n");
531}
532
533void ImmutableMessageFieldGenerator::GenerateParsingDoneCode(
534 io::Printer* printer) const {
535 // noop for messages.
536}
537
538void ImmutableMessageFieldGenerator::GenerateSerializationCode(
539 io::Printer* printer) const {
540 printer->Print(
541 variables: variables_,
542 text: "if ($is_field_present_message$) {\n"
543 " output.write$group_or_message$($number$, get$capitalized_name$());\n"
544 "}\n");
545}
546
547void ImmutableMessageFieldGenerator::GenerateSerializedSizeCode(
548 io::Printer* printer) const {
549 printer->Print(
550 variables: variables_,
551 text: "if ($is_field_present_message$) {\n"
552 " size += com.google.protobuf.CodedOutputStream\n"
553 " .compute$group_or_message$Size($number$, get$capitalized_name$());\n"
554 "}\n");
555}
556
557void ImmutableMessageFieldGenerator::GenerateEqualsCode(
558 io::Printer* printer) const {
559 printer->Print(variables: variables_,
560 text: "if (!get$capitalized_name$()\n"
561 " .equals(other.get$capitalized_name$())) return false;\n");
562}
563
564void ImmutableMessageFieldGenerator::GenerateHashCode(
565 io::Printer* printer) const {
566 printer->Print(variables: variables_,
567 text: "hash = (37 * hash) + $constant_name$;\n"
568 "hash = (53 * hash) + get$capitalized_name$().hashCode();\n");
569}
570
571std::string ImmutableMessageFieldGenerator::GetBoxedType() const {
572 return name_resolver_->GetImmutableClassName(descriptor: descriptor_->message_type());
573}
574
575// ===================================================================
576
577ImmutableMessageOneofFieldGenerator::ImmutableMessageOneofFieldGenerator(
578 const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex,
579 Context* context)
580 : ImmutableMessageFieldGenerator(descriptor, messageBitIndex,
581 builderBitIndex, context) {
582 const OneofGeneratorInfo* info =
583 context->GetOneofGeneratorInfo(oneof: descriptor->containing_oneof());
584 SetCommonOneofVariables(descriptor, info, variables: &variables_);
585}
586
587ImmutableMessageOneofFieldGenerator::~ImmutableMessageOneofFieldGenerator() {}
588
589void ImmutableMessageOneofFieldGenerator::GenerateMembers(
590 io::Printer* printer) const {
591 PrintExtraFieldInfo(variables: variables_, printer);
592 WriteFieldAccessorDocComment(printer, field: descriptor_, type: HAZZER);
593 printer->Print(variables: variables_,
594 text: "@java.lang.Override\n"
595 "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
596 " return $has_oneof_case_message$;\n"
597 "}\n");
598 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
599 WriteFieldAccessorDocComment(printer, field: descriptor_, type: GETTER);
600 printer->Print(variables: variables_,
601 text: "@java.lang.Override\n"
602 "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
603 " if ($has_oneof_case_message$) {\n"
604 " return ($type$) $oneof_name$_;\n"
605 " }\n"
606 " return $type$.getDefaultInstance();\n"
607 "}\n");
608 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
609
610 WriteFieldDocComment(printer, field: descriptor_);
611 printer->Print(variables: variables_,
612 text: "@java.lang.Override\n"
613 "$deprecation$public $type$OrBuilder "
614 "${$get$capitalized_name$OrBuilder$}$() {\n"
615 " if ($has_oneof_case_message$) {\n"
616 " return ($type$) $oneof_name$_;\n"
617 " }\n"
618 " return $type$.getDefaultInstance();\n"
619 "}\n");
620 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
621}
622
623void ImmutableMessageOneofFieldGenerator::GenerateBuilderMembers(
624 io::Printer* printer) const {
625 // When using nested-builders, the code initially works just like the
626 // non-nested builder case. It only creates a nested builder lazily on
627 // demand and then forever delegates to it after creation.
628 printer->Print(variables: variables_,
629 // If this builder is non-null, it is used and the other fields
630 // are ignored.
631 text: "private com.google.protobuf.SingleFieldBuilder$ver$<\n"
632 " $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;"
633 "\n");
634
635 // The comments above the methods below are based on a hypothetical
636 // field of type "Field" called "Field".
637
638 // boolean hasField()
639 WriteFieldAccessorDocComment(printer, field: descriptor_, type: HAZZER);
640 printer->Print(variables: variables_,
641 text: "@java.lang.Override\n"
642 "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
643 " return $has_oneof_case_message$;\n"
644 "}\n");
645 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
646
647 // Field getField()
648 WriteFieldAccessorDocComment(printer, field: descriptor_, type: GETTER);
649 PrintNestedBuilderFunction(
650 printer,
651 method_prototype: "@java.lang.Override\n"
652 "$deprecation$public $type$ ${$get$capitalized_name$$}$()",
653
654 regular_case: "if ($has_oneof_case_message$) {\n"
655 " return ($type$) $oneof_name$_;\n"
656 "}\n"
657 "return $type$.getDefaultInstance();\n",
658
659 nested_builder_case: "if ($has_oneof_case_message$) {\n"
660 " return $name$Builder_.getMessage();\n"
661 "}\n"
662 "return $type$.getDefaultInstance();\n",
663
664 NULL);
665
666 // Field.Builder setField(Field value)
667 WriteFieldDocComment(printer, field: descriptor_);
668 PrintNestedBuilderFunction(
669 printer,
670 method_prototype: "$deprecation$public Builder ${$set$capitalized_name$$}$($type$ value)",
671
672 regular_case: "if (value == null) {\n"
673 " throw new NullPointerException();\n"
674 "}\n"
675 "$oneof_name$_ = value;\n"
676 "$on_changed$\n",
677
678 nested_builder_case: "$name$Builder_.setMessage(value);\n",
679
680 trailing_code: "$set_oneof_case_message$;\n"
681 "return this;\n");
682
683 // Field.Builder setField(Field.Builder builderForValue)
684 WriteFieldDocComment(printer, field: descriptor_);
685 PrintNestedBuilderFunction(
686 printer,
687 method_prototype: "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
688 " $type$.Builder builderForValue)",
689
690 regular_case: "$oneof_name$_ = builderForValue.build();\n"
691 "$on_changed$\n",
692
693 nested_builder_case: "$name$Builder_.setMessage(builderForValue.build());\n",
694
695 trailing_code: "$set_oneof_case_message$;\n"
696 "return this;\n");
697
698 // Field.Builder mergeField(Field value)
699 WriteFieldDocComment(printer, field: descriptor_);
700 PrintNestedBuilderFunction(
701 printer,
702 method_prototype: "$deprecation$public Builder ${$merge$capitalized_name$$}$($type$ value)",
703
704 regular_case: "if ($has_oneof_case_message$ &&\n"
705 " $oneof_name$_ != $type$.getDefaultInstance()) {\n"
706 " $oneof_name$_ = $type$.newBuilder(($type$) $oneof_name$_)\n"
707 " .mergeFrom(value).buildPartial();\n"
708 "} else {\n"
709 " $oneof_name$_ = value;\n"
710 "}\n"
711 "$on_changed$\n",
712
713 nested_builder_case: "if ($has_oneof_case_message$) {\n"
714 " $name$Builder_.mergeFrom(value);\n"
715 "} else {\n"
716 " $name$Builder_.setMessage(value);\n"
717 "}\n",
718
719 trailing_code: "$set_oneof_case_message$;\n"
720 "return this;\n");
721
722 // Field.Builder clearField()
723 WriteFieldDocComment(printer, field: descriptor_);
724 PrintNestedBuilderFunction(
725 printer, method_prototype: "$deprecation$public Builder ${$clear$capitalized_name$$}$()",
726
727 regular_case: "if ($has_oneof_case_message$) {\n"
728 " $clear_oneof_case_message$;\n"
729 " $oneof_name$_ = null;\n"
730 " $on_changed$\n"
731 "}\n",
732
733 nested_builder_case: "if ($has_oneof_case_message$) {\n"
734 " $clear_oneof_case_message$;\n"
735 " $oneof_name$_ = null;\n"
736 "}\n"
737 "$name$Builder_.clear();\n",
738
739 trailing_code: "return this;\n");
740
741 WriteFieldDocComment(printer, field: descriptor_);
742 printer->Print(variables: variables_,
743 text: "$deprecation$public $type$.Builder "
744 "${$get$capitalized_name$Builder$}$() {\n"
745 " return get$capitalized_name$FieldBuilder().getBuilder();\n"
746 "}\n");
747 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
748 WriteFieldDocComment(printer, field: descriptor_);
749 printer->Print(
750 variables: variables_,
751 text: "@java.lang.Override\n"
752 "$deprecation$public $type$OrBuilder "
753 "${$get$capitalized_name$OrBuilder$}$() {\n"
754 " if (($has_oneof_case_message$) && ($name$Builder_ != null)) {\n"
755 " return $name$Builder_.getMessageOrBuilder();\n"
756 " } else {\n"
757 " if ($has_oneof_case_message$) {\n"
758 " return ($type$) $oneof_name$_;\n"
759 " }\n"
760 " return $type$.getDefaultInstance();\n"
761 " }\n"
762 "}\n");
763 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
764 WriteFieldDocComment(printer, field: descriptor_);
765 printer->Print(
766 variables: variables_,
767 text: "private com.google.protobuf.SingleFieldBuilder$ver$<\n"
768 " $type$, $type$.Builder, $type$OrBuilder> \n"
769 " ${$get$capitalized_name$FieldBuilder$}$() {\n"
770 " if ($name$Builder_ == null) {\n"
771 " if (!($has_oneof_case_message$)) {\n"
772 " $oneof_name$_ = $type$.getDefaultInstance();\n"
773 " }\n"
774 " $name$Builder_ = new com.google.protobuf.SingleFieldBuilder$ver$<\n"
775 " $type$, $type$.Builder, $type$OrBuilder>(\n"
776 " ($type$) $oneof_name$_,\n"
777 " getParentForChildren(),\n"
778 " isClean());\n"
779 " $oneof_name$_ = null;\n"
780 " }\n"
781 " $set_oneof_case_message$;\n"
782 " $on_changed$;\n"
783 " return $name$Builder_;\n"
784 "}\n");
785 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
786}
787
788void ImmutableMessageOneofFieldGenerator::GenerateBuildingCode(
789 io::Printer* printer) const {
790 printer->Print(variables: variables_, text: "if ($has_oneof_case_message$) {\n");
791 printer->Indent();
792
793 PrintNestedBuilderCondition(
794 printer, regular_case: "result.$oneof_name$_ = $oneof_name$_;\n",
795
796 nested_builder_case: "result.$oneof_name$_ = $name$Builder_.build();\n");
797
798 printer->Outdent();
799 printer->Print(text: "}\n");
800}
801
802void ImmutableMessageOneofFieldGenerator::GenerateMergingCode(
803 io::Printer* printer) const {
804 printer->Print(variables: variables_,
805 text: "merge$capitalized_name$(other.get$capitalized_name$());\n");
806}
807
808void ImmutableMessageOneofFieldGenerator::GenerateParsingCode(
809 io::Printer* printer) const {
810 printer->Print(variables: variables_,
811 text: "$type$.Builder subBuilder = null;\n"
812 "if ($has_oneof_case_message$) {\n"
813 " subBuilder = (($type$) $oneof_name$_).toBuilder();\n"
814 "}\n");
815
816 if (GetType(field: descriptor_) == FieldDescriptor::TYPE_GROUP) {
817 printer->Print(
818 variables: variables_,
819 text: "$oneof_name$_ = input.readGroup($number$, $type$.$get_parser$,\n"
820 " extensionRegistry);\n");
821 } else {
822 printer->Print(
823 variables: variables_,
824 text: "$oneof_name$_ =\n"
825 " input.readMessage($type$.$get_parser$, extensionRegistry);\n");
826 }
827
828 printer->Print(variables: variables_,
829 text: "if (subBuilder != null) {\n"
830 " subBuilder.mergeFrom(($type$) $oneof_name$_);\n"
831 " $oneof_name$_ = subBuilder.buildPartial();\n"
832 "}\n");
833 printer->Print(variables: variables_, text: "$set_oneof_case_message$;\n");
834}
835
836void ImmutableMessageOneofFieldGenerator::GenerateSerializationCode(
837 io::Printer* printer) const {
838 printer->Print(
839 variables: variables_,
840 text: "if ($has_oneof_case_message$) {\n"
841 " output.write$group_or_message$($number$, ($type$) $oneof_name$_);\n"
842 "}\n");
843}
844
845void ImmutableMessageOneofFieldGenerator::GenerateSerializedSizeCode(
846 io::Printer* printer) const {
847 printer->Print(
848 variables: variables_,
849 text: "if ($has_oneof_case_message$) {\n"
850 " size += com.google.protobuf.CodedOutputStream\n"
851 " .compute$group_or_message$Size($number$, ($type$) $oneof_name$_);\n"
852 "}\n");
853}
854
855// ===================================================================
856
857RepeatedImmutableMessageFieldGenerator::RepeatedImmutableMessageFieldGenerator(
858 const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex,
859 Context* context)
860 : descriptor_(descriptor), name_resolver_(context->GetNameResolver()) {
861 SetMessageVariables(descriptor, messageBitIndex, builderBitIndex,
862 info: context->GetFieldGeneratorInfo(field: descriptor),
863 name_resolver: name_resolver_, variables: &variables_);
864}
865
866RepeatedImmutableMessageFieldGenerator::
867 ~RepeatedImmutableMessageFieldGenerator() {}
868
869int RepeatedImmutableMessageFieldGenerator::GetNumBitsForMessage() const {
870 return 0;
871}
872
873int RepeatedImmutableMessageFieldGenerator::GetNumBitsForBuilder() const {
874 return 1;
875}
876
877void RepeatedImmutableMessageFieldGenerator::GenerateInterfaceMembers(
878 io::Printer* printer) const {
879 // TODO(jonp): In the future, consider having methods specific to the
880 // interface so that builders can choose dynamically to either return a
881 // message or a nested builder, so that asking for the interface doesn't
882 // cause a message to ever be built.
883 WriteFieldDocComment(printer, field: descriptor_);
884 printer->Print(variables: variables_,
885 text: "$deprecation$java.util.List<$type$> \n"
886 " get$capitalized_name$List();\n");
887 WriteFieldDocComment(printer, field: descriptor_);
888 printer->Print(variables: variables_,
889 text: "$deprecation$$type$ get$capitalized_name$(int index);\n");
890 WriteFieldDocComment(printer, field: descriptor_);
891 printer->Print(variables: variables_,
892 text: "$deprecation$int get$capitalized_name$Count();\n");
893
894 WriteFieldDocComment(printer, field: descriptor_);
895 printer->Print(variables: variables_,
896 text: "$deprecation$java.util.List<? extends $type$OrBuilder> \n"
897 " get$capitalized_name$OrBuilderList();\n");
898 WriteFieldDocComment(printer, field: descriptor_);
899 printer->Print(
900 variables: variables_,
901 text: "$deprecation$$type$OrBuilder get$capitalized_name$OrBuilder(\n"
902 " int index);\n");
903}
904
905void RepeatedImmutableMessageFieldGenerator::GenerateMembers(
906 io::Printer* printer) const {
907 printer->Print(variables: variables_, text: "private java.util.List<$type$> $name$_;\n");
908 PrintExtraFieldInfo(variables: variables_, printer);
909 WriteFieldDocComment(printer, field: descriptor_);
910 printer->Print(variables: variables_,
911 text: "@java.lang.Override\n"
912 "$deprecation$public java.util.List<$type$> "
913 "${$get$capitalized_name$List$}$() {\n"
914 " return $name$_;\n" // note: unmodifiable list
915 "}\n");
916 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
917 WriteFieldDocComment(printer, field: descriptor_);
918 printer->Print(
919 variables: variables_,
920 text: "@java.lang.Override\n"
921 "$deprecation$public java.util.List<? extends $type$OrBuilder> \n"
922 " ${$get$capitalized_name$OrBuilderList$}$() {\n"
923 " return $name$_;\n"
924 "}\n");
925 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
926 WriteFieldDocComment(printer, field: descriptor_);
927 printer->Print(
928 variables: variables_,
929 text: "@java.lang.Override\n"
930 "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
931 " return $name$_.size();\n"
932 "}\n");
933 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
934 WriteFieldDocComment(printer, field: descriptor_);
935 printer->Print(
936 variables: variables_,
937 text: "@java.lang.Override\n"
938 "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n"
939 " return $name$_.get(index);\n"
940 "}\n");
941 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
942 WriteFieldDocComment(printer, field: descriptor_);
943 printer->Print(variables: variables_,
944 text: "@java.lang.Override\n"
945 "$deprecation$public $type$OrBuilder "
946 "${$get$capitalized_name$OrBuilder$}$(\n"
947 " int index) {\n"
948 " return $name$_.get(index);\n"
949 "}\n");
950 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
951}
952
953void RepeatedImmutableMessageFieldGenerator::PrintNestedBuilderCondition(
954 io::Printer* printer, const char* regular_case,
955 const char* nested_builder_case) const {
956 printer->Print(variables: variables_, text: "if ($name$Builder_ == null) {\n");
957 printer->Indent();
958 printer->Print(variables: variables_, text: regular_case);
959 printer->Outdent();
960 printer->Print(text: "} else {\n");
961 printer->Indent();
962 printer->Print(variables: variables_, text: nested_builder_case);
963 printer->Outdent();
964 printer->Print(text: "}\n");
965}
966
967void RepeatedImmutableMessageFieldGenerator::PrintNestedBuilderFunction(
968 io::Printer* printer, const char* method_prototype,
969 const char* regular_case, const char* nested_builder_case,
970 const char* trailing_code) const {
971 printer->Print(variables: variables_, text: method_prototype);
972 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
973 printer->Print(text: " {\n");
974 printer->Indent();
975 PrintNestedBuilderCondition(printer, regular_case, nested_builder_case);
976 if (trailing_code != NULL) {
977 printer->Print(variables: variables_, text: trailing_code);
978 }
979 printer->Outdent();
980 printer->Print(text: "}\n");
981}
982
983void RepeatedImmutableMessageFieldGenerator::GenerateBuilderMembers(
984 io::Printer* printer) const {
985 // When using nested-builders, the code initially works just like the
986 // non-nested builder case. It only creates a nested builder lazily on
987 // demand and then forever delegates to it after creation.
988
989 printer->Print(
990 variables: variables_,
991 // Used when the builder is null.
992 // One field is the list and the other field keeps track of whether the
993 // list is immutable. If it's immutable, the invariant is that it must
994 // either an instance of Collections.emptyList() or it's an ArrayList
995 // wrapped in a Collections.unmodifiableList() wrapper and nobody else has
996 // a reference to the underlying ArrayList. This invariant allows us to
997 // share instances of lists between protocol buffers avoiding expensive
998 // memory allocations. Note, immutable is a strong guarantee here -- not
999 // just that the list cannot be modified via the reference but that the
1000 // list can never be modified.
1001 text: "private java.util.List<$type$> $name$_ =\n"
1002 " java.util.Collections.emptyList();\n"
1003
1004 "private void ensure$capitalized_name$IsMutable() {\n"
1005 " if (!$get_mutable_bit_builder$) {\n"
1006 " $name$_ = new java.util.ArrayList<$type$>($name$_);\n"
1007 " $set_mutable_bit_builder$;\n"
1008 " }\n"
1009 "}\n"
1010 "\n");
1011
1012 printer->Print(
1013 variables: variables_,
1014 // If this builder is non-null, it is used and the other fields are
1015 // ignored.
1016 text: "private com.google.protobuf.RepeatedFieldBuilder$ver$<\n"
1017 " $type$, $type$.Builder, $type$OrBuilder> $name$Builder_;\n"
1018 "\n");
1019
1020 // The comments above the methods below are based on a hypothetical
1021 // repeated field of type "Field" called "RepeatedField".
1022
1023 // List<Field> getRepeatedFieldList()
1024 WriteFieldDocComment(printer, field: descriptor_);
1025 PrintNestedBuilderFunction(
1026 printer,
1027 method_prototype: "$deprecation$public java.util.List<$type$> "
1028 "${$get$capitalized_name$List$}$()",
1029
1030 regular_case: "return java.util.Collections.unmodifiableList($name$_);\n",
1031 nested_builder_case: "return $name$Builder_.getMessageList();\n",
1032
1033 NULL);
1034
1035 // int getRepeatedFieldCount()
1036 WriteFieldDocComment(printer, field: descriptor_);
1037 PrintNestedBuilderFunction(
1038 printer, method_prototype: "$deprecation$public int ${$get$capitalized_name$Count$}$()",
1039
1040 regular_case: "return $name$_.size();\n", nested_builder_case: "return $name$Builder_.getCount();\n",
1041
1042 NULL);
1043
1044 // Field getRepeatedField(int index)
1045 WriteFieldDocComment(printer, field: descriptor_);
1046 PrintNestedBuilderFunction(
1047 printer,
1048 method_prototype: "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index)",
1049
1050 regular_case: "return $name$_.get(index);\n",
1051
1052 nested_builder_case: "return $name$Builder_.getMessage(index);\n",
1053
1054 NULL);
1055
1056 // Builder setRepeatedField(int index, Field value)
1057 WriteFieldDocComment(printer, field: descriptor_);
1058 PrintNestedBuilderFunction(
1059 printer,
1060 method_prototype: "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
1061 " int index, $type$ value)",
1062 regular_case: "if (value == null) {\n"
1063 " throw new NullPointerException();\n"
1064 "}\n"
1065 "ensure$capitalized_name$IsMutable();\n"
1066 "$name$_.set(index, value);\n"
1067 "$on_changed$\n",
1068 nested_builder_case: "$name$Builder_.setMessage(index, value);\n", trailing_code: "return this;\n");
1069
1070 // Builder setRepeatedField(int index, Field.Builder builderForValue)
1071 WriteFieldDocComment(printer, field: descriptor_);
1072 PrintNestedBuilderFunction(
1073 printer,
1074 method_prototype: "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
1075 " int index, $type$.Builder builderForValue)",
1076
1077 regular_case: "ensure$capitalized_name$IsMutable();\n"
1078 "$name$_.set(index, builderForValue.build());\n"
1079 "$on_changed$\n",
1080
1081 nested_builder_case: "$name$Builder_.setMessage(index, builderForValue.build());\n",
1082
1083 trailing_code: "return this;\n");
1084
1085 // Builder addRepeatedField(Field value)
1086 WriteFieldDocComment(printer, field: descriptor_);
1087 PrintNestedBuilderFunction(
1088 printer,
1089 method_prototype: "$deprecation$public Builder ${$add$capitalized_name$$}$($type$ value)",
1090
1091 regular_case: "if (value == null) {\n"
1092 " throw new NullPointerException();\n"
1093 "}\n"
1094 "ensure$capitalized_name$IsMutable();\n"
1095 "$name$_.add(value);\n"
1096
1097 "$on_changed$\n",
1098
1099 nested_builder_case: "$name$Builder_.addMessage(value);\n",
1100
1101 trailing_code: "return this;\n");
1102
1103 // Builder addRepeatedField(int index, Field value)
1104 WriteFieldDocComment(printer, field: descriptor_);
1105 PrintNestedBuilderFunction(
1106 printer,
1107 method_prototype: "$deprecation$public Builder ${$add$capitalized_name$$}$(\n"
1108 " int index, $type$ value)",
1109
1110 regular_case: "if (value == null) {\n"
1111 " throw new NullPointerException();\n"
1112 "}\n"
1113 "ensure$capitalized_name$IsMutable();\n"
1114 "$name$_.add(index, value);\n"
1115 "$on_changed$\n",
1116
1117 nested_builder_case: "$name$Builder_.addMessage(index, value);\n",
1118
1119 trailing_code: "return this;\n");
1120
1121 // Builder addRepeatedField(Field.Builder builderForValue)
1122 WriteFieldDocComment(printer, field: descriptor_);
1123 PrintNestedBuilderFunction(
1124 printer,
1125 method_prototype: "$deprecation$public Builder ${$add$capitalized_name$$}$(\n"
1126 " $type$.Builder builderForValue)",
1127
1128 regular_case: "ensure$capitalized_name$IsMutable();\n"
1129 "$name$_.add(builderForValue.build());\n"
1130 "$on_changed$\n",
1131
1132 nested_builder_case: "$name$Builder_.addMessage(builderForValue.build());\n",
1133
1134 trailing_code: "return this;\n");
1135
1136 // Builder addRepeatedField(int index, Field.Builder builderForValue)
1137 WriteFieldDocComment(printer, field: descriptor_);
1138 PrintNestedBuilderFunction(
1139 printer,
1140 method_prototype: "$deprecation$public Builder ${$add$capitalized_name$$}$(\n"
1141 " int index, $type$.Builder builderForValue)",
1142
1143 regular_case: "ensure$capitalized_name$IsMutable();\n"
1144 "$name$_.add(index, builderForValue.build());\n"
1145 "$on_changed$\n",
1146
1147 nested_builder_case: "$name$Builder_.addMessage(index, builderForValue.build());\n",
1148
1149 trailing_code: "return this;\n");
1150
1151 // Builder addAllRepeatedField(Iterable<Field> values)
1152 WriteFieldDocComment(printer, field: descriptor_);
1153 PrintNestedBuilderFunction(
1154 printer,
1155 method_prototype: "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n"
1156 " java.lang.Iterable<? extends $type$> values)",
1157
1158 regular_case: "ensure$capitalized_name$IsMutable();\n"
1159 "com.google.protobuf.AbstractMessageLite.Builder.addAll(\n"
1160 " values, $name$_);\n"
1161 "$on_changed$\n",
1162
1163 nested_builder_case: "$name$Builder_.addAllMessages(values);\n",
1164
1165 trailing_code: "return this;\n");
1166
1167 // Builder clearAllRepeatedField()
1168 WriteFieldDocComment(printer, field: descriptor_);
1169 PrintNestedBuilderFunction(
1170 printer, method_prototype: "$deprecation$public Builder ${$clear$capitalized_name$$}$()",
1171
1172 regular_case: "$name$_ = java.util.Collections.emptyList();\n"
1173 "$clear_mutable_bit_builder$;\n"
1174 "$on_changed$\n",
1175
1176 nested_builder_case: "$name$Builder_.clear();\n",
1177
1178 trailing_code: "return this;\n");
1179
1180 // Builder removeRepeatedField(int index)
1181 WriteFieldDocComment(printer, field: descriptor_);
1182 PrintNestedBuilderFunction(
1183 printer,
1184 method_prototype: "$deprecation$public Builder ${$remove$capitalized_name$$}$(int index)",
1185
1186 regular_case: "ensure$capitalized_name$IsMutable();\n"
1187 "$name$_.remove(index);\n"
1188 "$on_changed$\n",
1189
1190 nested_builder_case: "$name$Builder_.remove(index);\n",
1191
1192 trailing_code: "return this;\n");
1193
1194 WriteFieldDocComment(printer, field: descriptor_);
1195 printer->Print(
1196 variables: variables_,
1197 text: "$deprecation$public $type$.Builder ${$get$capitalized_name$Builder$}$(\n"
1198 " int index) {\n"
1199 " return get$capitalized_name$FieldBuilder().getBuilder(index);\n"
1200 "}\n");
1201 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
1202
1203 WriteFieldDocComment(printer, field: descriptor_);
1204 printer->Print(variables: variables_,
1205 text: "$deprecation$public $type$OrBuilder "
1206 "${$get$capitalized_name$OrBuilder$}$(\n"
1207 " int index) {\n"
1208 " if ($name$Builder_ == null) {\n"
1209 " return $name$_.get(index);"
1210 " } else {\n"
1211 " return $name$Builder_.getMessageOrBuilder(index);\n"
1212 " }\n"
1213 "}\n");
1214 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
1215
1216 WriteFieldDocComment(printer, field: descriptor_);
1217 printer->Print(
1218 variables: variables_,
1219 text: "$deprecation$public java.util.List<? extends $type$OrBuilder> \n"
1220 " ${$get$capitalized_name$OrBuilderList$}$() {\n"
1221 " if ($name$Builder_ != null) {\n"
1222 " return $name$Builder_.getMessageOrBuilderList();\n"
1223 " } else {\n"
1224 " return java.util.Collections.unmodifiableList($name$_);\n"
1225 " }\n"
1226 "}\n");
1227 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
1228
1229 WriteFieldDocComment(printer, field: descriptor_);
1230 printer->Print(variables: variables_,
1231 text: "$deprecation$public $type$.Builder "
1232 "${$add$capitalized_name$Builder$}$() {\n"
1233 " return get$capitalized_name$FieldBuilder().addBuilder(\n"
1234 " $type$.getDefaultInstance());\n"
1235 "}\n");
1236 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
1237 WriteFieldDocComment(printer, field: descriptor_);
1238 printer->Print(
1239 variables: variables_,
1240 text: "$deprecation$public $type$.Builder ${$add$capitalized_name$Builder$}$(\n"
1241 " int index) {\n"
1242 " return get$capitalized_name$FieldBuilder().addBuilder(\n"
1243 " index, $type$.getDefaultInstance());\n"
1244 "}\n");
1245 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
1246 WriteFieldDocComment(printer, field: descriptor_);
1247 printer->Print(
1248 variables: variables_,
1249 text: "$deprecation$public java.util.List<$type$.Builder> \n"
1250 " ${$get$capitalized_name$BuilderList$}$() {\n"
1251 " return get$capitalized_name$FieldBuilder().getBuilderList();\n"
1252 "}\n"
1253 "private com.google.protobuf.RepeatedFieldBuilder$ver$<\n"
1254 " $type$, $type$.Builder, $type$OrBuilder> \n"
1255 " get$capitalized_name$FieldBuilder() {\n"
1256 " if ($name$Builder_ == null) {\n"
1257 " $name$Builder_ = new "
1258 "com.google.protobuf.RepeatedFieldBuilder$ver$<\n"
1259 " $type$, $type$.Builder, $type$OrBuilder>(\n"
1260 " $name$_,\n"
1261 " $get_mutable_bit_builder$,\n"
1262 " getParentForChildren(),\n"
1263 " isClean());\n"
1264 " $name$_ = null;\n"
1265 " }\n"
1266 " return $name$Builder_;\n"
1267 "}\n");
1268 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
1269}
1270
1271void RepeatedImmutableMessageFieldGenerator::
1272 GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
1273 printer->Print(variables: variables_, text: "get$capitalized_name$FieldBuilder();\n");
1274}
1275
1276void RepeatedImmutableMessageFieldGenerator::GenerateInitializationCode(
1277 io::Printer* printer) const {
1278 printer->Print(variables: variables_, text: "$name$_ = java.util.Collections.emptyList();\n");
1279}
1280
1281void RepeatedImmutableMessageFieldGenerator::GenerateBuilderClearCode(
1282 io::Printer* printer) const {
1283 PrintNestedBuilderCondition(printer,
1284 regular_case: "$name$_ = java.util.Collections.emptyList();\n"
1285 "$clear_mutable_bit_builder$;\n",
1286
1287 nested_builder_case: "$name$Builder_.clear();\n");
1288}
1289
1290void RepeatedImmutableMessageFieldGenerator::GenerateMergingCode(
1291 io::Printer* printer) const {
1292 // The code below does two optimizations (non-nested builder case):
1293 // 1. If the other list is empty, there's nothing to do. This ensures we
1294 // don't allocate a new array if we already have an immutable one.
1295 // 2. If the other list is non-empty and our current list is empty, we can
1296 // reuse the other list which is guaranteed to be immutable.
1297 PrintNestedBuilderCondition(
1298 printer,
1299 regular_case: "if (!other.$name$_.isEmpty()) {\n"
1300 " if ($name$_.isEmpty()) {\n"
1301 " $name$_ = other.$name$_;\n"
1302 " $clear_mutable_bit_builder$;\n"
1303 " } else {\n"
1304 " ensure$capitalized_name$IsMutable();\n"
1305 " $name$_.addAll(other.$name$_);\n"
1306 " }\n"
1307 " $on_changed$\n"
1308 "}\n",
1309
1310 nested_builder_case: "if (!other.$name$_.isEmpty()) {\n"
1311 " if ($name$Builder_.isEmpty()) {\n"
1312 " $name$Builder_.dispose();\n"
1313 " $name$Builder_ = null;\n"
1314 " $name$_ = other.$name$_;\n"
1315 " $clear_mutable_bit_builder$;\n"
1316 " $name$Builder_ = \n"
1317 " com.google.protobuf.GeneratedMessage$ver$.alwaysUseFieldBuilders "
1318 "?\n"
1319 " get$capitalized_name$FieldBuilder() : null;\n"
1320 " } else {\n"
1321 " $name$Builder_.addAllMessages(other.$name$_);\n"
1322 " }\n"
1323 "}\n");
1324}
1325
1326void RepeatedImmutableMessageFieldGenerator::GenerateBuildingCode(
1327 io::Printer* printer) const {
1328 // The code below (non-nested builder case) ensures that the result has an
1329 // immutable list. If our list is immutable, we can just reuse it. If not,
1330 // we make it immutable.
1331 PrintNestedBuilderCondition(
1332 printer,
1333 regular_case: "if ($get_mutable_bit_builder$) {\n"
1334 " $name$_ = java.util.Collections.unmodifiableList($name$_);\n"
1335 " $clear_mutable_bit_builder$;\n"
1336 "}\n"
1337 "result.$name$_ = $name$_;\n",
1338
1339 nested_builder_case: "result.$name$_ = $name$Builder_.build();\n");
1340}
1341
1342void RepeatedImmutableMessageFieldGenerator::GenerateParsingCode(
1343 io::Printer* printer) const {
1344 printer->Print(variables: variables_,
1345 text: "if (!$get_mutable_bit_parser$) {\n"
1346 " $name$_ = new java.util.ArrayList<$type$>();\n"
1347 " $set_mutable_bit_parser$;\n"
1348 "}\n");
1349
1350 if (GetType(field: descriptor_) == FieldDescriptor::TYPE_GROUP) {
1351 printer->Print(
1352 variables: variables_,
1353 text: "$name$_.add(input.readGroup($number$, $type$.$get_parser$,\n"
1354 " extensionRegistry));\n");
1355 } else {
1356 printer->Print(
1357 variables: variables_,
1358 text: "$name$_.add(\n"
1359 " input.readMessage($type$.$get_parser$, extensionRegistry));\n");
1360 }
1361}
1362
1363void RepeatedImmutableMessageFieldGenerator::GenerateParsingDoneCode(
1364 io::Printer* printer) const {
1365 printer->Print(
1366 variables: variables_,
1367 text: "if ($get_mutable_bit_parser$) {\n"
1368 " $name$_ = java.util.Collections.unmodifiableList($name$_);\n"
1369 "}\n");
1370}
1371
1372void RepeatedImmutableMessageFieldGenerator::GenerateSerializationCode(
1373 io::Printer* printer) const {
1374 printer->Print(variables: variables_,
1375 text: "for (int i = 0; i < $name$_.size(); i++) {\n"
1376 " output.write$group_or_message$($number$, $name$_.get(i));\n"
1377 "}\n");
1378}
1379
1380void RepeatedImmutableMessageFieldGenerator::GenerateSerializedSizeCode(
1381 io::Printer* printer) const {
1382 printer->Print(
1383 variables: variables_,
1384 text: "for (int i = 0; i < $name$_.size(); i++) {\n"
1385 " size += com.google.protobuf.CodedOutputStream\n"
1386 " .compute$group_or_message$Size($number$, $name$_.get(i));\n"
1387 "}\n");
1388}
1389
1390void RepeatedImmutableMessageFieldGenerator::GenerateEqualsCode(
1391 io::Printer* printer) const {
1392 printer->Print(
1393 variables: variables_,
1394 text: "if (!get$capitalized_name$List()\n"
1395 " .equals(other.get$capitalized_name$List())) return false;\n");
1396}
1397
1398void RepeatedImmutableMessageFieldGenerator::GenerateHashCode(
1399 io::Printer* printer) const {
1400 printer->Print(
1401 variables: variables_,
1402 text: "if (get$capitalized_name$Count() > 0) {\n"
1403 " hash = (37 * hash) + $constant_name$;\n"
1404 " hash = (53 * hash) + get$capitalized_name$List().hashCode();\n"
1405 "}\n");
1406}
1407
1408std::string RepeatedImmutableMessageFieldGenerator::GetBoxedType() const {
1409 return name_resolver_->GetImmutableClassName(descriptor: descriptor_->message_type());
1410}
1411
1412void RepeatedImmutableMessageFieldGenerator::GenerateKotlinDslMembers(
1413 io::Printer* printer) const {
1414 printer->Print(
1415 variables: variables_,
1416 text: "/**\n"
1417 " * An uninstantiable, behaviorless type to represent the field in\n"
1418 " * generics.\n"
1419 " */\n"
1420 "@kotlin.OptIn"
1421 "(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)\n"
1422 "class ${$$kt_capitalized_name$Proxy$}$ private constructor()"
1423 " : com.google.protobuf.kotlin.DslProxy()\n");
1424
1425 WriteFieldDocComment(printer, field: descriptor_);
1426 printer->Print(variables: variables_,
1427 text: "$kt_deprecation$ val $kt_name$: "
1428 "com.google.protobuf.kotlin.DslList"
1429 "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>\n"
1430 " @kotlin.jvm.JvmSynthetic\n"
1431 " get() = com.google.protobuf.kotlin.DslList(\n"
1432 " $kt_dsl_builder$.${$get$capitalized_name$List$}$()\n"
1433 " )\n");
1434
1435 WriteFieldAccessorDocComment(printer, field: descriptor_, type: LIST_ADDER,
1436 /* builder */ false);
1437 printer->Print(variables: variables_,
1438 text: "@kotlin.jvm.JvmSynthetic\n"
1439 "@kotlin.jvm.JvmName(\"add$kt_capitalized_name$\")\n"
1440 "fun com.google.protobuf.kotlin.DslList"
1441 "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
1442 "add(value: $kt_type$) {\n"
1443 " $kt_dsl_builder$.${$add$capitalized_name$$}$(value)\n"
1444 "}\n");
1445
1446 WriteFieldAccessorDocComment(printer, field: descriptor_, type: LIST_ADDER,
1447 /* builder */ false);
1448 printer->Print(variables: variables_,
1449 text: "@kotlin.jvm.JvmSynthetic\n"
1450 "@kotlin.jvm.JvmName(\"plusAssign$kt_capitalized_name$\")\n"
1451 "@Suppress(\"NOTHING_TO_INLINE\")\n"
1452 "inline operator fun com.google.protobuf.kotlin.DslList"
1453 "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
1454 "plusAssign(value: $kt_type$) {\n"
1455 " add(value)\n"
1456 "}\n");
1457
1458 WriteFieldAccessorDocComment(printer, field: descriptor_, type: LIST_MULTI_ADDER,
1459 /* builder */ false);
1460 printer->Print(variables: variables_,
1461 text: "@kotlin.jvm.JvmSynthetic\n"
1462 "@kotlin.jvm.JvmName(\"addAll$kt_capitalized_name$\")\n"
1463 "fun com.google.protobuf.kotlin.DslList"
1464 "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
1465 "addAll(values: kotlin.collections.Iterable<$kt_type$>) {\n"
1466 " $kt_dsl_builder$.${$addAll$capitalized_name$$}$(values)\n"
1467 "}\n");
1468
1469 WriteFieldAccessorDocComment(printer, field: descriptor_, type: LIST_MULTI_ADDER,
1470 /* builder */ false);
1471 printer->Print(
1472 variables: variables_,
1473 text: "@kotlin.jvm.JvmSynthetic\n"
1474 "@kotlin.jvm.JvmName(\"plusAssignAll$kt_capitalized_name$\")\n"
1475 "@Suppress(\"NOTHING_TO_INLINE\")\n"
1476 "inline operator fun com.google.protobuf.kotlin.DslList"
1477 "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
1478 "plusAssign(values: kotlin.collections.Iterable<$kt_type$>) {\n"
1479 " addAll(values)\n"
1480 "}\n");
1481
1482 WriteFieldAccessorDocComment(printer, field: descriptor_, type: LIST_INDEXED_SETTER,
1483 /* builder */ false);
1484 printer->Print(
1485 variables: variables_,
1486 text: "@kotlin.jvm.JvmSynthetic\n"
1487 "@kotlin.jvm.JvmName(\"set$kt_capitalized_name$\")\n"
1488 "operator fun com.google.protobuf.kotlin.DslList"
1489 "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
1490 "set(index: kotlin.Int, value: $kt_type$) {\n"
1491 " $kt_dsl_builder$.${$set$capitalized_name$$}$(index, value)\n"
1492 "}\n");
1493
1494 WriteFieldAccessorDocComment(printer, field: descriptor_, type: CLEARER,
1495 /* builder */ false);
1496 printer->Print(variables: variables_,
1497 text: "@kotlin.jvm.JvmSynthetic\n"
1498 "@kotlin.jvm.JvmName(\"clear$kt_capitalized_name$\")\n"
1499 "fun com.google.protobuf.kotlin.DslList"
1500 "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
1501 "clear() {\n"
1502 " $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n"
1503 "}\n\n");
1504}
1505
1506} // namespace java
1507} // namespace compiler
1508} // namespace protobuf
1509} // namespace google
1510
1511#include <google/protobuf/port_undef.inc>
1512