Line data Source code
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 <map>
36 : #include <string>
37 :
38 : #include <google/protobuf/stubs/logging.h>
39 : #include <google/protobuf/stubs/common.h>
40 : #include <google/protobuf/compiler/java/java_context.h>
41 : #include <google/protobuf/compiler/java/java_doc_comment.h>
42 : #include <google/protobuf/compiler/java/java_enum_field.h>
43 : #include <google/protobuf/compiler/java/java_helpers.h>
44 : #include <google/protobuf/compiler/java/java_name_resolver.h>
45 : #include <google/protobuf/io/printer.h>
46 : #include <google/protobuf/wire_format.h>
47 : #include <google/protobuf/stubs/strutil.h>
48 :
49 : namespace google {
50 : namespace protobuf {
51 : namespace compiler {
52 : namespace java {
53 :
54 : namespace {
55 :
56 0 : void SetEnumVariables(const FieldDescriptor* descriptor,
57 : int messageBitIndex,
58 : int builderBitIndex,
59 : const FieldGeneratorInfo* info,
60 : ClassNameResolver* name_resolver,
61 : map<string, string>* variables) {
62 0 : SetCommonFieldVariables(descriptor, info, variables);
63 :
64 0 : (*variables)["type"] =
65 : name_resolver->GetImmutableClassName(descriptor->enum_type());
66 0 : (*variables)["mutable_type"] =
67 : name_resolver->GetMutableClassName(descriptor->enum_type());
68 0 : (*variables)["default"] = ImmutableDefaultValue(descriptor, name_resolver);
69 0 : (*variables)["default_number"] = SimpleItoa(
70 : descriptor->default_value_enum()->number());
71 0 : if (descriptor->is_packed()) {
72 0 : (*variables)["tag"] = SimpleItoa(internal::WireFormatLite::MakeTag(
73 : descriptor->number(),
74 : internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED));
75 : } else {
76 0 : (*variables)["tag"] = SimpleItoa(internal::WireFormat::MakeTag(descriptor));
77 : }
78 0 : (*variables)["tag_size"] = SimpleItoa(
79 : internal::WireFormat::TagSize(descriptor->number(), GetType(descriptor)));
80 : // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
81 : // by the proto compiler
82 0 : (*variables)["deprecation"] = descriptor->options().deprecated()
83 : ? "@java.lang.Deprecated " : "";
84 0 : (*variables)["on_changed"] =
85 0 : HasDescriptorMethods(descriptor->containing_type()) ? "onChanged();" : "";
86 :
87 0 : if (SupportFieldPresence(descriptor->file())) {
88 : // For singular messages and builders, one bit is used for the hasField bit.
89 0 : (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
90 0 : (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex);
91 :
92 : // Note that these have a trailing ";".
93 0 : (*variables)["set_has_field_bit_message"] =
94 0 : GenerateSetBit(messageBitIndex) + ";";
95 0 : (*variables)["set_has_field_bit_builder"] =
96 0 : GenerateSetBit(builderBitIndex) + ";";
97 0 : (*variables)["clear_has_field_bit_builder"] =
98 0 : GenerateClearBit(builderBitIndex) + ";";
99 :
100 0 : (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex);
101 : } else {
102 0 : (*variables)["set_has_field_bit_message"] = "";
103 0 : (*variables)["set_has_field_bit_builder"] = "";
104 0 : (*variables)["clear_has_field_bit_builder"] = "";
105 :
106 0 : (*variables)["is_field_present_message"] =
107 0 : (*variables)["name"] + "_ != " +
108 0 : (*variables)["default"] + ".getNumber()";
109 : }
110 :
111 : // For repated builders, one bit is used for whether the array is immutable.
112 0 : (*variables)["get_mutable_bit_builder"] = GenerateGetBit(builderBitIndex);
113 0 : (*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex);
114 0 : (*variables)["clear_mutable_bit_builder"] = GenerateClearBit(builderBitIndex);
115 :
116 : // For repeated fields, one bit is used for whether the array is immutable
117 : // in the parsing constructor.
118 0 : (*variables)["get_mutable_bit_parser"] =
119 : GenerateGetBitMutableLocal(builderBitIndex);
120 0 : (*variables)["set_mutable_bit_parser"] =
121 : GenerateSetBitMutableLocal(builderBitIndex);
122 :
123 0 : (*variables)["get_has_field_bit_from_local"] =
124 : GenerateGetBitFromLocal(builderBitIndex);
125 0 : (*variables)["set_has_field_bit_to_local"] =
126 : GenerateSetBitToLocal(messageBitIndex);
127 :
128 0 : if (SupportUnknownEnumValue(descriptor->file())) {
129 0 : (*variables)["unknown"] = (*variables)["type"] + ".UNRECOGNIZED";
130 : } else {
131 0 : (*variables)["unknown"] = (*variables)["default"];
132 : }
133 0 : }
134 :
135 : } // namespace
136 :
137 : // ===================================================================
138 :
139 0 : ImmutableEnumFieldGenerator::
140 : ImmutableEnumFieldGenerator(const FieldDescriptor* descriptor,
141 : int messageBitIndex,
142 : int builderBitIndex,
143 : Context* context)
144 : : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
145 : builderBitIndex_(builderBitIndex),
146 0 : name_resolver_(context->GetNameResolver()) {
147 : SetEnumVariables(descriptor, messageBitIndex, builderBitIndex,
148 : context->GetFieldGeneratorInfo(descriptor),
149 0 : name_resolver_, &variables_);
150 0 : }
151 :
152 0 : ImmutableEnumFieldGenerator::~ImmutableEnumFieldGenerator() {}
153 :
154 0 : int ImmutableEnumFieldGenerator::GetNumBitsForMessage() const {
155 0 : return 1;
156 : }
157 :
158 0 : int ImmutableEnumFieldGenerator::GetNumBitsForBuilder() const {
159 0 : return 1;
160 : }
161 :
162 0 : void ImmutableEnumFieldGenerator::
163 : GenerateInterfaceMembers(io::Printer* printer) const {
164 0 : if (SupportFieldPresence(descriptor_->file())) {
165 0 : WriteFieldDocComment(printer, descriptor_);
166 : printer->Print(variables_,
167 0 : "$deprecation$boolean has$capitalized_name$();\n");
168 : }
169 0 : if (SupportUnknownEnumValue(descriptor_->file())) {
170 0 : WriteFieldDocComment(printer, descriptor_);
171 : printer->Print(variables_,
172 0 : "$deprecation$int get$capitalized_name$Value();\n");
173 : }
174 0 : WriteFieldDocComment(printer, descriptor_);
175 : printer->Print(variables_,
176 0 : "$deprecation$$type$ get$capitalized_name$();\n");
177 0 : }
178 :
179 0 : void ImmutableEnumFieldGenerator::
180 : GenerateMembers(io::Printer* printer) const {
181 : printer->Print(variables_,
182 0 : "private int $name$_;\n");
183 0 : PrintExtraFieldInfo(variables_, printer);
184 0 : if (SupportFieldPresence(descriptor_->file())) {
185 0 : WriteFieldDocComment(printer, descriptor_);
186 : printer->Print(variables_,
187 : "$deprecation$public boolean has$capitalized_name$() {\n"
188 : " return $get_has_field_bit_message$;\n"
189 0 : "}\n");
190 : }
191 0 : if (SupportUnknownEnumValue(descriptor_->file())) {
192 0 : WriteFieldDocComment(printer, descriptor_);
193 : printer->Print(variables_,
194 : "$deprecation$public int get$capitalized_name$Value() {\n"
195 : " return $name$_;\n"
196 0 : "}\n");
197 : }
198 0 : WriteFieldDocComment(printer, descriptor_);
199 : printer->Print(variables_,
200 : "$deprecation$public $type$ get$capitalized_name$() {\n"
201 : " $type$ result = $type$.valueOf($name$_);\n"
202 : " return result == null ? $unknown$ : result;\n"
203 0 : "}\n");
204 0 : }
205 :
206 0 : void ImmutableEnumFieldGenerator::
207 : GenerateBuilderMembers(io::Printer* printer) const {
208 : printer->Print(variables_,
209 0 : "private int $name$_ = $default_number$;\n");
210 0 : if (SupportFieldPresence(descriptor_->file())) {
211 0 : WriteFieldDocComment(printer, descriptor_);
212 : printer->Print(variables_,
213 : "$deprecation$public boolean has$capitalized_name$() {\n"
214 : " return $get_has_field_bit_builder$;\n"
215 0 : "}\n");
216 : }
217 0 : if (SupportUnknownEnumValue(descriptor_->file())) {
218 0 : WriteFieldDocComment(printer, descriptor_);
219 : printer->Print(variables_,
220 : "$deprecation$public int get$capitalized_name$Value() {\n"
221 : " return $name$_;\n"
222 0 : "}\n");
223 0 : WriteFieldDocComment(printer, descriptor_);
224 : printer->Print(variables_,
225 : "$deprecation$public Builder set$capitalized_name$Value(int value) {\n"
226 : " $name$_ = value;\n"
227 : " $on_changed$\n"
228 : " return this;\n"
229 0 : "}\n");
230 : }
231 0 : WriteFieldDocComment(printer, descriptor_);
232 : printer->Print(variables_,
233 : "$deprecation$public $type$ get$capitalized_name$() {\n"
234 : " $type$ result = $type$.valueOf($name$_);\n"
235 : " return result == null ? $unknown$ : result;\n"
236 0 : "}\n");
237 0 : WriteFieldDocComment(printer, descriptor_);
238 : printer->Print(variables_,
239 : "$deprecation$public Builder set$capitalized_name$($type$ value) {\n"
240 : " if (value == null) {\n"
241 : " throw new NullPointerException();\n"
242 : " }\n"
243 : " $set_has_field_bit_builder$\n"
244 : " $name$_ = value.getNumber();\n"
245 : " $on_changed$\n"
246 : " return this;\n"
247 0 : "}\n");
248 0 : WriteFieldDocComment(printer, descriptor_);
249 : printer->Print(variables_,
250 : "$deprecation$public Builder clear$capitalized_name$() {\n"
251 : " $clear_has_field_bit_builder$\n"
252 : " $name$_ = $default_number$;\n"
253 : " $on_changed$\n"
254 : " return this;\n"
255 0 : "}\n");
256 0 : }
257 :
258 0 : void ImmutableEnumFieldGenerator::
259 : GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
260 : // noop for enums
261 0 : }
262 :
263 0 : void ImmutableEnumFieldGenerator::
264 : GenerateInitializationCode(io::Printer* printer) const {
265 0 : printer->Print(variables_, "$name$_ = $default_number$;\n");
266 0 : }
267 :
268 0 : void ImmutableEnumFieldGenerator::
269 : GenerateBuilderClearCode(io::Printer* printer) const {
270 : printer->Print(variables_,
271 : "$name$_ = $default_number$;\n"
272 0 : "$clear_has_field_bit_builder$\n");
273 0 : }
274 :
275 0 : void ImmutableEnumFieldGenerator::
276 : GenerateMergingCode(io::Printer* printer) const {
277 0 : if (SupportFieldPresence(descriptor_->file())) {
278 : printer->Print(variables_,
279 : "if (other.has$capitalized_name$()) {\n"
280 : " set$capitalized_name$(other.get$capitalized_name$());\n"
281 0 : "}\n");
282 0 : } else if (SupportUnknownEnumValue(descriptor_->file())) {
283 : printer->Print(variables_,
284 : "if (other.$name$_ != $default_number$) {\n"
285 : " set$capitalized_name$Value(other.get$capitalized_name$Value());\n"
286 0 : "}\n");
287 : } else {
288 0 : GOOGLE_LOG(FATAL) << "Can't reach here.";
289 : }
290 0 : }
291 :
292 0 : void ImmutableEnumFieldGenerator::
293 : GenerateBuildingCode(io::Printer* printer) const {
294 0 : if (SupportFieldPresence(descriptor_->file())) {
295 : printer->Print(variables_,
296 : "if ($get_has_field_bit_from_local$) {\n"
297 : " $set_has_field_bit_to_local$;\n"
298 0 : "}\n");
299 : }
300 : printer->Print(variables_,
301 0 : "result.$name$_ = $name$_;\n");
302 0 : }
303 :
304 0 : void ImmutableEnumFieldGenerator::
305 : GenerateParsingCode(io::Printer* printer) const {
306 0 : if (SupportUnknownEnumValue(descriptor_->file())) {
307 : printer->Print(variables_,
308 : "int rawValue = input.readEnum();\n"
309 : "$set_has_field_bit_message$\n"
310 0 : "$name$_ = rawValue;\n");
311 : } else {
312 : printer->Print(variables_,
313 : "int rawValue = input.readEnum();\n"
314 : "$type$ value = $type$.valueOf(rawValue);\n"
315 0 : "if (value == null) {\n");
316 0 : if (PreserveUnknownFields(descriptor_->containing_type())) {
317 : printer->Print(variables_,
318 0 : " unknownFields.mergeVarintField($number$, rawValue);\n");
319 : }
320 : printer->Print(variables_,
321 : "} else {\n"
322 : " $set_has_field_bit_message$\n"
323 : " $name$_ = rawValue;\n"
324 0 : "}\n");
325 : }
326 0 : }
327 :
328 0 : void ImmutableEnumFieldGenerator::
329 : GenerateParsingDoneCode(io::Printer* printer) const {
330 : // noop for enums
331 0 : }
332 :
333 0 : void ImmutableEnumFieldGenerator::
334 : GenerateSerializationCode(io::Printer* printer) const {
335 : printer->Print(variables_,
336 : "if ($is_field_present_message$) {\n"
337 : " output.writeEnum($number$, $name$_);\n"
338 0 : "}\n");
339 0 : }
340 :
341 0 : void ImmutableEnumFieldGenerator::
342 : GenerateSerializedSizeCode(io::Printer* printer) const {
343 : printer->Print(variables_,
344 : "if ($is_field_present_message$) {\n"
345 : " size += com.google.protobuf.CodedOutputStream\n"
346 : " .computeEnumSize($number$, $name$_);\n"
347 0 : "}\n");
348 0 : }
349 :
350 0 : void ImmutableEnumFieldGenerator::
351 : GenerateEqualsCode(io::Printer* printer) const {
352 : printer->Print(variables_,
353 0 : "result = result && $name$_ == other.$name$_;\n");
354 0 : }
355 :
356 0 : void ImmutableEnumFieldGenerator::
357 : GenerateHashCode(io::Printer* printer) const {
358 : printer->Print(variables_,
359 : "hash = (37 * hash) + $constant_name$;\n"
360 0 : "hash = (53 * hash) + $name$_;\n");
361 0 : }
362 :
363 0 : string ImmutableEnumFieldGenerator::GetBoxedType() const {
364 0 : return name_resolver_->GetImmutableClassName(descriptor_->enum_type());
365 : }
366 :
367 : // ===================================================================
368 :
369 0 : ImmutableEnumOneofFieldGenerator::
370 0 : ImmutableEnumOneofFieldGenerator(const FieldDescriptor* descriptor,
371 : int messageBitIndex,
372 : int builderBitIndex,
373 : Context* context)
374 : : ImmutableEnumFieldGenerator(
375 0 : descriptor, messageBitIndex, builderBitIndex, context) {
376 : const OneofGeneratorInfo* info =
377 0 : context->GetOneofGeneratorInfo(descriptor->containing_oneof());
378 0 : SetCommonOneofVariables(descriptor, info, &variables_);
379 0 : }
380 :
381 0 : ImmutableEnumOneofFieldGenerator::
382 0 : ~ImmutableEnumOneofFieldGenerator() {}
383 :
384 0 : void ImmutableEnumOneofFieldGenerator::
385 : GenerateMembers(io::Printer* printer) const {
386 0 : PrintExtraFieldInfo(variables_, printer);
387 0 : if (SupportFieldPresence(descriptor_->file())) {
388 0 : WriteFieldDocComment(printer, descriptor_);
389 : printer->Print(variables_,
390 : "$deprecation$public boolean has$capitalized_name$() {\n"
391 : " return $has_oneof_case_message$;\n"
392 0 : "}\n");
393 : }
394 0 : if (SupportUnknownEnumValue(descriptor_->file())) {
395 0 : WriteFieldDocComment(printer, descriptor_);
396 : printer->Print(variables_,
397 : "$deprecation$public int get$capitalized_name$Value() {\n"
398 : " if ($has_oneof_case_message$) {\n"
399 : " return (java.lang.Integer) $oneof_name$_;\n"
400 : " }\n"
401 : " return $default_number$;\n"
402 0 : "}\n");
403 : }
404 0 : WriteFieldDocComment(printer, descriptor_);
405 : printer->Print(variables_,
406 : "$deprecation$public $type$ get$capitalized_name$() {\n"
407 : " if ($has_oneof_case_message$) {\n"
408 : " $type$ result = $type$.valueOf((java.lang.Integer) $oneof_name$_);\n"
409 : " return result == null ? $unknown$ : result;\n"
410 : " }\n"
411 : " return $default$;\n"
412 0 : "}\n");
413 0 : }
414 :
415 0 : void ImmutableEnumOneofFieldGenerator::
416 : GenerateBuilderMembers(io::Printer* printer) const {
417 0 : if (SupportFieldPresence(descriptor_->file())) {
418 0 : WriteFieldDocComment(printer, descriptor_);
419 : printer->Print(variables_,
420 : "$deprecation$public boolean has$capitalized_name$() {\n"
421 : " return $has_oneof_case_message$;\n"
422 0 : "}\n");
423 : }
424 0 : if (SupportUnknownEnumValue(descriptor_->file())) {
425 0 : WriteFieldDocComment(printer, descriptor_);
426 : printer->Print(variables_,
427 : "$deprecation$public int get$capitalized_name$Value() {\n"
428 : " if ($has_oneof_case_message$) {\n"
429 : " return ((java.lang.Integer) $oneof_name$_).intValue();\n"
430 : " }\n"
431 : " return $default_number$;\n"
432 0 : "}\n");
433 0 : WriteFieldDocComment(printer, descriptor_);
434 : printer->Print(variables_,
435 : "$deprecation$public Builder set$capitalized_name$Value(int value) {\n"
436 : " $set_oneof_case_message$;\n"
437 : " $oneof_name$_ = value;\n"
438 : " $on_changed$\n"
439 : " return this;\n"
440 0 : "}\n");
441 : }
442 0 : WriteFieldDocComment(printer, descriptor_);
443 : printer->Print(variables_,
444 : "$deprecation$public $type$ get$capitalized_name$() {\n"
445 : " if ($has_oneof_case_message$) {\n"
446 : " $type$ result = $type$.valueOf((java.lang.Integer) $oneof_name$_);\n"
447 : " return result == null ? $unknown$ : result;\n"
448 : " }\n"
449 : " return $default$;\n"
450 0 : "}\n");
451 0 : WriteFieldDocComment(printer, descriptor_);
452 : printer->Print(variables_,
453 : "$deprecation$public Builder set$capitalized_name$($type$ value) {\n"
454 : " if (value == null) {\n"
455 : " throw new NullPointerException();\n"
456 : " }\n"
457 : " $set_oneof_case_message$;\n"
458 : " $oneof_name$_ = value.getNumber();\n"
459 : " $on_changed$\n"
460 : " return this;\n"
461 0 : "}\n");
462 0 : WriteFieldDocComment(printer, descriptor_);
463 : printer->Print(variables_,
464 : "$deprecation$public Builder clear$capitalized_name$() {\n"
465 : " if ($has_oneof_case_message$) {\n"
466 : " $clear_oneof_case_message$;\n"
467 : " $oneof_name$_ = null;\n"
468 : " $on_changed$\n"
469 : " }\n"
470 : " return this;\n"
471 0 : "}\n");
472 0 : }
473 :
474 0 : void ImmutableEnumOneofFieldGenerator::
475 : GenerateBuildingCode(io::Printer* printer) const {
476 : printer->Print(variables_,
477 : "if ($has_oneof_case_message$) {\n"
478 : " result.$oneof_name$_ = $oneof_name$_;\n"
479 0 : "}\n");
480 0 : }
481 :
482 0 : void ImmutableEnumOneofFieldGenerator::
483 : GenerateMergingCode(io::Printer* printer) const {
484 0 : if (SupportUnknownEnumValue(descriptor_->file())) {
485 : printer->Print(variables_,
486 0 : "set$capitalized_name$Value(other.get$capitalized_name$Value());\n");
487 : } else {
488 : printer->Print(variables_,
489 0 : "set$capitalized_name$(other.get$capitalized_name$());\n");
490 : }
491 0 : }
492 :
493 0 : void ImmutableEnumOneofFieldGenerator::
494 : GenerateParsingCode(io::Printer* printer) const {
495 0 : if (SupportUnknownEnumValue(descriptor_->file())) {
496 : printer->Print(variables_,
497 : "int rawValue = input.readEnum();\n"
498 : "$set_oneof_case_message$;\n"
499 0 : "$oneof_name$_ = rawValue;\n");
500 : } else {
501 : printer->Print(variables_,
502 : "int rawValue = input.readEnum();\n"
503 : "$type$ value = $type$.valueOf(rawValue);\n"
504 0 : "if (value == null) {\n");
505 0 : if (PreserveUnknownFields(descriptor_->containing_type())) {
506 : printer->Print(variables_,
507 0 : " unknownFields.mergeVarintField($number$, rawValue);\n");
508 : }
509 : printer->Print(variables_,
510 : "} else {\n"
511 : " $set_oneof_case_message$;\n"
512 : " $oneof_name$_ = rawValue;\n"
513 0 : "}\n");
514 : }
515 0 : }
516 :
517 0 : void ImmutableEnumOneofFieldGenerator::
518 : GenerateSerializationCode(io::Printer* printer) const {
519 : printer->Print(variables_,
520 : "if ($has_oneof_case_message$) {\n"
521 : " output.writeEnum($number$, ((java.lang.Integer) $oneof_name$_));\n"
522 0 : "}\n");
523 0 : }
524 :
525 0 : void ImmutableEnumOneofFieldGenerator::
526 : GenerateSerializedSizeCode(io::Printer* printer) const {
527 : printer->Print(variables_,
528 : "if ($has_oneof_case_message$) {\n"
529 : " size += com.google.protobuf.CodedOutputStream\n"
530 : " .computeEnumSize($number$, ((java.lang.Integer) $oneof_name$_));\n"
531 0 : "}\n");
532 0 : }
533 :
534 0 : void ImmutableEnumOneofFieldGenerator::
535 : GenerateEqualsCode(io::Printer* printer) const {
536 0 : if (SupportUnknownEnumValue(descriptor_->file())) {
537 : printer->Print(variables_,
538 : "result = result && get$capitalized_name$Value()\n"
539 0 : " == other.get$capitalized_name$Value();\n");
540 : } else {
541 : printer->Print(variables_,
542 : "result = result && get$capitalized_name$()\n"
543 0 : " .equals(other.get$capitalized_name$());\n");
544 : }
545 0 : }
546 :
547 0 : void ImmutableEnumOneofFieldGenerator::
548 : GenerateHashCode(io::Printer* printer) const {
549 0 : if (SupportUnknownEnumValue(descriptor_->file())) {
550 : printer->Print(variables_,
551 : "hash = (37 * hash) + $constant_name$;\n"
552 0 : "hash = (53 * hash) + get$capitalized_name$Value();\n");
553 : } else {
554 : printer->Print(variables_,
555 : "hash = (37 * hash) + $constant_name$;\n"
556 0 : "hash = (53 * hash) + get$capitalized_name$().getNumber();\n");
557 : }
558 0 : }
559 :
560 : // ===================================================================
561 :
562 0 : RepeatedImmutableEnumFieldGenerator::
563 : RepeatedImmutableEnumFieldGenerator(const FieldDescriptor* descriptor,
564 : int messageBitIndex,
565 : int builderBitIndex,
566 : Context* context)
567 : : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
568 : builderBitIndex_(builderBitIndex), context_(context),
569 0 : name_resolver_(context->GetNameResolver()) {
570 : SetEnumVariables(descriptor, messageBitIndex, builderBitIndex,
571 : context->GetFieldGeneratorInfo(descriptor),
572 0 : name_resolver_, &variables_);
573 0 : }
574 :
575 0 : RepeatedImmutableEnumFieldGenerator::~RepeatedImmutableEnumFieldGenerator() {}
576 :
577 0 : int RepeatedImmutableEnumFieldGenerator::GetNumBitsForMessage() const {
578 0 : return 0;
579 : }
580 :
581 0 : int RepeatedImmutableEnumFieldGenerator::GetNumBitsForBuilder() const {
582 0 : return 1;
583 : }
584 :
585 0 : void RepeatedImmutableEnumFieldGenerator::
586 : GenerateInterfaceMembers(io::Printer* printer) const {
587 0 : WriteFieldDocComment(printer, descriptor_);
588 : printer->Print(variables_,
589 0 : "$deprecation$java.util.List<$type$> get$capitalized_name$List();\n");
590 0 : WriteFieldDocComment(printer, descriptor_);
591 : printer->Print(variables_,
592 0 : "$deprecation$int get$capitalized_name$Count();\n");
593 0 : WriteFieldDocComment(printer, descriptor_);
594 : printer->Print(variables_,
595 0 : "$deprecation$$type$ get$capitalized_name$(int index);\n");
596 0 : if (SupportUnknownEnumValue(descriptor_->file())) {
597 0 : WriteFieldDocComment(printer, descriptor_);
598 : printer->Print(variables_,
599 : "$deprecation$java.util.List<java.lang.Integer>\n"
600 0 : "get$capitalized_name$ValueList();\n");
601 0 : WriteFieldDocComment(printer, descriptor_);
602 : printer->Print(variables_,
603 0 : "$deprecation$int get$capitalized_name$Value(int index);\n");
604 : }
605 0 : }
606 :
607 0 : void RepeatedImmutableEnumFieldGenerator::
608 : GenerateMembers(io::Printer* printer) const {
609 : printer->Print(variables_,
610 : "private java.util.List<java.lang.Integer> $name$_;\n"
611 : "private static final com.google.protobuf.Internal.ListAdapter.Converter<\n"
612 : " java.lang.Integer, $type$> $name$_converter_ =\n"
613 : " new com.google.protobuf.Internal.ListAdapter.Converter<\n"
614 : " java.lang.Integer, $type$>() {\n"
615 : " public $type$ convert(java.lang.Integer from) {\n"
616 : " $type$ result = $type$.valueOf(from);\n"
617 : " return result == null ? $unknown$ : result;\n"
618 : " }\n"
619 0 : " };\n");
620 0 : PrintExtraFieldInfo(variables_, printer);
621 0 : WriteFieldDocComment(printer, descriptor_);
622 : printer->Print(variables_,
623 : "$deprecation$public java.util.List<$type$> get$capitalized_name$List() {\n"
624 : " return new com.google.protobuf.Internal.ListAdapter<\n"
625 : " java.lang.Integer, $type$>($name$_, $name$_converter_);\n"
626 0 : "}\n");
627 0 : WriteFieldDocComment(printer, descriptor_);
628 : printer->Print(variables_,
629 : "$deprecation$public int get$capitalized_name$Count() {\n"
630 : " return $name$_.size();\n"
631 0 : "}\n");
632 0 : WriteFieldDocComment(printer, descriptor_);
633 : printer->Print(variables_,
634 : "$deprecation$public $type$ get$capitalized_name$(int index) {\n"
635 : " return $name$_converter_.convert($name$_.get(index));\n"
636 0 : "}\n");
637 0 : if (SupportUnknownEnumValue(descriptor_->file())) {
638 0 : WriteFieldDocComment(printer, descriptor_);
639 : printer->Print(variables_,
640 : "$deprecation$public java.util.List<java.lang.Integer>\n"
641 : "get$capitalized_name$ValueList() {\n"
642 : " return $name$_;\n"
643 0 : "}\n");
644 0 : WriteFieldDocComment(printer, descriptor_);
645 : printer->Print(variables_,
646 : "$deprecation$public int get$capitalized_name$Value(int index) {\n"
647 : " return $name$_.get(index);\n"
648 0 : "}\n");
649 : }
650 :
651 0 : if (descriptor_->is_packed() &&
652 0 : HasGeneratedMethods(descriptor_->containing_type())) {
653 : printer->Print(variables_,
654 0 : "private int $name$MemoizedSerializedSize;\n");
655 : }
656 0 : }
657 :
658 0 : void RepeatedImmutableEnumFieldGenerator::
659 : GenerateBuilderMembers(io::Printer* printer) const {
660 : printer->Print(variables_,
661 : // One field is the list and the other field keeps track of whether the
662 : // list is immutable. If it's immutable, the invariant is that it must
663 : // either an instance of Collections.emptyList() or it's an ArrayList
664 : // wrapped in a Collections.unmodifiableList() wrapper and nobody else has
665 : // a refererence to the underlying ArrayList. This invariant allows us to
666 : // share instances of lists between protocol buffers avoiding expensive
667 : // memory allocations. Note, immutable is a strong guarantee here -- not
668 : // just that the list cannot be modified via the reference but that the
669 : // list can never be modified.
670 : "private java.util.List<java.lang.Integer> $name$_ =\n"
671 : " java.util.Collections.emptyList();\n"
672 :
673 : "private void ensure$capitalized_name$IsMutable() {\n"
674 : " if (!$get_mutable_bit_builder$) {\n"
675 : " $name$_ = new java.util.ArrayList<java.lang.Integer>($name$_);\n"
676 : " $set_mutable_bit_builder$;\n"
677 : " }\n"
678 0 : "}\n");
679 :
680 0 : WriteFieldDocComment(printer, descriptor_);
681 : printer->Print(variables_,
682 : // Note: We return an unmodifiable list because otherwise the caller
683 : // could hold on to the returned list and modify it after the message
684 : // has been built, thus mutating the message which is supposed to be
685 : // immutable.
686 : "$deprecation$public java.util.List<$type$> get$capitalized_name$List() {\n"
687 : " return new com.google.protobuf.Internal.ListAdapter<\n"
688 : " java.lang.Integer, $type$>($name$_, $name$_converter_);\n"
689 0 : "}\n");
690 0 : WriteFieldDocComment(printer, descriptor_);
691 : printer->Print(variables_,
692 : "$deprecation$public int get$capitalized_name$Count() {\n"
693 : " return $name$_.size();\n"
694 0 : "}\n");
695 0 : WriteFieldDocComment(printer, descriptor_);
696 : printer->Print(variables_,
697 : "$deprecation$public $type$ get$capitalized_name$(int index) {\n"
698 : " return $name$_converter_.convert($name$_.get(index));\n"
699 0 : "}\n");
700 0 : WriteFieldDocComment(printer, descriptor_);
701 : printer->Print(variables_,
702 : "$deprecation$public Builder set$capitalized_name$(\n"
703 : " int index, $type$ value) {\n"
704 : " if (value == null) {\n"
705 : " throw new NullPointerException();\n"
706 : " }\n"
707 : " ensure$capitalized_name$IsMutable();\n"
708 : " $name$_.set(index, value.getNumber());\n"
709 : " $on_changed$\n"
710 : " return this;\n"
711 0 : "}\n");
712 0 : WriteFieldDocComment(printer, descriptor_);
713 : printer->Print(variables_,
714 : "$deprecation$public Builder add$capitalized_name$($type$ value) {\n"
715 : " if (value == null) {\n"
716 : " throw new NullPointerException();\n"
717 : " }\n"
718 : " ensure$capitalized_name$IsMutable();\n"
719 : " $name$_.add(value.getNumber());\n"
720 : " $on_changed$\n"
721 : " return this;\n"
722 0 : "}\n");
723 0 : WriteFieldDocComment(printer, descriptor_);
724 : printer->Print(variables_,
725 : "$deprecation$public Builder addAll$capitalized_name$(\n"
726 : " java.lang.Iterable<? extends $type$> values) {\n"
727 : " ensure$capitalized_name$IsMutable();\n"
728 : " for ($type$ value : values) {\n"
729 : " $name$_.add(value.getNumber());\n"
730 : " }\n"
731 : " $on_changed$\n"
732 : " return this;\n"
733 0 : "}\n");
734 0 : WriteFieldDocComment(printer, descriptor_);
735 : printer->Print(variables_,
736 : "$deprecation$public Builder clear$capitalized_name$() {\n"
737 : " $name$_ = java.util.Collections.emptyList();\n"
738 : " $clear_mutable_bit_builder$;\n"
739 : " $on_changed$\n"
740 : " return this;\n"
741 0 : "}\n");
742 :
743 0 : if (SupportUnknownEnumValue(descriptor_->file())) {
744 0 : WriteFieldDocComment(printer, descriptor_);
745 : printer->Print(variables_,
746 : "$deprecation$public java.util.List<java.lang.Integer>\n"
747 : "get$capitalized_name$ValueList() {\n"
748 : " return java.util.Collections.unmodifiableList($name$_);\n"
749 0 : "}\n");
750 0 : WriteFieldDocComment(printer, descriptor_);
751 : printer->Print(variables_,
752 : "$deprecation$public int get$capitalized_name$Value(int index) {\n"
753 : " return $name$_.get(index);\n"
754 0 : "}\n");
755 0 : WriteFieldDocComment(printer, descriptor_);
756 : printer->Print(variables_,
757 : "$deprecation$public Builder set$capitalized_name$Value(\n"
758 : " int index, int value) {\n"
759 : " ensure$capitalized_name$IsMutable();\n"
760 : " $name$_.set(index, value);\n"
761 : " $on_changed$\n"
762 : " return this;\n"
763 0 : "}\n");
764 0 : WriteFieldDocComment(printer, descriptor_);
765 : printer->Print(variables_,
766 : "$deprecation$public Builder add$capitalized_name$Value(int value) {\n"
767 : " ensure$capitalized_name$IsMutable();\n"
768 : " $name$_.add(value);\n"
769 : " $on_changed$\n"
770 : " return this;\n"
771 0 : "}\n");
772 0 : WriteFieldDocComment(printer, descriptor_);
773 : printer->Print(variables_,
774 : "$deprecation$public Builder addAll$capitalized_name$Value(\n"
775 : " java.lang.Iterable<java.lang.Integer> values) {\n"
776 : " ensure$capitalized_name$IsMutable();\n"
777 : " for (int value : values) {\n"
778 : " $name$_.add(value);\n"
779 : " }\n"
780 : " $on_changed$\n"
781 : " return this;\n"
782 0 : "}\n");
783 : }
784 0 : }
785 :
786 0 : void RepeatedImmutableEnumFieldGenerator::
787 : GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
788 : // noop for enums
789 0 : }
790 :
791 0 : void RepeatedImmutableEnumFieldGenerator::
792 : GenerateInitializationCode(io::Printer* printer) const {
793 0 : printer->Print(variables_, "$name$_ = java.util.Collections.emptyList();\n");
794 0 : }
795 :
796 0 : void RepeatedImmutableEnumFieldGenerator::
797 : GenerateBuilderClearCode(io::Printer* printer) const {
798 : printer->Print(variables_,
799 : "$name$_ = java.util.Collections.emptyList();\n"
800 0 : "$clear_mutable_bit_builder$;\n");
801 0 : }
802 :
803 0 : void RepeatedImmutableEnumFieldGenerator::
804 : GenerateMergingCode(io::Printer* printer) const {
805 : // The code below does two optimizations:
806 : // 1. If the other list is empty, there's nothing to do. This ensures we
807 : // don't allocate a new array if we already have an immutable one.
808 : // 2. If the other list is non-empty and our current list is empty, we can
809 : // reuse the other list which is guaranteed to be immutable.
810 : printer->Print(variables_,
811 : "if (!other.$name$_.isEmpty()) {\n"
812 : " if ($name$_.isEmpty()) {\n"
813 : " $name$_ = other.$name$_;\n"
814 : " $clear_mutable_bit_builder$;\n"
815 : " } else {\n"
816 : " ensure$capitalized_name$IsMutable();\n"
817 : " $name$_.addAll(other.$name$_);\n"
818 : " }\n"
819 : " $on_changed$\n"
820 0 : "}\n");
821 0 : }
822 :
823 0 : void RepeatedImmutableEnumFieldGenerator::
824 : GenerateBuildingCode(io::Printer* printer) const {
825 : // The code below ensures that the result has an immutable list. If our
826 : // list is immutable, we can just reuse it. If not, we make it immutable.
827 : printer->Print(variables_,
828 : "if ($get_mutable_bit_builder$) {\n"
829 : " $name$_ = java.util.Collections.unmodifiableList($name$_);\n"
830 : " $clear_mutable_bit_builder$;\n"
831 : "}\n"
832 0 : "result.$name$_ = $name$_;\n");
833 0 : }
834 :
835 0 : void RepeatedImmutableEnumFieldGenerator::
836 : GenerateParsingCode(io::Printer* printer) const {
837 : // Read and store the enum
838 0 : if (SupportUnknownEnumValue(descriptor_->file())) {
839 : printer->Print(variables_,
840 : "int rawValue = input.readEnum();\n"
841 : "if (!$get_mutable_bit_parser$) {\n"
842 : " $name$_ = new java.util.ArrayList<java.lang.Integer>();\n"
843 : " $set_mutable_bit_parser$;\n"
844 : "}\n"
845 0 : "$name$_.add(rawValue);\n");
846 : } else {
847 : printer->Print(variables_,
848 : "int rawValue = input.readEnum();\n"
849 : "$type$ value = $type$.valueOf(rawValue);\n"
850 0 : "if (value == null) {\n");
851 0 : if (PreserveUnknownFields(descriptor_->containing_type())) {
852 : printer->Print(variables_,
853 0 : " unknownFields.mergeVarintField($number$, rawValue);\n");
854 : }
855 : printer->Print(variables_,
856 : "} else {\n"
857 : " if (!$get_mutable_bit_parser$) {\n"
858 : " $name$_ = new java.util.ArrayList<java.lang.Integer>();\n"
859 : " $set_mutable_bit_parser$;\n"
860 : " }\n"
861 : " $name$_.add(rawValue);\n"
862 0 : "}\n");
863 : }
864 0 : }
865 :
866 0 : void RepeatedImmutableEnumFieldGenerator::
867 : GenerateParsingCodeFromPacked(io::Printer* printer) const {
868 : // Wrap GenerateParsingCode's contents with a while loop.
869 :
870 : printer->Print(variables_,
871 : "int length = input.readRawVarint32();\n"
872 : "int oldLimit = input.pushLimit(length);\n"
873 0 : "while(input.getBytesUntilLimit() > 0) {\n");
874 0 : printer->Indent();
875 :
876 0 : GenerateParsingCode(printer);
877 :
878 0 : printer->Outdent();
879 : printer->Print(variables_,
880 : "}\n"
881 0 : "input.popLimit(oldLimit);\n");
882 0 : }
883 :
884 0 : void RepeatedImmutableEnumFieldGenerator::
885 : GenerateParsingDoneCode(io::Printer* printer) const {
886 : printer->Print(variables_,
887 : "if ($get_mutable_bit_parser$) {\n"
888 : " $name$_ = java.util.Collections.unmodifiableList($name$_);\n"
889 0 : "}\n");
890 0 : }
891 :
892 0 : void RepeatedImmutableEnumFieldGenerator::
893 : GenerateSerializationCode(io::Printer* printer) const {
894 0 : if (descriptor_->is_packed()) {
895 : printer->Print(variables_,
896 : "if (get$capitalized_name$List().size() > 0) {\n"
897 : " output.writeRawVarint32($tag$);\n"
898 : " output.writeRawVarint32($name$MemoizedSerializedSize);\n"
899 : "}\n"
900 : "for (int i = 0; i < $name$_.size(); i++) {\n"
901 : " output.writeEnumNoTag($name$_.get(i));\n"
902 0 : "}\n");
903 : } else {
904 : printer->Print(variables_,
905 : "for (int i = 0; i < $name$_.size(); i++) {\n"
906 : " output.writeEnum($number$, $name$_.get(i));\n"
907 0 : "}\n");
908 : }
909 0 : }
910 :
911 0 : void RepeatedImmutableEnumFieldGenerator::
912 : GenerateSerializedSizeCode(io::Printer* printer) const {
913 : printer->Print(variables_,
914 : "{\n"
915 0 : " int dataSize = 0;\n");
916 0 : printer->Indent();
917 :
918 : printer->Print(variables_,
919 : "for (int i = 0; i < $name$_.size(); i++) {\n"
920 : " dataSize += com.google.protobuf.CodedOutputStream\n"
921 : " .computeEnumSizeNoTag($name$_.get(i));\n"
922 0 : "}\n");
923 : printer->Print(
924 0 : "size += dataSize;\n");
925 0 : if (descriptor_->is_packed()) {
926 : printer->Print(variables_,
927 : "if (!get$capitalized_name$List().isEmpty()) {"
928 : " size += $tag_size$;\n"
929 : " size += com.google.protobuf.CodedOutputStream\n"
930 : " .computeRawVarint32Size(dataSize);\n"
931 0 : "}");
932 : } else {
933 : printer->Print(variables_,
934 0 : "size += $tag_size$ * $name$_.size();\n");
935 : }
936 :
937 : // cache the data size for packed fields.
938 0 : if (descriptor_->is_packed()) {
939 : printer->Print(variables_,
940 0 : "$name$MemoizedSerializedSize = dataSize;\n");
941 : }
942 :
943 0 : printer->Outdent();
944 0 : printer->Print("}\n");
945 0 : }
946 :
947 0 : void RepeatedImmutableEnumFieldGenerator::
948 : GenerateEqualsCode(io::Printer* printer) const {
949 : printer->Print(variables_,
950 0 : "result = result && $name$_.equals(other.$name$_);\n");
951 0 : }
952 :
953 0 : void RepeatedImmutableEnumFieldGenerator::
954 : GenerateHashCode(io::Printer* printer) const {
955 : printer->Print(variables_,
956 : "if (get$capitalized_name$Count() > 0) {\n"
957 : " hash = (37 * hash) + $constant_name$;\n"
958 : " hash = (53 * hash) + $name$_.hashCode();\n"
959 0 : "}\n");
960 0 : }
961 :
962 0 : string RepeatedImmutableEnumFieldGenerator::GetBoxedType() const {
963 0 : return name_resolver_->GetImmutableClassName(descriptor_->enum_type());
964 : }
965 :
966 : } // namespace java
967 : } // namespace compiler
968 : } // namespace protobuf
969 : } // namespace google
|