blob: 049679df971fb6e92b5862e55684a4b57ae74f74 [file] [log] [blame]
Bo Yang5db21732015-05-21 14:28:59 -07001// 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_message_field_lite.h>
40#include <google/protobuf/compiler/java/java_doc_comment.h>
41#include <google/protobuf/compiler/java/java_helpers.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
47namespace google {
48namespace protobuf {
49namespace compiler {
50namespace java {
51
52namespace {
53
54void SetMessageVariables(const FieldDescriptor* descriptor,
55 int messageBitIndex,
56 int builderBitIndex,
57 const FieldGeneratorInfo* info,
58 ClassNameResolver* name_resolver,
59 map<string, string>* variables) {
60 SetCommonFieldVariables(descriptor, info, variables);
61
62 (*variables)["type"] =
63 name_resolver->GetImmutableClassName(descriptor->message_type());
64 (*variables)["mutable_type"] =
65 name_resolver->GetMutableClassName(descriptor->message_type());
66 (*variables)["group_or_message"] =
67 (GetType(descriptor) == FieldDescriptor::TYPE_GROUP) ?
68 "Group" : "Message";
69 // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
70 // by the proto compiler
71 (*variables)["deprecation"] = descriptor->options().deprecated()
72 ? "@java.lang.Deprecated " : "";
Bo Yang5db21732015-05-21 14:28:59 -070073
74 if (SupportFieldPresence(descriptor->file())) {
75 // For singular messages and builders, one bit is used for the hasField bit.
76 (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
77
78 // Note that these have a trailing ";".
79 (*variables)["set_has_field_bit_message"] =
80 GenerateSetBit(messageBitIndex) + ";";
81 (*variables)["clear_has_field_bit_message"] =
82 GenerateClearBit(messageBitIndex) + ";";
83
84 (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex);
85 } else {
86 (*variables)["set_has_field_bit_message"] = "";
87 (*variables)["clear_has_field_bit_message"] = "";
88
89 (*variables)["is_field_present_message"] =
90 (*variables)["name"] + "_ != null";
91 }
92
93 // For repeated builders, the underlying list tracks mutability state.
94 (*variables)["is_mutable"] = (*variables)["name"] + "_.isModifiable()";
95
96 (*variables)["get_has_field_bit_from_local"] =
97 GenerateGetBitFromLocal(builderBitIndex);
98 (*variables)["set_has_field_bit_to_local"] =
99 GenerateSetBitToLocal(messageBitIndex);
100}
101
102} // namespace
103
104// ===================================================================
105
106ImmutableMessageFieldLiteGenerator::
107ImmutableMessageFieldLiteGenerator(const FieldDescriptor* descriptor,
108 int messageBitIndex,
109 int builderBitIndex,
110 Context* context)
111 : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
112 builderBitIndex_(builderBitIndex), context_(context),
113 name_resolver_(context->GetNameResolver()) {
114 SetMessageVariables(descriptor, messageBitIndex, builderBitIndex,
115 context->GetFieldGeneratorInfo(descriptor),
116 name_resolver_, &variables_);
117}
118
119ImmutableMessageFieldLiteGenerator::~ImmutableMessageFieldLiteGenerator() {}
120
121int ImmutableMessageFieldLiteGenerator::GetNumBitsForMessage() const {
122 return 1;
123}
124
125int ImmutableMessageFieldLiteGenerator::GetNumBitsForBuilder() const {
126 return 0;
127}
128
129void ImmutableMessageFieldLiteGenerator::
130GenerateInterfaceMembers(io::Printer* printer) const {
131 // TODO(jonp): In the future, consider having a method specific to the
132 // interface so that builders can choose dynamically to either return a
133 // message or a nested builder, so that asking for the interface doesn't
134 // cause a message to ever be built.
135 if (SupportFieldPresence(descriptor_->file()) ||
136 descriptor_->containing_oneof() == NULL) {
137 WriteFieldDocComment(printer, descriptor_);
138 printer->Print(variables_,
139 "$deprecation$boolean has$capitalized_name$();\n");
140 }
141 WriteFieldDocComment(printer, descriptor_);
142 printer->Print(variables_,
143 "$deprecation$$type$ get$capitalized_name$();\n");
144}
145
146void ImmutableMessageFieldLiteGenerator::
147GenerateMembers(io::Printer* printer) const {
148 printer->Print(variables_,
149 "private $type$ $name$_;\n");
150 PrintExtraFieldInfo(variables_, printer);
151
152 if (SupportFieldPresence(descriptor_->file())) {
153 WriteFieldDocComment(printer, descriptor_);
154 printer->Print(variables_,
155 "$deprecation$public boolean has$capitalized_name$() {\n"
156 " return $get_has_field_bit_message$;\n"
157 "}\n");
158 WriteFieldDocComment(printer, descriptor_);
159 printer->Print(variables_,
160 "$deprecation$public $type$ get$capitalized_name$() {\n"
161 " return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n"
162 "}\n");
163 } else {
164 WriteFieldDocComment(printer, descriptor_);
165 printer->Print(variables_,
166 "$deprecation$public boolean has$capitalized_name$() {\n"
167 " return $name$_ != null;\n"
168 "}\n");
169 WriteFieldDocComment(printer, descriptor_);
170 printer->Print(variables_,
171 "$deprecation$public $type$ get$capitalized_name$() {\n"
172 " return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n"
173 "}\n");
174 }
175
176 // Field.Builder setField(Field value)
177 WriteFieldDocComment(printer, descriptor_);
178 printer->Print(variables_,
179 "private void set$capitalized_name$($type$ value) {\n"
180 " if (value == null) {\n"
181 " throw new NullPointerException();\n"
182 " }\n"
183 " $name$_ = value;\n"
184 " $set_has_field_bit_message$\n"
185 " }\n");
186
187 // Field.Builder setField(Field.Builder builderForValue)
188 WriteFieldDocComment(printer, descriptor_);
189 printer->Print(variables_,
190 "private void set$capitalized_name$(\n"
191 " $type$.Builder builderForValue) {\n"
192 " $name$_ = builderForValue.build();\n"
193 " $set_has_field_bit_message$\n"
194 "}\n");
195
196 // Field.Builder mergeField(Field value)
197 WriteFieldDocComment(printer, descriptor_);
198 printer->Print(variables_,
199 "private void merge$capitalized_name$($type$ value) {\n"
200 " if ($name$_ != null &&\n"
201 " $name$_ != $type$.getDefaultInstance()) {\n"
202 " $name$_ =\n"
203 " $type$.newBuilder($name$_).mergeFrom(value).buildPartial();\n"
204 " } else {\n"
205 " $name$_ = value;\n"
206 " }\n"
207 " $set_has_field_bit_message$\n"
208 "}\n");
209
210 // Field.Builder clearField()
211 WriteFieldDocComment(printer, descriptor_);
212 printer->Print(variables_,
213 "private void clear$capitalized_name$() {"
214 " $name$_ = null;\n"
215 " $clear_has_field_bit_message$\n"
216 "}\n");
217}
218
219void ImmutableMessageFieldLiteGenerator::
220GenerateBuilderMembers(io::Printer* printer) const {
221 // The comments above the methods below are based on a hypothetical
222 // field of type "Field" called "Field".
223
224 // boolean hasField()
225 WriteFieldDocComment(printer, descriptor_);
226 printer->Print(variables_,
227 "$deprecation$public boolean has$capitalized_name$() {\n"
228 " return instance.has$capitalized_name$();\n"
229 "}\n");
230
231 // Field getField()
232 WriteFieldDocComment(printer, descriptor_);
233 printer->Print(variables_,
234 "$deprecation$public $type$ get$capitalized_name$() {\n"
235 " return instance.get$capitalized_name$();\n"
236 "}\n");
237
238 // Field.Builder setField(Field value)
239 WriteFieldDocComment(printer, descriptor_);
240 printer->Print(variables_,
241 "$deprecation$public Builder set$capitalized_name$($type$ value) {\n"
242 " copyOnWrite();\n"
243 " instance.set$capitalized_name$(value);\n"
244 " return this;\n"
245 " }\n");
246
247 // Field.Builder setField(Field.Builder builderForValue)
248 WriteFieldDocComment(printer, descriptor_);
249 printer->Print(variables_,
250 "$deprecation$public Builder set$capitalized_name$(\n"
251 " $type$.Builder builderForValue) {\n"
252 " copyOnWrite();\n"
253 " instance.set$capitalized_name$(builderForValue);\n"
254 " return this;\n"
255 "}\n");
256
257 // Field.Builder mergeField(Field value)
258 WriteFieldDocComment(printer, descriptor_);
259 printer->Print(variables_,
260 "$deprecation$public Builder merge$capitalized_name$($type$ value) {\n"
261 " copyOnWrite();\n"
262 " instance.merge$capitalized_name$(value);\n"
263 " return this;\n"
264 "}\n");
265
266 // Field.Builder clearField()
267 WriteFieldDocComment(printer, descriptor_);
268 printer->Print(variables_,
269 "$deprecation$public Builder clear$capitalized_name$() {"
270 " copyOnWrite();\n"
271 " instance.clear$capitalized_name$();\n"
272 " return this;\n"
273 "}\n");
274}
275
276void ImmutableMessageFieldLiteGenerator::
277GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
278 if (SupportFieldPresence(descriptor_->file())) {
279 printer->Print(variables_,
280 "get$capitalized_name$FieldBuilder();\n");
281 }
282}
283
284
285void ImmutableMessageFieldLiteGenerator::
286GenerateInitializationCode(io::Printer* printer) const {}
287
288void ImmutableMessageFieldLiteGenerator::
289GenerateMergingCode(io::Printer* printer) const {
290 printer->Print(variables_,
291 "if (other.has$capitalized_name$()) {\n"
292 " merge$capitalized_name$(other.get$capitalized_name$());\n"
293 "}\n");
294}
295
296void ImmutableMessageFieldLiteGenerator::
297GenerateDynamicMethodMakeImmutableCode(io::Printer* printer) const {
298 // noop for scalars
299}
300
301void ImmutableMessageFieldLiteGenerator::
302GenerateParsingCode(io::Printer* printer) const {
303 printer->Print(variables_,
304 "$type$.Builder subBuilder = null;\n"
305 "if ($is_field_present_message$) {\n"
306 " subBuilder = $name$_.toBuilder();\n"
307 "}\n");
308
309 if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) {
310 printer->Print(variables_,
Feng Xiaoeee38b02015-08-22 18:25:48 -0700311 "$name$_ = input.readGroup($number$, $type$.parser(),\n"
Bo Yang5db21732015-05-21 14:28:59 -0700312 " extensionRegistry);\n");
313 } else {
314 printer->Print(variables_,
Feng Xiaoeee38b02015-08-22 18:25:48 -0700315 "$name$_ = input.readMessage($type$.parser(), extensionRegistry);\n");
Bo Yang5db21732015-05-21 14:28:59 -0700316 }
317
318 printer->Print(variables_,
319 "if (subBuilder != null) {\n"
320 " subBuilder.mergeFrom($name$_);\n"
321 " $name$_ = subBuilder.buildPartial();\n"
322 "}\n"
323 "$set_has_field_bit_message$\n");
324}
325
326void ImmutableMessageFieldLiteGenerator::
327GenerateParsingDoneCode(io::Printer* printer) const {
328 // noop for messages.
329}
330
331void ImmutableMessageFieldLiteGenerator::
332GenerateSerializationCode(io::Printer* printer) const {
333 printer->Print(variables_,
334 "if ($is_field_present_message$) {\n"
335 " output.write$group_or_message$($number$, get$capitalized_name$());\n"
336 "}\n");
337}
338
339void ImmutableMessageFieldLiteGenerator::
340GenerateSerializedSizeCode(io::Printer* printer) const {
341 printer->Print(variables_,
342 "if ($is_field_present_message$) {\n"
343 " size += com.google.protobuf.CodedOutputStream\n"
344 " .compute$group_or_message$Size($number$, get$capitalized_name$());\n"
345 "}\n");
346}
347
348void ImmutableMessageFieldLiteGenerator::
349GenerateEqualsCode(io::Printer* printer) const {
350 printer->Print(variables_,
351 "result = result && get$capitalized_name$()\n"
352 " .equals(other.get$capitalized_name$());\n");
353}
354
355void ImmutableMessageFieldLiteGenerator::
356GenerateHashCode(io::Printer* printer) const {
357 printer->Print(variables_,
358 "hash = (37 * hash) + $constant_name$;\n"
359 "hash = (53 * hash) + get$capitalized_name$().hashCode();\n");
360}
361
362string ImmutableMessageFieldLiteGenerator::GetBoxedType() const {
363 return name_resolver_->GetImmutableClassName(descriptor_->message_type());
364}
365
366// ===================================================================
367
368ImmutableMessageOneofFieldLiteGenerator::
369ImmutableMessageOneofFieldLiteGenerator(const FieldDescriptor* descriptor,
370 int messageBitIndex,
371 int builderBitIndex,
372 Context* context)
373 : ImmutableMessageFieldLiteGenerator(
374 descriptor, messageBitIndex, builderBitIndex, context) {
375 const OneofGeneratorInfo* info =
376 context->GetOneofGeneratorInfo(descriptor->containing_oneof());
377 SetCommonOneofVariables(descriptor, info, &variables_);
378}
379
380ImmutableMessageOneofFieldLiteGenerator::
381~ImmutableMessageOneofFieldLiteGenerator() {}
382
383void ImmutableMessageOneofFieldLiteGenerator::
384GenerateMembers(io::Printer* printer) const {
385 PrintExtraFieldInfo(variables_, printer);
386 if (SupportFieldPresence(descriptor_->file())) {
387 WriteFieldDocComment(printer, descriptor_);
388 printer->Print(variables_,
389 "$deprecation$public boolean has$capitalized_name$() {\n"
390 " return $has_oneof_case_message$;\n"
391 "}\n");
392 }
393 WriteFieldDocComment(printer, descriptor_);
394 printer->Print(variables_,
395 "$deprecation$public $type$ get$capitalized_name$() {\n"
396 " if ($has_oneof_case_message$) {\n"
397 " return ($type$) $oneof_name$_;\n"
398 " }\n"
399 " return $type$.getDefaultInstance();\n"
400 "}\n");
401
402 // Field.Builder setField(Field value)
403 WriteFieldDocComment(printer, descriptor_);
404 printer->Print(variables_,
405 "private void set$capitalized_name$($type$ value) {\n"
406 " if (value == null) {\n"
407 " throw new NullPointerException();\n"
408 " }\n"
409 " $oneof_name$_ = value;\n"
410 " $set_oneof_case_message$;\n"
411 "}\n");
412
413 // Field.Builder setField(Field.Builder builderForValue)
414 WriteFieldDocComment(printer, descriptor_);
415 printer->Print(variables_,
416 "private void set$capitalized_name$(\n"
417 " $type$.Builder builderForValue) {\n"
418 " $oneof_name$_ = builderForValue.build();\n"
419 " $set_oneof_case_message$;\n"
420 "}\n");
421
422 // Field.Builder mergeField(Field value)
423 WriteFieldDocComment(printer, descriptor_);
424 printer->Print(variables_,
425 "private void merge$capitalized_name$($type$ value) {\n"
426 " if ($has_oneof_case_message$ &&\n"
427 " $oneof_name$_ != $type$.getDefaultInstance()) {\n"
428 " $oneof_name$_ = $type$.newBuilder(($type$) $oneof_name$_)\n"
429 " .mergeFrom(value).buildPartial();\n"
430 " } else {\n"
431 " $oneof_name$_ = value;\n"
432 " }\n"
433 " $set_oneof_case_message$;\n"
434 "}\n");
435
436 // Field.Builder clearField()
437 WriteFieldDocComment(printer, descriptor_);
438 printer->Print(variables_,
439 "private void clear$capitalized_name$() {\n"
440 " if ($has_oneof_case_message$) {\n"
441 " $clear_oneof_case_message$;\n"
442 " $oneof_name$_ = null;\n"
443 " }\n"
444 "}\n");
445}
446
447void ImmutableMessageOneofFieldLiteGenerator::
448GenerateBuilderMembers(io::Printer* printer) const {
449 // The comments above the methods below are based on a hypothetical
450 // field of type "Field" called "Field".
451
452 if (SupportFieldPresence(descriptor_->file())) {
453 // boolean hasField()
454 WriteFieldDocComment(printer, descriptor_);
455 printer->Print(variables_,
456 "$deprecation$public boolean has$capitalized_name$() {\n"
457 " return instance.has$capitalized_name$();\n"
458 "}\n");
459 }
460
461 // Field getField()
462 WriteFieldDocComment(printer, descriptor_);
463 printer->Print(variables_,
464 "$deprecation$public $type$ get$capitalized_name$() {\n"
465 " return instance.get$capitalized_name$();\n"
466 "}\n");
467
468 // Field.Builder setField(Field value)
469 WriteFieldDocComment(printer, descriptor_);
470 printer->Print(variables_,
471 "$deprecation$public Builder set$capitalized_name$($type$ value) {\n"
472 " copyOnWrite();\n"
473 " instance.set$capitalized_name$(value);\n"
474 " return this;\n"
475 "}\n");
476
477 // Field.Builder setField(Field.Builder builderForValue)
478 WriteFieldDocComment(printer, descriptor_);
479 printer->Print(variables_,
480 "$deprecation$public Builder set$capitalized_name$(\n"
481 " $type$.Builder builderForValue) {\n"
482 " copyOnWrite();\n"
483 " instance.set$capitalized_name$(builderForValue);\n"
484 " return this;\n"
485 "}\n");
486
487 // Field.Builder mergeField(Field value)
488 WriteFieldDocComment(printer, descriptor_);
489 printer->Print(variables_,
490 "$deprecation$public Builder merge$capitalized_name$($type$ value) {\n"
491 " copyOnWrite();\n"
492 " instance.merge$capitalized_name$(value);\n"
493 " return this;\n"
494 "}\n");
495
496 // Field.Builder clearField()
497 WriteFieldDocComment(printer, descriptor_);
498 printer->Print(variables_,
499 "$deprecation$public Builder clear$capitalized_name$() {\n"
500 " copyOnWrite();\n"
501 " instance.clear$capitalized_name$();\n"
502 " return this;\n"
503 "}\n");
504}
505
506void ImmutableMessageOneofFieldLiteGenerator::
507GenerateMergingCode(io::Printer* printer) const {
508 printer->Print(variables_,
509 "merge$capitalized_name$(other.get$capitalized_name$());\n");
510}
511
512void ImmutableMessageOneofFieldLiteGenerator::
513GenerateParsingCode(io::Printer* printer) const {
514 printer->Print(variables_,
515 "$type$.Builder subBuilder = null;\n"
516 "if ($has_oneof_case_message$) {\n"
517 " subBuilder = (($type$) $oneof_name$_).toBuilder();\n"
518 "}\n");
519
520 if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) {
521 printer->Print(variables_,
Feng Xiaoeee38b02015-08-22 18:25:48 -0700522 "$oneof_name$_ = input.readGroup($number$, $type$.parser(),\n"
Bo Yang5db21732015-05-21 14:28:59 -0700523 " extensionRegistry);\n");
524 } else {
525 printer->Print(variables_,
Feng Xiaoeee38b02015-08-22 18:25:48 -0700526 "$oneof_name$_ =\n"
527 " input.readMessage($type$.parser(), extensionRegistry);\n");
Bo Yang5db21732015-05-21 14:28:59 -0700528 }
529
530 printer->Print(variables_,
531 "if (subBuilder != null) {\n"
532 " subBuilder.mergeFrom(($type$) $oneof_name$_);\n"
533 " $oneof_name$_ = subBuilder.buildPartial();\n"
534 "}\n");
535 printer->Print(variables_,
536 "$set_oneof_case_message$;\n");
537}
538
539void ImmutableMessageOneofFieldLiteGenerator::
540GenerateSerializationCode(io::Printer* printer) const {
541 printer->Print(variables_,
542 "if ($has_oneof_case_message$) {\n"
543 " output.write$group_or_message$($number$, ($type$) $oneof_name$_);\n"
544 "}\n");
545}
546
547void ImmutableMessageOneofFieldLiteGenerator::
548GenerateSerializedSizeCode(io::Printer* printer) const {
549 printer->Print(variables_,
550 "if ($has_oneof_case_message$) {\n"
551 " size += com.google.protobuf.CodedOutputStream\n"
552 " .compute$group_or_message$Size($number$, ($type$) $oneof_name$_);\n"
553 "}\n");
554}
555
556// ===================================================================
557
558RepeatedImmutableMessageFieldLiteGenerator::
559RepeatedImmutableMessageFieldLiteGenerator(const FieldDescriptor* descriptor,
560 int messageBitIndex,
561 int builderBitIndex,
562 Context* context)
563 : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
564 builderBitIndex_(builderBitIndex), context_(context),
565 name_resolver_(context->GetNameResolver()) {
566 SetMessageVariables(descriptor, messageBitIndex, builderBitIndex,
567 context->GetFieldGeneratorInfo(descriptor),
568 name_resolver_, &variables_);
569}
570
571RepeatedImmutableMessageFieldLiteGenerator::
572~RepeatedImmutableMessageFieldLiteGenerator() {}
573
574int RepeatedImmutableMessageFieldLiteGenerator::GetNumBitsForMessage() const {
575 return 0;
576}
577
578int RepeatedImmutableMessageFieldLiteGenerator::GetNumBitsForBuilder() const {
579 return 0;
580}
581
582void RepeatedImmutableMessageFieldLiteGenerator::
583GenerateInterfaceMembers(io::Printer* printer) const {
584 // TODO(jonp): In the future, consider having methods specific to the
585 // interface so that builders can choose dynamically to either return a
586 // message or a nested builder, so that asking for the interface doesn't
587 // cause a message to ever be built.
588 WriteFieldDocComment(printer, descriptor_);
589 printer->Print(variables_,
590 "$deprecation$java.util.List<$type$> \n"
591 " get$capitalized_name$List();\n");
592 WriteFieldDocComment(printer, descriptor_);
593 printer->Print(variables_,
594 "$deprecation$$type$ get$capitalized_name$(int index);\n");
595 WriteFieldDocComment(printer, descriptor_);
596 printer->Print(variables_,
597 "$deprecation$int get$capitalized_name$Count();\n");
598}
599
600void RepeatedImmutableMessageFieldLiteGenerator::
601GenerateMembers(io::Printer* printer) const {
602 printer->Print(variables_,
603 "private com.google.protobuf.Internal.ProtobufList<$type$> $name$_;\n");
604 PrintExtraFieldInfo(variables_, printer);
605 WriteFieldDocComment(printer, descriptor_);
606 printer->Print(variables_,
607 "$deprecation$public java.util.List<$type$> get$capitalized_name$List() {\n"
608 " return $name$_;\n" // note: unmodifiable list
609 "}\n");
610 WriteFieldDocComment(printer, descriptor_);
611 printer->Print(variables_,
612 "$deprecation$public java.util.List<? extends $type$OrBuilder> \n"
613 " get$capitalized_name$OrBuilderList() {\n"
614 " return $name$_;\n"
615 "}\n");
616 WriteFieldDocComment(printer, descriptor_);
617 printer->Print(variables_,
618 "$deprecation$public int get$capitalized_name$Count() {\n"
619 " return $name$_.size();\n"
620 "}\n");
621 WriteFieldDocComment(printer, descriptor_);
622 printer->Print(variables_,
623 "$deprecation$public $type$ get$capitalized_name$(int index) {\n"
624 " return $name$_.get(index);\n"
625 "}\n");
626 WriteFieldDocComment(printer, descriptor_);
627 printer->Print(variables_,
628 "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder(\n"
629 " int index) {\n"
630 " return $name$_.get(index);\n"
631 "}\n");
632
633 printer->Print(variables_,
634 "private void ensure$capitalized_name$IsMutable() {\n"
635 " if (!$is_mutable$) {\n"
636 " $name$_ = newProtobufList($name$_);\n"
637 " }\n"
638 "}\n"
639 "\n");
640
641 // Builder setRepeatedField(int index, Field value)
642 WriteFieldDocComment(printer, descriptor_);
643 printer->Print(variables_,
644 "private void set$capitalized_name$(\n"
645 " int index, $type$ value) {\n"
646 " if (value == null) {\n"
647 " throw new NullPointerException();\n"
648 " }\n"
649 " ensure$capitalized_name$IsMutable();\n"
650 " $name$_.set(index, value);\n"
651 "}\n");
652
653 // Builder setRepeatedField(int index, Field.Builder builderForValue)
654 WriteFieldDocComment(printer, descriptor_);
655 printer->Print(variables_,
656 "private void set$capitalized_name$(\n"
657 " int index, $type$.Builder builderForValue) {\n"
658 " ensure$capitalized_name$IsMutable();\n"
659 " $name$_.set(index, builderForValue.build());\n"
660 "}\n");
661
662 // Builder addRepeatedField(Field value)
663 WriteFieldDocComment(printer, descriptor_);
664 printer->Print(variables_,
665 "private void add$capitalized_name$($type$ value) {\n"
666 " if (value == null) {\n"
667 " throw new NullPointerException();\n"
668 " }\n"
669 " ensure$capitalized_name$IsMutable();\n"
670 " $name$_.add(value);\n"
671 "}\n");
672
673 // Builder addRepeatedField(int index, Field value)
674 WriteFieldDocComment(printer, descriptor_);
675 printer->Print(variables_,
676 "private void add$capitalized_name$(\n"
677 " int index, $type$ value) {\n"
678 " if (value == null) {\n"
679 " throw new NullPointerException();\n"
680 " }\n"
681 " ensure$capitalized_name$IsMutable();\n"
682 " $name$_.add(index, value);\n"
683 "}\n");
684 // Builder addRepeatedField(Field.Builder builderForValue)
685 WriteFieldDocComment(printer, descriptor_);
686 printer->Print(variables_,
687 "private void add$capitalized_name$(\n"
688 " $type$.Builder builderForValue) {\n"
689 " ensure$capitalized_name$IsMutable();\n"
690 " $name$_.add(builderForValue.build());\n"
691 "}\n");
692
693 // Builder addRepeatedField(int index, Field.Builder builderForValue)
694 WriteFieldDocComment(printer, descriptor_);
695 printer->Print(variables_,
696 "private void add$capitalized_name$(\n"
697 " int index, $type$.Builder builderForValue) {\n"
698 " ensure$capitalized_name$IsMutable();\n"
699 " $name$_.add(index, builderForValue.build());\n"
700 "}\n");
701
702 // Builder addAllRepeatedField(Iterable<Field> values)
703 WriteFieldDocComment(printer, descriptor_);
704 printer->Print(variables_,
705 "private void addAll$capitalized_name$(\n"
706 " java.lang.Iterable<? extends $type$> values) {\n"
707 " ensure$capitalized_name$IsMutable();\n"
708 " com.google.protobuf.AbstractMessageLite.addAll(\n"
709 " values, $name$_);\n"
710 "}\n");
711
712 // Builder clearAllRepeatedField()
713 WriteFieldDocComment(printer, descriptor_);
714 printer->Print(variables_,
715 "private void clear$capitalized_name$() {\n"
716 " $name$_ = emptyProtobufList();\n"
717 "}\n");
718
719 // Builder removeRepeatedField(int index)
720 WriteFieldDocComment(printer, descriptor_);
721 printer->Print(variables_,
722 "private void remove$capitalized_name$(int index) {\n"
723 " ensure$capitalized_name$IsMutable();\n"
724 " $name$_.remove(index);\n"
725 "}\n");
726}
727
728void RepeatedImmutableMessageFieldLiteGenerator::
729GenerateBuilderMembers(io::Printer* printer) const {
730 // The comments above the methods below are based on a hypothetical
731 // repeated field of type "Field" called "RepeatedField".
732
733 // List<Field> getRepeatedFieldList()
734 WriteFieldDocComment(printer, descriptor_);
735 printer->Print(variables_,
736 "$deprecation$public java.util.List<$type$> get$capitalized_name$List() {\n"
737 " return java.util.Collections.unmodifiableList(\n"
738 " instance.get$capitalized_name$List());\n"
739 "}\n");
740
741 // int getRepeatedFieldCount()
742 WriteFieldDocComment(printer, descriptor_);
743 printer->Print(variables_,
744 "$deprecation$public int get$capitalized_name$Count() {\n"
745 " return instance.get$capitalized_name$Count();\n"
746 "}");
747
748 // Field getRepeatedField(int index)
749 WriteFieldDocComment(printer, descriptor_);
750 printer->Print(variables_,
751 "$deprecation$public $type$ get$capitalized_name$(int index) {\n"
752 " return instance.get$capitalized_name$(index);\n"
753 "}\n");
754
755 // Builder setRepeatedField(int index, Field value)
756 WriteFieldDocComment(printer, descriptor_);
757 printer->Print(variables_,
758 "$deprecation$public Builder set$capitalized_name$(\n"
759 " int index, $type$ value) {\n"
760 " copyOnWrite();\n"
761 " instance.set$capitalized_name$(index, value);\n"
762 " return this;\n"
763 "}\n");
764
765 // Builder setRepeatedField(int index, Field.Builder builderForValue)
766 WriteFieldDocComment(printer, descriptor_);
767 printer->Print(variables_,
768 "$deprecation$public Builder set$capitalized_name$(\n"
769 " int index, $type$.Builder builderForValue) {\n"
770 " copyOnWrite();\n"
771 " instance.set$capitalized_name$(index, builderForValue);\n"
772 " return this;\n"
773 "}\n");
774
775 // Builder addRepeatedField(Field value)
776 WriteFieldDocComment(printer, descriptor_);
777 printer->Print(variables_,
778 "$deprecation$public Builder add$capitalized_name$($type$ value) {\n"
779 " copyOnWrite();\n"
780 " instance.add$capitalized_name$(value);\n"
781 " return this;\n"
782 "}\n");
783
784 // Builder addRepeatedField(int index, Field value)
785 WriteFieldDocComment(printer, descriptor_);
786 printer->Print(variables_,
787 "$deprecation$public Builder add$capitalized_name$(\n"
788 " int index, $type$ value) {\n"
789 " copyOnWrite();\n"
790 " instance.add$capitalized_name$(index, value);\n"
791 " return this;\n"
792 "}\n");
793 // Builder addRepeatedField(Field.Builder builderForValue)
794 WriteFieldDocComment(printer, descriptor_);
795 printer->Print(variables_,
796 "$deprecation$public Builder add$capitalized_name$(\n"
797 " $type$.Builder builderForValue) {\n"
798 " copyOnWrite();\n"
799 " instance.add$capitalized_name$(builderForValue);\n"
800 " return this;\n"
801 "}\n");
802
803 // Builder addRepeatedField(int index, Field.Builder builderForValue)
804 WriteFieldDocComment(printer, descriptor_);
805 printer->Print(variables_,
806 "$deprecation$public Builder add$capitalized_name$(\n"
807 " int index, $type$.Builder builderForValue) {\n"
808 " copyOnWrite();\n"
809 " instance.add$capitalized_name$(index, builderForValue);\n"
810 " return this;\n"
811 "}\n");
812
813 // Builder addAllRepeatedField(Iterable<Field> values)
814 WriteFieldDocComment(printer, descriptor_);
815 printer->Print(variables_,
816 "$deprecation$public Builder addAll$capitalized_name$(\n"
817 " java.lang.Iterable<? extends $type$> values) {\n"
818 " copyOnWrite();\n"
819 " instance.addAll$capitalized_name$(values);\n"
820 " return this;\n"
821 "}\n");
822
823 // Builder clearAllRepeatedField()
824 WriteFieldDocComment(printer, descriptor_);
825 printer->Print(variables_,
826 "$deprecation$public Builder clear$capitalized_name$() {\n"
827 " copyOnWrite();\n"
828 " instance.clear$capitalized_name$();\n"
829 " return this;\n"
830 "}\n");
831
832 // Builder removeRepeatedField(int index)
833 WriteFieldDocComment(printer, descriptor_);
834 printer->Print(variables_,
835 "$deprecation$public Builder remove$capitalized_name$(int index) {\n"
836 " copyOnWrite();\n"
837 " instance.remove$capitalized_name$(index);\n"
838 " return this;\n"
839 "}\n");
840}
841
842void RepeatedImmutableMessageFieldLiteGenerator::
843GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
844 printer->Print(variables_,
845 "get$capitalized_name$FieldBuilder();\n");
846}
847
848void RepeatedImmutableMessageFieldLiteGenerator::
849GenerateInitializationCode(io::Printer* printer) const {
850 printer->Print(variables_, "$name$_ = emptyProtobufList();\n");
851}
852
853void RepeatedImmutableMessageFieldLiteGenerator::
854GenerateMergingCode(io::Printer* printer) const {
855 // The code below does two optimizations (non-nested builder case):
856 // 1. If the other list is empty, there's nothing to do. This ensures we
857 // don't allocate a new array if we already have an immutable one.
858 // 2. If the other list is non-empty and our current list is empty, we can
859 // reuse the other list which is guaranteed to be immutable.
860 printer->Print(variables_,
861 "if (!other.$name$_.isEmpty()) {\n"
862 " if ($name$_.isEmpty()) {\n"
863 " $name$_ = other.$name$_;\n"
864 " } else {\n"
865 " ensure$capitalized_name$IsMutable();\n"
866 " $name$_.addAll(other.$name$_);\n"
867 " }\n"
Bo Yang5db21732015-05-21 14:28:59 -0700868 "}\n");
869}
870
871void RepeatedImmutableMessageFieldLiteGenerator::
872GenerateDynamicMethodMakeImmutableCode(io::Printer* printer) const {
873 printer->Print(variables_,
874 "$name$_.makeImmutable();\n");
875}
876
877void RepeatedImmutableMessageFieldLiteGenerator::
878GenerateParsingCode(io::Printer* printer) const {
879 printer->Print(variables_,
880 "if (!$is_mutable$) {\n"
881 " $name$_ = newProtobufList();\n"
882 "}\n");
883
884 if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) {
885 printer->Print(variables_,
Feng Xiaoeee38b02015-08-22 18:25:48 -0700886 "$name$_.add(input.readGroup($number$, $type$.parser(),\n"
Bo Yang5db21732015-05-21 14:28:59 -0700887 " extensionRegistry));\n");
888 } else {
889 printer->Print(variables_,
Feng Xiaoeee38b02015-08-22 18:25:48 -0700890 "$name$_.add(\n"
891 " input.readMessage($type$.parser(), extensionRegistry));\n");
Bo Yang5db21732015-05-21 14:28:59 -0700892 }
893}
894
895void RepeatedImmutableMessageFieldLiteGenerator::
896GenerateParsingDoneCode(io::Printer* printer) const {
897 printer->Print(variables_,
898 "if ($is_mutable$) {\n"
899 " $name$_.makeImmutable();\n"
900 "}\n");
901}
902
903void RepeatedImmutableMessageFieldLiteGenerator::
904GenerateSerializationCode(io::Printer* printer) const {
905 printer->Print(variables_,
906 "for (int i = 0; i < $name$_.size(); i++) {\n"
907 " output.write$group_or_message$($number$, $name$_.get(i));\n"
908 "}\n");
909}
910
911void RepeatedImmutableMessageFieldLiteGenerator::
912GenerateSerializedSizeCode(io::Printer* printer) const {
913 printer->Print(variables_,
914 "for (int i = 0; i < $name$_.size(); i++) {\n"
915 " size += com.google.protobuf.CodedOutputStream\n"
916 " .compute$group_or_message$Size($number$, $name$_.get(i));\n"
917 "}\n");
918}
919
920void RepeatedImmutableMessageFieldLiteGenerator::
921GenerateEqualsCode(io::Printer* printer) const {
922 printer->Print(variables_,
923 "result = result && get$capitalized_name$List()\n"
924 " .equals(other.get$capitalized_name$List());\n");
925}
926
927void RepeatedImmutableMessageFieldLiteGenerator::
928GenerateHashCode(io::Printer* printer) const {
929 printer->Print(variables_,
930 "if (get$capitalized_name$Count() > 0) {\n"
931 " hash = (37 * hash) + $constant_name$;\n"
932 " hash = (53 * hash) + get$capitalized_name$List().hashCode();\n"
933 "}\n");
934}
935
936string RepeatedImmutableMessageFieldLiteGenerator::GetBoxedType() const {
937 return name_resolver_->GetImmutableClassName(descriptor_->message_type());
938}
939
940} // namespace java
941} // namespace compiler
942} // namespace protobuf
943} // namespace google