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