• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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