• 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/full/enum_field.h"
13 
14 #include <cstdint>
15 #include <string>
16 
17 #include "absl/container/flat_hash_map.h"
18 #include "absl/log/absl_check.h"
19 #include "absl/log/absl_log.h"
20 #include "absl/strings/str_cat.h"
21 #include "google/protobuf/compiler/java/context.h"
22 #include "google/protobuf/compiler/java/doc_comment.h"
23 #include "google/protobuf/compiler/java/field_common.h"
24 #include "google/protobuf/compiler/java/helpers.h"
25 #include "google/protobuf/compiler/java/internal_helpers.h"
26 #include "google/protobuf/compiler/java/name_resolver.h"
27 #include "google/protobuf/io/printer.h"
28 #include "google/protobuf/wire_format.h"
29 
30 // Must be last.
31 #include "google/protobuf/port_def.inc"
32 
33 namespace google {
34 namespace protobuf {
35 namespace compiler {
36 namespace java {
37 
38 namespace {
39 using Semantic = ::google::protobuf::io::AnnotationCollector::Semantic;
40 
SetEnumVariables(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)41 void SetEnumVariables(
42     const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex,
43     const FieldGeneratorInfo* info, ClassNameResolver* name_resolver,
44     absl::flat_hash_map<absl::string_view, std::string>* variables,
45     Context* context) {
46   SetCommonFieldVariables(descriptor, info, variables);
47 
48   (*variables)["type"] =
49       name_resolver->GetImmutableClassName(descriptor->enum_type());
50   variables->insert({"kt_type", EscapeKotlinKeywords((*variables)["type"])});
51   (*variables)["mutable_type"] =
52       name_resolver->GetMutableClassName(descriptor->enum_type());
53   (*variables)["default"] =
54       ImmutableDefaultValue(descriptor, name_resolver, context->options());
55   (*variables)["default_number"] =
56       absl::StrCat(descriptor->default_value_enum()->number());
57   (*variables)["tag"] = absl::StrCat(
58       static_cast<int32_t>(internal::WireFormat::MakeTag(descriptor)));
59   (*variables)["tag_size"] = absl::StrCat(
60       internal::WireFormat::TagSize(descriptor->number(), GetType(descriptor)));
61   // TODO: Add @deprecated javadoc when generating javadoc is supported
62   // by the proto compiler
63   (*variables)["deprecation"] =
64       descriptor->options().deprecated() ? "@java.lang.Deprecated " : "";
65   variables->insert(
66       {"kt_deprecation",
67        descriptor->options().deprecated()
68            ? absl::StrCat("@kotlin.Deprecated(message = \"Field ",
69                           (*variables)["name"], " is deprecated\") ")
70            : ""});
71   if (HasHasbit(descriptor)) {
72     // For singular messages and builders, one bit is used for the hasField bit.
73     (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
74     // Note that these have a trailing ";".
75     (*variables)["set_has_field_bit_message"] =
76         absl::StrCat(GenerateSetBit(messageBitIndex), ";");
77     (*variables)["set_has_field_bit_to_local"] =
78         GenerateSetBitToLocal(messageBitIndex);
79     (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex);
80   } else {
81     (*variables)["set_has_field_bit_message"] = "";
82     (*variables)["set_has_field_bit_to_local"] = "";
83     variables->insert({"is_field_present_message",
84                        absl::StrCat((*variables)["name"], "_ != ",
85                                     (*variables)["default"], ".getNumber()")});
86   }
87 
88   // For repeated builders, one bit is used for whether the array is immutable.
89   (*variables)["get_mutable_bit_builder"] = GenerateGetBit(builderBitIndex);
90   (*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex);
91   (*variables)["clear_mutable_bit_builder"] = GenerateClearBit(builderBitIndex);
92 
93   (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex);
94 
95   // Note that these have a trailing ";".
96   (*variables)["set_has_field_bit_builder"] =
97       absl::StrCat(GenerateSetBit(builderBitIndex), ";");
98   (*variables)["clear_has_field_bit_builder"] =
99       absl::StrCat(GenerateClearBit(builderBitIndex), ";");
100   (*variables)["get_has_field_bit_from_local"] =
101       GenerateGetBitFromLocal(builderBitIndex);
102 
103   if (SupportUnknownEnumValue(descriptor)) {
104     variables->insert(
105         {"unknown", absl::StrCat((*variables)["type"], ".UNRECOGNIZED")});
106   } else {
107     variables->insert({"unknown", (*variables)["default"]});
108   }
109 }
110 
111 }  // namespace
112 
113 // ===================================================================
114 
ImmutableEnumFieldGenerator(const FieldDescriptor * descriptor,int messageBitIndex,int builderBitIndex,Context * context)115 ImmutableEnumFieldGenerator::ImmutableEnumFieldGenerator(
116     const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex,
117     Context* context)
118     : descriptor_(descriptor),
119       message_bit_index_(messageBitIndex),
120       builder_bit_index_(builderBitIndex),
121       context_(context),
122       name_resolver_(context->GetNameResolver()) {
123   SetEnumVariables(descriptor, messageBitIndex, builderBitIndex,
124                    context->GetFieldGeneratorInfo(descriptor), name_resolver_,
125                    &variables_, context);
126 }
127 
~ImmutableEnumFieldGenerator()128 ImmutableEnumFieldGenerator::~ImmutableEnumFieldGenerator() {}
129 
GetMessageBitIndex() const130 int ImmutableEnumFieldGenerator::GetMessageBitIndex() const {
131   return message_bit_index_;
132 }
133 
GetBuilderBitIndex() const134 int ImmutableEnumFieldGenerator::GetBuilderBitIndex() const {
135   return builder_bit_index_;
136 }
137 
GetNumBitsForMessage() const138 int ImmutableEnumFieldGenerator::GetNumBitsForMessage() const {
139   return HasHasbit(descriptor_) ? 1 : 0;
140 }
141 
GetNumBitsForBuilder() const142 int ImmutableEnumFieldGenerator::GetNumBitsForBuilder() const { return 1; }
143 
GenerateInterfaceMembers(io::Printer * printer) const144 void ImmutableEnumFieldGenerator::GenerateInterfaceMembers(
145     io::Printer* printer) const {
146   if (descriptor_->has_presence()) {
147     WriteFieldAccessorDocComment(printer, descriptor_, HAZZER,
148                                  context_->options());
149     printer->Print(variables_,
150                    "$deprecation$boolean has$capitalized_name$();\n");
151   }
152   if (SupportUnknownEnumValue(descriptor_)) {
153     WriteFieldEnumValueAccessorDocComment(printer, descriptor_, GETTER,
154                                           context_->options());
155     printer->Print(variables_,
156                    "$deprecation$int get$capitalized_name$Value();\n");
157   }
158   WriteFieldAccessorDocComment(printer, descriptor_, GETTER,
159                                context_->options());
160   printer->Print(variables_, "$deprecation$$type$ get$capitalized_name$();\n");
161 }
162 
GenerateMembers(io::Printer * printer) const163 void ImmutableEnumFieldGenerator::GenerateMembers(io::Printer* printer) const {
164   printer->Print(variables_, "private int $name$_ = $default_number$;\n");
165   PrintExtraFieldInfo(variables_, printer);
166   if (descriptor_->has_presence()) {
167     WriteFieldAccessorDocComment(printer, descriptor_, HAZZER,
168                                  context_->options());
169     printer->Print(variables_,
170                    "@java.lang.Override $deprecation$public boolean "
171                    "${$has$capitalized_name$$}$() {\n"
172                    "  return $get_has_field_bit_message$;\n"
173                    "}\n");
174     printer->Annotate("{", "}", descriptor_);
175   }
176   if (SupportUnknownEnumValue(descriptor_)) {
177     WriteFieldEnumValueAccessorDocComment(printer, descriptor_, GETTER,
178                                           context_->options());
179     printer->Print(variables_,
180                    "@java.lang.Override $deprecation$public int "
181                    "${$get$capitalized_name$Value$}$() {\n"
182                    "  return $name$_;\n"
183                    "}\n");
184     printer->Annotate("{", "}", descriptor_);
185   }
186   WriteFieldAccessorDocComment(printer, descriptor_, GETTER,
187                                context_->options());
188   printer->Print(variables_,
189                  "@java.lang.Override $deprecation$public $type$ "
190                  "${$get$capitalized_name$$}$() {\n"
191                  "  $type$ result = $type$.forNumber($name$_);\n"
192                  "  return result == null ? $unknown$ : result;\n"
193                  "}\n");
194   printer->Annotate("{", "}", descriptor_);
195 }
196 
GenerateBuilderMembers(io::Printer * printer) const197 void ImmutableEnumFieldGenerator::GenerateBuilderMembers(
198     io::Printer* printer) const {
199   printer->Print(variables_, "private int $name$_ = $default_number$;\n");
200   if (descriptor_->has_presence()) {
201     WriteFieldAccessorDocComment(printer, descriptor_, HAZZER,
202                                  context_->options());
203     printer->Print(variables_,
204                    "@java.lang.Override $deprecation$public boolean "
205                    "${$has$capitalized_name$$}$() {\n"
206                    "  return $get_has_field_bit_builder$;\n"
207                    "}\n");
208     printer->Annotate("{", "}", descriptor_);
209   }
210   if (SupportUnknownEnumValue(descriptor_)) {
211     WriteFieldEnumValueAccessorDocComment(printer, descriptor_, GETTER,
212                                           context_->options());
213     printer->Print(variables_,
214                    "@java.lang.Override $deprecation$public int "
215                    "${$get$capitalized_name$Value$}$() {\n"
216                    "  return $name$_;\n"
217                    "}\n");
218     printer->Annotate("{", "}", descriptor_);
219     WriteFieldEnumValueAccessorDocComment(printer, descriptor_, SETTER,
220                                           context_->options(),
221                                           /* builder */ true);
222     printer->Print(variables_,
223                    "$deprecation$public Builder "
224                    "${$set$capitalized_name$Value$}$(int value) {\n"
225                    "  $name$_ = value;\n"
226                    "  $set_has_field_bit_builder$\n"
227                    "  onChanged();\n"
228                    "  return this;\n"
229                    "}\n");
230     printer->Annotate("{", "}", descriptor_, Semantic::kSet);
231   }
232   WriteFieldAccessorDocComment(printer, descriptor_, GETTER,
233                                context_->options());
234   printer->Print(variables_,
235                  "@java.lang.Override\n"
236                  "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
237                  "  $type$ result = $type$.forNumber($name$_);\n"
238                  "  return result == null ? $unknown$ : result;\n"
239                  "}\n");
240   printer->Annotate("{", "}", descriptor_);
241   WriteFieldAccessorDocComment(printer, descriptor_, SETTER,
242                                context_->options(),
243                                /* builder */ true);
244   printer->Print(variables_,
245                  "$deprecation$public Builder "
246                  "${$set$capitalized_name$$}$($type$ value) {\n"
247                  "  if (value == null) {\n"
248                  "    throw new NullPointerException();\n"
249                  "  }\n"
250                  "  $set_has_field_bit_builder$\n"
251                  "  $name$_ = value.getNumber();\n"
252                  "  onChanged();\n"
253                  "  return this;\n"
254                  "}\n");
255   printer->Annotate("{", "}", descriptor_, Semantic::kSet);
256   WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
257                                context_->options(),
258                                /* builder */ true);
259   printer->Print(
260       variables_,
261       "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
262       "  $clear_has_field_bit_builder$\n"
263       "  $name$_ = $default_number$;\n"
264       "  onChanged();\n"
265       "  return this;\n"
266       "}\n");
267   printer->Annotate("{", "}", descriptor_, Semantic::kSet);
268 }
269 
GenerateKotlinDslMembers(io::Printer * printer) const270 void ImmutableEnumFieldGenerator::GenerateKotlinDslMembers(
271     io::Printer* printer) const {
272   WriteFieldDocComment(printer, descriptor_, context_->options(),
273                        /* kdoc */ true);
274   printer->Print(variables_,
275                  "$kt_deprecation$public var $kt_name$: $kt_type$\n"
276                  "  @JvmName(\"${$get$kt_capitalized_name$$}$\")\n"
277                  "  get() = $kt_dsl_builder$.${$$kt_safe_name$$}$\n"
278                  "  @JvmName(\"${$set$kt_capitalized_name$$}$\")\n"
279                  "  set(value) {\n"
280                  "    $kt_dsl_builder$.${$$kt_safe_name$$}$ = value\n"
281                  "  }\n");
282 
283   if (SupportUnknownEnumValue(descriptor_)) {
284     printer->Print(
285         variables_,
286         "$kt_deprecation$public var $kt_name$Value: kotlin.Int\n"
287         "  @JvmName(\"${$get$kt_capitalized_name$Value$}$\")\n"
288         "  get() = $kt_dsl_builder$.${$$kt_property_name$Value$}$\n"
289         "  @JvmName(\"${$set$kt_capitalized_name$Value$}$\")\n"
290         "  set(value) {\n"
291         "    $kt_dsl_builder$.${$$kt_property_name$Value$}$ = value\n"
292         "  }\n");
293   }
294 
295   WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
296                                context_->options(),
297                                /* builder */ false, /* kdoc */ true);
298   printer->Print(variables_,
299                  "public fun ${$clear$kt_capitalized_name$$}$() {\n"
300                  "  $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n"
301                  "}\n");
302 
303   if (descriptor_->has_presence()) {
304     WriteFieldAccessorDocComment(printer, descriptor_, HAZZER,
305                                  context_->options(),
306                                  /* builder */ false, /* kdoc */ true);
307     printer->Print(
308         variables_,
309         "public fun ${$has$kt_capitalized_name$$}$(): kotlin.Boolean {\n"
310         "  return $kt_dsl_builder$.${$has$capitalized_name$$}$()\n"
311         "}\n");
312   }
313 }
314 
GenerateFieldBuilderInitializationCode(io::Printer * printer) const315 void ImmutableEnumFieldGenerator::GenerateFieldBuilderInitializationCode(
316     io::Printer* printer) const {
317   // noop for enums
318 }
319 
GenerateInitializationCode(io::Printer * printer) const320 void ImmutableEnumFieldGenerator::GenerateInitializationCode(
321     io::Printer* printer) const {
322   printer->Print(variables_, "$name$_ = $default_number$;\n");
323 }
324 
GenerateBuilderClearCode(io::Printer * printer) const325 void ImmutableEnumFieldGenerator::GenerateBuilderClearCode(
326     io::Printer* printer) const {
327   printer->Print(variables_, "$name$_ = $default_number$;\n");
328 }
329 
GenerateMergingCode(io::Printer * printer) const330 void ImmutableEnumFieldGenerator::GenerateMergingCode(
331     io::Printer* printer) const {
332   if (descriptor_->has_presence()) {
333     printer->Print(variables_,
334                    "if (other.has$capitalized_name$()) {\n"
335                    "  set$capitalized_name$(other.get$capitalized_name$());\n"
336                    "}\n");
337   } else if (SupportUnknownEnumValue(descriptor_)) {
338     printer->Print(
339         variables_,
340         "if (other.$name$_ != $default_number$) {\n"
341         "  set$capitalized_name$Value(other.get$capitalized_name$Value());\n"
342         "}\n");
343   } else {
344     ABSL_LOG(FATAL) << "Can't reach here.";
345   }
346 }
347 
GenerateBuildingCode(io::Printer * printer) const348 void ImmutableEnumFieldGenerator::GenerateBuildingCode(
349     io::Printer* printer) const {
350   printer->Print(variables_,
351                  "if ($get_has_field_bit_from_local$) {\n"
352                  "  result.$name$_ = $name$_;\n");
353   if (GetNumBitsForMessage() > 0) {
354     printer->Print(variables_, "  $set_has_field_bit_to_local$;\n");
355   }
356   printer->Print("}\n");
357 }
358 
GenerateBuilderParsingCode(io::Printer * printer) const359 void ImmutableEnumFieldGenerator::GenerateBuilderParsingCode(
360     io::Printer* printer) const {
361   if (SupportUnknownEnumValue(descriptor_)) {
362     printer->Print(variables_,
363                    "$name$_ = input.readEnum();\n"
364                    "$set_has_field_bit_builder$\n");
365   } else {
366     printer->Print(variables_,
367                    "int tmpRaw = input.readEnum();\n"
368                    "$type$ tmpValue =\n"
369                    "    $type$.forNumber(tmpRaw);\n"
370                    "if (tmpValue == null) {\n"
371                    "  mergeUnknownVarintField($number$, tmpRaw);\n"
372                    "} else {\n"
373                    "  $name$_ = tmpRaw;\n"
374                    "  $set_has_field_bit_builder$\n"
375                    "}\n");
376   }
377 }
378 
GenerateSerializationCode(io::Printer * printer) const379 void ImmutableEnumFieldGenerator::GenerateSerializationCode(
380     io::Printer* printer) const {
381   printer->Print(variables_,
382                  "if ($is_field_present_message$) {\n"
383                  "  output.writeEnum($number$, $name$_);\n"
384                  "}\n");
385 }
386 
GenerateSerializedSizeCode(io::Printer * printer) const387 void ImmutableEnumFieldGenerator::GenerateSerializedSizeCode(
388     io::Printer* printer) const {
389   printer->Print(variables_,
390                  "if ($is_field_present_message$) {\n"
391                  "  size += com.google.protobuf.CodedOutputStream\n"
392                  "    .computeEnumSize($number$, $name$_);\n"
393                  "}\n");
394 }
395 
GenerateEqualsCode(io::Printer * printer) const396 void ImmutableEnumFieldGenerator::GenerateEqualsCode(
397     io::Printer* printer) const {
398   printer->Print(variables_, "if ($name$_ != other.$name$_) return false;\n");
399 }
400 
GenerateHashCode(io::Printer * printer) const401 void ImmutableEnumFieldGenerator::GenerateHashCode(io::Printer* printer) const {
402   printer->Print(variables_,
403                  "hash = (37 * hash) + $constant_name$;\n"
404                  "hash = (53 * hash) + $name$_;\n");
405 }
406 
GetBoxedType() const407 std::string ImmutableEnumFieldGenerator::GetBoxedType() const {
408   return name_resolver_->GetImmutableClassName(descriptor_->enum_type());
409 }
410 
411 // ===================================================================
412 
ImmutableEnumOneofFieldGenerator(const FieldDescriptor * descriptor,int messageBitIndex,int builderBitIndex,Context * context)413 ImmutableEnumOneofFieldGenerator::ImmutableEnumOneofFieldGenerator(
414     const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex,
415     Context* context)
416     : ImmutableEnumFieldGenerator(descriptor, messageBitIndex, builderBitIndex,
417                                   context) {
418   const OneofGeneratorInfo* info =
419       context->GetOneofGeneratorInfo(descriptor->containing_oneof());
420   SetCommonOneofVariables(descriptor, info, &variables_);
421 }
422 
~ImmutableEnumOneofFieldGenerator()423 ImmutableEnumOneofFieldGenerator::~ImmutableEnumOneofFieldGenerator() {}
424 
GenerateMembers(io::Printer * printer) const425 void ImmutableEnumOneofFieldGenerator::GenerateMembers(
426     io::Printer* printer) const {
427   PrintExtraFieldInfo(variables_, printer);
428   ABSL_DCHECK(descriptor_->has_presence());
429   WriteFieldAccessorDocComment(printer, descriptor_, HAZZER,
430                                context_->options());
431   printer->Print(variables_,
432                  "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
433                  "  return $has_oneof_case_message$;\n"
434                  "}\n");
435   printer->Annotate("{", "}", descriptor_);
436 
437   if (SupportUnknownEnumValue(descriptor_)) {
438     WriteFieldEnumValueAccessorDocComment(printer, descriptor_, GETTER,
439                                           context_->options());
440     printer->Print(
441         variables_,
442         "$deprecation$public int ${$get$capitalized_name$Value$}$() {\n"
443         "  if ($has_oneof_case_message$) {\n"
444         "    return (java.lang.Integer) $oneof_name$_;\n"
445         "  }\n"
446         "  return $default_number$;\n"
447         "}\n");
448     printer->Annotate("{", "}", descriptor_);
449   }
450   WriteFieldAccessorDocComment(printer, descriptor_, GETTER,
451                                context_->options());
452   printer->Print(variables_,
453                  "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
454                  "  if ($has_oneof_case_message$) {\n"
455                  "    $type$ result = $type$.forNumber(\n"
456                  "        (java.lang.Integer) $oneof_name$_);\n"
457                  "    return result == null ? $unknown$ : result;\n"
458                  "  }\n"
459                  "  return $default$;\n"
460                  "}\n");
461   printer->Annotate("{", "}", descriptor_);
462 }
463 
GenerateBuilderMembers(io::Printer * printer) const464 void ImmutableEnumOneofFieldGenerator::GenerateBuilderMembers(
465     io::Printer* printer) const {
466   ABSL_DCHECK(descriptor_->has_presence());
467   WriteFieldAccessorDocComment(printer, descriptor_, HAZZER,
468                                context_->options());
469   printer->Print(variables_,
470                  "@java.lang.Override\n"
471                  "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
472                  "  return $has_oneof_case_message$;\n"
473                  "}\n");
474   printer->Annotate("{", "}", descriptor_);
475 
476   if (SupportUnknownEnumValue(descriptor_)) {
477     WriteFieldEnumValueAccessorDocComment(printer, descriptor_, GETTER,
478                                           context_->options());
479     printer->Print(
480         variables_,
481         "@java.lang.Override\n"
482         "$deprecation$public int ${$get$capitalized_name$Value$}$() {\n"
483         "  if ($has_oneof_case_message$) {\n"
484         "    return ((java.lang.Integer) $oneof_name$_).intValue();\n"
485         "  }\n"
486         "  return $default_number$;\n"
487         "}\n");
488     printer->Annotate("{", "}", descriptor_);
489     WriteFieldEnumValueAccessorDocComment(printer, descriptor_, SETTER,
490                                           context_->options(),
491                                           /* builder */ true);
492     printer->Print(variables_,
493                    "$deprecation$public Builder "
494                    "${$set$capitalized_name$Value$}$(int value) {\n"
495                    "  $set_oneof_case_message$;\n"
496                    "  $oneof_name$_ = value;\n"
497                    "  onChanged();\n"
498                    "  return this;\n"
499                    "}\n");
500     printer->Annotate("{", "}", descriptor_, Semantic::kSet);
501   }
502   WriteFieldAccessorDocComment(printer, descriptor_, GETTER,
503                                context_->options());
504   printer->Print(variables_,
505                  "@java.lang.Override\n"
506                  "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
507                  "  if ($has_oneof_case_message$) {\n"
508                  "    $type$ result = $type$.forNumber(\n"
509                  "        (java.lang.Integer) $oneof_name$_);\n"
510                  "    return result == null ? $unknown$ : result;\n"
511                  "  }\n"
512                  "  return $default$;\n"
513                  "}\n");
514   printer->Annotate("{", "}", descriptor_);
515 
516   WriteFieldAccessorDocComment(printer, descriptor_, SETTER,
517                                context_->options(),
518                                /* builder */ true);
519   printer->Print(variables_,
520                  "$deprecation$public Builder "
521                  "${$set$capitalized_name$$}$($type$ value) {\n"
522                  "  if (value == null) {\n"
523                  "    throw new NullPointerException();\n"
524                  "  }\n"
525                  "  $set_oneof_case_message$;\n"
526                  "  $oneof_name$_ = value.getNumber();\n"
527                  "  onChanged();\n"
528                  "  return this;\n"
529                  "}\n");
530   printer->Annotate("{", "}", descriptor_, Semantic::kSet);
531 
532   WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
533                                context_->options(),
534                                /* builder */ true);
535   printer->Print(
536       variables_,
537       "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
538       "  if ($has_oneof_case_message$) {\n"
539       "    $clear_oneof_case_message$;\n"
540       "    $oneof_name$_ = null;\n"
541       "    onChanged();\n"
542       "  }\n"
543       "  return this;\n"
544       "}\n");
545   printer->Annotate("{", "}", descriptor_, Semantic::kSet);
546 }
547 
GenerateBuilderClearCode(io::Printer * printer) const548 void ImmutableEnumOneofFieldGenerator::GenerateBuilderClearCode(
549     io::Printer* printer) const {
550   // No-op: Enum fields in oneofs are correctly cleared by clearing the oneof
551 }
552 
GenerateBuildingCode(io::Printer * printer) const553 void ImmutableEnumOneofFieldGenerator::GenerateBuildingCode(
554     io::Printer* printer) const {
555   // No-Op: Handled by single statement for the oneof
556 }
557 
GenerateMergingCode(io::Printer * printer) const558 void ImmutableEnumOneofFieldGenerator::GenerateMergingCode(
559     io::Printer* printer) const {
560   if (SupportUnknownEnumValue(descriptor_)) {
561     printer->Print(
562         variables_,
563         "set$capitalized_name$Value(other.get$capitalized_name$Value());\n");
564   } else {
565     printer->Print(variables_,
566                    "set$capitalized_name$(other.get$capitalized_name$());\n");
567   }
568 }
569 
GenerateBuilderParsingCode(io::Printer * printer) const570 void ImmutableEnumOneofFieldGenerator::GenerateBuilderParsingCode(
571     io::Printer* printer) const {
572   if (SupportUnknownEnumValue(descriptor_)) {
573     printer->Print(variables_,
574                    "int rawValue = input.readEnum();\n"
575                    "$set_oneof_case_message$;\n"
576                    "$oneof_name$_ = rawValue;\n");
577   } else {
578     printer->Print(variables_,
579                    "int rawValue = input.readEnum();\n"
580                    "$type$ value =\n"
581                    "    $type$.forNumber(rawValue);\n"
582                    "if (value == null) {\n"
583                    "  mergeUnknownVarintField($number$, rawValue);\n"
584                    "} else {\n"
585                    "  $set_oneof_case_message$;\n"
586                    "  $oneof_name$_ = rawValue;\n"
587                    "}\n");
588   }
589 }
590 
GenerateSerializationCode(io::Printer * printer) const591 void ImmutableEnumOneofFieldGenerator::GenerateSerializationCode(
592     io::Printer* printer) const {
593   printer->Print(
594       variables_,
595       "if ($has_oneof_case_message$) {\n"
596       "  output.writeEnum($number$, ((java.lang.Integer) $oneof_name$_));\n"
597       "}\n");
598 }
599 
GenerateSerializedSizeCode(io::Printer * printer) const600 void ImmutableEnumOneofFieldGenerator::GenerateSerializedSizeCode(
601     io::Printer* printer) const {
602   printer->Print(
603       variables_,
604       "if ($has_oneof_case_message$) {\n"
605       "  size += com.google.protobuf.CodedOutputStream\n"
606       "    .computeEnumSize($number$, ((java.lang.Integer) $oneof_name$_));\n"
607       "}\n");
608 }
609 
GenerateEqualsCode(io::Printer * printer) const610 void ImmutableEnumOneofFieldGenerator::GenerateEqualsCode(
611     io::Printer* printer) const {
612   if (SupportUnknownEnumValue(descriptor_)) {
613     printer->Print(
614         variables_,
615         "if (get$capitalized_name$Value()\n"
616         "    != other.get$capitalized_name$Value()) return false;\n");
617   } else {
618     printer->Print(
619         variables_,
620         "if (!get$capitalized_name$()\n"
621         "    .equals(other.get$capitalized_name$())) return false;\n");
622   }
623 }
624 
GenerateHashCode(io::Printer * printer) const625 void ImmutableEnumOneofFieldGenerator::GenerateHashCode(
626     io::Printer* printer) const {
627   if (SupportUnknownEnumValue(descriptor_)) {
628     printer->Print(variables_,
629                    "hash = (37 * hash) + $constant_name$;\n"
630                    "hash = (53 * hash) + get$capitalized_name$Value();\n");
631   } else {
632     printer->Print(
633         variables_,
634         "hash = (37 * hash) + $constant_name$;\n"
635         "hash = (53 * hash) + get$capitalized_name$().getNumber();\n");
636   }
637 }
638 
639 // ===================================================================
640 
RepeatedImmutableEnumFieldGenerator(const FieldDescriptor * descriptor,int messageBitIndex,int builderBitIndex,Context * context)641 RepeatedImmutableEnumFieldGenerator::RepeatedImmutableEnumFieldGenerator(
642     const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex,
643     Context* context)
644     : ImmutableEnumFieldGenerator(descriptor, messageBitIndex, builderBitIndex,
645                                   context) {}
646 
~RepeatedImmutableEnumFieldGenerator()647 RepeatedImmutableEnumFieldGenerator::~RepeatedImmutableEnumFieldGenerator() {}
648 
GetNumBitsForMessage() const649 int RepeatedImmutableEnumFieldGenerator::GetNumBitsForMessage() const {
650   return 0;
651 }
652 
GetNumBitsForBuilder() const653 int RepeatedImmutableEnumFieldGenerator::GetNumBitsForBuilder() const {
654   return 1;
655 }
656 
GenerateInterfaceMembers(io::Printer * printer) const657 void RepeatedImmutableEnumFieldGenerator::GenerateInterfaceMembers(
658     io::Printer* printer) const {
659   WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER,
660                                context_->options());
661   printer->Print(
662       variables_,
663       "$deprecation$java.util.List<$type$> get$capitalized_name$List();\n");
664   WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT,
665                                context_->options());
666   printer->Print(variables_,
667                  "$deprecation$int get$capitalized_name$Count();\n");
668   WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER,
669                                context_->options());
670   printer->Print(variables_,
671                  "$deprecation$$type$ get$capitalized_name$(int index);\n");
672   if (SupportUnknownEnumValue(descriptor_)) {
673     WriteFieldEnumValueAccessorDocComment(printer, descriptor_, LIST_GETTER,
674                                           context_->options());
675     printer->Print(variables_,
676                    "$deprecation$java.util.List<java.lang.Integer>\n"
677                    "get$capitalized_name$ValueList();\n");
678     WriteFieldEnumValueAccessorDocComment(
679         printer, descriptor_, LIST_INDEXED_GETTER, context_->options());
680     printer->Print(variables_,
681                    "$deprecation$int get$capitalized_name$Value(int index);\n");
682   }
683 }
684 
GenerateMembers(io::Printer * printer) const685 void RepeatedImmutableEnumFieldGenerator::GenerateMembers(
686     io::Printer* printer) const {
687   printer->Print(
688       variables_,
689       "@SuppressWarnings(\"serial\")\n"
690       "private com.google.protobuf.Internal.IntList $name$_;\n"
691       "private static final "
692       "com.google.protobuf.Internal.IntListAdapter.IntConverter<\n"
693       "    $type$> $name$_converter_ =\n"
694       "        new com.google.protobuf.Internal.IntListAdapter.IntConverter<\n"
695       "            $type$>() {\n"
696       "          public $type$ convert(int from) {\n"
697       "            $type$ result = $type$.forNumber(from);\n"
698       "            return result == null ? $unknown$ : result;\n"
699       "          }\n"
700       "        };\n");
701   PrintExtraFieldInfo(variables_, printer);
702   WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER,
703                                context_->options());
704   printer->Print(variables_,
705                  "@java.lang.Override\n"
706                  "$deprecation$public java.util.List<$type$> "
707                  "${$get$capitalized_name$List$}$() {\n"
708                  "  return new com.google.protobuf.Internal.IntListAdapter<\n"
709                  "      $type$>($name$_, $name$_converter_);\n"
710                  "}\n");
711   printer->Annotate("{", "}", descriptor_);
712   WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT,
713                                context_->options());
714   printer->Print(
715       variables_,
716       "@java.lang.Override\n"
717       "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
718       "  return $name$_.size();\n"
719       "}\n");
720   printer->Annotate("{", "}", descriptor_);
721   WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER,
722                                context_->options());
723   printer->Print(
724       variables_,
725       "@java.lang.Override\n"
726       "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n"
727       "  return $name$_converter_.convert($name$_.getInt(index));\n"
728       "}\n");
729   printer->Annotate("{", "}", descriptor_);
730   if (SupportUnknownEnumValue(descriptor_)) {
731     WriteFieldEnumValueAccessorDocComment(printer, descriptor_, LIST_GETTER,
732                                           context_->options());
733     printer->Print(variables_,
734                    "@java.lang.Override\n"
735                    "$deprecation$public java.util.List<java.lang.Integer>\n"
736                    "${$get$capitalized_name$ValueList$}$() {\n"
737                    "  return $name$_;\n"
738                    "}\n");
739     printer->Annotate("{", "}", descriptor_);
740     WriteFieldEnumValueAccessorDocComment(
741         printer, descriptor_, LIST_INDEXED_GETTER, context_->options());
742     printer->Print(variables_,
743                    "@java.lang.Override\n"
744                    "$deprecation$public int "
745                    "${$get$capitalized_name$Value$}$(int index) {\n"
746                    "  return $name$_.getInt(index);\n"
747                    "}\n");
748     printer->Annotate("{", "}", descriptor_);
749   }
750 
751   if (descriptor_->is_packed()) {
752     printer->Print(variables_, "private int $name$MemoizedSerializedSize;\n");
753   }
754 }
755 
GenerateBuilderMembers(io::Printer * printer) const756 void RepeatedImmutableEnumFieldGenerator::GenerateBuilderMembers(
757     io::Printer* printer) const {
758   printer->Print(
759       variables_,
760       // One field is the list and the other field keeps track of whether the
761       // list is immutable. If it's immutable, the invariant is that it must
762       // either an instance of emptyIntList() or it's an immutable IntArrayList
763       // and nobody else has a reference to the underlying ArrayList. This
764       // invariant allows us to share instances of lists between protocol
765       // buffers avoiding expensive memory allocations. Note, immutable is a
766       // strong guarantee here -- not just that the list cannot be modified via
767       // the reference but that the list can never be modified.
768       "private com.google.protobuf.Internal.IntList $name$_ =\n"
769       "  emptyIntList();\n"
770 
771       "private void ensure$capitalized_name$IsMutable() {\n"
772       "  if (!$get_mutable_bit_builder$) {\n"
773       "    $name$_ = makeMutableCopy($name$_);\n"
774       "    $set_mutable_bit_builder$;\n"
775       "  }\n"
776       "}\n");
777 
778   WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER,
779                                context_->options());
780   printer->Print(
781       variables_,
782       // Note:  We return an unmodifiable list because otherwise the caller
783       //   could hold on to the returned list and modify it after the message
784       //   has been built, thus mutating the message which is supposed to be
785       //   immutable.
786       "$deprecation$public java.util.List<$type$> "
787       "${$get$capitalized_name$List$}$() {\n"
788       "  return new com.google.protobuf.Internal.IntListAdapter<\n"
789       "      $type$>($name$_, $name$_converter_);\n"
790       "}\n");
791   printer->Annotate("{", "}", descriptor_);
792   WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT,
793                                context_->options());
794   printer->Print(
795       variables_,
796       "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
797       "  return $name$_.size();\n"
798       "}\n");
799   printer->Annotate("{", "}", descriptor_);
800   WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER,
801                                context_->options());
802   printer->Print(
803       variables_,
804       "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n"
805       "  return $name$_converter_.convert($name$_.getInt(index));\n"
806       "}\n");
807   printer->Annotate("{", "}", descriptor_);
808   WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER,
809                                context_->options(),
810                                /* builder */ true);
811   printer->Print(variables_,
812                  "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
813                  "    int index, $type$ value) {\n"
814                  "  if (value == null) {\n"
815                  "    throw new NullPointerException();\n"
816                  "  }\n"
817                  "  ensure$capitalized_name$IsMutable();\n"
818                  "  $name$_.setInt(index, value.getNumber());\n"
819                  "  onChanged();\n"
820                  "  return this;\n"
821                  "}\n");
822   printer->Annotate("{", "}", descriptor_, Semantic::kSet);
823   WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER,
824                                context_->options(),
825                                /* builder */ true);
826   printer->Print(variables_,
827                  "$deprecation$public Builder "
828                  "${$add$capitalized_name$$}$($type$ value) {\n"
829                  "  if (value == null) {\n"
830                  "    throw new NullPointerException();\n"
831                  "  }\n"
832                  "  ensure$capitalized_name$IsMutable();\n"
833                  "  $name$_.addInt(value.getNumber());\n"
834                  "  onChanged();\n"
835                  "  return this;\n"
836                  "}\n");
837   printer->Annotate("{", "}", descriptor_, Semantic::kSet);
838   WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER,
839                                context_->options(),
840                                /* builder */ true);
841   printer->Print(variables_,
842                  "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n"
843                  "    java.lang.Iterable<? extends $type$> values) {\n"
844                  "  ensure$capitalized_name$IsMutable();\n"
845                  "  for ($type$ value : values) {\n"
846                  "    $name$_.addInt(value.getNumber());\n"
847                  "  }\n"
848                  "  onChanged();\n"
849                  "  return this;\n"
850                  "}\n");
851   printer->Annotate("{", "}", descriptor_, Semantic::kSet);
852   WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
853                                context_->options(),
854                                /* builder */ true);
855   printer->Print(
856       variables_,
857       "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
858       "  $name$_ = emptyIntList();\n"
859       "  $clear_mutable_bit_builder$;\n"
860       "  onChanged();\n"
861       "  return this;\n"
862       "}\n");
863   printer->Annotate("{", "}", descriptor_, Semantic::kSet);
864 
865   if (SupportUnknownEnumValue(descriptor_)) {
866     WriteFieldEnumValueAccessorDocComment(printer, descriptor_, LIST_GETTER,
867                                           context_->options());
868     printer->Print(variables_,
869                    "$deprecation$public java.util.List<java.lang.Integer>\n"
870                    "${$get$capitalized_name$ValueList$}$() {\n"
871                    "  return java.util.Collections.unmodifiableList($name$_);\n"
872                    "}\n");
873     printer->Annotate("{", "}", descriptor_);
874     WriteFieldEnumValueAccessorDocComment(
875         printer, descriptor_, LIST_INDEXED_GETTER, context_->options());
876     printer->Print(variables_,
877                    "$deprecation$public int "
878                    "${$get$capitalized_name$Value$}$(int index) {\n"
879                    "  return $name$_.getInt(index);\n"
880                    "}\n");
881     printer->Annotate("{", "}", descriptor_);
882     WriteFieldEnumValueAccessorDocComment(
883         printer, descriptor_, LIST_INDEXED_SETTER, context_->options(),
884         /* builder */ true);
885     printer->Print(
886         variables_,
887         "$deprecation$public Builder ${$set$capitalized_name$Value$}$(\n"
888         "    int index, int value) {\n"
889         "  ensure$capitalized_name$IsMutable();\n"
890         "  $name$_.setInt(index, value);\n"
891         "  onChanged();\n"
892         "  return this;\n"
893         "}\n");
894     printer->Annotate("{", "}", descriptor_, Semantic::kSet);
895     WriteFieldEnumValueAccessorDocComment(printer, descriptor_, LIST_ADDER,
896                                           context_->options(),
897                                           /* builder */ true);
898     printer->Print(variables_,
899                    "$deprecation$public Builder "
900                    "${$add$capitalized_name$Value$}$(int value) {\n"
901                    "  ensure$capitalized_name$IsMutable();\n"
902                    "  $name$_.addInt(value);\n"
903                    "  onChanged();\n"
904                    "  return this;\n"
905                    "}\n");
906     printer->Annotate("{", "}", descriptor_, Semantic::kSet);
907     WriteFieldEnumValueAccessorDocComment(printer, descriptor_,
908                                           LIST_MULTI_ADDER, context_->options(),
909                                           /* builder */ true);
910     printer->Print(
911         variables_,
912         "$deprecation$public Builder ${$addAll$capitalized_name$Value$}$(\n"
913         "    java.lang.Iterable<java.lang.Integer> values) {\n"
914         "  ensure$capitalized_name$IsMutable();\n"
915         "  for (int value : values) {\n"
916         "    $name$_.addInt(value);\n"
917         "  }\n"
918         "  onChanged();\n"
919         "  return this;\n"
920         "}\n");
921     printer->Annotate("{", "}", descriptor_);
922   }
923 }
924 
925 void RepeatedImmutableEnumFieldGenerator::
GenerateFieldBuilderInitializationCode(io::Printer * printer) const926     GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
927   // noop for enums
928 }
929 
GenerateInitializationCode(io::Printer * printer) const930 void RepeatedImmutableEnumFieldGenerator::GenerateInitializationCode(
931     io::Printer* printer) const {
932   printer->Print(variables_, "$name$_ = emptyIntList();\n");
933 }
934 
GenerateBuilderClearCode(io::Printer * printer) const935 void RepeatedImmutableEnumFieldGenerator::GenerateBuilderClearCode(
936     io::Printer* printer) const {
937   printer->Print(variables_,
938                  "$name$_ = emptyIntList();\n"
939                  "$clear_mutable_bit_builder$;\n");
940 }
941 
GenerateMergingCode(io::Printer * printer) const942 void RepeatedImmutableEnumFieldGenerator::GenerateMergingCode(
943     io::Printer* printer) const {
944   // The code below does two optimizations:
945   //   1. If the other list is empty, there's nothing to do. This ensures we
946   //      don't allocate a new array if we already have an immutable one.
947   //   2. If the other list is non-empty and our current list is empty, we can
948   //      reuse the other list which is guaranteed to be immutable.
949   printer->Print(variables_,
950                  "if (!other.$name$_.isEmpty()) {\n"
951                  "  if ($name$_.isEmpty()) {\n"
952                  "    $name$_ = other.$name$_;\n"
953                  "    $clear_mutable_bit_builder$;\n"
954                  "  } else {\n"
955                  "    ensure$capitalized_name$IsMutable();\n"
956                  "    $name$_.addAll(other.$name$_);\n"
957                  "  }\n"
958                  "  onChanged();\n"
959                  "}\n");
960 }
961 
GenerateBuildingCode(io::Printer * printer) const962 void RepeatedImmutableEnumFieldGenerator::GenerateBuildingCode(
963     io::Printer* printer) const {
964   // The code below ensures that the result has an immutable list. If our
965   // list is immutable, we can just reuse it. If not, we make it immutable.
966   printer->Print(variables_,
967                  "if ($get_mutable_bit_builder$) {\n"
968                  "  $name$_.makeImmutable();\n"
969                  "  $clear_mutable_bit_builder$;\n"
970                  "}\n"
971                  "result.$name$_ = $name$_;\n");
972 }
973 
GenerateBuilderParsingCode(io::Printer * printer) const974 void RepeatedImmutableEnumFieldGenerator::GenerateBuilderParsingCode(
975     io::Printer* printer) const {
976   // Read and store the enum
977   if (SupportUnknownEnumValue(descriptor_)) {
978     printer->Print(variables_,
979                    "int tmpRaw = input.readEnum();\n"
980                    "ensure$capitalized_name$IsMutable();\n"
981                    "$name$_.addInt(tmpRaw);\n");
982   } else {
983     printer->Print(variables_,
984                    "int tmpRaw = input.readEnum();\n"
985                    "$type$ tmpValue =\n"
986                    "    $type$.forNumber(tmpRaw);\n"
987                    "if (tmpValue == null) {\n"
988                    "  mergeUnknownVarintField($number$, tmpRaw);\n"
989                    "} else {\n"
990                    "  ensure$capitalized_name$IsMutable();\n"
991                    "  $name$_.addInt(tmpRaw);\n"
992                    "}\n");
993   }
994 }
995 
GenerateBuilderParsingCodeFromPacked(io::Printer * printer) const996 void RepeatedImmutableEnumFieldGenerator::GenerateBuilderParsingCodeFromPacked(
997     io::Printer* printer) const {
998   // Wrap GenerateParsingCode's contents with a while loop.
999 
1000   printer->Print(variables_,
1001                  "int length = input.readRawVarint32();\n"
1002                  "int oldLimit = input.pushLimit(length);\n"
1003                  "while(input.getBytesUntilLimit() > 0) {\n");
1004   printer->Indent();
1005 
1006   GenerateBuilderParsingCode(printer);
1007 
1008   printer->Outdent();
1009   printer->Print(variables_,
1010                  "}\n"
1011                  "input.popLimit(oldLimit);\n");
1012 }
GenerateSerializationCode(io::Printer * printer) const1013 void RepeatedImmutableEnumFieldGenerator::GenerateSerializationCode(
1014     io::Printer* printer) const {
1015   if (descriptor_->is_packed()) {
1016     printer->Print(variables_,
1017                    "if (get$capitalized_name$List().size() > 0) {\n"
1018                    "  output.writeUInt32NoTag($tag$);\n"
1019                    "  output.writeUInt32NoTag($name$MemoizedSerializedSize);\n"
1020                    "}\n"
1021                    "for (int i = 0; i < $name$_.size(); i++) {\n"
1022                    "  output.writeEnumNoTag($name$_.getInt(i));\n"
1023                    "}\n");
1024   } else {
1025     printer->Print(variables_,
1026                    "for (int i = 0; i < $name$_.size(); i++) {\n"
1027                    "  output.writeEnum($number$, $name$_.getInt(i));\n"
1028                    "}\n");
1029   }
1030 }
1031 
GenerateSerializedSizeCode(io::Printer * printer) const1032 void RepeatedImmutableEnumFieldGenerator::GenerateSerializedSizeCode(
1033     io::Printer* printer) const {
1034   printer->Print(variables_,
1035                  "{\n"
1036                  "  int dataSize = 0;\n");
1037   printer->Indent();
1038 
1039   printer->Print(variables_,
1040                  "for (int i = 0; i < $name$_.size(); i++) {\n"
1041                  "  dataSize += com.google.protobuf.CodedOutputStream\n"
1042                  "    .computeEnumSizeNoTag($name$_.getInt(i));\n"
1043                  "}\n");
1044   printer->Print("size += dataSize;\n");
1045   if (descriptor_->is_packed()) {
1046     printer->Print(variables_,
1047                    "if (!get$capitalized_name$List().isEmpty()) {"
1048                    "  size += $tag_size$;\n"
1049                    "  size += com.google.protobuf.CodedOutputStream\n"
1050                    "    .computeUInt32SizeNoTag(dataSize);\n"
1051                    "}");
1052   } else {
1053     printer->Print(variables_, "size += $tag_size$ * $name$_.size();\n");
1054   }
1055 
1056   // cache the data size for packed fields.
1057   if (descriptor_->is_packed()) {
1058     printer->Print(variables_, "$name$MemoizedSerializedSize = dataSize;\n");
1059   }
1060 
1061   printer->Outdent();
1062   printer->Print("}\n");
1063 }
1064 
GenerateEqualsCode(io::Printer * printer) const1065 void RepeatedImmutableEnumFieldGenerator::GenerateEqualsCode(
1066     io::Printer* printer) const {
1067   printer->Print(variables_,
1068                  "if (!$name$_.equals(other.$name$_)) return false;\n");
1069 }
1070 
GenerateHashCode(io::Printer * printer) const1071 void RepeatedImmutableEnumFieldGenerator::GenerateHashCode(
1072     io::Printer* printer) const {
1073   printer->Print(variables_,
1074                  "if (get$capitalized_name$Count() > 0) {\n"
1075                  "  hash = (37 * hash) + $constant_name$;\n"
1076                  "  hash = (53 * hash) + $name$_.hashCode();\n"
1077                  "}\n");
1078 }
1079 
GenerateKotlinDslMembers(io::Printer * printer) const1080 void RepeatedImmutableEnumFieldGenerator::GenerateKotlinDslMembers(
1081     io::Printer* printer) const {
1082   printer->Print(
1083       variables_,
1084       "/**\n"
1085       " * An uninstantiable, behaviorless type to represent the field in\n"
1086       " * generics.\n"
1087       " */\n"
1088       "@kotlin.OptIn"
1089       "(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)\n"
1090       "public class ${$$kt_capitalized_name$Proxy$}$ private constructor()"
1091       " : com.google.protobuf.kotlin.DslProxy()\n");
1092 
1093   WriteFieldDocComment(printer, descriptor_, context_->options(),
1094                        /* kdoc */ true);
1095   printer->Print(variables_,
1096                  "$kt_deprecation$public val $kt_name$: "
1097                  "com.google.protobuf.kotlin.DslList"
1098                  "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>\n"
1099                  "  @kotlin.jvm.JvmSynthetic\n"
1100                  "  get() = com.google.protobuf.kotlin.DslList(\n"
1101                  "    $kt_dsl_builder$.${$$kt_property_name$List$}$\n"
1102                  "  )\n");
1103 
1104   WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER,
1105                                context_->options(),
1106                                /* builder */ false, /* kdoc */ true);
1107   printer->Print(variables_,
1108                  "@kotlin.jvm.JvmSynthetic\n"
1109                  "@kotlin.jvm.JvmName(\"add$kt_capitalized_name$\")\n"
1110                  "public fun com.google.protobuf.kotlin.DslList"
1111                  "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
1112                  "add(value: $kt_type$) {\n"
1113                  "  $kt_dsl_builder$.${$add$capitalized_name$$}$(value)\n"
1114                  "}");
1115 
1116   WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER,
1117                                context_->options(),
1118                                /* builder */ false, /* kdoc */ true);
1119   printer->Print(variables_,
1120                  "@kotlin.jvm.JvmSynthetic\n"
1121                  "@kotlin.jvm.JvmName(\"plusAssign$kt_capitalized_name$\")\n"
1122                  "@Suppress(\"NOTHING_TO_INLINE\")\n"
1123                  "public inline operator fun com.google.protobuf.kotlin.DslList"
1124                  "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
1125                  "plusAssign(value: $kt_type$) {\n"
1126                  "  add(value)\n"
1127                  "}");
1128 
1129   WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER,
1130                                context_->options(),
1131                                /* builder */ false, /* kdoc */ true);
1132   printer->Print(variables_,
1133                  "@kotlin.jvm.JvmSynthetic\n"
1134                  "@kotlin.jvm.JvmName(\"addAll$kt_capitalized_name$\")\n"
1135                  "public fun com.google.protobuf.kotlin.DslList"
1136                  "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
1137                  "addAll(values: kotlin.collections.Iterable<$kt_type$>) {\n"
1138                  "  $kt_dsl_builder$.${$addAll$capitalized_name$$}$(values)\n"
1139                  "}");
1140 
1141   WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER,
1142                                context_->options(),
1143                                /* builder */ false, /* kdoc */ true);
1144   printer->Print(
1145       variables_,
1146       "@kotlin.jvm.JvmSynthetic\n"
1147       "@kotlin.jvm.JvmName(\"plusAssignAll$kt_capitalized_name$\")\n"
1148       "@Suppress(\"NOTHING_TO_INLINE\")\n"
1149       "public inline operator fun com.google.protobuf.kotlin.DslList"
1150       "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
1151       "plusAssign(values: kotlin.collections.Iterable<$kt_type$>) {\n"
1152       "  addAll(values)\n"
1153       "}");
1154 
1155   WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER,
1156                                context_->options(),
1157                                /* builder */ false, /* kdoc */ true);
1158   printer->Print(
1159       variables_,
1160       "@kotlin.jvm.JvmSynthetic\n"
1161       "@kotlin.jvm.JvmName(\"set$kt_capitalized_name$\")\n"
1162       "public operator fun com.google.protobuf.kotlin.DslList"
1163       "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
1164       "set(index: kotlin.Int, value: $kt_type$) {\n"
1165       "  $kt_dsl_builder$.${$set$capitalized_name$$}$(index, value)\n"
1166       "}");
1167 
1168   WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
1169                                context_->options(),
1170                                /* builder */ false, /* kdoc */ true);
1171   printer->Print(variables_,
1172                  "@kotlin.jvm.JvmSynthetic\n"
1173                  "@kotlin.jvm.JvmName(\"clear$kt_capitalized_name$\")\n"
1174                  "public fun com.google.protobuf.kotlin.DslList"
1175                  "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
1176                  "clear() {\n"
1177                  "  $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n"
1178                  "}");
1179 }
1180 
GetBoxedType() const1181 std::string RepeatedImmutableEnumFieldGenerator::GetBoxedType() const {
1182   return name_resolver_->GetImmutableClassName(descriptor_->enum_type());
1183 }
1184 
1185 }  // namespace java
1186 }  // namespace compiler
1187 }  // namespace protobuf
1188 }  // namespace google
1189 
1190 #include "google/protobuf/port_undef.inc"
1191