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
47namespace google {
48namespace protobuf {
49namespace compiler {
50namespace java {
51
52namespace {
53
54void SetMessageVariables(const FieldDescriptor* descriptor,
55                         int messageBitIndex,
56                         int builderBitIndex,
57                         const FieldGeneratorInfo* info,
58                         ClassNameResolver* name_resolver,
59                         map<string, string>* variables) {
60  SetCommonFieldVariables(descriptor, info, variables);
61
62  (*variables)["type"] =
63      name_resolver->GetImmutableClassName(descriptor->message_type());
64  (*variables)["mutable_type"] =
65      name_resolver->GetMutableClassName(descriptor->message_type());
66  (*variables)["group_or_message"] =
67    (GetType(descriptor) == FieldDescriptor::TYPE_GROUP) ?
68    "Group" : "Message";
69  // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
70  // by the proto compiler
71  (*variables)["deprecation"] = descriptor->options().deprecated()
72      ? "@java.lang.Deprecated " : "";
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
106ImmutableMessageFieldLiteGenerator::
107ImmutableMessageFieldLiteGenerator(const FieldDescriptor* descriptor,
108                      int messageBitIndex,
109                      int builderBitIndex,
110                      Context* context)
111  : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
112    builderBitIndex_(builderBitIndex), context_(context),
113    name_resolver_(context->GetNameResolver()) {
114    SetMessageVariables(descriptor, messageBitIndex, builderBitIndex,
115                        context->GetFieldGeneratorInfo(descriptor),
116                        name_resolver_, &variables_);
117}
118
119ImmutableMessageFieldLiteGenerator::~ImmutableMessageFieldLiteGenerator() {}
120
121int ImmutableMessageFieldLiteGenerator::GetNumBitsForMessage() const {
122  return 1;
123}
124
125int ImmutableMessageFieldLiteGenerator::GetNumBitsForBuilder() const {
126  return 0;
127}
128
129void ImmutableMessageFieldLiteGenerator::
130GenerateInterfaceMembers(io::Printer* printer) const {
131  // TODO(jonp): In the future, consider having a method specific to the
132  // interface so that builders can choose dynamically to either return a
133  // message or a nested builder, so that asking for the interface doesn't
134  // cause a message to ever be built.
135  if (SupportFieldPresence(descriptor_->file()) ||
136      descriptor_->containing_oneof() == NULL) {
137    WriteFieldDocComment(printer, descriptor_);
138    printer->Print(variables_,
139      "$deprecation$boolean has$capitalized_name$();\n");
140  }
141  WriteFieldDocComment(printer, descriptor_);
142  printer->Print(variables_,
143    "$deprecation$$type$ get$capitalized_name$();\n");
144}
145
146void ImmutableMessageFieldLiteGenerator::
147GenerateMembers(io::Printer* printer) const {
148  printer->Print(variables_,
149    "private $type$ $name$_;\n");
150  PrintExtraFieldInfo(variables_, printer);
151
152  if (SupportFieldPresence(descriptor_->file())) {
153    WriteFieldDocComment(printer, descriptor_);
154    printer->Print(variables_,
155      "$deprecation$public boolean has$capitalized_name$() {\n"
156      "  return $get_has_field_bit_message$;\n"
157      "}\n");
158    WriteFieldDocComment(printer, descriptor_);
159    printer->Print(variables_,
160      "$deprecation$public $type$ get$capitalized_name$() {\n"
161      "  return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n"
162      "}\n");
163  } else {
164    WriteFieldDocComment(printer, descriptor_);
165    printer->Print(variables_,
166      "$deprecation$public boolean has$capitalized_name$() {\n"
167      "  return $name$_ != null;\n"
168      "}\n");
169    WriteFieldDocComment(printer, descriptor_);
170    printer->Print(variables_,
171      "$deprecation$public $type$ get$capitalized_name$() {\n"
172      "  return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n"
173      "}\n");
174  }
175
176  // Field.Builder setField(Field value)
177  WriteFieldDocComment(printer, descriptor_);
178  printer->Print(variables_,
179    "private void set$capitalized_name$($type$ value) {\n"
180    "  if (value == null) {\n"
181    "    throw new NullPointerException();\n"
182    "  }\n"
183    "  $name$_ = value;\n"
184    "  $set_has_field_bit_message$\n"
185    "  }\n");
186
187  // Field.Builder setField(Field.Builder builderForValue)
188  WriteFieldDocComment(printer, descriptor_);
189  printer->Print(variables_,
190    "private void set$capitalized_name$(\n"
191    "    $type$.Builder builderForValue) {\n"
192    "  $name$_ = builderForValue.build();\n"
193    "  $set_has_field_bit_message$\n"
194    "}\n");
195
196  // Field.Builder mergeField(Field value)
197  WriteFieldDocComment(printer, descriptor_);
198  printer->Print(variables_,
199    "private void merge$capitalized_name$($type$ value) {\n"
200    "  if ($name$_ != null &&\n"
201    "      $name$_ != $type$.getDefaultInstance()) {\n"
202    "    $name$_ =\n"
203    "      $type$.newBuilder($name$_).mergeFrom(value).buildPartial();\n"
204    "  } else {\n"
205    "    $name$_ = value;\n"
206    "  }\n"
207    "  $set_has_field_bit_message$\n"
208    "}\n");
209
210  // Field.Builder clearField()
211  WriteFieldDocComment(printer, descriptor_);
212  printer->Print(variables_,
213    "private void clear$capitalized_name$() {"
214    "  $name$_ = null;\n"
215    "  $clear_has_field_bit_message$\n"
216    "}\n");
217}
218
219void ImmutableMessageFieldLiteGenerator::
220GenerateBuilderMembers(io::Printer* printer) const {
221  // The comments above the methods below are based on a hypothetical
222  // field of type "Field" called "Field".
223
224  // boolean hasField()
225  WriteFieldDocComment(printer, descriptor_);
226  printer->Print(variables_,
227    "$deprecation$public boolean has$capitalized_name$() {\n"
228    "  return instance.has$capitalized_name$();\n"
229    "}\n");
230
231  // Field getField()
232  WriteFieldDocComment(printer, descriptor_);
233  printer->Print(variables_,
234    "$deprecation$public $type$ get$capitalized_name$() {\n"
235    "  return instance.get$capitalized_name$();\n"
236    "}\n");
237
238  // Field.Builder setField(Field value)
239  WriteFieldDocComment(printer, descriptor_);
240  printer->Print(variables_,
241    "$deprecation$public Builder set$capitalized_name$($type$ value) {\n"
242    "  copyOnWrite();\n"
243    "  instance.set$capitalized_name$(value);\n"
244    "  return this;\n"
245    "  }\n");
246
247  // Field.Builder setField(Field.Builder builderForValue)
248  WriteFieldDocComment(printer, descriptor_);
249  printer->Print(variables_,
250    "$deprecation$public Builder set$capitalized_name$(\n"
251    "    $type$.Builder builderForValue) {\n"
252    "  copyOnWrite();\n"
253    "  instance.set$capitalized_name$(builderForValue);\n"
254    "  return this;\n"
255    "}\n");
256
257  // Field.Builder mergeField(Field value)
258  WriteFieldDocComment(printer, descriptor_);
259  printer->Print(variables_,
260    "$deprecation$public Builder merge$capitalized_name$($type$ value) {\n"
261    "  copyOnWrite();\n"
262    "  instance.merge$capitalized_name$(value);\n"
263    "  return this;\n"
264    "}\n");
265
266  // Field.Builder clearField()
267  WriteFieldDocComment(printer, descriptor_);
268  printer->Print(variables_,
269    "$deprecation$public Builder clear$capitalized_name$() {"
270    "  copyOnWrite();\n"
271    "  instance.clear$capitalized_name$();\n"
272    "  return this;\n"
273    "}\n");
274}
275
276void ImmutableMessageFieldLiteGenerator::
277GenerateFieldBuilderInitializationCode(io::Printer* printer)  const {
278  if (SupportFieldPresence(descriptor_->file())) {
279    printer->Print(variables_,
280      "get$capitalized_name$FieldBuilder();\n");
281  }
282}
283
284
285void ImmutableMessageFieldLiteGenerator::
286GenerateInitializationCode(io::Printer* printer) const {}
287
288void ImmutableMessageFieldLiteGenerator::
289GenerateVisitCode(io::Printer* printer) const {
290  printer->Print(variables_,
291    "$name$_ = visitor.visitMessage($name$_, other.$name$_);\n");
292}
293
294void ImmutableMessageFieldLiteGenerator::
295GenerateDynamicMethodMakeImmutableCode(io::Printer* printer) const {
296  // noop for scalars
297}
298
299void ImmutableMessageFieldLiteGenerator::
300GenerateParsingCode(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
331void ImmutableMessageFieldLiteGenerator::
332GenerateParsingDoneCode(io::Printer* printer) const {
333  // noop for messages.
334}
335
336void ImmutableMessageFieldLiteGenerator::
337GenerateSerializationCode(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
344void ImmutableMessageFieldLiteGenerator::
345GenerateSerializedSizeCode(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
353void ImmutableMessageFieldLiteGenerator::
354GenerateEqualsCode(io::Printer* printer) const {
355  printer->Print(variables_,
356    "result = result && get$capitalized_name$()\n"
357    "    .equals(other.get$capitalized_name$());\n");
358}
359
360void ImmutableMessageFieldLiteGenerator::
361GenerateHashCode(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
367string ImmutableMessageFieldLiteGenerator::GetBoxedType() const {
368  return name_resolver_->GetImmutableClassName(descriptor_->message_type());
369}
370
371// ===================================================================
372
373ImmutableMessageOneofFieldLiteGenerator::
374ImmutableMessageOneofFieldLiteGenerator(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
385ImmutableMessageOneofFieldLiteGenerator::
386~ImmutableMessageOneofFieldLiteGenerator() {}
387
388void ImmutableMessageOneofFieldLiteGenerator::
389GenerateMembers(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
452void ImmutableMessageOneofFieldLiteGenerator::
453GenerateBuilderMembers(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
511void ImmutableMessageOneofFieldLiteGenerator::
512GenerateVisitCode(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
520void ImmutableMessageOneofFieldLiteGenerator::
521GenerateParsingCode(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
547void ImmutableMessageOneofFieldLiteGenerator::
548GenerateSerializationCode(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
555void ImmutableMessageOneofFieldLiteGenerator::
556GenerateSerializedSizeCode(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
566RepeatedImmutableMessageFieldLiteGenerator::
567RepeatedImmutableMessageFieldLiteGenerator(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
579RepeatedImmutableMessageFieldLiteGenerator::
580~RepeatedImmutableMessageFieldLiteGenerator() {}
581
582int RepeatedImmutableMessageFieldLiteGenerator::GetNumBitsForMessage() const {
583  return 0;
584}
585
586int RepeatedImmutableMessageFieldLiteGenerator::GetNumBitsForBuilder() const {
587  return 0;
588}
589
590void RepeatedImmutableMessageFieldLiteGenerator::
591GenerateInterfaceMembers(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
608void RepeatedImmutableMessageFieldLiteGenerator::
609GenerateMembers(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
737void RepeatedImmutableMessageFieldLiteGenerator::
738GenerateBuilderMembers(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
851void RepeatedImmutableMessageFieldLiteGenerator::
852GenerateFieldBuilderInitializationCode(io::Printer* printer)  const {
853  printer->Print(variables_,
854    "get$capitalized_name$FieldBuilder();\n");
855}
856
857void RepeatedImmutableMessageFieldLiteGenerator::
858GenerateInitializationCode(io::Printer* printer) const {
859  printer->Print(variables_, "$name$_ = emptyProtobufList();\n");
860}
861
862void RepeatedImmutableMessageFieldLiteGenerator::
863GenerateVisitCode(io::Printer* printer) const {
864  printer->Print(variables_,
865      "$name$_= visitor.visitList($name$_, other.$name$_);\n");
866}
867
868void RepeatedImmutableMessageFieldLiteGenerator::
869GenerateDynamicMethodMakeImmutableCode(io::Printer* printer) const {
870  printer->Print(variables_,
871    "$name$_.makeImmutable();\n");
872}
873
874void RepeatedImmutableMessageFieldLiteGenerator::
875GenerateParsingCode(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
893void RepeatedImmutableMessageFieldLiteGenerator::
894GenerateParsingDoneCode(io::Printer* printer) const {
895  printer->Print(variables_,
896    "if ($is_mutable$) {\n"
897    "  $name$_.makeImmutable();\n"
898    "}\n");
899}
900
901void RepeatedImmutableMessageFieldLiteGenerator::
902GenerateSerializationCode(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
909void RepeatedImmutableMessageFieldLiteGenerator::
910GenerateSerializedSizeCode(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
918void RepeatedImmutableMessageFieldLiteGenerator::
919GenerateEqualsCode(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
925void RepeatedImmutableMessageFieldLiteGenerator::
926GenerateHashCode(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
934string 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