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 | |
54 | namespace google { |
55 | namespace protobuf { |
56 | namespace compiler { |
57 | namespace java { |
58 | |
59 | namespace { |
60 | |
61 | void 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 | |
147 | ImmutableEnumFieldGenerator::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 | |
156 | ImmutableEnumFieldGenerator::~ImmutableEnumFieldGenerator() {} |
157 | |
158 | int ImmutableEnumFieldGenerator::GetNumBitsForMessage() const { |
159 | return HasHasbit(descriptor: descriptor_) ? 1 : 0; |
160 | } |
161 | |
162 | int ImmutableEnumFieldGenerator::GetNumBitsForBuilder() const { |
163 | return GetNumBitsForMessage(); |
164 | } |
165 | |
166 | void 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 | |
182 | void 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 | |
214 | void 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 | |
282 | void 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 | |
311 | void ImmutableEnumFieldGenerator::GenerateFieldBuilderInitializationCode( |
312 | io::Printer* printer) const { |
313 | // noop for enums |
314 | } |
315 | |
316 | void ImmutableEnumFieldGenerator::GenerateInitializationCode( |
317 | io::Printer* printer) const { |
318 | printer->Print(variables: variables_, text: "$name$_ = $default_number$;\n" ); |
319 | } |
320 | |
321 | void 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 | |
328 | void 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 | |
346 | void 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 | |
357 | void 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 | |
378 | void ImmutableEnumFieldGenerator::GenerateParsingDoneCode( |
379 | io::Printer* printer) const { |
380 | // noop for enums |
381 | } |
382 | |
383 | void 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 | |
391 | void 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 | |
400 | void ImmutableEnumFieldGenerator::GenerateEqualsCode( |
401 | io::Printer* printer) const { |
402 | printer->Print(variables: variables_, text: "if ($name$_ != other.$name$_) return false;\n" ); |
403 | } |
404 | |
405 | void 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 | |
411 | std::string ImmutableEnumFieldGenerator::GetBoxedType() const { |
412 | return name_resolver_->GetImmutableClassName(descriptor: descriptor_->enum_type()); |
413 | } |
414 | |
415 | // =================================================================== |
416 | |
417 | ImmutableEnumOneofFieldGenerator::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 | |
427 | ImmutableEnumOneofFieldGenerator::~ImmutableEnumOneofFieldGenerator() {} |
428 | |
429 | void 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 | |
466 | void 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 | |
543 | void 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 | |
551 | void 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 | |
563 | void 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 | |
584 | void 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 | |
593 | void 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 | |
603 | void 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 | |
618 | void 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 | |
634 | RepeatedImmutableEnumFieldGenerator::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 | |
643 | RepeatedImmutableEnumFieldGenerator::~RepeatedImmutableEnumFieldGenerator() {} |
644 | |
645 | int RepeatedImmutableEnumFieldGenerator::GetNumBitsForMessage() const { |
646 | return 0; |
647 | } |
648 | |
649 | int RepeatedImmutableEnumFieldGenerator::GetNumBitsForBuilder() const { |
650 | return 1; |
651 | } |
652 | |
653 | void 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 | |
677 | void 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 | |
745 | void 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 | |
905 | void RepeatedImmutableEnumFieldGenerator:: |
906 | GenerateFieldBuilderInitializationCode(io::Printer* printer) const { |
907 | // noop for enums |
908 | } |
909 | |
910 | void RepeatedImmutableEnumFieldGenerator::GenerateInitializationCode( |
911 | io::Printer* printer) const { |
912 | printer->Print(variables: variables_, text: "$name$_ = java.util.Collections.emptyList();\n" ); |
913 | } |
914 | |
915 | void 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 | |
922 | void 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 | |
942 | void 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 | |
955 | void 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 | |
984 | void 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 | |
1002 | void 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 | |
1011 | void 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 | |
1030 | void 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 | |
1063 | void RepeatedImmutableEnumFieldGenerator::GenerateEqualsCode( |
1064 | io::Printer* printer) const { |
1065 | printer->Print(variables: variables_, |
1066 | text: "if (!$name$_.equals(other.$name$_)) return false;\n" ); |
1067 | } |
1068 | |
1069 | void 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 | |
1078 | void 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 | |
1172 | std::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 | |