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