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