• 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 <google/protobuf/compiler/java/java_primitive_field_lite.h>
36 
37 #include <map>
38 #include <string>
39 
40 #include <google/protobuf/stubs/logging.h>
41 #include <google/protobuf/stubs/common.h>
42 #include <google/protobuf/compiler/java/java_context.h>
43 #include <google/protobuf/compiler/java/java_doc_comment.h>
44 #include <google/protobuf/compiler/java/java_helpers.h>
45 #include <google/protobuf/compiler/java/java_name_resolver.h>
46 #include <google/protobuf/io/printer.h>
47 #include <google/protobuf/wire_format.h>
48 #include <google/protobuf/stubs/strutil.h>
49 
50 namespace google {
51 namespace protobuf {
52 namespace compiler {
53 namespace java {
54 
55 using internal::WireFormat;
56 using internal::WireFormatLite;
57 
58 namespace {
EnableExperimentalRuntimeForLite()59 bool EnableExperimentalRuntimeForLite() {
60 #ifdef PROTOBUF_EXPERIMENT
61   return PROTOBUF_EXPERIMENT;
62 #else   // PROTOBUF_EXPERIMENT
63   return false;
64 #endif  // !PROTOBUF_EXPERIMENT
65 }
66 
SetPrimitiveVariables(const FieldDescriptor * descriptor,int messageBitIndex,int builderBitIndex,const FieldGeneratorInfo * info,ClassNameResolver * name_resolver,std::map<std::string,std::string> * variables)67 void SetPrimitiveVariables(const FieldDescriptor* descriptor,
68                            int messageBitIndex, int builderBitIndex,
69                            const FieldGeneratorInfo* info,
70                            ClassNameResolver* name_resolver,
71                            std::map<std::string, std::string>* variables) {
72   SetCommonFieldVariables(descriptor, info, variables);
73   JavaType javaType = GetJavaType(descriptor);
74   (*variables)["type"] = PrimitiveTypeName(javaType);
75   (*variables)["boxed_type"] = BoxedPrimitiveTypeName(javaType);
76   (*variables)["field_type"] = (*variables)["type"];
77   (*variables)["default"] = ImmutableDefaultValue(descriptor, name_resolver);
78   (*variables)["capitalized_type"] =
79       GetCapitalizedType(descriptor, /* immutable = */ true);
80   (*variables)["tag"] =
81       StrCat(static_cast<int32>(WireFormat::MakeTag(descriptor)));
82   (*variables)["tag_size"] = StrCat(
83       WireFormat::TagSize(descriptor->number(), GetType(descriptor)));
84   (*variables)["required"] = descriptor->is_required() ? "true" : "false";
85 
86   std::string capitalized_type = UnderscoresToCamelCase(
87       PrimitiveTypeName(javaType), true /* cap_next_letter */);
88   switch (javaType) {
89     case JAVATYPE_INT:
90     case JAVATYPE_LONG:
91     case JAVATYPE_FLOAT:
92     case JAVATYPE_DOUBLE:
93     case JAVATYPE_BOOLEAN:
94       (*variables)["field_list_type"] =
95           "com.google.protobuf.Internal." + capitalized_type + "List";
96       (*variables)["empty_list"] = "empty" + capitalized_type + "List()";
97       (*variables)["make_name_unmodifiable"] =
98           (*variables)["name"] + "_.makeImmutable()";
99       (*variables)["repeated_get"] =
100           (*variables)["name"] + "_.get" + capitalized_type;
101       (*variables)["repeated_add"] =
102           (*variables)["name"] + "_.add" + capitalized_type;
103       (*variables)["repeated_set"] =
104           (*variables)["name"] + "_.set" + capitalized_type;
105       (*variables)["visit_type"] = capitalized_type;
106       (*variables)["visit_type_list"] = "visit" + capitalized_type + "List";
107       break;
108     default:
109       (*variables)["field_list_type"] =
110           "com.google.protobuf.Internal.ProtobufList<" +
111           (*variables)["boxed_type"] + ">";
112       (*variables)["empty_list"] = "emptyProtobufList()";
113       (*variables)["make_name_unmodifiable"] =
114           (*variables)["name"] + "_.makeImmutable()";
115       (*variables)["repeated_get"] = (*variables)["name"] + "_.get";
116       (*variables)["repeated_add"] = (*variables)["name"] + "_.add";
117       (*variables)["repeated_set"] = (*variables)["name"] + "_.set";
118       (*variables)["visit_type"] = "ByteString";
119       (*variables)["visit_type_list"] = "visitList";
120   }
121 
122   if (javaType == JAVATYPE_BYTES) {
123     (*variables)["bytes_default"] =
124         ToUpper((*variables)["name"]) + "_DEFAULT_VALUE";
125   }
126 
127   if (IsReferenceType(javaType)) {
128     // We use `x.getClass()` as a null check because it generates less bytecode
129     // than an `if (x == null) { throw ... }` statement.
130     (*variables)["null_check"] = "  value.getClass();\n";
131   } else {
132     (*variables)["null_check"] = "";
133   }
134   // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
135   // by the proto compiler
136   (*variables)["deprecation"] =
137       descriptor->options().deprecated() ? "@java.lang.Deprecated " : "";
138   int fixed_size = FixedSize(GetType(descriptor));
139   if (fixed_size != -1) {
140     (*variables)["fixed_size"] = StrCat(fixed_size);
141   }
142 
143   if (SupportFieldPresence(descriptor)) {
144     // For singular messages and builders, one bit is used for the hasField bit.
145     (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
146 
147     // Note that these have a trailing ";".
148     (*variables)["set_has_field_bit_message"] =
149         GenerateSetBit(messageBitIndex) + ";";
150     (*variables)["clear_has_field_bit_message"] =
151         GenerateClearBit(messageBitIndex) + ";";
152 
153     (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex);
154   } else {
155     (*variables)["set_has_field_bit_message"] = "";
156     (*variables)["set_has_field_bit_message"] = "";
157     (*variables)["clear_has_field_bit_message"] = "";
158 
159     if (descriptor->type() == FieldDescriptor::TYPE_BYTES) {
160       (*variables)["is_field_present_message"] =
161           "!" + (*variables)["name"] + "_.isEmpty()";
162     } else {
163       (*variables)["is_field_present_message"] =
164           (*variables)["name"] + "_ != " + (*variables)["default"];
165     }
166   }
167 
168   (*variables)["get_has_field_bit_from_local"] =
169       GenerateGetBitFromLocal(builderBitIndex);
170   (*variables)["set_has_field_bit_to_local"] =
171       GenerateSetBitToLocal(messageBitIndex);
172 }
173 
174 }  // namespace
175 
176 // ===================================================================
177 
ImmutablePrimitiveFieldLiteGenerator(const FieldDescriptor * descriptor,int messageBitIndex,Context * context)178 ImmutablePrimitiveFieldLiteGenerator::ImmutablePrimitiveFieldLiteGenerator(
179     const FieldDescriptor* descriptor, int messageBitIndex, Context* context)
180     : descriptor_(descriptor),
181       messageBitIndex_(messageBitIndex),
182       name_resolver_(context->GetNameResolver()) {
183   SetPrimitiveVariables(descriptor, messageBitIndex, 0,
184                         context->GetFieldGeneratorInfo(descriptor),
185                         name_resolver_, &variables_);
186 }
187 
~ImmutablePrimitiveFieldLiteGenerator()188 ImmutablePrimitiveFieldLiteGenerator::~ImmutablePrimitiveFieldLiteGenerator() {}
189 
GetNumBitsForMessage() const190 int ImmutablePrimitiveFieldLiteGenerator::GetNumBitsForMessage() const {
191   return SupportFieldPresence(descriptor_) ? 1 : 0;
192 }
193 
GenerateInterfaceMembers(io::Printer * printer) const194 void ImmutablePrimitiveFieldLiteGenerator::GenerateInterfaceMembers(
195     io::Printer* printer) const {
196   if (SupportFieldPresence(descriptor_)) {
197     WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
198     printer->Print(variables_,
199                    "$deprecation$boolean has$capitalized_name$();\n");
200   }
201   WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
202   printer->Print(variables_, "$deprecation$$type$ get$capitalized_name$();\n");
203 }
204 
GenerateMembers(io::Printer * printer) const205 void ImmutablePrimitiveFieldLiteGenerator::GenerateMembers(
206     io::Printer* printer) const {
207   if (IsByteStringWithCustomDefaultValue(descriptor_)) {
208     // allocate this once statically since we know ByteStrings are immutable
209     // values that can be reused.
210     printer->Print(
211         variables_,
212         "private static final $field_type$ $bytes_default$ = $default$;\n");
213   }
214   printer->Print(variables_, "private $field_type$ $name$_;\n");
215   PrintExtraFieldInfo(variables_, printer);
216   if (SupportFieldPresence(descriptor_)) {
217     WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
218     printer->Print(
219         variables_,
220         "@java.lang.Override\n"
221         "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
222         "  return $get_has_field_bit_message$;\n"
223         "}\n");
224     printer->Annotate("{", "}", descriptor_);
225   }
226 
227   WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
228   printer->Print(variables_,
229                  "@java.lang.Override\n"
230                  "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
231                  "  return $name$_;\n"
232                  "}\n");
233   printer->Annotate("{", "}", descriptor_);
234 
235   WriteFieldAccessorDocComment(printer, descriptor_, SETTER);
236   printer->Print(variables_,
237                  "private void set$capitalized_name$($type$ value) {\n"
238                  "$null_check$"
239                  "  $set_has_field_bit_message$\n"
240                  "  $name$_ = value;\n"
241                  "}\n");
242 
243   WriteFieldAccessorDocComment(printer, descriptor_, CLEARER);
244   printer->Print(variables_,
245                  "private void clear$capitalized_name$() {\n"
246                  "  $clear_has_field_bit_message$\n");
247   JavaType type = GetJavaType(descriptor_);
248   if (type == JAVATYPE_STRING || type == JAVATYPE_BYTES) {
249     // The default value is not a simple literal so we want to avoid executing
250     // it multiple times.  Instead, get the default out of the default instance.
251     printer->Print(
252         variables_,
253         "  $name$_ = getDefaultInstance().get$capitalized_name$();\n");
254   } else {
255     printer->Print(variables_, "  $name$_ = $default$;\n");
256   }
257   printer->Print(variables_, "}\n");
258 }
259 
GenerateBuilderMembers(io::Printer * printer) const260 void ImmutablePrimitiveFieldLiteGenerator::GenerateBuilderMembers(
261     io::Printer* printer) const {
262   if (SupportFieldPresence(descriptor_)) {
263     WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
264     printer->Print(
265         variables_,
266         "@java.lang.Override\n"
267         "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
268         "  return instance.has$capitalized_name$();\n"
269         "}\n");
270     printer->Annotate("{", "}", descriptor_);
271   }
272 
273   WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
274   printer->Print(variables_,
275                  "@java.lang.Override\n"
276                  "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
277                  "  return instance.get$capitalized_name$();\n"
278                  "}\n");
279   printer->Annotate("{", "}", descriptor_);
280 
281   WriteFieldAccessorDocComment(printer, descriptor_, SETTER,
282                                /* builder */ true);
283   printer->Print(variables_,
284                  "$deprecation$public Builder "
285                  "${$set$capitalized_name$$}$($type$ value) {\n"
286                  "  copyOnWrite();\n"
287                  "  instance.set$capitalized_name$(value);\n"
288                  "  return this;\n"
289                  "}\n");
290   printer->Annotate("{", "}", descriptor_);
291 
292   WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
293                                /* builder */ true);
294   printer->Print(
295       variables_,
296       "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
297       "  copyOnWrite();\n"
298       "  instance.clear$capitalized_name$();\n"
299       "  return this;\n"
300       "}\n");
301   printer->Annotate("{", "}", descriptor_);
302 }
303 
304 
GenerateFieldInfo(io::Printer * printer,std::vector<uint16> * output) const305 void ImmutablePrimitiveFieldLiteGenerator::GenerateFieldInfo(
306     io::Printer* printer, std::vector<uint16>* output) const {
307   WriteIntToUtf16CharSequence(descriptor_->number(), output);
308   WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_),
309                               output);
310   if (HasHasbit(descriptor_)) {
311     WriteIntToUtf16CharSequence(messageBitIndex_, output);
312   }
313   printer->Print(variables_, "\"$name$_\",\n");
314 }
315 
GenerateInitializationCode(io::Printer * printer) const316 void ImmutablePrimitiveFieldLiteGenerator::GenerateInitializationCode(
317     io::Printer* printer) const {
318   if (IsByteStringWithCustomDefaultValue(descriptor_)) {
319     printer->Print(variables_, "$name$_ = $bytes_default$;\n");
320   } else if (!IsDefaultValueJavaDefault(descriptor_)) {
321     printer->Print(variables_, "$name$_ = $default$;\n");
322   }
323 }
324 
GetBoxedType() const325 std::string ImmutablePrimitiveFieldLiteGenerator::GetBoxedType() const {
326   return BoxedPrimitiveTypeName(GetJavaType(descriptor_));
327 }
328 
329 // ===================================================================
330 
331 ImmutablePrimitiveOneofFieldLiteGenerator::
ImmutablePrimitiveOneofFieldLiteGenerator(const FieldDescriptor * descriptor,int messageBitIndex,Context * context)332     ImmutablePrimitiveOneofFieldLiteGenerator(const FieldDescriptor* descriptor,
333                                               int messageBitIndex,
334                                               Context* context)
335     : ImmutablePrimitiveFieldLiteGenerator(descriptor, messageBitIndex,
336                                            context) {
337   const OneofGeneratorInfo* info =
338       context->GetOneofGeneratorInfo(descriptor->containing_oneof());
339   SetCommonOneofVariables(descriptor, info, &variables_);
340 }
341 
342 ImmutablePrimitiveOneofFieldLiteGenerator::
~ImmutablePrimitiveOneofFieldLiteGenerator()343     ~ImmutablePrimitiveOneofFieldLiteGenerator() {}
344 
GenerateMembers(io::Printer * printer) const345 void ImmutablePrimitiveOneofFieldLiteGenerator::GenerateMembers(
346     io::Printer* printer) const {
347   PrintExtraFieldInfo(variables_, printer);
348   if (SupportFieldPresence(descriptor_)) {
349     WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
350     printer->Print(
351         variables_,
352         "@java.lang.Override\n"
353         "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
354         "  return $has_oneof_case_message$;\n"
355         "}\n");
356     printer->Annotate("{", "}", descriptor_);
357   }
358 
359   WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
360   printer->Print(variables_,
361                  "@java.lang.Override\n"
362                  "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
363                  "  if ($has_oneof_case_message$) {\n"
364                  "    return ($boxed_type$) $oneof_name$_;\n"
365                  "  }\n"
366                  "  return $default$;\n"
367                  "}\n");
368   printer->Annotate("{", "}", descriptor_);
369 
370   WriteFieldAccessorDocComment(printer, descriptor_, SETTER);
371   printer->Print(variables_,
372                  "private void set$capitalized_name$($type$ value) {\n"
373                  "$null_check$"
374                  "  $set_oneof_case_message$;\n"
375                  "  $oneof_name$_ = value;\n"
376                  "}\n");
377 
378   WriteFieldAccessorDocComment(printer, descriptor_, CLEARER);
379   printer->Print(variables_,
380                  "private void clear$capitalized_name$() {\n"
381                  "  if ($has_oneof_case_message$) {\n"
382                  "    $clear_oneof_case_message$;\n"
383                  "    $oneof_name$_ = null;\n"
384                  "  }\n"
385                  "}\n");
386 }
387 
GenerateFieldInfo(io::Printer * printer,std::vector<uint16> * output) const388 void ImmutablePrimitiveOneofFieldLiteGenerator::GenerateFieldInfo(
389     io::Printer* printer, std::vector<uint16>* output) const {
390   WriteIntToUtf16CharSequence(descriptor_->number(), output);
391   WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_),
392                               output);
393   WriteIntToUtf16CharSequence(descriptor_->containing_oneof()->index(), output);
394 }
395 
GenerateBuilderMembers(io::Printer * printer) const396 void ImmutablePrimitiveOneofFieldLiteGenerator::GenerateBuilderMembers(
397     io::Printer* printer) const {
398   if (SupportFieldPresence(descriptor_)) {
399     WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
400     printer->Print(
401         variables_,
402         "@java.lang.Override\n"
403         "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
404         "  return instance.has$capitalized_name$();\n"
405         "}\n");
406     printer->Annotate("{", "}", descriptor_);
407   }
408 
409   WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
410   printer->Print(variables_,
411                  "@java.lang.Override\n"
412                  "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
413                  "  return instance.get$capitalized_name$();\n"
414                  "}\n");
415   printer->Annotate("{", "}", descriptor_);
416 
417   WriteFieldAccessorDocComment(printer, descriptor_, SETTER,
418                                /* builder */ true);
419   printer->Print(variables_,
420                  "$deprecation$public Builder "
421                  "${$set$capitalized_name$$}$($type$ value) {\n"
422                  "  copyOnWrite();\n"
423                  "  instance.set$capitalized_name$(value);\n"
424                  "  return this;\n"
425                  "}\n");
426   printer->Annotate("{", "}", descriptor_);
427 
428   WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
429                                /* builder */ true);
430   printer->Print(
431       variables_,
432       "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
433       "  copyOnWrite();\n"
434       "  instance.clear$capitalized_name$();\n"
435       "  return this;\n"
436       "}\n");
437   printer->Annotate("{", "}", descriptor_);
438 }
439 
440 // ===================================================================
441 
442 RepeatedImmutablePrimitiveFieldLiteGenerator::
RepeatedImmutablePrimitiveFieldLiteGenerator(const FieldDescriptor * descriptor,int messageBitIndex,Context * context)443     RepeatedImmutablePrimitiveFieldLiteGenerator(
444         const FieldDescriptor* descriptor, int messageBitIndex,
445         Context* context)
446     : descriptor_(descriptor),
447       context_(context),
448       name_resolver_(context->GetNameResolver()) {
449   SetPrimitiveVariables(descriptor, messageBitIndex, 0,
450                         context->GetFieldGeneratorInfo(descriptor),
451                         name_resolver_, &variables_);
452 }
453 
454 RepeatedImmutablePrimitiveFieldLiteGenerator::
~RepeatedImmutablePrimitiveFieldLiteGenerator()455     ~RepeatedImmutablePrimitiveFieldLiteGenerator() {}
456 
GetNumBitsForMessage() const457 int RepeatedImmutablePrimitiveFieldLiteGenerator::GetNumBitsForMessage() const {
458   return 0;
459 }
460 
GenerateInterfaceMembers(io::Printer * printer) const461 void RepeatedImmutablePrimitiveFieldLiteGenerator::GenerateInterfaceMembers(
462     io::Printer* printer) const {
463   WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER);
464   printer->Print(variables_,
465                  "$deprecation$java.util.List<$boxed_type$> "
466                  "get$capitalized_name$List();\n");
467   WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT);
468   printer->Print(variables_,
469                  "$deprecation$int get$capitalized_name$Count();\n");
470   WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER);
471   printer->Print(variables_,
472                  "$deprecation$$type$ get$capitalized_name$(int index);\n");
473 }
474 
GenerateMembers(io::Printer * printer) const475 void RepeatedImmutablePrimitiveFieldLiteGenerator::GenerateMembers(
476     io::Printer* printer) const {
477   printer->Print(variables_, "private $field_list_type$ $name$_;\n");
478   PrintExtraFieldInfo(variables_, printer);
479   WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER);
480   printer->Print(variables_,
481                  "@java.lang.Override\n"
482                  "$deprecation$public java.util.List<$boxed_type$>\n"
483                  "    ${$get$capitalized_name$List$}$() {\n"
484                  "  return $name$_;\n"  // note:  unmodifiable list
485                  "}\n");
486   printer->Annotate("{", "}", descriptor_);
487   WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT);
488   printer->Print(
489       variables_,
490       "@java.lang.Override\n"
491       "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
492       "  return $name$_.size();\n"
493       "}\n");
494   printer->Annotate("{", "}", descriptor_);
495   WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER);
496   printer->Print(
497       variables_,
498       "@java.lang.Override\n"
499       "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n"
500       "  return $repeated_get$(index);\n"
501       "}\n");
502   printer->Annotate("{", "}", descriptor_);
503 
504   if (!EnableExperimentalRuntimeForLite() && descriptor_->is_packed() &&
505       context_->HasGeneratedMethods(descriptor_->containing_type())) {
506     printer->Print(variables_,
507                    "private int $name$MemoizedSerializedSize = -1;\n");
508   }
509 
510   printer->Print(
511       variables_,
512       "private void ensure$capitalized_name$IsMutable() {\n"
513       // Use a temporary to avoid a redundant iget-object.
514       "  $field_list_type$ tmp = $name$_;\n"
515       "  if (!tmp.isModifiable()) {\n"
516       "    $name$_ =\n"
517       "        com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);\n"
518       "   }\n"
519       "}\n");
520 
521   WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER);
522   printer->Print(variables_,
523                  "private void set$capitalized_name$(\n"
524                  "    int index, $type$ value) {\n"
525                  "$null_check$"
526                  "  ensure$capitalized_name$IsMutable();\n"
527                  "  $repeated_set$(index, value);\n"
528                  "}\n");
529   WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER);
530   printer->Print(variables_,
531                  "private void add$capitalized_name$($type$ value) {\n"
532                  "$null_check$"
533                  "  ensure$capitalized_name$IsMutable();\n"
534                  "  $repeated_add$(value);\n"
535                  "}\n");
536   WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER);
537   printer->Print(variables_,
538                  "private void addAll$capitalized_name$(\n"
539                  "    java.lang.Iterable<? extends $boxed_type$> values) {\n"
540                  "  ensure$capitalized_name$IsMutable();\n"
541                  "  com.google.protobuf.AbstractMessageLite.addAll(\n"
542                  "      values, $name$_);\n"
543                  "}\n");
544   WriteFieldAccessorDocComment(printer, descriptor_, CLEARER);
545   printer->Print(variables_,
546                  "private void clear$capitalized_name$() {\n"
547                  "  $name$_ = $empty_list$;\n"
548                  "}\n");
549 }
550 
GenerateBuilderMembers(io::Printer * printer) const551 void RepeatedImmutablePrimitiveFieldLiteGenerator::GenerateBuilderMembers(
552     io::Printer* printer) const {
553   WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER);
554   printer->Print(variables_,
555                  "@java.lang.Override\n"
556                  "$deprecation$public java.util.List<$boxed_type$>\n"
557                  "    ${$get$capitalized_name$List$}$() {\n"
558                  "  return java.util.Collections.unmodifiableList(\n"
559                  "      instance.get$capitalized_name$List());\n"
560                  "}\n");
561   printer->Annotate("{", "}", descriptor_);
562   WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT);
563   printer->Print(
564       variables_,
565       "@java.lang.Override\n"
566       "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
567       "  return instance.get$capitalized_name$Count();\n"
568       "}\n");
569   printer->Annotate("{", "}", descriptor_);
570   WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER);
571   printer->Print(
572       variables_,
573       "@java.lang.Override\n"
574       "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n"
575       "  return instance.get$capitalized_name$(index);\n"
576       "}\n");
577   printer->Annotate("{", "}", descriptor_);
578   WriteFieldAccessorDocComment(printer, descriptor_, SETTER,
579                                /* builder */ true);
580   printer->Print(variables_,
581                  "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
582                  "    int index, $type$ value) {\n"
583                  "  copyOnWrite();\n"
584                  "  instance.set$capitalized_name$(index, value);\n"
585                  "  return this;\n"
586                  "}\n");
587   printer->Annotate("{", "}", descriptor_);
588   WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER,
589                                /* builder */ true);
590   printer->Print(variables_,
591                  "$deprecation$public Builder "
592                  "${$add$capitalized_name$$}$($type$ value) {\n"
593                  "  copyOnWrite();\n"
594                  "  instance.add$capitalized_name$(value);\n"
595                  "  return this;\n"
596                  "}\n");
597   printer->Annotate("{", "}", descriptor_);
598   WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER,
599                                /* builder */ true);
600   printer->Print(variables_,
601                  "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n"
602                  "    java.lang.Iterable<? extends $boxed_type$> values) {\n"
603                  "  copyOnWrite();\n"
604                  "  instance.addAll$capitalized_name$(values);\n"
605                  "  return this;\n"
606                  "}\n");
607   printer->Annotate("{", "}", descriptor_);
608   WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
609                                /* builder */ true);
610   printer->Print(
611       variables_,
612       "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
613       "  copyOnWrite();\n"
614       "  instance.clear$capitalized_name$();\n"
615       "  return this;\n"
616       "}\n");
617   printer->Annotate("{", "}", descriptor_);
618 }
619 
GenerateFieldInfo(io::Printer * printer,std::vector<uint16> * output) const620 void RepeatedImmutablePrimitiveFieldLiteGenerator::GenerateFieldInfo(
621     io::Printer* printer, std::vector<uint16>* output) const {
622   WriteIntToUtf16CharSequence(descriptor_->number(), output);
623   WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_),
624                               output);
625   printer->Print(variables_, "\"$name$_\",\n");
626 }
627 
GenerateInitializationCode(io::Printer * printer) const628 void RepeatedImmutablePrimitiveFieldLiteGenerator::GenerateInitializationCode(
629     io::Printer* printer) const {
630   printer->Print(variables_, "$name$_ = $empty_list$;\n");
631 }
632 
GetBoxedType() const633 std::string RepeatedImmutablePrimitiveFieldLiteGenerator::GetBoxedType() const {
634   return BoxedPrimitiveTypeName(GetJavaType(descriptor_));
635 }
636 
637 }  // namespace java
638 }  // namespace compiler
639 }  // namespace protobuf
640 }  // namespace google
641