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