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_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
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,map<string,string> * variables)54 void 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 " : "";
73
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
106 ImmutableMessageFieldLiteGenerator::
ImmutableMessageFieldLiteGenerator(const FieldDescriptor * descriptor,int messageBitIndex,int builderBitIndex,Context * context)107 ImmutableMessageFieldLiteGenerator(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
~ImmutableMessageFieldLiteGenerator()119 ImmutableMessageFieldLiteGenerator::~ImmutableMessageFieldLiteGenerator() {}
120
GetNumBitsForMessage() const121 int ImmutableMessageFieldLiteGenerator::GetNumBitsForMessage() const {
122 return 1;
123 }
124
GetNumBitsForBuilder() const125 int ImmutableMessageFieldLiteGenerator::GetNumBitsForBuilder() const {
126 return 0;
127 }
128
129 void ImmutableMessageFieldLiteGenerator::
GenerateInterfaceMembers(io::Printer * printer) const130 GenerateInterfaceMembers(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
146 void ImmutableMessageFieldLiteGenerator::
GenerateMembers(io::Printer * printer) const147 GenerateMembers(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
219 void ImmutableMessageFieldLiteGenerator::
GenerateBuilderMembers(io::Printer * printer) const220 GenerateBuilderMembers(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
276 void ImmutableMessageFieldLiteGenerator::
GenerateFieldBuilderInitializationCode(io::Printer * printer) const277 GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
278 if (SupportFieldPresence(descriptor_->file())) {
279 printer->Print(variables_,
280 "get$capitalized_name$FieldBuilder();\n");
281 }
282 }
283
284
285 void ImmutableMessageFieldLiteGenerator::
GenerateInitializationCode(io::Printer * printer) const286 GenerateInitializationCode(io::Printer* printer) const {}
287
288 void ImmutableMessageFieldLiteGenerator::
GenerateVisitCode(io::Printer * printer) const289 GenerateVisitCode(io::Printer* printer) const {
290 printer->Print(variables_,
291 "$name$_ = visitor.visitMessage($name$_, other.$name$_);\n");
292 }
293
294 void ImmutableMessageFieldLiteGenerator::
GenerateDynamicMethodMakeImmutableCode(io::Printer * printer) const295 GenerateDynamicMethodMakeImmutableCode(io::Printer* printer) const {
296 // noop for scalars
297 }
298
299 void ImmutableMessageFieldLiteGenerator::
GenerateParsingCode(io::Printer * printer) const300 GenerateParsingCode(io::Printer* printer) const {
301 // TODO(dweis): Update this code to avoid the builder allocation and instead
302 // only allocate a submessage that isn't made immutable. Rely on the top
303 // message calling makeImmutable once done to actually traverse the tree and
304 // finalize state. This will avoid:
305 // - transitive builder allocations
306 // - the extra transitive iteration for streamed fields
307 // - reallocations for copying repeated fields
308 printer->Print(variables_,
309 "$type$.Builder subBuilder = null;\n"
310 "if ($is_field_present_message$) {\n"
311 " subBuilder = $name$_.toBuilder();\n"
312 "}\n");
313
314 if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) {
315 printer->Print(variables_,
316 "$name$_ = input.readGroup($number$, $type$.parser(),\n"
317 " extensionRegistry);\n");
318 } else {
319 printer->Print(variables_,
320 "$name$_ = input.readMessage($type$.parser(), extensionRegistry);\n");
321 }
322
323 printer->Print(variables_,
324 "if (subBuilder != null) {\n"
325 " subBuilder.mergeFrom($name$_);\n"
326 " $name$_ = subBuilder.buildPartial();\n"
327 "}\n"
328 "$set_has_field_bit_message$\n");
329 }
330
331 void ImmutableMessageFieldLiteGenerator::
GenerateParsingDoneCode(io::Printer * printer) const332 GenerateParsingDoneCode(io::Printer* printer) const {
333 // noop for messages.
334 }
335
336 void ImmutableMessageFieldLiteGenerator::
GenerateSerializationCode(io::Printer * printer) const337 GenerateSerializationCode(io::Printer* printer) const {
338 printer->Print(variables_,
339 "if ($is_field_present_message$) {\n"
340 " output.write$group_or_message$($number$, get$capitalized_name$());\n"
341 "}\n");
342 }
343
344 void ImmutableMessageFieldLiteGenerator::
GenerateSerializedSizeCode(io::Printer * printer) const345 GenerateSerializedSizeCode(io::Printer* printer) const {
346 printer->Print(variables_,
347 "if ($is_field_present_message$) {\n"
348 " size += com.google.protobuf.CodedOutputStream\n"
349 " .compute$group_or_message$Size($number$, get$capitalized_name$());\n"
350 "}\n");
351 }
352
353 void ImmutableMessageFieldLiteGenerator::
GenerateEqualsCode(io::Printer * printer) const354 GenerateEqualsCode(io::Printer* printer) const {
355 printer->Print(variables_,
356 "result = result && get$capitalized_name$()\n"
357 " .equals(other.get$capitalized_name$());\n");
358 }
359
360 void ImmutableMessageFieldLiteGenerator::
GenerateHashCode(io::Printer * printer) const361 GenerateHashCode(io::Printer* printer) const {
362 printer->Print(variables_,
363 "hash = (37 * hash) + $constant_name$;\n"
364 "hash = (53 * hash) + get$capitalized_name$().hashCode();\n");
365 }
366
GetBoxedType() const367 string ImmutableMessageFieldLiteGenerator::GetBoxedType() const {
368 return name_resolver_->GetImmutableClassName(descriptor_->message_type());
369 }
370
371 // ===================================================================
372
373 ImmutableMessageOneofFieldLiteGenerator::
ImmutableMessageOneofFieldLiteGenerator(const FieldDescriptor * descriptor,int messageBitIndex,int builderBitIndex,Context * context)374 ImmutableMessageOneofFieldLiteGenerator(const FieldDescriptor* descriptor,
375 int messageBitIndex,
376 int builderBitIndex,
377 Context* context)
378 : ImmutableMessageFieldLiteGenerator(
379 descriptor, messageBitIndex, builderBitIndex, context) {
380 const OneofGeneratorInfo* info =
381 context->GetOneofGeneratorInfo(descriptor->containing_oneof());
382 SetCommonOneofVariables(descriptor, info, &variables_);
383 }
384
385 ImmutableMessageOneofFieldLiteGenerator::
~ImmutableMessageOneofFieldLiteGenerator()386 ~ImmutableMessageOneofFieldLiteGenerator() {}
387
388 void ImmutableMessageOneofFieldLiteGenerator::
GenerateMembers(io::Printer * printer) const389 GenerateMembers(io::Printer* printer) const {
390 PrintExtraFieldInfo(variables_, printer);
391 if (SupportFieldPresence(descriptor_->file())) {
392 WriteFieldDocComment(printer, descriptor_);
393 printer->Print(variables_,
394 "$deprecation$public boolean has$capitalized_name$() {\n"
395 " return $has_oneof_case_message$;\n"
396 "}\n");
397 }
398 WriteFieldDocComment(printer, descriptor_);
399 printer->Print(variables_,
400 "$deprecation$public $type$ get$capitalized_name$() {\n"
401 " if ($has_oneof_case_message$) {\n"
402 " return ($type$) $oneof_name$_;\n"
403 " }\n"
404 " return $type$.getDefaultInstance();\n"
405 "}\n");
406
407 // Field.Builder setField(Field value)
408 WriteFieldDocComment(printer, descriptor_);
409 printer->Print(variables_,
410 "private void set$capitalized_name$($type$ value) {\n"
411 " if (value == null) {\n"
412 " throw new NullPointerException();\n"
413 " }\n"
414 " $oneof_name$_ = value;\n"
415 " $set_oneof_case_message$;\n"
416 "}\n");
417
418 // Field.Builder setField(Field.Builder builderForValue)
419 WriteFieldDocComment(printer, descriptor_);
420 printer->Print(variables_,
421 "private void set$capitalized_name$(\n"
422 " $type$.Builder builderForValue) {\n"
423 " $oneof_name$_ = builderForValue.build();\n"
424 " $set_oneof_case_message$;\n"
425 "}\n");
426
427 // Field.Builder mergeField(Field value)
428 WriteFieldDocComment(printer, descriptor_);
429 printer->Print(variables_,
430 "private void merge$capitalized_name$($type$ value) {\n"
431 " if ($has_oneof_case_message$ &&\n"
432 " $oneof_name$_ != $type$.getDefaultInstance()) {\n"
433 " $oneof_name$_ = $type$.newBuilder(($type$) $oneof_name$_)\n"
434 " .mergeFrom(value).buildPartial();\n"
435 " } else {\n"
436 " $oneof_name$_ = value;\n"
437 " }\n"
438 " $set_oneof_case_message$;\n"
439 "}\n");
440
441 // Field.Builder clearField()
442 WriteFieldDocComment(printer, descriptor_);
443 printer->Print(variables_,
444 "private void clear$capitalized_name$() {\n"
445 " if ($has_oneof_case_message$) {\n"
446 " $clear_oneof_case_message$;\n"
447 " $oneof_name$_ = null;\n"
448 " }\n"
449 "}\n");
450 }
451
452 void ImmutableMessageOneofFieldLiteGenerator::
GenerateBuilderMembers(io::Printer * printer) const453 GenerateBuilderMembers(io::Printer* printer) const {
454 // The comments above the methods below are based on a hypothetical
455 // field of type "Field" called "Field".
456
457 if (SupportFieldPresence(descriptor_->file())) {
458 // boolean hasField()
459 WriteFieldDocComment(printer, descriptor_);
460 printer->Print(variables_,
461 "$deprecation$public boolean has$capitalized_name$() {\n"
462 " return instance.has$capitalized_name$();\n"
463 "}\n");
464 }
465
466 // Field getField()
467 WriteFieldDocComment(printer, descriptor_);
468 printer->Print(variables_,
469 "$deprecation$public $type$ get$capitalized_name$() {\n"
470 " return instance.get$capitalized_name$();\n"
471 "}\n");
472
473 // Field.Builder setField(Field value)
474 WriteFieldDocComment(printer, descriptor_);
475 printer->Print(variables_,
476 "$deprecation$public Builder set$capitalized_name$($type$ value) {\n"
477 " copyOnWrite();\n"
478 " instance.set$capitalized_name$(value);\n"
479 " return this;\n"
480 "}\n");
481
482 // Field.Builder setField(Field.Builder builderForValue)
483 WriteFieldDocComment(printer, descriptor_);
484 printer->Print(variables_,
485 "$deprecation$public Builder set$capitalized_name$(\n"
486 " $type$.Builder builderForValue) {\n"
487 " copyOnWrite();\n"
488 " instance.set$capitalized_name$(builderForValue);\n"
489 " return this;\n"
490 "}\n");
491
492 // Field.Builder mergeField(Field value)
493 WriteFieldDocComment(printer, descriptor_);
494 printer->Print(variables_,
495 "$deprecation$public Builder merge$capitalized_name$($type$ value) {\n"
496 " copyOnWrite();\n"
497 " instance.merge$capitalized_name$(value);\n"
498 " return this;\n"
499 "}\n");
500
501 // Field.Builder clearField()
502 WriteFieldDocComment(printer, descriptor_);
503 printer->Print(variables_,
504 "$deprecation$public Builder clear$capitalized_name$() {\n"
505 " copyOnWrite();\n"
506 " instance.clear$capitalized_name$();\n"
507 " return this;\n"
508 "}\n");
509 }
510
511 void ImmutableMessageOneofFieldLiteGenerator::
GenerateVisitCode(io::Printer * printer) const512 GenerateVisitCode(io::Printer* printer) const {
513 printer->Print(variables_,
514 "$oneof_name$_ = visitor.visitOneofMessage(\n"
515 " $has_oneof_case_message$,\n"
516 " $oneof_name$_,\n"
517 " other.$oneof_name$_);\n");
518 }
519
520 void ImmutableMessageOneofFieldLiteGenerator::
GenerateParsingCode(io::Printer * printer) const521 GenerateParsingCode(io::Printer* printer) const {
522 printer->Print(variables_,
523 "$type$.Builder subBuilder = null;\n"
524 "if ($has_oneof_case_message$) {\n"
525 " subBuilder = (($type$) $oneof_name$_).toBuilder();\n"
526 "}\n");
527
528 if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) {
529 printer->Print(variables_,
530 "$oneof_name$_ = input.readGroup($number$, $type$.parser(),\n"
531 " extensionRegistry);\n");
532 } else {
533 printer->Print(variables_,
534 "$oneof_name$_ =\n"
535 " input.readMessage($type$.parser(), extensionRegistry);\n");
536 }
537
538 printer->Print(variables_,
539 "if (subBuilder != null) {\n"
540 " subBuilder.mergeFrom(($type$) $oneof_name$_);\n"
541 " $oneof_name$_ = subBuilder.buildPartial();\n"
542 "}\n");
543 printer->Print(variables_,
544 "$set_oneof_case_message$;\n");
545 }
546
547 void ImmutableMessageOneofFieldLiteGenerator::
GenerateSerializationCode(io::Printer * printer) const548 GenerateSerializationCode(io::Printer* printer) const {
549 printer->Print(variables_,
550 "if ($has_oneof_case_message$) {\n"
551 " output.write$group_or_message$($number$, ($type$) $oneof_name$_);\n"
552 "}\n");
553 }
554
555 void ImmutableMessageOneofFieldLiteGenerator::
GenerateSerializedSizeCode(io::Printer * printer) const556 GenerateSerializedSizeCode(io::Printer* printer) const {
557 printer->Print(variables_,
558 "if ($has_oneof_case_message$) {\n"
559 " size += com.google.protobuf.CodedOutputStream\n"
560 " .compute$group_or_message$Size($number$, ($type$) $oneof_name$_);\n"
561 "}\n");
562 }
563
564 // ===================================================================
565
566 RepeatedImmutableMessageFieldLiteGenerator::
RepeatedImmutableMessageFieldLiteGenerator(const FieldDescriptor * descriptor,int messageBitIndex,int builderBitIndex,Context * context)567 RepeatedImmutableMessageFieldLiteGenerator(const FieldDescriptor* descriptor,
568 int messageBitIndex,
569 int builderBitIndex,
570 Context* context)
571 : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
572 builderBitIndex_(builderBitIndex), context_(context),
573 name_resolver_(context->GetNameResolver()) {
574 SetMessageVariables(descriptor, messageBitIndex, builderBitIndex,
575 context->GetFieldGeneratorInfo(descriptor),
576 name_resolver_, &variables_);
577 }
578
579 RepeatedImmutableMessageFieldLiteGenerator::
~RepeatedImmutableMessageFieldLiteGenerator()580 ~RepeatedImmutableMessageFieldLiteGenerator() {}
581
GetNumBitsForMessage() const582 int RepeatedImmutableMessageFieldLiteGenerator::GetNumBitsForMessage() const {
583 return 0;
584 }
585
GetNumBitsForBuilder() const586 int RepeatedImmutableMessageFieldLiteGenerator::GetNumBitsForBuilder() const {
587 return 0;
588 }
589
590 void RepeatedImmutableMessageFieldLiteGenerator::
GenerateInterfaceMembers(io::Printer * printer) const591 GenerateInterfaceMembers(io::Printer* printer) const {
592 // TODO(jonp): In the future, consider having methods specific to the
593 // interface so that builders can choose dynamically to either return a
594 // message or a nested builder, so that asking for the interface doesn't
595 // cause a message to ever be built.
596 WriteFieldDocComment(printer, descriptor_);
597 printer->Print(variables_,
598 "$deprecation$java.util.List<$type$> \n"
599 " get$capitalized_name$List();\n");
600 WriteFieldDocComment(printer, descriptor_);
601 printer->Print(variables_,
602 "$deprecation$$type$ get$capitalized_name$(int index);\n");
603 WriteFieldDocComment(printer, descriptor_);
604 printer->Print(variables_,
605 "$deprecation$int get$capitalized_name$Count();\n");
606 }
607
608 void RepeatedImmutableMessageFieldLiteGenerator::
GenerateMembers(io::Printer * printer) const609 GenerateMembers(io::Printer* printer) const {
610 printer->Print(variables_,
611 "private com.google.protobuf.Internal.ProtobufList<$type$> $name$_;\n");
612 PrintExtraFieldInfo(variables_, printer);
613 WriteFieldDocComment(printer, descriptor_);
614 printer->Print(variables_,
615 "$deprecation$public java.util.List<$type$> get$capitalized_name$List() {\n"
616 " return $name$_;\n" // note: unmodifiable list
617 "}\n");
618 WriteFieldDocComment(printer, descriptor_);
619 printer->Print(variables_,
620 "$deprecation$public java.util.List<? extends $type$OrBuilder> \n"
621 " get$capitalized_name$OrBuilderList() {\n"
622 " return $name$_;\n"
623 "}\n");
624 WriteFieldDocComment(printer, descriptor_);
625 printer->Print(variables_,
626 "$deprecation$public int get$capitalized_name$Count() {\n"
627 " return $name$_.size();\n"
628 "}\n");
629 WriteFieldDocComment(printer, descriptor_);
630 printer->Print(variables_,
631 "$deprecation$public $type$ get$capitalized_name$(int index) {\n"
632 " return $name$_.get(index);\n"
633 "}\n");
634 WriteFieldDocComment(printer, descriptor_);
635 printer->Print(variables_,
636 "$deprecation$public $type$OrBuilder get$capitalized_name$OrBuilder(\n"
637 " int index) {\n"
638 " return $name$_.get(index);\n"
639 "}\n");
640
641 printer->Print(variables_,
642 "private void ensure$capitalized_name$IsMutable() {\n"
643 " if (!$is_mutable$) {\n"
644 " $name$_ =\n"
645 " com.google.protobuf.GeneratedMessageLite.mutableCopy($name$_);\n"
646 " }\n"
647 "}\n"
648 "\n");
649
650 // Builder setRepeatedField(int index, Field value)
651 WriteFieldDocComment(printer, descriptor_);
652 printer->Print(variables_,
653 "private void set$capitalized_name$(\n"
654 " int index, $type$ value) {\n"
655 " if (value == null) {\n"
656 " throw new NullPointerException();\n"
657 " }\n"
658 " ensure$capitalized_name$IsMutable();\n"
659 " $name$_.set(index, value);\n"
660 "}\n");
661
662 // Builder setRepeatedField(int index, Field.Builder builderForValue)
663 WriteFieldDocComment(printer, descriptor_);
664 printer->Print(variables_,
665 "private void set$capitalized_name$(\n"
666 " int index, $type$.Builder builderForValue) {\n"
667 " ensure$capitalized_name$IsMutable();\n"
668 " $name$_.set(index, builderForValue.build());\n"
669 "}\n");
670
671 // Builder addRepeatedField(Field value)
672 WriteFieldDocComment(printer, descriptor_);
673 printer->Print(variables_,
674 "private void add$capitalized_name$($type$ value) {\n"
675 " if (value == null) {\n"
676 " throw new NullPointerException();\n"
677 " }\n"
678 " ensure$capitalized_name$IsMutable();\n"
679 " $name$_.add(value);\n"
680 "}\n");
681
682 // Builder addRepeatedField(int index, Field value)
683 WriteFieldDocComment(printer, descriptor_);
684 printer->Print(variables_,
685 "private void add$capitalized_name$(\n"
686 " int index, $type$ value) {\n"
687 " if (value == null) {\n"
688 " throw new NullPointerException();\n"
689 " }\n"
690 " ensure$capitalized_name$IsMutable();\n"
691 " $name$_.add(index, value);\n"
692 "}\n");
693 // Builder addRepeatedField(Field.Builder builderForValue)
694 WriteFieldDocComment(printer, descriptor_);
695 printer->Print(variables_,
696 "private void add$capitalized_name$(\n"
697 " $type$.Builder builderForValue) {\n"
698 " ensure$capitalized_name$IsMutable();\n"
699 " $name$_.add(builderForValue.build());\n"
700 "}\n");
701
702 // Builder addRepeatedField(int index, Field.Builder builderForValue)
703 WriteFieldDocComment(printer, descriptor_);
704 printer->Print(variables_,
705 "private void add$capitalized_name$(\n"
706 " int index, $type$.Builder builderForValue) {\n"
707 " ensure$capitalized_name$IsMutable();\n"
708 " $name$_.add(index, builderForValue.build());\n"
709 "}\n");
710
711 // Builder addAllRepeatedField(Iterable<Field> values)
712 WriteFieldDocComment(printer, descriptor_);
713 printer->Print(variables_,
714 "private void addAll$capitalized_name$(\n"
715 " java.lang.Iterable<? extends $type$> values) {\n"
716 " ensure$capitalized_name$IsMutable();\n"
717 " com.google.protobuf.AbstractMessageLite.addAll(\n"
718 " values, $name$_);\n"
719 "}\n");
720
721 // Builder clearAllRepeatedField()
722 WriteFieldDocComment(printer, descriptor_);
723 printer->Print(variables_,
724 "private void clear$capitalized_name$() {\n"
725 " $name$_ = emptyProtobufList();\n"
726 "}\n");
727
728 // Builder removeRepeatedField(int index)
729 WriteFieldDocComment(printer, descriptor_);
730 printer->Print(variables_,
731 "private void remove$capitalized_name$(int index) {\n"
732 " ensure$capitalized_name$IsMutable();\n"
733 " $name$_.remove(index);\n"
734 "}\n");
735 }
736
737 void RepeatedImmutableMessageFieldLiteGenerator::
GenerateBuilderMembers(io::Printer * printer) const738 GenerateBuilderMembers(io::Printer* printer) const {
739 // The comments above the methods below are based on a hypothetical
740 // repeated field of type "Field" called "RepeatedField".
741
742 // List<Field> getRepeatedFieldList()
743 WriteFieldDocComment(printer, descriptor_);
744 printer->Print(variables_,
745 "$deprecation$public java.util.List<$type$> get$capitalized_name$List() {\n"
746 " return java.util.Collections.unmodifiableList(\n"
747 " instance.get$capitalized_name$List());\n"
748 "}\n");
749
750 // int getRepeatedFieldCount()
751 WriteFieldDocComment(printer, descriptor_);
752 printer->Print(variables_,
753 "$deprecation$public int get$capitalized_name$Count() {\n"
754 " return instance.get$capitalized_name$Count();\n"
755 "}");
756
757 // Field getRepeatedField(int index)
758 WriteFieldDocComment(printer, descriptor_);
759 printer->Print(variables_,
760 "$deprecation$public $type$ get$capitalized_name$(int index) {\n"
761 " return instance.get$capitalized_name$(index);\n"
762 "}\n");
763
764 // Builder setRepeatedField(int index, Field value)
765 WriteFieldDocComment(printer, descriptor_);
766 printer->Print(variables_,
767 "$deprecation$public Builder set$capitalized_name$(\n"
768 " int index, $type$ value) {\n"
769 " copyOnWrite();\n"
770 " instance.set$capitalized_name$(index, value);\n"
771 " return this;\n"
772 "}\n");
773
774 // Builder setRepeatedField(int index, Field.Builder builderForValue)
775 WriteFieldDocComment(printer, descriptor_);
776 printer->Print(variables_,
777 "$deprecation$public Builder set$capitalized_name$(\n"
778 " int index, $type$.Builder builderForValue) {\n"
779 " copyOnWrite();\n"
780 " instance.set$capitalized_name$(index, builderForValue);\n"
781 " return this;\n"
782 "}\n");
783
784 // Builder addRepeatedField(Field value)
785 WriteFieldDocComment(printer, descriptor_);
786 printer->Print(variables_,
787 "$deprecation$public Builder add$capitalized_name$($type$ value) {\n"
788 " copyOnWrite();\n"
789 " instance.add$capitalized_name$(value);\n"
790 " return this;\n"
791 "}\n");
792
793 // Builder addRepeatedField(int index, Field value)
794 WriteFieldDocComment(printer, descriptor_);
795 printer->Print(variables_,
796 "$deprecation$public Builder add$capitalized_name$(\n"
797 " int index, $type$ value) {\n"
798 " copyOnWrite();\n"
799 " instance.add$capitalized_name$(index, value);\n"
800 " return this;\n"
801 "}\n");
802 // Builder addRepeatedField(Field.Builder builderForValue)
803 WriteFieldDocComment(printer, descriptor_);
804 printer->Print(variables_,
805 "$deprecation$public Builder add$capitalized_name$(\n"
806 " $type$.Builder builderForValue) {\n"
807 " copyOnWrite();\n"
808 " instance.add$capitalized_name$(builderForValue);\n"
809 " return this;\n"
810 "}\n");
811
812 // Builder addRepeatedField(int index, Field.Builder builderForValue)
813 WriteFieldDocComment(printer, descriptor_);
814 printer->Print(variables_,
815 "$deprecation$public Builder add$capitalized_name$(\n"
816 " int index, $type$.Builder builderForValue) {\n"
817 " copyOnWrite();\n"
818 " instance.add$capitalized_name$(index, builderForValue);\n"
819 " return this;\n"
820 "}\n");
821
822 // Builder addAllRepeatedField(Iterable<Field> values)
823 WriteFieldDocComment(printer, descriptor_);
824 printer->Print(variables_,
825 "$deprecation$public Builder addAll$capitalized_name$(\n"
826 " java.lang.Iterable<? extends $type$> values) {\n"
827 " copyOnWrite();\n"
828 " instance.addAll$capitalized_name$(values);\n"
829 " return this;\n"
830 "}\n");
831
832 // Builder clearAllRepeatedField()
833 WriteFieldDocComment(printer, descriptor_);
834 printer->Print(variables_,
835 "$deprecation$public Builder clear$capitalized_name$() {\n"
836 " copyOnWrite();\n"
837 " instance.clear$capitalized_name$();\n"
838 " return this;\n"
839 "}\n");
840
841 // Builder removeRepeatedField(int index)
842 WriteFieldDocComment(printer, descriptor_);
843 printer->Print(variables_,
844 "$deprecation$public Builder remove$capitalized_name$(int index) {\n"
845 " copyOnWrite();\n"
846 " instance.remove$capitalized_name$(index);\n"
847 " return this;\n"
848 "}\n");
849 }
850
851 void RepeatedImmutableMessageFieldLiteGenerator::
GenerateFieldBuilderInitializationCode(io::Printer * printer) const852 GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
853 printer->Print(variables_,
854 "get$capitalized_name$FieldBuilder();\n");
855 }
856
857 void RepeatedImmutableMessageFieldLiteGenerator::
GenerateInitializationCode(io::Printer * printer) const858 GenerateInitializationCode(io::Printer* printer) const {
859 printer->Print(variables_, "$name$_ = emptyProtobufList();\n");
860 }
861
862 void RepeatedImmutableMessageFieldLiteGenerator::
GenerateVisitCode(io::Printer * printer) const863 GenerateVisitCode(io::Printer* printer) const {
864 printer->Print(variables_,
865 "$name$_= visitor.visitList($name$_, other.$name$_);\n");
866 }
867
868 void RepeatedImmutableMessageFieldLiteGenerator::
GenerateDynamicMethodMakeImmutableCode(io::Printer * printer) const869 GenerateDynamicMethodMakeImmutableCode(io::Printer* printer) const {
870 printer->Print(variables_,
871 "$name$_.makeImmutable();\n");
872 }
873
874 void RepeatedImmutableMessageFieldLiteGenerator::
GenerateParsingCode(io::Printer * printer) const875 GenerateParsingCode(io::Printer* printer) const {
876 printer->Print(variables_,
877 "if (!$is_mutable$) {\n"
878 " $name$_ =\n"
879 " com.google.protobuf.GeneratedMessageLite.mutableCopy($name$_);\n"
880 "}\n");
881
882 if (GetType(descriptor_) == FieldDescriptor::TYPE_GROUP) {
883 printer->Print(variables_,
884 "$name$_.add(input.readGroup($number$, $type$.parser(),\n"
885 " extensionRegistry));\n");
886 } else {
887 printer->Print(variables_,
888 "$name$_.add(\n"
889 " input.readMessage($type$.parser(), extensionRegistry));\n");
890 }
891 }
892
893 void RepeatedImmutableMessageFieldLiteGenerator::
GenerateParsingDoneCode(io::Printer * printer) const894 GenerateParsingDoneCode(io::Printer* printer) const {
895 printer->Print(variables_,
896 "if ($is_mutable$) {\n"
897 " $name$_.makeImmutable();\n"
898 "}\n");
899 }
900
901 void RepeatedImmutableMessageFieldLiteGenerator::
GenerateSerializationCode(io::Printer * printer) const902 GenerateSerializationCode(io::Printer* printer) const {
903 printer->Print(variables_,
904 "for (int i = 0; i < $name$_.size(); i++) {\n"
905 " output.write$group_or_message$($number$, $name$_.get(i));\n"
906 "}\n");
907 }
908
909 void RepeatedImmutableMessageFieldLiteGenerator::
GenerateSerializedSizeCode(io::Printer * printer) const910 GenerateSerializedSizeCode(io::Printer* printer) const {
911 printer->Print(variables_,
912 "for (int i = 0; i < $name$_.size(); i++) {\n"
913 " size += com.google.protobuf.CodedOutputStream\n"
914 " .compute$group_or_message$Size($number$, $name$_.get(i));\n"
915 "}\n");
916 }
917
918 void RepeatedImmutableMessageFieldLiteGenerator::
GenerateEqualsCode(io::Printer * printer) const919 GenerateEqualsCode(io::Printer* printer) const {
920 printer->Print(variables_,
921 "result = result && get$capitalized_name$List()\n"
922 " .equals(other.get$capitalized_name$List());\n");
923 }
924
925 void RepeatedImmutableMessageFieldLiteGenerator::
GenerateHashCode(io::Printer * printer) const926 GenerateHashCode(io::Printer* printer) const {
927 printer->Print(variables_,
928 "if (get$capitalized_name$Count() > 0) {\n"
929 " hash = (37 * hash) + $constant_name$;\n"
930 " hash = (53 * hash) + get$capitalized_name$List().hashCode();\n"
931 "}\n");
932 }
933
GetBoxedType() const934 string RepeatedImmutableMessageFieldLiteGenerator::GetBoxedType() const {
935 return name_resolver_->GetImmutableClassName(descriptor_->message_type());
936 }
937
938 } // namespace java
939 } // namespace compiler
940 } // namespace protobuf
941 } // namespace google
942