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