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