• 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/message_field_lite.h>
36 
37 #include <cstdint>
38 #include <map>
39 #include <string>
40 
41 #include <google/protobuf/io/printer.h>
42 #include <google/protobuf/wire_format.h>
43 #include <google/protobuf/stubs/strutil.h>
44 #include <google/protobuf/compiler/java/context.h>
45 #include <google/protobuf/compiler/java/doc_comment.h>
46 #include <google/protobuf/compiler/java/helpers.h>
47 #include <google/protobuf/compiler/java/name_resolver.h>
48 
49 // Must be last.
50 #include <google/protobuf/port_def.inc>
51 
52 namespace google {
53 namespace protobuf {
54 namespace compiler {
55 namespace java {
56 
57 namespace {
58 
SetMessageVariables(const FieldDescriptor * descriptor,int messageBitIndex,int builderBitIndex,const FieldGeneratorInfo * info,ClassNameResolver * name_resolver,std::map<std::string,std::string> * variables)59 void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex,
60                          int builderBitIndex, const FieldGeneratorInfo* info,
61                          ClassNameResolver* name_resolver,
62                          std::map<std::string, std::string>* variables) {
63   SetCommonFieldVariables(descriptor, info, variables);
64 
65   (*variables)["type"] =
66       name_resolver->GetImmutableClassName(descriptor->message_type());
67   (*variables)["kt_type"] = (*variables)["type"];
68   (*variables)["mutable_type"] =
69       name_resolver->GetMutableClassName(descriptor->message_type());
70   (*variables)["group_or_message"] =
71       (GetType(descriptor) == FieldDescriptor::TYPE_GROUP) ? "Group"
72                                                            : "Message";
73   // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
74   // by the proto compiler
75   (*variables)["deprecation"] =
76       descriptor->options().deprecated() ? "@java.lang.Deprecated " : "";
77   (*variables)["kt_deprecation"] =
78       descriptor->options().deprecated()
79           ? "@kotlin.Deprecated(message = \"Field " + (*variables)["name"] +
80                 " is deprecated\") "
81           : "";
82   (*variables)["required"] = descriptor->is_required() ? "true" : "false";
83 
84   if (HasHasbit(descriptor)) {
85     // For singular messages and builders, one bit is used for the hasField bit.
86     (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
87 
88     // Note that these have a trailing ";".
89     (*variables)["set_has_field_bit_message"] =
90         GenerateSetBit(messageBitIndex) + ";";
91     (*variables)["clear_has_field_bit_message"] =
92         GenerateClearBit(messageBitIndex) + ";";
93 
94     (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex);
95   } else {
96     (*variables)["set_has_field_bit_message"] = "";
97     (*variables)["clear_has_field_bit_message"] = "";
98 
99     (*variables)["is_field_present_message"] =
100         (*variables)["name"] + "_ != null";
101   }
102 
103   (*variables)["get_has_field_bit_from_local"] =
104       GenerateGetBitFromLocal(builderBitIndex);
105   (*variables)["set_has_field_bit_to_local"] =
106       GenerateSetBitToLocal(messageBitIndex);
107 
108   // We use `x.getClass()` as a null check because it generates less bytecode
109   // than an `if (x == null) { throw ... }` statement.
110   (*variables)["null_check"] = "value.getClass();\n";
111 }
112 
113 }  // namespace
114 
115 // ===================================================================
116 
ImmutableMessageFieldLiteGenerator(const FieldDescriptor * descriptor,int messageBitIndex,Context * context)117 ImmutableMessageFieldLiteGenerator::ImmutableMessageFieldLiteGenerator(
118     const FieldDescriptor* descriptor, int messageBitIndex, Context* context)
119     : descriptor_(descriptor),
120       messageBitIndex_(messageBitIndex),
121       name_resolver_(context->GetNameResolver()) {
122   SetMessageVariables(descriptor, messageBitIndex, 0,
123                       context->GetFieldGeneratorInfo(descriptor),
124                       name_resolver_, &variables_);
125 }
126 
~ImmutableMessageFieldLiteGenerator()127 ImmutableMessageFieldLiteGenerator::~ImmutableMessageFieldLiteGenerator() {}
128 
GetNumBitsForMessage() const129 int ImmutableMessageFieldLiteGenerator::GetNumBitsForMessage() const {
130   // TODO(dweis): We don't need a has bit for messages as they have null
131   // sentinels and no user should be reflecting on this. We could save some
132   // bits by setting to 0 and updating the runtimes but this might come at a
133   // runtime performance cost since we can't memoize has-bit reads.
134   return HasHasbit(descriptor_) ? 1 : 0;
135 }
136 
GenerateInterfaceMembers(io::Printer * printer) const137 void ImmutableMessageFieldLiteGenerator::GenerateInterfaceMembers(
138     io::Printer* printer) const {
139   WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
140   printer->Print(variables_, "$deprecation$boolean has$capitalized_name$();\n");
141   WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
142   printer->Print(variables_, "$deprecation$$type$ get$capitalized_name$();\n");
143 }
144 
GenerateMembers(io::Printer * printer) const145 void ImmutableMessageFieldLiteGenerator::GenerateMembers(
146     io::Printer* printer) const {
147 
148   printer->Print(variables_, "private $type$ $name$_;\n");
149   PrintExtraFieldInfo(variables_, printer);
150 
151   if (HasHasbit(descriptor_)) {
152     WriteFieldDocComment(printer, descriptor_);
153     printer->Print(
154         variables_,
155         "@java.lang.Override\n"
156         "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
157         "  return $get_has_field_bit_message$;\n"
158         "}\n");
159     printer->Annotate("{", "}", descriptor_);
160     WriteFieldDocComment(printer, descriptor_);
161     printer->Print(
162         variables_,
163         "@java.lang.Override\n"
164         "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
165         "  return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n"
166         "}\n");
167     printer->Annotate("{", "}", descriptor_);
168   } else {
169     WriteFieldDocComment(printer, descriptor_);
170     printer->Print(
171         variables_,
172         "@java.lang.Override\n"
173         "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
174         "  return $name$_ != null;\n"
175         "}\n");
176     printer->Annotate("{", "}", descriptor_);
177     WriteFieldDocComment(printer, descriptor_);
178     printer->Print(
179         variables_,
180         "@java.lang.Override\n"
181         "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
182         "  return $name$_ == null ? $type$.getDefaultInstance() : $name$_;\n"
183         "}\n");
184     printer->Annotate("{", "}", descriptor_);
185   }
186 
187   // Field.Builder setField(Field value)
188   WriteFieldDocComment(printer, descriptor_);
189   printer->Print(variables_,
190                  "private void set$capitalized_name$($type$ value) {\n"
191                  "  $null_check$"
192                  "  $name$_ = value;\n"
193                  "  $set_has_field_bit_message$\n"
194                  "  }\n");
195 
196   // Field.Builder mergeField(Field value)
197   WriteFieldDocComment(printer, descriptor_);
198   printer->Print(
199       variables_,
200       "@java.lang.SuppressWarnings({\"ReferenceEquality\"})\n"
201       "private void merge$capitalized_name$($type$ value) {\n"
202       "  $null_check$"
203       "  if ($name$_ != null &&\n"
204       "      $name$_ != $type$.getDefaultInstance()) {\n"
205       "    $name$_ =\n"
206       "      $type$.newBuilder($name$_).mergeFrom(value).buildPartial();\n"
207       "  } else {\n"
208       "    $name$_ = value;\n"
209       "  }\n"
210       "  $set_has_field_bit_message$\n"
211       "}\n");
212 
213   // Field.Builder clearField()
214   WriteFieldDocComment(printer, descriptor_);
215   printer->Print(variables_,
216                  "private void clear$capitalized_name$() {"
217                  "  $name$_ = null;\n"
218                  "  $clear_has_field_bit_message$\n"
219                  "}\n");
220 }
221 
GenerateBuilderMembers(io::Printer * printer) const222 void ImmutableMessageFieldLiteGenerator::GenerateBuilderMembers(
223     io::Printer* printer) const {
224   // The comments above the methods below are based on a hypothetical
225   // field of type "Field" called "Field".
226 
227   // boolean hasField()
228   WriteFieldDocComment(printer, descriptor_);
229   printer->Print(variables_,
230                  "@java.lang.Override\n"
231                  "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
232                  "  return instance.has$capitalized_name$();\n"
233                  "}\n");
234   printer->Annotate("{", "}", descriptor_);
235 
236   // Field getField()
237   WriteFieldDocComment(printer, descriptor_);
238   printer->Print(variables_,
239                  "@java.lang.Override\n"
240                  "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
241                  "  return instance.get$capitalized_name$();\n"
242                  "}\n");
243   printer->Annotate("{", "}", descriptor_);
244 
245   // Field.Builder setField(Field value)
246   WriteFieldDocComment(printer, descriptor_);
247   printer->Print(variables_,
248                  "$deprecation$public Builder "
249                  "${$set$capitalized_name$$}$($type$ value) {\n"
250                  "  copyOnWrite();\n"
251                  "  instance.set$capitalized_name$(value);\n"
252                  "  return this;\n"
253                  "  }\n");
254   printer->Annotate("{", "}", descriptor_);
255 
256   // Field.Builder setField(Field.Builder builderForValue)
257   WriteFieldDocComment(printer, descriptor_);
258   printer->Print(variables_,
259                  "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
260                  "    $type$.Builder builderForValue) {\n"
261                  "  copyOnWrite();\n"
262                  "  instance.set$capitalized_name$(builderForValue.build());\n"
263                  "  return this;\n"
264                  "}\n");
265   printer->Annotate("{", "}", descriptor_);
266 
267   // Field.Builder mergeField(Field value)
268   WriteFieldDocComment(printer, descriptor_);
269   printer->Print(variables_,
270                  "$deprecation$public Builder "
271                  "${$merge$capitalized_name$$}$($type$ value) {\n"
272                  "  copyOnWrite();\n"
273                  "  instance.merge$capitalized_name$(value);\n"
274                  "  return this;\n"
275                  "}\n");
276   printer->Annotate("{", "}", descriptor_);
277 
278   // Field.Builder clearField()
279   WriteFieldDocComment(printer, descriptor_);
280   printer->Print(variables_,
281                  "$deprecation$public Builder ${$clear$capitalized_name$$}$() {"
282                  "  copyOnWrite();\n"
283                  "  instance.clear$capitalized_name$();\n"
284                  "  return this;\n"
285                  "}\n");
286   printer->Annotate("{", "}", descriptor_);
287 }
288 
GenerateKotlinDslMembers(io::Printer * printer) const289 void ImmutableMessageFieldLiteGenerator::GenerateKotlinDslMembers(
290     io::Printer* printer) const {
291   WriteFieldDocComment(printer, descriptor_);
292   printer->Print(variables_,
293                  "$kt_deprecation$public var $kt_name$: $kt_type$\n"
294                  "  @JvmName(\"${$get$kt_capitalized_name$$}$\")\n"
295                  "  get() = $kt_dsl_builder$.${$get$capitalized_name$$}$()\n"
296                  "  @JvmName(\"${$set$kt_capitalized_name$$}$\")\n"
297                  "  set(value) {\n"
298                  "    $kt_dsl_builder$.${$set$capitalized_name$$}$(value)\n"
299                  "  }\n");
300 
301   WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
302                                /* builder */ false);
303   printer->Print(variables_,
304                  "public fun ${$clear$kt_capitalized_name$$}$() {\n"
305                  "  $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n"
306                  "}\n");
307 
308   WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
309   printer->Print(
310       variables_,
311       "public fun ${$has$kt_capitalized_name$$}$(): kotlin.Boolean {\n"
312       "  return $kt_dsl_builder$.${$has$capitalized_name$$}$()\n"
313       "}\n");
314   GenerateKotlinOrNull(printer);
315 }
316 
GenerateKotlinOrNull(io::Printer * printer) const317 void ImmutableMessageFieldLiteGenerator::GenerateKotlinOrNull(io::Printer* printer) const {
318   if (descriptor_->has_optional_keyword()) {
319     printer->Print(variables_,
320                    "public val $classname$Kt.Dsl.$name$OrNull: $kt_type$?\n"
321                    "  get() = $kt_dsl_builder$.$name$OrNull\n");
322   }
323 }
324 
GenerateFieldInfo(io::Printer * printer,std::vector<uint16_t> * output) const325 void ImmutableMessageFieldLiteGenerator::GenerateFieldInfo(
326     io::Printer* printer, std::vector<uint16_t>* output) const {
327   WriteIntToUtf16CharSequence(descriptor_->number(), output);
328   WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_),
329                               output);
330   if (HasHasbit(descriptor_)) {
331     WriteIntToUtf16CharSequence(messageBitIndex_, output);
332   }
333   printer->Print(variables_, "\"$name$_\",\n");
334 }
335 
GenerateInitializationCode(io::Printer * printer) const336 void ImmutableMessageFieldLiteGenerator::GenerateInitializationCode(
337     io::Printer* printer) const {}
338 
GetBoxedType() const339 std::string ImmutableMessageFieldLiteGenerator::GetBoxedType() const {
340   return name_resolver_->GetImmutableClassName(descriptor_->message_type());
341 }
342 
343 // ===================================================================
344 
345 ImmutableMessageOneofFieldLiteGenerator::
ImmutableMessageOneofFieldLiteGenerator(const FieldDescriptor * descriptor,int messageBitIndex,Context * context)346     ImmutableMessageOneofFieldLiteGenerator(const FieldDescriptor* descriptor,
347                                             int messageBitIndex,
348                                             Context* context)
349     : ImmutableMessageFieldLiteGenerator(descriptor, messageBitIndex, context) {
350   const OneofGeneratorInfo* info =
351       context->GetOneofGeneratorInfo(descriptor->containing_oneof());
352   SetCommonOneofVariables(descriptor, info, &variables_);
353 }
354 
355 ImmutableMessageOneofFieldLiteGenerator::
~ImmutableMessageOneofFieldLiteGenerator()356     ~ImmutableMessageOneofFieldLiteGenerator() {}
357 
GenerateMembers(io::Printer * printer) const358 void ImmutableMessageOneofFieldLiteGenerator::GenerateMembers(
359     io::Printer* printer) const {
360   PrintExtraFieldInfo(variables_, printer);
361   WriteFieldDocComment(printer, descriptor_);
362   printer->Print(variables_,
363                  "@java.lang.Override\n"
364                  "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
365                  "  return $has_oneof_case_message$;\n"
366                  "}\n");
367   printer->Annotate("{", "}", descriptor_);
368   WriteFieldDocComment(printer, descriptor_);
369   printer->Print(variables_,
370                  "@java.lang.Override\n"
371                  "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
372                  "  if ($has_oneof_case_message$) {\n"
373                  "     return ($type$) $oneof_name$_;\n"
374                  "  }\n"
375                  "  return $type$.getDefaultInstance();\n"
376                  "}\n");
377   printer->Annotate("{", "}", descriptor_);
378 
379   // Field.Builder setField(Field value)
380   WriteFieldDocComment(printer, descriptor_);
381   printer->Print(variables_,
382                  "private void set$capitalized_name$($type$ value) {\n"
383                  "  $null_check$"
384                  "  $oneof_name$_ = value;\n"
385                  "  $set_oneof_case_message$;\n"
386                  "}\n");
387 
388   // Field.Builder mergeField(Field value)
389   WriteFieldDocComment(printer, descriptor_);
390   printer->Print(
391       variables_,
392       "private void merge$capitalized_name$($type$ value) {\n"
393       "  $null_check$"
394       "  if ($has_oneof_case_message$ &&\n"
395       "      $oneof_name$_ != $type$.getDefaultInstance()) {\n"
396       "    $oneof_name$_ = $type$.newBuilder(($type$) $oneof_name$_)\n"
397       "        .mergeFrom(value).buildPartial();\n"
398       "  } else {\n"
399       "    $oneof_name$_ = value;\n"
400       "  }\n"
401       "  $set_oneof_case_message$;\n"
402       "}\n");
403 
404   // Field.Builder clearField()
405   WriteFieldDocComment(printer, descriptor_);
406   printer->Print(variables_,
407                  "private void clear$capitalized_name$() {\n"
408                  "  if ($has_oneof_case_message$) {\n"
409                  "    $clear_oneof_case_message$;\n"
410                  "    $oneof_name$_ = null;\n"
411                  "  }\n"
412                  "}\n");
413 }
414 
GenerateFieldInfo(io::Printer * printer,std::vector<uint16_t> * output) const415 void ImmutableMessageOneofFieldLiteGenerator::GenerateFieldInfo(
416     io::Printer* printer, std::vector<uint16_t>* output) const {
417   WriteIntToUtf16CharSequence(descriptor_->number(), output);
418   WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_),
419                               output);
420   WriteIntToUtf16CharSequence(descriptor_->containing_oneof()->index(), output);
421   printer->Print(variables_, "$oneof_stored_type$.class,\n");
422 }
423 
GenerateBuilderMembers(io::Printer * printer) const424 void ImmutableMessageOneofFieldLiteGenerator::GenerateBuilderMembers(
425     io::Printer* printer) const {
426   // The comments above the methods below are based on a hypothetical
427   // field of type "Field" called "Field".
428 
429   // boolean hasField()
430   WriteFieldDocComment(printer, descriptor_);
431   printer->Print(variables_,
432                  "@java.lang.Override\n"
433                  "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
434                  "  return instance.has$capitalized_name$();\n"
435                  "}\n");
436   printer->Annotate("{", "}", descriptor_);
437 
438   // Field getField()
439   WriteFieldDocComment(printer, descriptor_);
440   printer->Print(variables_,
441                  "@java.lang.Override\n"
442                  "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
443                  "  return instance.get$capitalized_name$();\n"
444                  "}\n");
445   printer->Annotate("{", "}", descriptor_);
446 
447   // Field.Builder setField(Field value)
448   WriteFieldDocComment(printer, descriptor_);
449   printer->Print(variables_,
450                  "$deprecation$public Builder "
451                  "${$set$capitalized_name$$}$($type$ value) {\n"
452                  "  copyOnWrite();\n"
453                  "  instance.set$capitalized_name$(value);\n"
454                  "  return this;\n"
455                  "}\n");
456   printer->Annotate("{", "}", descriptor_);
457 
458   // Field.Builder setField(Field.Builder builderForValue)
459   WriteFieldDocComment(printer, descriptor_);
460   printer->Print(variables_,
461                  "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
462                  "    $type$.Builder builderForValue) {\n"
463                  "  copyOnWrite();\n"
464                  "  instance.set$capitalized_name$(builderForValue.build());\n"
465                  "  return this;\n"
466                  "}\n");
467   printer->Annotate("{", "}", descriptor_);
468 
469   // Field.Builder mergeField(Field value)
470   WriteFieldDocComment(printer, descriptor_);
471   printer->Print(variables_,
472                  "$deprecation$public Builder "
473                  "${$merge$capitalized_name$$}$($type$ value) {\n"
474                  "  copyOnWrite();\n"
475                  "  instance.merge$capitalized_name$(value);\n"
476                  "  return this;\n"
477                  "}\n");
478   printer->Annotate("{", "}", descriptor_);
479 
480   // Field.Builder clearField()
481   WriteFieldDocComment(printer, descriptor_);
482   printer->Print(
483       variables_,
484       "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
485       "  copyOnWrite();\n"
486       "  instance.clear$capitalized_name$();\n"
487       "  return this;\n"
488       "}\n");
489   printer->Annotate("{", "}", descriptor_);
490 }
491 
492 // ===================================================================
493 
494 RepeatedImmutableMessageFieldLiteGenerator::
RepeatedImmutableMessageFieldLiteGenerator(const FieldDescriptor * descriptor,int messageBitIndex,Context * context)495     RepeatedImmutableMessageFieldLiteGenerator(
496         const FieldDescriptor* descriptor, int messageBitIndex,
497         Context* context)
498     : descriptor_(descriptor), name_resolver_(context->GetNameResolver()) {
499   SetMessageVariables(descriptor, messageBitIndex, 0,
500                       context->GetFieldGeneratorInfo(descriptor),
501                       name_resolver_, &variables_);
502 }
503 
504 RepeatedImmutableMessageFieldLiteGenerator::
~RepeatedImmutableMessageFieldLiteGenerator()505     ~RepeatedImmutableMessageFieldLiteGenerator() {}
506 
GetNumBitsForMessage() const507 int RepeatedImmutableMessageFieldLiteGenerator::GetNumBitsForMessage() const {
508   return 0;
509 }
510 
GenerateInterfaceMembers(io::Printer * printer) const511 void RepeatedImmutableMessageFieldLiteGenerator::GenerateInterfaceMembers(
512     io::Printer* printer) const {
513   // TODO(jonp): In the future, consider having methods specific to the
514   // interface so that builders can choose dynamically to either return a
515   // message or a nested builder, so that asking for the interface doesn't
516   // cause a message to ever be built.
517   WriteFieldDocComment(printer, descriptor_);
518   printer->Print(variables_,
519                  "$deprecation$java.util.List<$type$> \n"
520                  "    get$capitalized_name$List();\n");
521   WriteFieldDocComment(printer, descriptor_);
522   printer->Print(variables_,
523                  "$deprecation$$type$ get$capitalized_name$(int index);\n");
524   WriteFieldDocComment(printer, descriptor_);
525   printer->Print(variables_,
526                  "$deprecation$int get$capitalized_name$Count();\n");
527 }
528 
GenerateMembers(io::Printer * printer) const529 void RepeatedImmutableMessageFieldLiteGenerator::GenerateMembers(
530     io::Printer* printer) const {
531   printer->Print(
532       variables_,
533       "private com.google.protobuf.Internal.ProtobufList<$type$> $name$_;\n");
534   PrintExtraFieldInfo(variables_, printer);
535   WriteFieldDocComment(printer, descriptor_);
536   printer->Print(variables_,
537                  "@java.lang.Override\n"
538                  "$deprecation$public java.util.List<$type$> "
539                  "${$get$capitalized_name$List$}$() {\n"
540                  "  return $name$_;\n"  // note:  unmodifiable list
541                  "}\n");
542   printer->Annotate("{", "}", descriptor_);
543   WriteFieldDocComment(printer, descriptor_);
544   printer->Print(
545       variables_,
546       "$deprecation$public java.util.List<? extends $type$OrBuilder> \n"
547       "    ${$get$capitalized_name$OrBuilderList$}$() {\n"
548       "  return $name$_;\n"
549       "}\n");
550   printer->Annotate("{", "}", descriptor_);
551   WriteFieldDocComment(printer, descriptor_);
552   printer->Print(
553       variables_,
554       "@java.lang.Override\n"
555       "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
556       "  return $name$_.size();\n"
557       "}\n");
558   printer->Annotate("{", "}", descriptor_);
559   WriteFieldDocComment(printer, descriptor_);
560   printer->Print(
561       variables_,
562       "@java.lang.Override\n"
563       "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n"
564       "  return $name$_.get(index);\n"
565       "}\n");
566   printer->Annotate("{", "}", descriptor_);
567   WriteFieldDocComment(printer, descriptor_);
568   printer->Print(variables_,
569                  "$deprecation$public $type$OrBuilder "
570                  "${$get$capitalized_name$OrBuilder$}$(\n"
571                  "    int index) {\n"
572                  "  return $name$_.get(index);\n"
573                  "}\n");
574   printer->Annotate("{", "}", descriptor_);
575 
576   printer->Print(
577       variables_,
578       "private void ensure$capitalized_name$IsMutable() {\n"
579       // Use a temporary to avoid a redundant iget-object.
580       "  com.google.protobuf.Internal.ProtobufList<$type$> tmp = $name$_;\n"
581       "  if (!tmp.isModifiable()) {\n"
582       "    $name$_ =\n"
583       "        com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);\n"
584       "   }\n"
585       "}\n"
586       "\n");
587 
588   // Builder setRepeatedField(int index, Field value)
589   WriteFieldDocComment(printer, descriptor_);
590   printer->Print(variables_,
591                  "private void set$capitalized_name$(\n"
592                  "    int index, $type$ value) {\n"
593                  "  $null_check$"
594                  "  ensure$capitalized_name$IsMutable();\n"
595                  "  $name$_.set(index, value);\n"
596                  "}\n");
597 
598   // Builder addRepeatedField(Field value)
599   WriteFieldDocComment(printer, descriptor_);
600   printer->Print(variables_,
601                  "private void add$capitalized_name$($type$ value) {\n"
602                  "  $null_check$"
603                  "  ensure$capitalized_name$IsMutable();\n"
604                  "  $name$_.add(value);\n"
605                  "}\n");
606 
607   // Builder addRepeatedField(int index, Field value)
608   WriteFieldDocComment(printer, descriptor_);
609   printer->Print(variables_,
610                  "private void add$capitalized_name$(\n"
611                  "    int index, $type$ value) {\n"
612                  "  $null_check$"
613                  "  ensure$capitalized_name$IsMutable();\n"
614                  "  $name$_.add(index, value);\n"
615                  "}\n");
616 
617   // Builder addAllRepeatedField(Iterable<Field> values)
618   WriteFieldDocComment(printer, descriptor_);
619   printer->Print(variables_,
620                  "private void addAll$capitalized_name$(\n"
621                  "    java.lang.Iterable<? extends $type$> values) {\n"
622                  "  ensure$capitalized_name$IsMutable();\n"
623                  "  com.google.protobuf.AbstractMessageLite.addAll(\n"
624                  "      values, $name$_);\n"
625                  "}\n");
626 
627   // Builder clearAllRepeatedField()
628   WriteFieldDocComment(printer, descriptor_);
629   printer->Print(variables_,
630                  "private void clear$capitalized_name$() {\n"
631                  "  $name$_ = emptyProtobufList();\n"
632                  "}\n");
633 
634   // Builder removeRepeatedField(int index)
635   WriteFieldDocComment(printer, descriptor_);
636   printer->Print(variables_,
637                  "private void remove$capitalized_name$(int index) {\n"
638                  "  ensure$capitalized_name$IsMutable();\n"
639                  "  $name$_.remove(index);\n"
640                  "}\n");
641 }
642 
GenerateBuilderMembers(io::Printer * printer) const643 void RepeatedImmutableMessageFieldLiteGenerator::GenerateBuilderMembers(
644     io::Printer* printer) const {
645   // The comments above the methods below are based on a hypothetical
646   // repeated field of type "Field" called "RepeatedField".
647 
648   // List<Field> getRepeatedFieldList()
649   WriteFieldDocComment(printer, descriptor_);
650   printer->Print(variables_,
651                  "@java.lang.Override\n"
652                  "$deprecation$public java.util.List<$type$> "
653                  "${$get$capitalized_name$List$}$() {\n"
654                  "  return java.util.Collections.unmodifiableList(\n"
655                  "      instance.get$capitalized_name$List());\n"
656                  "}\n");
657   printer->Annotate("{", "}", descriptor_);
658 
659   // int getRepeatedFieldCount()
660   WriteFieldDocComment(printer, descriptor_);
661   printer->Print(
662       variables_,
663       "@java.lang.Override\n"
664       "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
665       "  return instance.get$capitalized_name$Count();\n"
666       "}");
667   printer->Annotate("{", "}", descriptor_);
668 
669   // Field getRepeatedField(int index)
670   WriteFieldDocComment(printer, descriptor_);
671   printer->Print(
672       variables_,
673       "@java.lang.Override\n"
674       "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n"
675       "  return instance.get$capitalized_name$(index);\n"
676       "}\n");
677   printer->Annotate("{", "}", descriptor_);
678 
679   // Builder setRepeatedField(int index, Field value)
680   WriteFieldDocComment(printer, descriptor_);
681   printer->Print(variables_,
682                  "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
683                  "    int index, $type$ value) {\n"
684                  "  copyOnWrite();\n"
685                  "  instance.set$capitalized_name$(index, value);\n"
686                  "  return this;\n"
687                  "}\n");
688   printer->Annotate("{", "}", descriptor_);
689 
690   // Builder setRepeatedField(int index, Field.Builder builderForValue)
691   WriteFieldDocComment(printer, descriptor_);
692   printer->Print(variables_,
693                  "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
694                  "    int index, $type$.Builder builderForValue) {\n"
695                  "  copyOnWrite();\n"
696                  "  instance.set$capitalized_name$(index,\n"
697                  "      builderForValue.build());\n"
698                  "  return this;\n"
699                  "}\n");
700   printer->Annotate("{", "}", descriptor_);
701 
702   // Builder addRepeatedField(Field value)
703   WriteFieldDocComment(printer, descriptor_);
704   printer->Print(variables_,
705                  "$deprecation$public Builder "
706                  "${$add$capitalized_name$$}$($type$ value) {\n"
707                  "  copyOnWrite();\n"
708                  "  instance.add$capitalized_name$(value);\n"
709                  "  return this;\n"
710                  "}\n");
711   printer->Annotate("{", "}", descriptor_);
712 
713   // Builder addRepeatedField(int index, Field value)
714   WriteFieldDocComment(printer, descriptor_);
715   printer->Print(variables_,
716                  "$deprecation$public Builder ${$add$capitalized_name$$}$(\n"
717                  "    int index, $type$ value) {\n"
718                  "  copyOnWrite();\n"
719                  "  instance.add$capitalized_name$(index, value);\n"
720                  "  return this;\n"
721                  "}\n");
722   printer->Annotate("{", "}", descriptor_);
723   // Builder addRepeatedField(Field.Builder builderForValue)
724   WriteFieldDocComment(printer, descriptor_);
725   printer->Print(variables_,
726                  "$deprecation$public Builder ${$add$capitalized_name$$}$(\n"
727                  "    $type$.Builder builderForValue) {\n"
728                  "  copyOnWrite();\n"
729                  "  instance.add$capitalized_name$(builderForValue.build());\n"
730                  "  return this;\n"
731                  "}\n");
732   printer->Annotate("{", "}", descriptor_);
733 
734   // Builder addRepeatedField(int index, Field.Builder builderForValue)
735   WriteFieldDocComment(printer, descriptor_);
736   printer->Print(variables_,
737                  "$deprecation$public Builder ${$add$capitalized_name$$}$(\n"
738                  "    int index, $type$.Builder builderForValue) {\n"
739                  "  copyOnWrite();\n"
740                  "  instance.add$capitalized_name$(index,\n"
741                  "      builderForValue.build());\n"
742                  "  return this;\n"
743                  "}\n");
744   printer->Annotate("{", "}", descriptor_);
745 
746   // Builder addAllRepeatedField(Iterable<Field> values)
747   WriteFieldDocComment(printer, descriptor_);
748   printer->Print(variables_,
749                  "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n"
750                  "    java.lang.Iterable<? extends $type$> values) {\n"
751                  "  copyOnWrite();\n"
752                  "  instance.addAll$capitalized_name$(values);\n"
753                  "  return this;\n"
754                  "}\n");
755   printer->Annotate("{", "}", descriptor_);
756 
757   // Builder clearAllRepeatedField()
758   WriteFieldDocComment(printer, descriptor_);
759   printer->Print(
760       variables_,
761       "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
762       "  copyOnWrite();\n"
763       "  instance.clear$capitalized_name$();\n"
764       "  return this;\n"
765       "}\n");
766   printer->Annotate("{", "}", descriptor_);
767 
768   // Builder removeRepeatedField(int index)
769   WriteFieldDocComment(printer, descriptor_);
770   printer->Print(variables_,
771                  "$deprecation$public Builder "
772                  "${$remove$capitalized_name$$}$(int index) {\n"
773                  "  copyOnWrite();\n"
774                  "  instance.remove$capitalized_name$(index);\n"
775                  "  return this;\n"
776                  "}\n");
777   printer->Annotate("{", "}", descriptor_);
778 }
779 
GenerateFieldInfo(io::Printer * printer,std::vector<uint16_t> * output) const780 void RepeatedImmutableMessageFieldLiteGenerator::GenerateFieldInfo(
781     io::Printer* printer, std::vector<uint16_t>* output) const {
782   WriteIntToUtf16CharSequence(descriptor_->number(), output);
783   WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_),
784                               output);
785   printer->Print(variables_,
786                  "\"$name$_\",\n"
787                  "$type$.class,\n");
788 }
789 
GenerateInitializationCode(io::Printer * printer) const790 void RepeatedImmutableMessageFieldLiteGenerator::GenerateInitializationCode(
791     io::Printer* printer) const {
792   printer->Print(variables_, "$name$_ = emptyProtobufList();\n");
793 }
794 
GetBoxedType() const795 std::string RepeatedImmutableMessageFieldLiteGenerator::GetBoxedType() const {
796   return name_resolver_->GetImmutableClassName(descriptor_->message_type());
797 }
798 
GenerateKotlinDslMembers(io::Printer * printer) const799 void RepeatedImmutableMessageFieldLiteGenerator::GenerateKotlinDslMembers(
800     io::Printer* printer) const {
801   printer->Print(
802       variables_,
803       "/**\n"
804       " * An uninstantiable, behaviorless type to represent the field in\n"
805       " * generics.\n"
806       " */\n"
807       "@kotlin.OptIn"
808       "(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)\n"
809       "public class ${$$kt_capitalized_name$Proxy$}$ private constructor()"
810       " : com.google.protobuf.kotlin.DslProxy()\n");
811 
812   WriteFieldDocComment(printer, descriptor_);
813   printer->Print(variables_,
814                  "$kt_deprecation$ public val $kt_name$: "
815                  "com.google.protobuf.kotlin.DslList"
816                  "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>\n"
817                  "  @kotlin.jvm.JvmSynthetic\n"
818                  "  get() = com.google.protobuf.kotlin.DslList(\n"
819                  "    $kt_dsl_builder$.${$get$capitalized_name$List$}$()\n"
820                  "  )\n");
821 
822   WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER,
823                                /* builder */ false);
824   printer->Print(variables_,
825                  "@kotlin.jvm.JvmSynthetic\n"
826                  "@kotlin.jvm.JvmName(\"add$kt_capitalized_name$\")\n"
827                  "public fun com.google.protobuf.kotlin.DslList"
828                  "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
829                  "add(value: $kt_type$) {\n"
830                  "  $kt_dsl_builder$.${$add$capitalized_name$$}$(value)\n"
831                  "}\n");
832 
833   WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER,
834                                /* builder */ false);
835   printer->Print(variables_,
836                  "@kotlin.jvm.JvmSynthetic\n"
837                  "@kotlin.jvm.JvmName(\"plusAssign$kt_capitalized_name$\")\n"
838                  "@Suppress(\"NOTHING_TO_INLINE\")\n"
839                  "public inline operator fun com.google.protobuf.kotlin.DslList"
840                  "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
841                  "plusAssign(value: $kt_type$) {\n"
842                  "  add(value)\n"
843                  "}\n");
844 
845   WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER,
846                                /* builder */ false);
847   printer->Print(variables_,
848                  "@kotlin.jvm.JvmSynthetic\n"
849                  "@kotlin.jvm.JvmName(\"addAll$kt_capitalized_name$\")\n"
850                  "public fun com.google.protobuf.kotlin.DslList"
851                  "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
852                  "addAll(values: kotlin.collections.Iterable<$kt_type$>) {\n"
853                  "  $kt_dsl_builder$.${$addAll$capitalized_name$$}$(values)\n"
854                  "}\n");
855 
856   WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER,
857                                /* builder */ false);
858   printer->Print(
859       variables_,
860       "@kotlin.jvm.JvmSynthetic\n"
861       "@kotlin.jvm.JvmName(\"plusAssignAll$kt_capitalized_name$\")\n"
862       "@Suppress(\"NOTHING_TO_INLINE\")\n"
863       "public inline operator fun com.google.protobuf.kotlin.DslList"
864       "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
865       "plusAssign(values: kotlin.collections.Iterable<$kt_type$>) {\n"
866       "  addAll(values)\n"
867       "}\n");
868 
869   WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER,
870                                /* builder */ false);
871   printer->Print(
872       variables_,
873       "@kotlin.jvm.JvmSynthetic\n"
874       "@kotlin.jvm.JvmName(\"set$kt_capitalized_name$\")\n"
875       "public operator fun com.google.protobuf.kotlin.DslList"
876       "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
877       "set(index: kotlin.Int, value: $kt_type$) {\n"
878       "  $kt_dsl_builder$.${$set$capitalized_name$$}$(index, value)\n"
879       "}\n");
880 
881   WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
882                                /* builder */ false);
883   printer->Print(variables_,
884                  "@kotlin.jvm.JvmSynthetic\n"
885                  "@kotlin.jvm.JvmName(\"clear$kt_capitalized_name$\")\n"
886                  "public fun com.google.protobuf.kotlin.DslList"
887                  "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
888                  "clear() {\n"
889                  "  $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n"
890                  "}\n");
891 }
892 
893 }  // namespace java
894 }  // namespace compiler
895 }  // namespace protobuf
896 }  // namespace google
897 
898 #include <google/protobuf/port_undef.inc>
899