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 if (!IsDefaultValueJavaDefault(descriptor_)) {
262 printer->Print(variables_, "$name$_ = $default_number$;\n");
263 }
264 }
265
266 void ImmutableEnumFieldLiteGenerator::
GenerateVisitCode(io::Printer * printer) const267 GenerateVisitCode(io::Printer* printer) const {
268 if (SupportFieldPresence(descriptor_->file())) {
269 printer->Print(variables_,
270 "$name$_ = visitor.visitInt(has$capitalized_name$(), $name$_,\n"
271 " other.has$capitalized_name$(), other.$name$_);\n");
272 } else if (SupportUnknownEnumValue(descriptor_->file())) {
273 printer->Print(variables_,
274 "$name$_ = visitor.visitInt($name$_ != $default_number$, $name$_,"
275 " other.$name$_ != $default_number$, other.$name$_);\n");
276 } else {
277 GOOGLE_LOG(FATAL) << "Can't reach here.";
278 }
279 }
280
281 void ImmutableEnumFieldLiteGenerator::
GenerateDynamicMethodMakeImmutableCode(io::Printer * printer) const282 GenerateDynamicMethodMakeImmutableCode(io::Printer* printer) const {
283 // noop for scalars
284 }
285
286 void ImmutableEnumFieldLiteGenerator::
GenerateParsingCode(io::Printer * printer) const287 GenerateParsingCode(io::Printer* printer) const {
288 if (SupportUnknownEnumValue(descriptor_->file())) {
289 printer->Print(variables_,
290 "int rawValue = input.readEnum();\n"
291 "$set_has_field_bit_message$\n"
292 "$name$_ = rawValue;\n");
293 } else {
294 printer->Print(variables_,
295 "int rawValue = input.readEnum();\n"
296 "$type$ value = $type$.forNumber(rawValue);\n"
297 "if (value == null) {\n");
298 if (PreserveUnknownFields(descriptor_->containing_type())) {
299 printer->Print(variables_,
300 " super.mergeVarintField($number$, rawValue);\n");
301 }
302 printer->Print(variables_,
303 "} else {\n"
304 " $set_has_field_bit_message$\n"
305 " $name$_ = rawValue;\n"
306 "}\n");
307 }
308 }
309
310 void ImmutableEnumFieldLiteGenerator::
GenerateParsingDoneCode(io::Printer * printer) const311 GenerateParsingDoneCode(io::Printer* printer) const {
312 // noop for enums
313 }
314
315 void ImmutableEnumFieldLiteGenerator::
GenerateSerializationCode(io::Printer * printer) const316 GenerateSerializationCode(io::Printer* printer) const {
317 printer->Print(variables_,
318 "if ($is_field_present_message$) {\n"
319 " output.writeEnum($number$, $name$_);\n"
320 "}\n");
321 }
322
323 void ImmutableEnumFieldLiteGenerator::
GenerateSerializedSizeCode(io::Printer * printer) const324 GenerateSerializedSizeCode(io::Printer* printer) const {
325 printer->Print(variables_,
326 "if ($is_field_present_message$) {\n"
327 " size += com.google.protobuf.CodedOutputStream\n"
328 " .computeEnumSize($number$, $name$_);\n"
329 "}\n");
330 }
331
332 void ImmutableEnumFieldLiteGenerator::
GenerateEqualsCode(io::Printer * printer) const333 GenerateEqualsCode(io::Printer* printer) const {
334 printer->Print(variables_,
335 "result = result && $name$_ == other.$name$_;\n");
336 }
337
338 void ImmutableEnumFieldLiteGenerator::
GenerateHashCode(io::Printer * printer) const339 GenerateHashCode(io::Printer* printer) const {
340 printer->Print(variables_,
341 "hash = (37 * hash) + $constant_name$;\n"
342 "hash = (53 * hash) + $name$_;\n");
343 }
344
GetBoxedType() const345 string ImmutableEnumFieldLiteGenerator::GetBoxedType() const {
346 return name_resolver_->GetImmutableClassName(descriptor_->enum_type());
347 }
348
349 // ===================================================================
350
351 ImmutableEnumOneofFieldLiteGenerator::
ImmutableEnumOneofFieldLiteGenerator(const FieldDescriptor * descriptor,int messageBitIndex,int builderBitIndex,Context * context)352 ImmutableEnumOneofFieldLiteGenerator(const FieldDescriptor* descriptor,
353 int messageBitIndex,
354 int builderBitIndex,
355 Context* context)
356 : ImmutableEnumFieldLiteGenerator(
357 descriptor, messageBitIndex, builderBitIndex, context) {
358 const OneofGeneratorInfo* info =
359 context->GetOneofGeneratorInfo(descriptor->containing_oneof());
360 SetCommonOneofVariables(descriptor, info, &variables_);
361 }
362
363 ImmutableEnumOneofFieldLiteGenerator::
~ImmutableEnumOneofFieldLiteGenerator()364 ~ImmutableEnumOneofFieldLiteGenerator() {}
365
366 void ImmutableEnumOneofFieldLiteGenerator::
GenerateMembers(io::Printer * printer) const367 GenerateMembers(io::Printer* printer) const {
368 PrintExtraFieldInfo(variables_, printer);
369 if (SupportFieldPresence(descriptor_->file())) {
370 WriteFieldDocComment(printer, descriptor_);
371 printer->Print(variables_,
372 "$deprecation$public boolean has$capitalized_name$() {\n"
373 " return $has_oneof_case_message$;\n"
374 "}\n");
375 }
376 if (SupportUnknownEnumValue(descriptor_->file())) {
377 WriteFieldDocComment(printer, descriptor_);
378 printer->Print(variables_,
379 "$deprecation$public int get$capitalized_name$Value() {\n"
380 " if ($has_oneof_case_message$) {\n"
381 " return (java.lang.Integer) $oneof_name$_;\n"
382 " }\n"
383 " return $default_number$;\n"
384 "}\n");
385 }
386 WriteFieldDocComment(printer, descriptor_);
387 printer->Print(variables_,
388 "$deprecation$public $type$ get$capitalized_name$() {\n"
389 " if ($has_oneof_case_message$) {\n"
390 " $type$ result = $type$.forNumber((java.lang.Integer) $oneof_name$_);\n"
391 " return result == null ? $unknown$ : result;\n"
392 " }\n"
393 " return $default$;\n"
394 "}\n");
395
396 // Generate private setters for the builder to proxy into.
397 if (SupportUnknownEnumValue(descriptor_->file())) {
398 WriteFieldDocComment(printer, descriptor_);
399 printer->Print(variables_,
400 "private void set$capitalized_name$Value(int value) {\n"
401 " $set_oneof_case_message$;\n"
402 " $oneof_name$_ = value;\n"
403 "}\n");
404 }
405 WriteFieldDocComment(printer, descriptor_);
406 printer->Print(variables_,
407 "private void set$capitalized_name$($type$ value) {\n"
408 " if (value == null) {\n"
409 " throw new NullPointerException();\n"
410 " }\n"
411 " $set_oneof_case_message$;\n"
412 " $oneof_name$_ = value.getNumber();\n"
413 "}\n");
414 WriteFieldDocComment(printer, descriptor_);
415 printer->Print(variables_,
416 "private void clear$capitalized_name$() {\n"
417 " if ($has_oneof_case_message$) {\n"
418 " $clear_oneof_case_message$;\n"
419 " $oneof_name$_ = null;\n"
420 " }\n"
421 "}\n");
422 }
423
424 void ImmutableEnumOneofFieldLiteGenerator::
GenerateBuilderMembers(io::Printer * printer) const425 GenerateBuilderMembers(io::Printer* printer) const {
426 if (SupportFieldPresence(descriptor_->file())) {
427 WriteFieldDocComment(printer, descriptor_);
428 printer->Print(variables_,
429 "$deprecation$public boolean has$capitalized_name$() {\n"
430 " return instance.has$capitalized_name$();\n"
431 "}\n");
432 }
433 if (SupportUnknownEnumValue(descriptor_->file())) {
434 WriteFieldDocComment(printer, descriptor_);
435 printer->Print(variables_,
436 "$deprecation$public int get$capitalized_name$Value() {\n"
437 " return instance.get$capitalized_name$Value();\n"
438 "}\n");
439 WriteFieldDocComment(printer, descriptor_);
440 printer->Print(variables_,
441 "$deprecation$public Builder set$capitalized_name$Value(int value) {\n"
442 " copyOnWrite();\n"
443 " instance.set$capitalized_name$Value(value);\n"
444 " return this;\n"
445 "}\n");
446 }
447 WriteFieldDocComment(printer, descriptor_);
448 printer->Print(variables_,
449 "$deprecation$public $type$ get$capitalized_name$() {\n"
450 " return instance.get$capitalized_name$();\n"
451 "}\n");
452 WriteFieldDocComment(printer, descriptor_);
453 printer->Print(variables_,
454 "$deprecation$public Builder set$capitalized_name$($type$ value) {\n"
455 " copyOnWrite();\n"
456 " instance.set$capitalized_name$(value);\n"
457 " return this;\n"
458 "}\n");
459 WriteFieldDocComment(printer, descriptor_);
460 printer->Print(variables_,
461 "$deprecation$public Builder clear$capitalized_name$() {\n"
462 " copyOnWrite();\n"
463 " instance.clear$capitalized_name$();\n"
464 " return this;\n"
465 "}\n");
466 }
467
468 void ImmutableEnumOneofFieldLiteGenerator::
GenerateVisitCode(io::Printer * printer) const469 GenerateVisitCode(io::Printer* printer) const {
470 printer->Print(variables_,
471 "$oneof_name$_ = visitor.visitOneofInt(\n"
472 " $has_oneof_case_message$, $oneof_name$_, other.$oneof_name$_);\n");
473 }
474
475 void ImmutableEnumOneofFieldLiteGenerator::
GenerateParsingCode(io::Printer * printer) const476 GenerateParsingCode(io::Printer* printer) const {
477 if (SupportUnknownEnumValue(descriptor_->file())) {
478 printer->Print(variables_,
479 "int rawValue = input.readEnum();\n"
480 "$set_oneof_case_message$;\n"
481 "$oneof_name$_ = rawValue;\n");
482 } else {
483 printer->Print(variables_,
484 "int rawValue = input.readEnum();\n"
485 "$type$ value = $type$.forNumber(rawValue);\n"
486 "if (value == null) {\n");
487 if (PreserveUnknownFields(descriptor_->containing_type())) {
488 printer->Print(variables_,
489 " super.mergeVarintField($number$, rawValue);\n");
490 }
491 printer->Print(variables_,
492 "} else {\n"
493 " $set_oneof_case_message$;\n"
494 " $oneof_name$_ = rawValue;\n"
495 "}\n");
496 }
497 }
498
499 void ImmutableEnumOneofFieldLiteGenerator::
GenerateSerializationCode(io::Printer * printer) const500 GenerateSerializationCode(io::Printer* printer) const {
501 printer->Print(variables_,
502 "if ($has_oneof_case_message$) {\n"
503 " output.writeEnum($number$, ((java.lang.Integer) $oneof_name$_));\n"
504 "}\n");
505 }
506
507 void ImmutableEnumOneofFieldLiteGenerator::
GenerateSerializedSizeCode(io::Printer * printer) const508 GenerateSerializedSizeCode(io::Printer* printer) const {
509 printer->Print(variables_,
510 "if ($has_oneof_case_message$) {\n"
511 " size += com.google.protobuf.CodedOutputStream\n"
512 " .computeEnumSize($number$, ((java.lang.Integer) $oneof_name$_));\n"
513 "}\n");
514 }
515
516 void ImmutableEnumOneofFieldLiteGenerator::
GenerateEqualsCode(io::Printer * printer) const517 GenerateEqualsCode(io::Printer* printer) const {
518 if (SupportUnknownEnumValue(descriptor_->file())) {
519 printer->Print(variables_,
520 "result = result && get$capitalized_name$Value()\n"
521 " == other.get$capitalized_name$Value();\n");
522 } else {
523 printer->Print(variables_,
524 "result = result && get$capitalized_name$()\n"
525 " .equals(other.get$capitalized_name$());\n");
526 }
527 }
528
529 void ImmutableEnumOneofFieldLiteGenerator::
GenerateHashCode(io::Printer * printer) const530 GenerateHashCode(io::Printer* printer) const {
531 if (SupportUnknownEnumValue(descriptor_->file())) {
532 printer->Print(variables_,
533 "hash = (37 * hash) + $constant_name$;\n"
534 "hash = (53 * hash) + get$capitalized_name$Value();\n");
535 } else {
536 printer->Print(variables_,
537 "hash = (37 * hash) + $constant_name$;\n"
538 "hash = (53 * hash) + get$capitalized_name$().getNumber();\n");
539 }
540 }
541
542 // ===================================================================
543
544 RepeatedImmutableEnumFieldLiteGenerator::
RepeatedImmutableEnumFieldLiteGenerator(const FieldDescriptor * descriptor,int messageBitIndex,int builderBitIndex,Context * context)545 RepeatedImmutableEnumFieldLiteGenerator(const FieldDescriptor* descriptor,
546 int messageBitIndex,
547 int builderBitIndex,
548 Context* context)
549 : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
550 builderBitIndex_(builderBitIndex), context_(context),
551 name_resolver_(context->GetNameResolver()) {
552 SetEnumVariables(descriptor, messageBitIndex, builderBitIndex,
553 context->GetFieldGeneratorInfo(descriptor),
554 name_resolver_, &variables_);
555 }
556
557 RepeatedImmutableEnumFieldLiteGenerator::
~RepeatedImmutableEnumFieldLiteGenerator()558 ~RepeatedImmutableEnumFieldLiteGenerator() {}
559
GetNumBitsForMessage() const560 int RepeatedImmutableEnumFieldLiteGenerator::GetNumBitsForMessage() const {
561 return 0;
562 }
563
GetNumBitsForBuilder() const564 int RepeatedImmutableEnumFieldLiteGenerator::GetNumBitsForBuilder() const {
565 return 0;
566 }
567
568 void RepeatedImmutableEnumFieldLiteGenerator::
GenerateInterfaceMembers(io::Printer * printer) const569 GenerateInterfaceMembers(io::Printer* printer) const {
570 WriteFieldDocComment(printer, descriptor_);
571 printer->Print(variables_,
572 "$deprecation$java.util.List<$type$> get$capitalized_name$List();\n");
573 WriteFieldDocComment(printer, descriptor_);
574 printer->Print(variables_,
575 "$deprecation$int get$capitalized_name$Count();\n");
576 WriteFieldDocComment(printer, descriptor_);
577 printer->Print(variables_,
578 "$deprecation$$type$ get$capitalized_name$(int index);\n");
579 if (SupportUnknownEnumValue(descriptor_->file())) {
580 WriteFieldDocComment(printer, descriptor_);
581 printer->Print(variables_,
582 "$deprecation$java.util.List<java.lang.Integer>\n"
583 "get$capitalized_name$ValueList();\n");
584 WriteFieldDocComment(printer, descriptor_);
585 printer->Print(variables_,
586 "$deprecation$int get$capitalized_name$Value(int index);\n");
587 }
588 }
589
590 void RepeatedImmutableEnumFieldLiteGenerator::
GenerateMembers(io::Printer * printer) const591 GenerateMembers(io::Printer* printer) const {
592 printer->Print(variables_,
593 "private com.google.protobuf.Internal.IntList $name$_;\n"
594 "private static final com.google.protobuf.Internal.ListAdapter.Converter<\n"
595 " java.lang.Integer, $type$> $name$_converter_ =\n"
596 " new com.google.protobuf.Internal.ListAdapter.Converter<\n"
597 " java.lang.Integer, $type$>() {\n"
598 " public $type$ convert(java.lang.Integer from) {\n"
599 " $type$ result = $type$.forNumber(from);\n"
600 " return result == null ? $unknown$ : result;\n"
601 " }\n"
602 " };\n");
603 PrintExtraFieldInfo(variables_, printer);
604 WriteFieldDocComment(printer, descriptor_);
605 printer->Print(variables_,
606 "$deprecation$public java.util.List<$type$> get$capitalized_name$List() {\n"
607 " return new com.google.protobuf.Internal.ListAdapter<\n"
608 " java.lang.Integer, $type$>($name$_, $name$_converter_);\n"
609 "}\n");
610 WriteFieldDocComment(printer, descriptor_);
611 printer->Print(variables_,
612 "$deprecation$public int get$capitalized_name$Count() {\n"
613 " return $name$_.size();\n"
614 "}\n");
615 WriteFieldDocComment(printer, descriptor_);
616 printer->Print(variables_,
617 "$deprecation$public $type$ get$capitalized_name$(int index) {\n"
618 " return $name$_converter_.convert($name$_.getInt(index));\n"
619 "}\n");
620 if (SupportUnknownEnumValue(descriptor_->file())) {
621 WriteFieldDocComment(printer, descriptor_);
622 printer->Print(variables_,
623 "$deprecation$public java.util.List<java.lang.Integer>\n"
624 "get$capitalized_name$ValueList() {\n"
625 " return $name$_;\n"
626 "}\n");
627 WriteFieldDocComment(printer, descriptor_);
628 printer->Print(variables_,
629 "$deprecation$public int get$capitalized_name$Value(int index) {\n"
630 " return $name$_.getInt(index);\n"
631 "}\n");
632 }
633
634 if (descriptor_->options().packed() &&
635 context_->HasGeneratedMethods(descriptor_->containing_type())) {
636 printer->Print(variables_,
637 "private int $name$MemoizedSerializedSize;\n");
638 }
639
640 // Generate private setters for the builder to proxy into.
641 printer->Print(variables_,
642 "private void ensure$capitalized_name$IsMutable() {\n"
643 " if (!$is_mutable$) {\n"
644 " $name$_ =\n"
645 " com.google.protobuf.GeneratedMessageLite.mutableCopy($name$_);\n"
646 " }\n"
647 "}\n");
648 WriteFieldDocComment(printer, descriptor_);
649 printer->Print(variables_,
650 "private void set$capitalized_name$(\n"
651 " int index, $type$ value) {\n"
652 " if (value == null) {\n"
653 " throw new NullPointerException();\n"
654 " }\n"
655 " ensure$capitalized_name$IsMutable();\n"
656 " $name$_.setInt(index, value.getNumber());\n"
657 "}\n");
658 WriteFieldDocComment(printer, descriptor_);
659 printer->Print(variables_,
660 "private void add$capitalized_name$($type$ value) {\n"
661 " if (value == null) {\n"
662 " throw new NullPointerException();\n"
663 " }\n"
664 " ensure$capitalized_name$IsMutable();\n"
665 " $name$_.addInt(value.getNumber());\n"
666 "}\n");
667 WriteFieldDocComment(printer, descriptor_);
668 printer->Print(variables_,
669 "private void addAll$capitalized_name$(\n"
670 " java.lang.Iterable<? extends $type$> values) {\n"
671 " ensure$capitalized_name$IsMutable();\n"
672 " for ($type$ value : values) {\n"
673 " $name$_.addInt(value.getNumber());\n"
674 " }\n"
675 "}\n");
676 WriteFieldDocComment(printer, descriptor_);
677 printer->Print(variables_,
678 "private void clear$capitalized_name$() {\n"
679 " $name$_ = emptyIntList();\n"
680 "}\n");
681
682 if (SupportUnknownEnumValue(descriptor_->file())) {
683 WriteFieldDocComment(printer, descriptor_);
684 printer->Print(variables_,
685 "private void set$capitalized_name$Value(\n"
686 " int index, int value) {\n"
687 " ensure$capitalized_name$IsMutable();\n"
688 " $name$_.setInt(index, value);\n"
689 "}\n");
690 WriteFieldDocComment(printer, descriptor_);
691 printer->Print(variables_,
692 "private void add$capitalized_name$Value(int value) {\n"
693 " ensure$capitalized_name$IsMutable();\n"
694 " $name$_.addInt(value);\n"
695 "}\n");
696 WriteFieldDocComment(printer, descriptor_);
697 printer->Print(variables_,
698 "private void addAll$capitalized_name$Value(\n"
699 " java.lang.Iterable<java.lang.Integer> values) {\n"
700 " ensure$capitalized_name$IsMutable();\n"
701 " for (int value : values) {\n"
702 " $name$_.addInt(value);\n"
703 " }\n"
704 "}\n");
705 }
706 }
707
708 void RepeatedImmutableEnumFieldLiteGenerator::
GenerateBuilderMembers(io::Printer * printer) const709 GenerateBuilderMembers(io::Printer* printer) const {
710 WriteFieldDocComment(printer, descriptor_);
711 printer->Print(variables_,
712 "$deprecation$public java.util.List<$type$> get$capitalized_name$List() {\n"
713 " return instance.get$capitalized_name$List();\n"
714 "}\n");
715 WriteFieldDocComment(printer, descriptor_);
716 printer->Print(variables_,
717 "$deprecation$public int get$capitalized_name$Count() {\n"
718 " return instance.get$capitalized_name$Count();\n"
719 "}\n");
720 WriteFieldDocComment(printer, descriptor_);
721 printer->Print(variables_,
722 "$deprecation$public $type$ get$capitalized_name$(int index) {\n"
723 " return instance.get$capitalized_name$(index);\n"
724 "}\n");
725 WriteFieldDocComment(printer, descriptor_);
726 printer->Print(variables_,
727 "$deprecation$public Builder set$capitalized_name$(\n"
728 " int index, $type$ value) {\n"
729 " copyOnWrite();\n"
730 " instance.set$capitalized_name$(index, value);\n"
731 " return this;\n"
732 "}\n");
733 WriteFieldDocComment(printer, descriptor_);
734 printer->Print(variables_,
735 "$deprecation$public Builder add$capitalized_name$($type$ value) {\n"
736 " copyOnWrite();\n"
737 " instance.add$capitalized_name$(value);\n"
738 " return this;\n"
739 "}\n");
740 WriteFieldDocComment(printer, descriptor_);
741 printer->Print(variables_,
742 "$deprecation$public Builder addAll$capitalized_name$(\n"
743 " java.lang.Iterable<? extends $type$> values) {\n"
744 " copyOnWrite();\n"
745 " instance.addAll$capitalized_name$(values);"
746 " return this;\n"
747 "}\n");
748 WriteFieldDocComment(printer, descriptor_);
749 printer->Print(variables_,
750 "$deprecation$public Builder clear$capitalized_name$() {\n"
751 " copyOnWrite();\n"
752 " instance.clear$capitalized_name$();\n"
753 " return this;\n"
754 "}\n");
755
756 if (SupportUnknownEnumValue(descriptor_->file())) {
757 WriteFieldDocComment(printer, descriptor_);
758 printer->Print(variables_,
759 "$deprecation$public java.util.List<java.lang.Integer>\n"
760 "get$capitalized_name$ValueList() {\n"
761 " return java.util.Collections.unmodifiableList(\n"
762 " instance.get$capitalized_name$ValueList());\n"
763 "}\n");
764 WriteFieldDocComment(printer, descriptor_);
765 printer->Print(variables_,
766 "$deprecation$public int get$capitalized_name$Value(int index) {\n"
767 " return instance.get$capitalized_name$Value(index);\n"
768 "}\n");
769 WriteFieldDocComment(printer, descriptor_);
770 printer->Print(variables_,
771 "$deprecation$public Builder set$capitalized_name$Value(\n"
772 " int index, int value) {\n"
773 " copyOnWrite();\n"
774 " instance.set$capitalized_name$Value(index, value);\n"
775 " return this;\n"
776 "}\n");
777 WriteFieldDocComment(printer, descriptor_);
778 printer->Print(variables_,
779 "$deprecation$public Builder add$capitalized_name$Value(int value) {\n"
780 " instance.add$capitalized_name$Value(value);\n"
781 " return this;\n"
782 "}\n");
783 WriteFieldDocComment(printer, descriptor_);
784 printer->Print(variables_,
785 "$deprecation$public Builder addAll$capitalized_name$Value(\n"
786 " java.lang.Iterable<java.lang.Integer> values) {\n"
787 " copyOnWrite();\n"
788 " instance.addAll$capitalized_name$Value(values);\n"
789 " return this;\n"
790 "}\n");
791 }
792 }
793
794 void RepeatedImmutableEnumFieldLiteGenerator::
GenerateFieldBuilderInitializationCode(io::Printer * printer) const795 GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
796 // noop for enums
797 }
798
799 void RepeatedImmutableEnumFieldLiteGenerator::
GenerateInitializationCode(io::Printer * printer) const800 GenerateInitializationCode(io::Printer* printer) const {
801 printer->Print(variables_, "$name$_ = emptyIntList();\n");
802 }
803
804 void RepeatedImmutableEnumFieldLiteGenerator::
GenerateVisitCode(io::Printer * printer) const805 GenerateVisitCode(io::Printer* printer) const {
806 printer->Print(variables_,
807 "$name$_= visitor.visitIntList($name$_, other.$name$_);\n");
808 }
809
810 void RepeatedImmutableEnumFieldLiteGenerator::
GenerateDynamicMethodMakeImmutableCode(io::Printer * printer) const811 GenerateDynamicMethodMakeImmutableCode(io::Printer* printer) const {
812 printer->Print(variables_,
813 "$name$_.makeImmutable();\n");
814 }
815
816 void RepeatedImmutableEnumFieldLiteGenerator::
GenerateParsingCode(io::Printer * printer) const817 GenerateParsingCode(io::Printer* printer) const {
818 // Read and store the enum
819 printer->Print(variables_,
820 "if (!$is_mutable$) {\n"
821 " $name$_ =\n"
822 " com.google.protobuf.GeneratedMessageLite.mutableCopy($name$_);\n"
823 "}\n");
824
825 if (SupportUnknownEnumValue(descriptor_->file())) {
826 printer->Print(variables_,
827 "$name$_.addInt(input.readEnum());\n");
828 } else {
829 printer->Print(variables_,
830 "int rawValue = input.readEnum();\n"
831 "$type$ value = $type$.forNumber(rawValue);\n"
832 "if (value == null) {\n"
833 // We store the unknown value in unknown fields.
834 " super.mergeVarintField($number$, rawValue);\n"
835 "} else {\n"
836 " $name$_.addInt(rawValue);\n"
837 "}\n");
838 }
839 }
840
841 void RepeatedImmutableEnumFieldLiteGenerator::
GenerateParsingCodeFromPacked(io::Printer * printer) const842 GenerateParsingCodeFromPacked(io::Printer* printer) const {
843 printer->Print(variables_,
844 "if (!$is_mutable$) {\n"
845 " $name$_ =\n"
846 " com.google.protobuf.GeneratedMessageLite.mutableCopy($name$_);\n"
847 "}\n");
848
849 printer->Print(variables_,
850 "int length = input.readRawVarint32();\n"
851 "int oldLimit = input.pushLimit(length);\n"
852 "while(input.getBytesUntilLimit() > 0) {\n");
853 printer->Indent();
854
855 // Read and store the enum
856 if (SupportUnknownEnumValue(descriptor_->file())) {
857 printer->Print(variables_,
858 "$name$_.addInt(input.readEnum());\n");
859 } else {
860 printer->Print(variables_,
861 "int rawValue = input.readEnum();\n"
862 "$type$ value = $type$.forNumber(rawValue);\n"
863 "if (value == null) {\n"
864 // We store the unknown value in unknown fields.
865 " super.mergeVarintField($number$, rawValue);\n"
866 "} else {\n"
867 " $name$_.addInt(rawValue);\n"
868 "}\n");
869 }
870
871 printer->Outdent();
872 printer->Print(variables_,
873 "}\n"
874 "input.popLimit(oldLimit);\n");
875 }
876
877 void RepeatedImmutableEnumFieldLiteGenerator::
GenerateParsingDoneCode(io::Printer * printer) const878 GenerateParsingDoneCode(io::Printer* printer) const {
879 printer->Print(variables_,
880 "if ($is_mutable$) {\n"
881 " $name$_.makeImmutable();\n"
882 "}\n");
883 }
884
885 void RepeatedImmutableEnumFieldLiteGenerator::
GenerateSerializationCode(io::Printer * printer) const886 GenerateSerializationCode(io::Printer* printer) const {
887 if (descriptor_->options().packed()) {
888 printer->Print(variables_,
889 "if (get$capitalized_name$List().size() > 0) {\n"
890 " output.writeUInt32NoTag($tag$);\n"
891 " output.writeUInt32NoTag($name$MemoizedSerializedSize);\n"
892 "}\n"
893 "for (int i = 0; i < $name$_.size(); i++) {\n"
894 " output.writeEnumNoTag($name$_.getInt(i));\n"
895 "}\n");
896 } else {
897 printer->Print(variables_,
898 "for (int i = 0; i < $name$_.size(); i++) {\n"
899 " output.writeEnum($number$, $name$_.getInt(i));\n"
900 "}\n");
901 }
902 }
903
904 void RepeatedImmutableEnumFieldLiteGenerator::
GenerateSerializedSizeCode(io::Printer * printer) const905 GenerateSerializedSizeCode(io::Printer* printer) const {
906 printer->Print(variables_,
907 "{\n"
908 " int dataSize = 0;\n");
909 printer->Indent();
910
911 printer->Print(variables_,
912 "for (int i = 0; i < $name$_.size(); i++) {\n"
913 " dataSize += com.google.protobuf.CodedOutputStream\n"
914 " .computeEnumSizeNoTag($name$_.getInt(i));\n"
915 "}\n");
916 printer->Print(
917 "size += dataSize;\n");
918 if (descriptor_->options().packed()) {
919 printer->Print(variables_,
920 "if (!get$capitalized_name$List().isEmpty()) {"
921 " size += $tag_size$;\n"
922 " size += com.google.protobuf.CodedOutputStream\n"
923 " .computeUInt32SizeNoTag(dataSize);\n"
924 "}");
925 } else {
926 printer->Print(variables_,
927 "size += $tag_size$ * $name$_.size();\n");
928 }
929
930 // cache the data size for packed fields.
931 if (descriptor_->options().packed()) {
932 printer->Print(variables_,
933 "$name$MemoizedSerializedSize = dataSize;\n");
934 }
935
936 printer->Outdent();
937 printer->Print("}\n");
938 }
939
940 void RepeatedImmutableEnumFieldLiteGenerator::
GenerateEqualsCode(io::Printer * printer) const941 GenerateEqualsCode(io::Printer* printer) const {
942 printer->Print(variables_,
943 "result = result && $name$_.equals(other.$name$_);\n");
944 }
945
946 void RepeatedImmutableEnumFieldLiteGenerator::
GenerateHashCode(io::Printer * printer) const947 GenerateHashCode(io::Printer* printer) const {
948 printer->Print(variables_,
949 "if (get$capitalized_name$Count() > 0) {\n"
950 " hash = (37 * hash) + $constant_name$;\n"
951 " hash = (53 * hash) + $name$_.hashCode();\n"
952 "}\n");
953 }
954
GetBoxedType() const955 string RepeatedImmutableEnumFieldLiteGenerator::GetBoxedType() const {
956 return name_resolver_->GetImmutableClassName(descriptor_->enum_type());
957 }
958
959 } // namespace java
960 } // namespace compiler
961 } // namespace protobuf
962 } // namespace google
963