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