• 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/stubs/logging.h>
39 #include <google/protobuf/stubs/common.h>
40 #include <google/protobuf/compiler/java/java_context.h>
41 #include <google/protobuf/compiler/java/java_doc_comment.h>
42 #include <google/protobuf/compiler/java/java_helpers.h>
43 #include <google/protobuf/compiler/java/java_name_resolver.h>
44 #include <google/protobuf/compiler/java/java_primitive_field_lite.h>
45 #include <google/protobuf/io/printer.h>
46 #include <google/protobuf/wire_format.h>
47 #include <google/protobuf/stubs/strutil.h>
48 
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     (*variables)["null_check"] =
129         "  if (value == null) {\n"
130         "    throw new NullPointerException();\n"
131         "  }\n";
132   } else {
133     (*variables)["null_check"] = "";
134   }
135   // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
136   // by the proto compiler
137   (*variables)["deprecation"] =
138       descriptor->options().deprecated() ? "@java.lang.Deprecated " : "";
139   int fixed_size = FixedSize(GetType(descriptor));
140   if (fixed_size != -1) {
141     (*variables)["fixed_size"] = StrCat(fixed_size);
142   }
143 
144   if (SupportFieldPresence(descriptor->file())) {
145     // For singular messages and builders, one bit is used for the hasField bit.
146     (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
147 
148     // Note that these have a trailing ";".
149     (*variables)["set_has_field_bit_message"] =
150         GenerateSetBit(messageBitIndex) + ";";
151     (*variables)["clear_has_field_bit_message"] =
152         GenerateClearBit(messageBitIndex) + ";";
153 
154     (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex);
155   } else {
156     (*variables)["set_has_field_bit_message"] = "";
157     (*variables)["set_has_field_bit_message"] = "";
158     (*variables)["clear_has_field_bit_message"] = "";
159 
160     if (descriptor->type() == FieldDescriptor::TYPE_BYTES) {
161       (*variables)["is_field_present_message"] =
162           "!" + (*variables)["name"] + "_.isEmpty()";
163     } else {
164       (*variables)["is_field_present_message"] =
165           (*variables)["name"] + "_ != " + (*variables)["default"];
166     }
167   }
168 
169   // For repeated builders, the underlying list tracks mutability state.
170   (*variables)["is_mutable"] = (*variables)["name"] + "_.isModifiable()";
171 
172   (*variables)["get_has_field_bit_from_local"] =
173       GenerateGetBitFromLocal(builderBitIndex);
174   (*variables)["set_has_field_bit_to_local"] =
175       GenerateSetBitToLocal(messageBitIndex);
176 }
177 
178 }  // namespace
179 
180 // ===================================================================
181 
ImmutablePrimitiveFieldLiteGenerator(const FieldDescriptor * descriptor,int messageBitIndex,Context * context)182 ImmutablePrimitiveFieldLiteGenerator::ImmutablePrimitiveFieldLiteGenerator(
183     const FieldDescriptor* descriptor, int messageBitIndex, Context* context)
184     : descriptor_(descriptor),
185       messageBitIndex_(messageBitIndex),
186       name_resolver_(context->GetNameResolver()) {
187   SetPrimitiveVariables(descriptor, messageBitIndex, 0,
188                         context->GetFieldGeneratorInfo(descriptor),
189                         name_resolver_, &variables_);
190 }
191 
~ImmutablePrimitiveFieldLiteGenerator()192 ImmutablePrimitiveFieldLiteGenerator::~ImmutablePrimitiveFieldLiteGenerator() {}
193 
GetNumBitsForMessage() const194 int ImmutablePrimitiveFieldLiteGenerator::GetNumBitsForMessage() const {
195   return SupportFieldPresence(descriptor_->file()) ? 1 : 0;
196 }
197 
GenerateInterfaceMembers(io::Printer * printer) const198 void ImmutablePrimitiveFieldLiteGenerator::GenerateInterfaceMembers(
199     io::Printer* printer) const {
200   if (SupportFieldPresence(descriptor_->file())) {
201     WriteFieldDocComment(printer, descriptor_);
202     printer->Print(variables_,
203                    "$deprecation$boolean has$capitalized_name$();\n");
204   }
205   WriteFieldDocComment(printer, descriptor_);
206   printer->Print(variables_, "$deprecation$$type$ get$capitalized_name$();\n");
207 }
208 
GenerateMembers(io::Printer * printer) const209 void ImmutablePrimitiveFieldLiteGenerator::GenerateMembers(
210     io::Printer* printer) const {
211   if (IsByteStringWithCustomDefaultValue(descriptor_)) {
212     // allocate this once statically since we know ByteStrings are immutable
213     // values that can be reused.
214     printer->Print(
215         variables_,
216         "private static final $field_type$ $bytes_default$ = $default$;\n");
217   }
218   printer->Print(variables_, "private $field_type$ $name$_;\n");
219   PrintExtraFieldInfo(variables_, printer);
220   if (SupportFieldPresence(descriptor_->file())) {
221     WriteFieldDocComment(printer, descriptor_);
222     printer->Print(
223         variables_,
224         "@java.lang.Override\n"
225         "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
226         "  return $get_has_field_bit_message$;\n"
227         "}\n");
228     printer->Annotate("{", "}", descriptor_);
229   }
230 
231   WriteFieldDocComment(printer, descriptor_);
232   printer->Print(variables_,
233                  "@java.lang.Override\n"
234                  "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
235                  "  return $name$_;\n"
236                  "}\n");
237   printer->Annotate("{", "}", descriptor_);
238 
239   WriteFieldDocComment(printer, descriptor_);
240   printer->Print(variables_,
241                  "private void set$capitalized_name$($type$ value) {\n"
242                  "$null_check$"
243                  "  $set_has_field_bit_message$\n"
244                  "  $name$_ = value;\n"
245                  "}\n");
246 
247   WriteFieldDocComment(printer, descriptor_);
248   printer->Print(variables_,
249                  "private void clear$capitalized_name$() {\n"
250                  "  $clear_has_field_bit_message$\n");
251   JavaType type = GetJavaType(descriptor_);
252   if (type == JAVATYPE_STRING || type == JAVATYPE_BYTES) {
253     // The default value is not a simple literal so we want to avoid executing
254     // it multiple times.  Instead, get the default out of the default instance.
255     printer->Print(
256         variables_,
257         "  $name$_ = getDefaultInstance().get$capitalized_name$();\n");
258   } else {
259     printer->Print(variables_, "  $name$_ = $default$;\n");
260   }
261   printer->Print(variables_, "}\n");
262 }
263 
GenerateBuilderMembers(io::Printer * printer) const264 void ImmutablePrimitiveFieldLiteGenerator::GenerateBuilderMembers(
265     io::Printer* printer) const {
266   if (SupportFieldPresence(descriptor_->file())) {
267     WriteFieldDocComment(printer, descriptor_);
268     printer->Print(
269         variables_,
270         "@java.lang.Override\n"
271         "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
272         "  return instance.has$capitalized_name$();\n"
273         "}\n");
274     printer->Annotate("{", "}", descriptor_);
275   }
276 
277   WriteFieldDocComment(printer, descriptor_);
278   printer->Print(variables_,
279                  "@java.lang.Override\n"
280                  "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
281                  "  return instance.get$capitalized_name$();\n"
282                  "}\n");
283   printer->Annotate("{", "}", descriptor_);
284 
285   WriteFieldDocComment(printer, descriptor_);
286   printer->Print(variables_,
287                  "$deprecation$public Builder "
288                  "${$set$capitalized_name$$}$($type$ value) {\n"
289                  "  copyOnWrite();\n"
290                  "  instance.set$capitalized_name$(value);\n"
291                  "  return this;\n"
292                  "}\n");
293   printer->Annotate("{", "}", descriptor_);
294 
295   WriteFieldDocComment(printer, descriptor_);
296   printer->Print(
297       variables_,
298       "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
299       "  copyOnWrite();\n"
300       "  instance.clear$capitalized_name$();\n"
301       "  return this;\n"
302       "}\n");
303   printer->Annotate("{", "}", descriptor_);
304 }
305 
GenerateFieldInfo(io::Printer * printer,std::vector<uint16> * output) const306 void ImmutablePrimitiveFieldLiteGenerator::GenerateFieldInfo(
307     io::Printer* printer, std::vector<uint16>* output) const {
308   WriteIntToUtf16CharSequence(descriptor_->number(), output);
309   WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_),
310                               output);
311   if (SupportFieldPresence(descriptor_->file())) {
312     WriteIntToUtf16CharSequence(messageBitIndex_, output);
313   }
314   printer->Print(variables_, "\"$name$_\",\n");
315 }
316 
GenerateInitializationCode(io::Printer * printer) const317 void ImmutablePrimitiveFieldLiteGenerator::GenerateInitializationCode(
318     io::Printer* printer) const {
319   if (IsByteStringWithCustomDefaultValue(descriptor_)) {
320     printer->Print(variables_, "$name$_ = $bytes_default$;\n");
321   } else if (!IsDefaultValueJavaDefault(descriptor_)) {
322     printer->Print(variables_, "$name$_ = $default$;\n");
323   }
324 }
325 
GetBoxedType() const326 std::string ImmutablePrimitiveFieldLiteGenerator::GetBoxedType() const {
327   return BoxedPrimitiveTypeName(GetJavaType(descriptor_));
328 }
329 
330 // ===================================================================
331 
332 ImmutablePrimitiveOneofFieldLiteGenerator::
ImmutablePrimitiveOneofFieldLiteGenerator(const FieldDescriptor * descriptor,int messageBitIndex,Context * context)333     ImmutablePrimitiveOneofFieldLiteGenerator(const FieldDescriptor* descriptor,
334                                               int messageBitIndex,
335                                               Context* context)
336     : ImmutablePrimitiveFieldLiteGenerator(descriptor, messageBitIndex,
337                                            context) {
338   const OneofGeneratorInfo* info =
339       context->GetOneofGeneratorInfo(descriptor->containing_oneof());
340   SetCommonOneofVariables(descriptor, info, &variables_);
341 }
342 
343 ImmutablePrimitiveOneofFieldLiteGenerator::
~ImmutablePrimitiveOneofFieldLiteGenerator()344     ~ImmutablePrimitiveOneofFieldLiteGenerator() {}
345 
GenerateMembers(io::Printer * printer) const346 void ImmutablePrimitiveOneofFieldLiteGenerator::GenerateMembers(
347     io::Printer* printer) const {
348   PrintExtraFieldInfo(variables_, printer);
349   if (SupportFieldPresence(descriptor_->file())) {
350     WriteFieldDocComment(printer, descriptor_);
351     printer->Print(
352         variables_,
353         "@java.lang.Override\n"
354         "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
355         "  return $has_oneof_case_message$;\n"
356         "}\n");
357     printer->Annotate("{", "}", descriptor_);
358   }
359 
360   WriteFieldDocComment(printer, descriptor_);
361   printer->Print(variables_,
362                  "@java.lang.Override\n"
363                  "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
364                  "  if ($has_oneof_case_message$) {\n"
365                  "    return ($boxed_type$) $oneof_name$_;\n"
366                  "  }\n"
367                  "  return $default$;\n"
368                  "}\n");
369   printer->Annotate("{", "}", descriptor_);
370 
371   WriteFieldDocComment(printer, descriptor_);
372   printer->Print(variables_,
373                  "private void set$capitalized_name$($type$ value) {\n"
374                  "$null_check$"
375                  "  $set_oneof_case_message$;\n"
376                  "  $oneof_name$_ = value;\n"
377                  "}\n");
378 
379   WriteFieldDocComment(printer, descriptor_);
380   printer->Print(variables_,
381                  "private void clear$capitalized_name$() {\n"
382                  "  if ($has_oneof_case_message$) {\n"
383                  "    $clear_oneof_case_message$;\n"
384                  "    $oneof_name$_ = null;\n"
385                  "  }\n"
386                  "}\n");
387 }
388 
GenerateFieldInfo(io::Printer * printer,std::vector<uint16> * output) const389 void ImmutablePrimitiveOneofFieldLiteGenerator::GenerateFieldInfo(
390     io::Printer* printer, std::vector<uint16>* output) const {
391   WriteIntToUtf16CharSequence(descriptor_->number(), output);
392   WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_),
393                               output);
394   WriteIntToUtf16CharSequence(descriptor_->containing_oneof()->index(), output);
395 }
396 
GenerateBuilderMembers(io::Printer * printer) const397 void ImmutablePrimitiveOneofFieldLiteGenerator::GenerateBuilderMembers(
398     io::Printer* printer) const {
399   if (SupportFieldPresence(descriptor_->file())) {
400     WriteFieldDocComment(printer, descriptor_);
401     printer->Print(
402         variables_,
403         "@java.lang.Override\n"
404         "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
405         "  return instance.has$capitalized_name$();\n"
406         "}\n");
407     printer->Annotate("{", "}", descriptor_);
408   }
409 
410   WriteFieldDocComment(printer, descriptor_);
411   printer->Print(variables_,
412                  "@java.lang.Override\n"
413                  "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
414                  "  return instance.get$capitalized_name$();\n"
415                  "}\n");
416   printer->Annotate("{", "}", descriptor_);
417 
418   WriteFieldDocComment(printer, descriptor_);
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   WriteFieldDocComment(printer, descriptor_);
429   printer->Print(
430       variables_,
431       "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
432       "  copyOnWrite();\n"
433       "  instance.clear$capitalized_name$();\n"
434       "  return this;\n"
435       "}\n");
436   printer->Annotate("{", "}", descriptor_);
437 }
438 
439 // ===================================================================
440 
441 RepeatedImmutablePrimitiveFieldLiteGenerator::
RepeatedImmutablePrimitiveFieldLiteGenerator(const FieldDescriptor * descriptor,int messageBitIndex,Context * context)442     RepeatedImmutablePrimitiveFieldLiteGenerator(
443         const FieldDescriptor* descriptor, int messageBitIndex,
444         Context* context)
445     : descriptor_(descriptor),
446       context_(context),
447       name_resolver_(context->GetNameResolver()) {
448   SetPrimitiveVariables(descriptor, messageBitIndex, 0,
449                         context->GetFieldGeneratorInfo(descriptor),
450                         name_resolver_, &variables_);
451 }
452 
453 RepeatedImmutablePrimitiveFieldLiteGenerator::
~RepeatedImmutablePrimitiveFieldLiteGenerator()454     ~RepeatedImmutablePrimitiveFieldLiteGenerator() {}
455 
GetNumBitsForMessage() const456 int RepeatedImmutablePrimitiveFieldLiteGenerator::GetNumBitsForMessage() const {
457   return 0;
458 }
459 
GenerateInterfaceMembers(io::Printer * printer) const460 void RepeatedImmutablePrimitiveFieldLiteGenerator::GenerateInterfaceMembers(
461     io::Printer* printer) const {
462   WriteFieldDocComment(printer, descriptor_);
463   printer->Print(variables_,
464                  "$deprecation$java.util.List<$boxed_type$> "
465                  "get$capitalized_name$List();\n");
466   WriteFieldDocComment(printer, descriptor_);
467   printer->Print(variables_,
468                  "$deprecation$int get$capitalized_name$Count();\n");
469   WriteFieldDocComment(printer, descriptor_);
470   printer->Print(variables_,
471                  "$deprecation$$type$ get$capitalized_name$(int index);\n");
472 }
473 
GenerateMembers(io::Printer * printer) const474 void RepeatedImmutablePrimitiveFieldLiteGenerator::GenerateMembers(
475     io::Printer* printer) const {
476   printer->Print(variables_, "private $field_list_type$ $name$_;\n");
477   PrintExtraFieldInfo(variables_, printer);
478   WriteFieldDocComment(printer, descriptor_);
479   printer->Print(variables_,
480                  "@java.lang.Override\n"
481                  "$deprecation$public java.util.List<$boxed_type$>\n"
482                  "    ${$get$capitalized_name$List$}$() {\n"
483                  "  return $name$_;\n"  // note:  unmodifiable list
484                  "}\n");
485   printer->Annotate("{", "}", descriptor_);
486   WriteFieldDocComment(printer, descriptor_);
487   printer->Print(
488       variables_,
489       "@java.lang.Override\n"
490       "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
491       "  return $name$_.size();\n"
492       "}\n");
493   printer->Annotate("{", "}", descriptor_);
494   WriteFieldDocComment(printer, descriptor_);
495   printer->Print(
496       variables_,
497       "@java.lang.Override\n"
498       "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n"
499       "  return $repeated_get$(index);\n"
500       "}\n");
501   printer->Annotate("{", "}", descriptor_);
502 
503   if (!EnableExperimentalRuntimeForLite() && descriptor_->is_packed() &&
504       context_->HasGeneratedMethods(descriptor_->containing_type())) {
505     printer->Print(variables_,
506                    "private int $name$MemoizedSerializedSize = -1;\n");
507   }
508 
509   printer->Print(
510       variables_,
511       "private void ensure$capitalized_name$IsMutable() {\n"
512       "  if (!$is_mutable$) {\n"
513       "    $name$_ =\n"
514       "        com.google.protobuf.GeneratedMessageLite.mutableCopy($name$_);\n"
515       "   }\n"
516       "}\n");
517 
518   WriteFieldDocComment(printer, descriptor_);
519   printer->Print(variables_,
520                  "private void set$capitalized_name$(\n"
521                  "    int index, $type$ value) {\n"
522                  "$null_check$"
523                  "  ensure$capitalized_name$IsMutable();\n"
524                  "  $repeated_set$(index, value);\n"
525                  "}\n");
526   WriteFieldDocComment(printer, descriptor_);
527   printer->Print(variables_,
528                  "private void add$capitalized_name$($type$ value) {\n"
529                  "$null_check$"
530                  "  ensure$capitalized_name$IsMutable();\n"
531                  "  $repeated_add$(value);\n"
532                  "}\n");
533   WriteFieldDocComment(printer, descriptor_);
534   printer->Print(variables_,
535                  "private void addAll$capitalized_name$(\n"
536                  "    java.lang.Iterable<? extends $boxed_type$> values) {\n"
537                  "  ensure$capitalized_name$IsMutable();\n"
538                  "  com.google.protobuf.AbstractMessageLite.addAll(\n"
539                  "      values, $name$_);\n"
540                  "}\n");
541   WriteFieldDocComment(printer, descriptor_);
542   printer->Print(variables_,
543                  "private void clear$capitalized_name$() {\n"
544                  "  $name$_ = $empty_list$;\n"
545                  "}\n");
546 }
547 
GenerateBuilderMembers(io::Printer * printer) const548 void RepeatedImmutablePrimitiveFieldLiteGenerator::GenerateBuilderMembers(
549     io::Printer* printer) const {
550   WriteFieldDocComment(printer, descriptor_);
551   printer->Print(variables_,
552                  "@java.lang.Override\n"
553                  "$deprecation$public java.util.List<$boxed_type$>\n"
554                  "    ${$get$capitalized_name$List$}$() {\n"
555                  "  return java.util.Collections.unmodifiableList(\n"
556                  "      instance.get$capitalized_name$List());\n"
557                  "}\n");
558   printer->Annotate("{", "}", descriptor_);
559   WriteFieldDocComment(printer, descriptor_);
560   printer->Print(
561       variables_,
562       "@java.lang.Override\n"
563       "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
564       "  return instance.get$capitalized_name$Count();\n"
565       "}\n");
566   printer->Annotate("{", "}", descriptor_);
567   WriteFieldDocComment(printer, descriptor_);
568   printer->Print(
569       variables_,
570       "@java.lang.Override\n"
571       "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n"
572       "  return instance.get$capitalized_name$(index);\n"
573       "}\n");
574   printer->Annotate("{", "}", descriptor_);
575   WriteFieldDocComment(printer, descriptor_);
576   printer->Print(variables_,
577                  "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
578                  "    int index, $type$ value) {\n"
579                  "  copyOnWrite();\n"
580                  "  instance.set$capitalized_name$(index, value);\n"
581                  "  return this;\n"
582                  "}\n");
583   printer->Annotate("{", "}", descriptor_);
584   WriteFieldDocComment(printer, descriptor_);
585   printer->Print(variables_,
586                  "$deprecation$public Builder "
587                  "${$add$capitalized_name$$}$($type$ value) {\n"
588                  "  copyOnWrite();\n"
589                  "  instance.add$capitalized_name$(value);\n"
590                  "  return this;\n"
591                  "}\n");
592   printer->Annotate("{", "}", descriptor_);
593   WriteFieldDocComment(printer, descriptor_);
594   printer->Print(variables_,
595                  "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n"
596                  "    java.lang.Iterable<? extends $boxed_type$> values) {\n"
597                  "  copyOnWrite();\n"
598                  "  instance.addAll$capitalized_name$(values);\n"
599                  "  return this;\n"
600                  "}\n");
601   printer->Annotate("{", "}", descriptor_);
602   WriteFieldDocComment(printer, descriptor_);
603   printer->Print(
604       variables_,
605       "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
606       "  copyOnWrite();\n"
607       "  instance.clear$capitalized_name$();\n"
608       "  return this;\n"
609       "}\n");
610   printer->Annotate("{", "}", descriptor_);
611 }
612 
GenerateFieldInfo(io::Printer * printer,std::vector<uint16> * output) const613 void RepeatedImmutablePrimitiveFieldLiteGenerator::GenerateFieldInfo(
614     io::Printer* printer, std::vector<uint16>* output) const {
615   WriteIntToUtf16CharSequence(descriptor_->number(), output);
616   WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_),
617                               output);
618   printer->Print(variables_, "\"$name$_\",\n");
619 }
620 
GenerateInitializationCode(io::Printer * printer) const621 void RepeatedImmutablePrimitiveFieldLiteGenerator::GenerateInitializationCode(
622     io::Printer* printer) const {
623   printer->Print(variables_, "$name$_ = $empty_list$;\n");
624 }
625 
GetBoxedType() const626 std::string RepeatedImmutablePrimitiveFieldLiteGenerator::GetBoxedType() const {
627   return BoxedPrimitiveTypeName(GetJavaType(descriptor_));
628 }
629 
630 }  // namespace java
631 }  // namespace compiler
632 }  // namespace protobuf
633 }  // namespace google
634