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