• 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_doc_comment.h>
40 #include <google/protobuf/compiler/java/java_helpers.h>
41 #include <google/protobuf/compiler/java/java_message_field_lite.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,std::map<std::string,std::string> * variables)54 void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex,
55                          int builderBitIndex, const FieldGeneratorInfo* info,
56                          ClassNameResolver* name_resolver,
57                          std::map<std::string, std::string>* variables) {
58   SetCommonFieldVariables(descriptor, info, variables);
59 
60   (*variables)["type"] =
61       name_resolver->GetImmutableClassName(descriptor->message_type());
62   (*variables)["mutable_type"] =
63       name_resolver->GetMutableClassName(descriptor->message_type());
64   (*variables)["group_or_message"] =
65       (GetType(descriptor) == FieldDescriptor::TYPE_GROUP) ? "Group"
66                                                            : "Message";
67   // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
68   // by the proto compiler
69   (*variables)["deprecation"] =
70       descriptor->options().deprecated() ? "@java.lang.Deprecated " : "";
71   (*variables)["required"] = descriptor->is_required() ? "true" : "false";
72 
73   if (HasHasbit(descriptor)) {
74     // For singular messages and builders, one bit is used for the hasField bit.
75     (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
76 
77     // Note that these have a trailing ";".
78     (*variables)["set_has_field_bit_message"] =
79         GenerateSetBit(messageBitIndex) + ";";
80     (*variables)["clear_has_field_bit_message"] =
81         GenerateClearBit(messageBitIndex) + ";";
82 
83     (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex);
84   } else {
85     (*variables)["set_has_field_bit_message"] = "";
86     (*variables)["clear_has_field_bit_message"] = "";
87 
88     (*variables)["is_field_present_message"] =
89         (*variables)["name"] + "_ != null";
90   }
91 
92   (*variables)["get_has_field_bit_from_local"] =
93       GenerateGetBitFromLocal(builderBitIndex);
94   (*variables)["set_has_field_bit_to_local"] =
95       GenerateSetBitToLocal(messageBitIndex);
96 
97   // We use `x.getClass()` as a null check because it generates less bytecode
98   // than an `if (x == null) { throw ... }` statement.
99   (*variables)["null_check"] = "value.getClass();\n";
100 }
101 
102 }  // namespace
103 
104 // ===================================================================
105 
ImmutableMessageFieldLiteGenerator(const FieldDescriptor * descriptor,int messageBitIndex,Context * context)106 ImmutableMessageFieldLiteGenerator::ImmutableMessageFieldLiteGenerator(
107     const FieldDescriptor* descriptor, int messageBitIndex, Context* context)
108     : descriptor_(descriptor),
109       messageBitIndex_(messageBitIndex),
110       name_resolver_(context->GetNameResolver()) {
111   SetMessageVariables(descriptor, messageBitIndex, 0,
112                       context->GetFieldGeneratorInfo(descriptor),
113                       name_resolver_, &variables_);
114 }
115 
~ImmutableMessageFieldLiteGenerator()116 ImmutableMessageFieldLiteGenerator::~ImmutableMessageFieldLiteGenerator() {}
117 
GetNumBitsForMessage() const118 int ImmutableMessageFieldLiteGenerator::GetNumBitsForMessage() const {
119   // TODO(dweis): We don't need a has bit for messages as they have null
120   // sentinels and no user should be reflecting on this. We could save some
121   // bits by setting to 0 and updating the runtimes but this might come at a
122   // runtime performance cost since we can't memoize has-bit reads.
123   return HasHasbit(descriptor_) ? 1 : 0;
124 }
125 
GenerateInterfaceMembers(io::Printer * printer) const126 void ImmutableMessageFieldLiteGenerator::GenerateInterfaceMembers(
127     io::Printer* printer) const {
128   WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
129   printer->Print(variables_, "$deprecation$boolean has$capitalized_name$();\n");
130   WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
131   printer->Print(variables_, "$deprecation$$type$ get$capitalized_name$();\n");
132 }
133 
GenerateMembers(io::Printer * printer) const134 void ImmutableMessageFieldLiteGenerator::GenerateMembers(
135     io::Printer* printer) const {
136 
137   printer->Print(variables_, "private $type$ $name$_;\n");
138   PrintExtraFieldInfo(variables_, printer);
139 
140   if (HasHasbit(descriptor_)) {
141     WriteFieldDocComment(printer, descriptor_);
142     printer->Print(
143         variables_,
144         "@java.lang.Override\n"
145         "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
146         "  return $get_has_field_bit_message$;\n"
147         "}\n");
148     printer->Annotate("{", "}", descriptor_);
149     WriteFieldDocComment(printer, descriptor_);
150     printer->Print(
151         variables_,
152         "@java.lang.Override\n"
153         "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
154         "  return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n"
155         "}\n");
156     printer->Annotate("{", "}", descriptor_);
157   } else {
158     WriteFieldDocComment(printer, descriptor_);
159     printer->Print(
160         variables_,
161         "@java.lang.Override\n"
162         "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
163         "  return $name$_ != null;\n"
164         "}\n");
165     printer->Annotate("{", "}", descriptor_);
166     WriteFieldDocComment(printer, descriptor_);
167     printer->Print(
168         variables_,
169         "@java.lang.Override\n"
170         "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
171         "  return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n"
172         "}\n");
173     printer->Annotate("{", "}", descriptor_);
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                  "  $null_check$"
181                  "  $name$_ = value;\n"
182                  "  $set_has_field_bit_message$\n"
183                  "  }\n");
184 
185   // Field.Builder mergeField(Field value)
186   WriteFieldDocComment(printer, descriptor_);
187   printer->Print(
188       variables_,
189       "@java.lang.SuppressWarnings({\"ReferenceEquality\"})\n"
190       "private void merge$capitalized_name$($type$ value) {\n"
191       "  $null_check$"
192       "  if ($name$_ != null &&\n"
193       "      $name$_ != $type$.getDefaultInstance()) {\n"
194       "    $name$_ =\n"
195       "      $type$.newBuilder($name$_).mergeFrom(value).buildPartial();\n"
196       "  } else {\n"
197       "    $name$_ = value;\n"
198       "  }\n"
199       "  $set_has_field_bit_message$\n"
200       "}\n");
201 
202   // Field.Builder clearField()
203   WriteFieldDocComment(printer, descriptor_);
204   printer->Print(variables_,
205                  "private void clear$capitalized_name$() {"
206                  "  $name$_ = null;\n"
207                  "  $clear_has_field_bit_message$\n"
208                  "}\n");
209 }
210 
GenerateBuilderMembers(io::Printer * printer) const211 void ImmutableMessageFieldLiteGenerator::GenerateBuilderMembers(
212     io::Printer* printer) const {
213   // The comments above the methods below are based on a hypothetical
214   // field of type "Field" called "Field".
215 
216   // boolean hasField()
217   WriteFieldDocComment(printer, descriptor_);
218   printer->Print(variables_,
219                  "@java.lang.Override\n"
220                  "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
221                  "  return instance.has$capitalized_name$();\n"
222                  "}\n");
223   printer->Annotate("{", "}", descriptor_);
224 
225   // Field getField()
226   WriteFieldDocComment(printer, descriptor_);
227   printer->Print(variables_,
228                  "@java.lang.Override\n"
229                  "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
230                  "  return instance.get$capitalized_name$();\n"
231                  "}\n");
232   printer->Annotate("{", "}", descriptor_);
233 
234   // Field.Builder setField(Field value)
235   WriteFieldDocComment(printer, descriptor_);
236   printer->Print(variables_,
237                  "$deprecation$public Builder "
238                  "${$set$capitalized_name$$}$($type$ value) {\n"
239                  "  copyOnWrite();\n"
240                  "  instance.set$capitalized_name$(value);\n"
241                  "  return this;\n"
242                  "  }\n");
243   printer->Annotate("{", "}", descriptor_);
244 
245   // Field.Builder setField(Field.Builder builderForValue)
246   WriteFieldDocComment(printer, descriptor_);
247   printer->Print(variables_,
248                  "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
249                  "    $type$.Builder builderForValue) {\n"
250                  "  copyOnWrite();\n"
251                  "  instance.set$capitalized_name$(builderForValue.build());\n"
252                  "  return this;\n"
253                  "}\n");
254   printer->Annotate("{", "}", descriptor_);
255 
256   // Field.Builder mergeField(Field value)
257   WriteFieldDocComment(printer, descriptor_);
258   printer->Print(variables_,
259                  "$deprecation$public Builder "
260                  "${$merge$capitalized_name$$}$($type$ value) {\n"
261                  "  copyOnWrite();\n"
262                  "  instance.merge$capitalized_name$(value);\n"
263                  "  return this;\n"
264                  "}\n");
265   printer->Annotate("{", "}", descriptor_);
266 
267   // Field.Builder clearField()
268   WriteFieldDocComment(printer, descriptor_);
269   printer->Print(variables_,
270                  "$deprecation$public Builder ${$clear$capitalized_name$$}$() {"
271                  "  copyOnWrite();\n"
272                  "  instance.clear$capitalized_name$();\n"
273                  "  return this;\n"
274                  "}\n");
275   printer->Annotate("{", "}", descriptor_);
276 }
277 
GenerateFieldInfo(io::Printer * printer,std::vector<uint16> * output) const278 void ImmutableMessageFieldLiteGenerator::GenerateFieldInfo(
279     io::Printer* printer, std::vector<uint16>* output) const {
280   WriteIntToUtf16CharSequence(descriptor_->number(), output);
281   WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_),
282                               output);
283   if (HasHasbit(descriptor_)) {
284     WriteIntToUtf16CharSequence(messageBitIndex_, output);
285   }
286   printer->Print(variables_, "\"$name$_\",\n");
287 }
288 
GenerateInitializationCode(io::Printer * printer) const289 void ImmutableMessageFieldLiteGenerator::GenerateInitializationCode(
290     io::Printer* printer) const {}
291 
GetBoxedType() const292 std::string ImmutableMessageFieldLiteGenerator::GetBoxedType() const {
293   return name_resolver_->GetImmutableClassName(descriptor_->message_type());
294 }
295 
296 // ===================================================================
297 
298 ImmutableMessageOneofFieldLiteGenerator::
ImmutableMessageOneofFieldLiteGenerator(const FieldDescriptor * descriptor,int messageBitIndex,Context * context)299     ImmutableMessageOneofFieldLiteGenerator(const FieldDescriptor* descriptor,
300                                             int messageBitIndex,
301                                             Context* context)
302     : ImmutableMessageFieldLiteGenerator(descriptor, messageBitIndex, context) {
303   const OneofGeneratorInfo* info =
304       context->GetOneofGeneratorInfo(descriptor->containing_oneof());
305   SetCommonOneofVariables(descriptor, info, &variables_);
306 }
307 
308 ImmutableMessageOneofFieldLiteGenerator::
~ImmutableMessageOneofFieldLiteGenerator()309     ~ImmutableMessageOneofFieldLiteGenerator() {}
310 
GenerateMembers(io::Printer * printer) const311 void ImmutableMessageOneofFieldLiteGenerator::GenerateMembers(
312     io::Printer* printer) const {
313   PrintExtraFieldInfo(variables_, printer);
314   WriteFieldDocComment(printer, descriptor_);
315   printer->Print(variables_,
316                  "@java.lang.Override\n"
317                  "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
318                  "  return $has_oneof_case_message$;\n"
319                  "}\n");
320   printer->Annotate("{", "}", descriptor_);
321   WriteFieldDocComment(printer, descriptor_);
322   printer->Print(variables_,
323                  "@java.lang.Override\n"
324                  "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
325                  "  if ($has_oneof_case_message$) {\n"
326                  "     return ($type$) $oneof_name$_;\n"
327                  "  }\n"
328                  "  return $type$.getDefaultInstance();\n"
329                  "}\n");
330   printer->Annotate("{", "}", descriptor_);
331 
332   // Field.Builder setField(Field value)
333   WriteFieldDocComment(printer, descriptor_);
334   printer->Print(variables_,
335                  "private void set$capitalized_name$($type$ value) {\n"
336                  "  $null_check$"
337                  "  $oneof_name$_ = value;\n"
338                  "  $set_oneof_case_message$;\n"
339                  "}\n");
340 
341   // Field.Builder mergeField(Field value)
342   WriteFieldDocComment(printer, descriptor_);
343   printer->Print(
344       variables_,
345       "private void merge$capitalized_name$($type$ value) {\n"
346       "  $null_check$"
347       "  if ($has_oneof_case_message$ &&\n"
348       "      $oneof_name$_ != $type$.getDefaultInstance()) {\n"
349       "    $oneof_name$_ = $type$.newBuilder(($type$) $oneof_name$_)\n"
350       "        .mergeFrom(value).buildPartial();\n"
351       "  } else {\n"
352       "    $oneof_name$_ = value;\n"
353       "  }\n"
354       "  $set_oneof_case_message$;\n"
355       "}\n");
356 
357   // Field.Builder clearField()
358   WriteFieldDocComment(printer, descriptor_);
359   printer->Print(variables_,
360                  "private void clear$capitalized_name$() {\n"
361                  "  if ($has_oneof_case_message$) {\n"
362                  "    $clear_oneof_case_message$;\n"
363                  "    $oneof_name$_ = null;\n"
364                  "  }\n"
365                  "}\n");
366 }
367 
GenerateFieldInfo(io::Printer * printer,std::vector<uint16> * output) const368 void ImmutableMessageOneofFieldLiteGenerator::GenerateFieldInfo(
369     io::Printer* printer, std::vector<uint16>* output) const {
370   WriteIntToUtf16CharSequence(descriptor_->number(), output);
371   WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_),
372                               output);
373   WriteIntToUtf16CharSequence(descriptor_->containing_oneof()->index(), output);
374   printer->Print(variables_, "$oneof_stored_type$.class,\n");
375 }
376 
GenerateBuilderMembers(io::Printer * printer) const377 void ImmutableMessageOneofFieldLiteGenerator::GenerateBuilderMembers(
378     io::Printer* printer) const {
379   // The comments above the methods below are based on a hypothetical
380   // field of type "Field" called "Field".
381 
382   // boolean hasField()
383   WriteFieldDocComment(printer, descriptor_);
384   printer->Print(variables_,
385                  "@java.lang.Override\n"
386                  "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
387                  "  return instance.has$capitalized_name$();\n"
388                  "}\n");
389   printer->Annotate("{", "}", descriptor_);
390 
391   // Field getField()
392   WriteFieldDocComment(printer, descriptor_);
393   printer->Print(variables_,
394                  "@java.lang.Override\n"
395                  "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
396                  "  return instance.get$capitalized_name$();\n"
397                  "}\n");
398   printer->Annotate("{", "}", descriptor_);
399 
400   // Field.Builder setField(Field value)
401   WriteFieldDocComment(printer, descriptor_);
402   printer->Print(variables_,
403                  "$deprecation$public Builder "
404                  "${$set$capitalized_name$$}$($type$ value) {\n"
405                  "  copyOnWrite();\n"
406                  "  instance.set$capitalized_name$(value);\n"
407                  "  return this;\n"
408                  "}\n");
409   printer->Annotate("{", "}", descriptor_);
410 
411   // Field.Builder setField(Field.Builder builderForValue)
412   WriteFieldDocComment(printer, descriptor_);
413   printer->Print(variables_,
414                  "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
415                  "    $type$.Builder builderForValue) {\n"
416                  "  copyOnWrite();\n"
417                  "  instance.set$capitalized_name$(builderForValue.build());\n"
418                  "  return this;\n"
419                  "}\n");
420   printer->Annotate("{", "}", descriptor_);
421 
422   // Field.Builder mergeField(Field value)
423   WriteFieldDocComment(printer, descriptor_);
424   printer->Print(variables_,
425                  "$deprecation$public Builder "
426                  "${$merge$capitalized_name$$}$($type$ value) {\n"
427                  "  copyOnWrite();\n"
428                  "  instance.merge$capitalized_name$(value);\n"
429                  "  return this;\n"
430                  "}\n");
431   printer->Annotate("{", "}", descriptor_);
432 
433   // Field.Builder clearField()
434   WriteFieldDocComment(printer, descriptor_);
435   printer->Print(
436       variables_,
437       "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
438       "  copyOnWrite();\n"
439       "  instance.clear$capitalized_name$();\n"
440       "  return this;\n"
441       "}\n");
442   printer->Annotate("{", "}", descriptor_);
443 }
444 
445 // ===================================================================
446 
447 RepeatedImmutableMessageFieldLiteGenerator::
RepeatedImmutableMessageFieldLiteGenerator(const FieldDescriptor * descriptor,int messageBitIndex,Context * context)448     RepeatedImmutableMessageFieldLiteGenerator(
449         const FieldDescriptor* descriptor, int messageBitIndex,
450         Context* context)
451     : descriptor_(descriptor), name_resolver_(context->GetNameResolver()) {
452   SetMessageVariables(descriptor, messageBitIndex, 0,
453                       context->GetFieldGeneratorInfo(descriptor),
454                       name_resolver_, &variables_);
455 }
456 
457 RepeatedImmutableMessageFieldLiteGenerator::
~RepeatedImmutableMessageFieldLiteGenerator()458     ~RepeatedImmutableMessageFieldLiteGenerator() {}
459 
GetNumBitsForMessage() const460 int RepeatedImmutableMessageFieldLiteGenerator::GetNumBitsForMessage() const {
461   return 0;
462 }
463 
GenerateInterfaceMembers(io::Printer * printer) const464 void RepeatedImmutableMessageFieldLiteGenerator::GenerateInterfaceMembers(
465     io::Printer* printer) const {
466   // TODO(jonp): In the future, consider having methods specific to the
467   // interface so that builders can choose dynamically to either return a
468   // message or a nested builder, so that asking for the interface doesn't
469   // cause a message to ever be built.
470   WriteFieldDocComment(printer, descriptor_);
471   printer->Print(variables_,
472                  "$deprecation$java.util.List<$type$> \n"
473                  "    get$capitalized_name$List();\n");
474   WriteFieldDocComment(printer, descriptor_);
475   printer->Print(variables_,
476                  "$deprecation$$type$ get$capitalized_name$(int index);\n");
477   WriteFieldDocComment(printer, descriptor_);
478   printer->Print(variables_,
479                  "$deprecation$int get$capitalized_name$Count();\n");
480 }
481 
GenerateMembers(io::Printer * printer) const482 void RepeatedImmutableMessageFieldLiteGenerator::GenerateMembers(
483     io::Printer* printer) const {
484   printer->Print(
485       variables_,
486       "private com.google.protobuf.Internal.ProtobufList<$type$> $name$_;\n");
487   PrintExtraFieldInfo(variables_, printer);
488   WriteFieldDocComment(printer, descriptor_);
489   printer->Print(variables_,
490                  "@java.lang.Override\n"
491                  "$deprecation$public java.util.List<$type$> "
492                  "${$get$capitalized_name$List$}$() {\n"
493                  "  return $name$_;\n"  // note:  unmodifiable list
494                  "}\n");
495   printer->Annotate("{", "}", descriptor_);
496   WriteFieldDocComment(printer, descriptor_);
497   printer->Print(
498       variables_,
499       "$deprecation$public java.util.List<? extends $type$OrBuilder> \n"
500       "    ${$get$capitalized_name$OrBuilderList$}$() {\n"
501       "  return $name$_;\n"
502       "}\n");
503   printer->Annotate("{", "}", descriptor_);
504   WriteFieldDocComment(printer, descriptor_);
505   printer->Print(
506       variables_,
507       "@java.lang.Override\n"
508       "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
509       "  return $name$_.size();\n"
510       "}\n");
511   printer->Annotate("{", "}", descriptor_);
512   WriteFieldDocComment(printer, descriptor_);
513   printer->Print(
514       variables_,
515       "@java.lang.Override\n"
516       "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n"
517       "  return $name$_.get(index);\n"
518       "}\n");
519   printer->Annotate("{", "}", descriptor_);
520   WriteFieldDocComment(printer, descriptor_);
521   printer->Print(variables_,
522                  "$deprecation$public $type$OrBuilder "
523                  "${$get$capitalized_name$OrBuilder$}$(\n"
524                  "    int index) {\n"
525                  "  return $name$_.get(index);\n"
526                  "}\n");
527   printer->Annotate("{", "}", descriptor_);
528 
529   printer->Print(
530       variables_,
531       "private void ensure$capitalized_name$IsMutable() {\n"
532       // Use a temporary to avoid a redundant iget-object.
533       "  com.google.protobuf.Internal.ProtobufList<$type$> tmp = $name$_;\n"
534       "  if (!tmp.isModifiable()) {\n"
535       "    $name$_ =\n"
536       "        com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);\n"
537       "   }\n"
538       "}\n"
539       "\n");
540 
541   // Builder setRepeatedField(int index, Field value)
542   WriteFieldDocComment(printer, descriptor_);
543   printer->Print(variables_,
544                  "private void set$capitalized_name$(\n"
545                  "    int index, $type$ value) {\n"
546                  "  $null_check$"
547                  "  ensure$capitalized_name$IsMutable();\n"
548                  "  $name$_.set(index, value);\n"
549                  "}\n");
550 
551   // Builder addRepeatedField(Field value)
552   WriteFieldDocComment(printer, descriptor_);
553   printer->Print(variables_,
554                  "private void add$capitalized_name$($type$ value) {\n"
555                  "  $null_check$"
556                  "  ensure$capitalized_name$IsMutable();\n"
557                  "  $name$_.add(value);\n"
558                  "}\n");
559 
560   // Builder addRepeatedField(int index, Field value)
561   WriteFieldDocComment(printer, descriptor_);
562   printer->Print(variables_,
563                  "private void add$capitalized_name$(\n"
564                  "    int index, $type$ value) {\n"
565                  "  $null_check$"
566                  "  ensure$capitalized_name$IsMutable();\n"
567                  "  $name$_.add(index, value);\n"
568                  "}\n");
569 
570   // Builder addAllRepeatedField(Iterable<Field> values)
571   WriteFieldDocComment(printer, descriptor_);
572   printer->Print(variables_,
573                  "private void addAll$capitalized_name$(\n"
574                  "    java.lang.Iterable<? extends $type$> values) {\n"
575                  "  ensure$capitalized_name$IsMutable();\n"
576                  "  com.google.protobuf.AbstractMessageLite.addAll(\n"
577                  "      values, $name$_);\n"
578                  "}\n");
579 
580   // Builder clearAllRepeatedField()
581   WriteFieldDocComment(printer, descriptor_);
582   printer->Print(variables_,
583                  "private void clear$capitalized_name$() {\n"
584                  "  $name$_ = emptyProtobufList();\n"
585                  "}\n");
586 
587   // Builder removeRepeatedField(int index)
588   WriteFieldDocComment(printer, descriptor_);
589   printer->Print(variables_,
590                  "private void remove$capitalized_name$(int index) {\n"
591                  "  ensure$capitalized_name$IsMutable();\n"
592                  "  $name$_.remove(index);\n"
593                  "}\n");
594 }
595 
GenerateBuilderMembers(io::Printer * printer) const596 void RepeatedImmutableMessageFieldLiteGenerator::GenerateBuilderMembers(
597     io::Printer* printer) const {
598   // The comments above the methods below are based on a hypothetical
599   // repeated field of type "Field" called "RepeatedField".
600 
601   // List<Field> getRepeatedFieldList()
602   WriteFieldDocComment(printer, descriptor_);
603   printer->Print(variables_,
604                  "@java.lang.Override\n"
605                  "$deprecation$public java.util.List<$type$> "
606                  "${$get$capitalized_name$List$}$() {\n"
607                  "  return java.util.Collections.unmodifiableList(\n"
608                  "      instance.get$capitalized_name$List());\n"
609                  "}\n");
610   printer->Annotate("{", "}", descriptor_);
611 
612   // int getRepeatedFieldCount()
613   WriteFieldDocComment(printer, descriptor_);
614   printer->Print(
615       variables_,
616       "@java.lang.Override\n"
617       "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
618       "  return instance.get$capitalized_name$Count();\n"
619       "}");
620   printer->Annotate("{", "}", descriptor_);
621 
622   // Field getRepeatedField(int index)
623   WriteFieldDocComment(printer, descriptor_);
624   printer->Print(
625       variables_,
626       "@java.lang.Override\n"
627       "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n"
628       "  return instance.get$capitalized_name$(index);\n"
629       "}\n");
630   printer->Annotate("{", "}", descriptor_);
631 
632   // Builder setRepeatedField(int index, Field value)
633   WriteFieldDocComment(printer, descriptor_);
634   printer->Print(variables_,
635                  "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
636                  "    int index, $type$ value) {\n"
637                  "  copyOnWrite();\n"
638                  "  instance.set$capitalized_name$(index, value);\n"
639                  "  return this;\n"
640                  "}\n");
641   printer->Annotate("{", "}", descriptor_);
642 
643   // Builder setRepeatedField(int index, Field.Builder builderForValue)
644   WriteFieldDocComment(printer, descriptor_);
645   printer->Print(variables_,
646                  "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
647                  "    int index, $type$.Builder builderForValue) {\n"
648                  "  copyOnWrite();\n"
649                  "  instance.set$capitalized_name$(index,\n"
650                  "      builderForValue.build());\n"
651                  "  return this;\n"
652                  "}\n");
653   printer->Annotate("{", "}", descriptor_);
654 
655   // Builder addRepeatedField(Field value)
656   WriteFieldDocComment(printer, descriptor_);
657   printer->Print(variables_,
658                  "$deprecation$public Builder "
659                  "${$add$capitalized_name$$}$($type$ value) {\n"
660                  "  copyOnWrite();\n"
661                  "  instance.add$capitalized_name$(value);\n"
662                  "  return this;\n"
663                  "}\n");
664   printer->Annotate("{", "}", descriptor_);
665 
666   // Builder addRepeatedField(int index, Field value)
667   WriteFieldDocComment(printer, descriptor_);
668   printer->Print(variables_,
669                  "$deprecation$public Builder ${$add$capitalized_name$$}$(\n"
670                  "    int index, $type$ value) {\n"
671                  "  copyOnWrite();\n"
672                  "  instance.add$capitalized_name$(index, value);\n"
673                  "  return this;\n"
674                  "}\n");
675   printer->Annotate("{", "}", descriptor_);
676   // Builder addRepeatedField(Field.Builder builderForValue)
677   WriteFieldDocComment(printer, descriptor_);
678   printer->Print(variables_,
679                  "$deprecation$public Builder ${$add$capitalized_name$$}$(\n"
680                  "    $type$.Builder builderForValue) {\n"
681                  "  copyOnWrite();\n"
682                  "  instance.add$capitalized_name$(builderForValue.build());\n"
683                  "  return this;\n"
684                  "}\n");
685   printer->Annotate("{", "}", descriptor_);
686 
687   // Builder addRepeatedField(int index, Field.Builder builderForValue)
688   WriteFieldDocComment(printer, descriptor_);
689   printer->Print(variables_,
690                  "$deprecation$public Builder ${$add$capitalized_name$$}$(\n"
691                  "    int index, $type$.Builder builderForValue) {\n"
692                  "  copyOnWrite();\n"
693                  "  instance.add$capitalized_name$(index,\n"
694                  "      builderForValue.build());\n"
695                  "  return this;\n"
696                  "}\n");
697   printer->Annotate("{", "}", descriptor_);
698 
699   // Builder addAllRepeatedField(Iterable<Field> values)
700   WriteFieldDocComment(printer, descriptor_);
701   printer->Print(variables_,
702                  "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n"
703                  "    java.lang.Iterable<? extends $type$> values) {\n"
704                  "  copyOnWrite();\n"
705                  "  instance.addAll$capitalized_name$(values);\n"
706                  "  return this;\n"
707                  "}\n");
708   printer->Annotate("{", "}", descriptor_);
709 
710   // Builder clearAllRepeatedField()
711   WriteFieldDocComment(printer, descriptor_);
712   printer->Print(
713       variables_,
714       "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
715       "  copyOnWrite();\n"
716       "  instance.clear$capitalized_name$();\n"
717       "  return this;\n"
718       "}\n");
719   printer->Annotate("{", "}", descriptor_);
720 
721   // Builder removeRepeatedField(int index)
722   WriteFieldDocComment(printer, descriptor_);
723   printer->Print(variables_,
724                  "$deprecation$public Builder "
725                  "${$remove$capitalized_name$$}$(int index) {\n"
726                  "  copyOnWrite();\n"
727                  "  instance.remove$capitalized_name$(index);\n"
728                  "  return this;\n"
729                  "}\n");
730   printer->Annotate("{", "}", descriptor_);
731 }
732 
GenerateFieldInfo(io::Printer * printer,std::vector<uint16> * output) const733 void RepeatedImmutableMessageFieldLiteGenerator::GenerateFieldInfo(
734     io::Printer* printer, std::vector<uint16>* output) const {
735   WriteIntToUtf16CharSequence(descriptor_->number(), output);
736   WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_),
737                               output);
738   printer->Print(variables_,
739                  "\"$name$_\",\n"
740                  "$type$.class,\n");
741 }
742 
GenerateInitializationCode(io::Printer * printer) const743 void RepeatedImmutableMessageFieldLiteGenerator::GenerateInitializationCode(
744     io::Printer* printer) const {
745   printer->Print(variables_, "$name$_ = emptyProtobufList();\n");
746 }
747 
GetBoxedType() const748 std::string RepeatedImmutableMessageFieldLiteGenerator::GetBoxedType() const {
749   return name_resolver_->GetImmutableClassName(descriptor_->message_type());
750 }
751 
752 }  // namespace java
753 }  // namespace compiler
754 }  // namespace protobuf
755 }  // namespace google
756