blob: e3e87c58f45ce165859c0beacf04b79aa21fc952 [file] [log] [blame]
Bo Yang5db21732015-05-21 14:28:59 -07001// 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
Feng Xiaoeee38b02015-08-22 18:25:48 -070038#include <google/protobuf/stubs/logging.h>
Bo Yang5db21732015-05-21 14:28:59 -070039#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
49namespace google {
50namespace protobuf {
51namespace compiler {
52namespace java {
53
54namespace {
55
56void 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 (*variables)["on_changed"] =
79 HasDescriptorMethods(descriptor->containing_type()) ? "onChanged();" : "";
80
81 if (SupportFieldPresence(descriptor->file())) {
82 // For singular messages and builders, one bit is used for the hasField bit.
83 (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
84
85 // Note that these have a trailing ";".
86 (*variables)["set_has_field_bit_message"] =
87 GenerateSetBit(messageBitIndex) + ";";
88 (*variables)["clear_has_field_bit_message"] =
89 GenerateClearBit(messageBitIndex) + ";";
90
91 (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex);
92 } else {
93 (*variables)["set_has_field_bit_message"] = "";
94 (*variables)["clear_has_field_bit_message"] = "";
95
96 (*variables)["is_field_present_message"] =
97 (*variables)["name"] + "_ != " +
98 (*variables)["default"] + ".getNumber()";
99 }
100
101 // For repeated builders, the underlying list tracks mutability state.
102 (*variables)["is_mutable"] = (*variables)["name"] + "_.isModifiable()";
103
104 (*variables)["get_has_field_bit_from_local"] =
105 GenerateGetBitFromLocal(builderBitIndex);
106 (*variables)["set_has_field_bit_to_local"] =
107 GenerateSetBitToLocal(messageBitIndex);
108
109 if (SupportUnknownEnumValue(descriptor->file())) {
110 (*variables)["unknown"] = (*variables)["type"] + ".UNRECOGNIZED";
111 } else {
112 (*variables)["unknown"] = (*variables)["default"];
113 }
114}
115
116} // namespace
117
118// ===================================================================
119
120ImmutableEnumFieldLiteGenerator::
121ImmutableEnumFieldLiteGenerator(const FieldDescriptor* descriptor,
122 int messageBitIndex,
123 int builderBitIndex,
124 Context* context)
125 : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
126 builderBitIndex_(builderBitIndex),
127 name_resolver_(context->GetNameResolver()) {
128 SetEnumVariables(descriptor, messageBitIndex, builderBitIndex,
129 context->GetFieldGeneratorInfo(descriptor),
130 name_resolver_, &variables_);
131}
132
133ImmutableEnumFieldLiteGenerator::~ImmutableEnumFieldLiteGenerator() {}
134
135int ImmutableEnumFieldLiteGenerator::GetNumBitsForMessage() const {
136 return 1;
137}
138
139int ImmutableEnumFieldLiteGenerator::GetNumBitsForBuilder() const {
140 return 0;
141}
142
143void ImmutableEnumFieldLiteGenerator::
144GenerateInterfaceMembers(io::Printer* printer) const {
145 if (SupportFieldPresence(descriptor_->file())) {
146 WriteFieldDocComment(printer, descriptor_);
147 printer->Print(variables_,
148 "$deprecation$boolean has$capitalized_name$();\n");
149 }
150 if (SupportUnknownEnumValue(descriptor_->file())) {
151 WriteFieldDocComment(printer, descriptor_);
152 printer->Print(variables_,
153 "$deprecation$int get$capitalized_name$Value();\n");
154 }
155 WriteFieldDocComment(printer, descriptor_);
156 printer->Print(variables_,
157 "$deprecation$$type$ get$capitalized_name$();\n");
158}
159
160void ImmutableEnumFieldLiteGenerator::
161GenerateMembers(io::Printer* printer) const {
162 printer->Print(variables_,
163 "private int $name$_;\n");
164 PrintExtraFieldInfo(variables_, printer);
165 if (SupportFieldPresence(descriptor_->file())) {
166 WriteFieldDocComment(printer, descriptor_);
167 printer->Print(variables_,
168 "$deprecation$public boolean has$capitalized_name$() {\n"
169 " return $get_has_field_bit_message$;\n"
170 "}\n");
171 }
172 if (SupportUnknownEnumValue(descriptor_->file())) {
173 WriteFieldDocComment(printer, descriptor_);
174 printer->Print(variables_,
175 "$deprecation$public int get$capitalized_name$Value() {\n"
176 " return $name$_;\n"
177 "}\n");
178 }
179 WriteFieldDocComment(printer, descriptor_);
180 printer->Print(variables_,
181 "$deprecation$public $type$ get$capitalized_name$() {\n"
182 " $type$ result = $type$.valueOf($name$_);\n"
183 " return result == null ? $unknown$ : result;\n"
184 "}\n");
185
186 // Generate private setters for the builder to proxy into.
187 if (SupportUnknownEnumValue(descriptor_->file())) {
188 WriteFieldDocComment(printer, descriptor_);
189 printer->Print(variables_,
190 "private void set$capitalized_name$Value(int value) {\n"
191 " $set_has_field_bit_message$"
192 " $name$_ = value;\n"
193 "}\n");
194 }
195 WriteFieldDocComment(printer, descriptor_);
196 printer->Print(variables_,
197 "private void set$capitalized_name$($type$ value) {\n"
198 " if (value == null) {\n"
199 " throw new NullPointerException();\n"
200 " }\n"
201 " $set_has_field_bit_message$\n"
202 " $name$_ = value.getNumber();\n"
203 "}\n");
204 WriteFieldDocComment(printer, descriptor_);
205 printer->Print(variables_,
206 "private void clear$capitalized_name$() {\n"
207 " $clear_has_field_bit_message$\n"
208 " $name$_ = $default_number$;\n"
209 "}\n");
210}
211
212void ImmutableEnumFieldLiteGenerator::
213GenerateBuilderMembers(io::Printer* printer) const {
214 if (SupportFieldPresence(descriptor_->file())) {
215 WriteFieldDocComment(printer, descriptor_);
216 printer->Print(variables_,
217 "$deprecation$public boolean has$capitalized_name$() {\n"
218 " return instance.has$capitalized_name$();\n"
219 "}\n");
220 }
221 if (SupportUnknownEnumValue(descriptor_->file())) {
222 WriteFieldDocComment(printer, descriptor_);
223 printer->Print(variables_,
224 "$deprecation$public int get$capitalized_name$Value() {\n"
225 " return instance.get$capitalized_name$Value();\n"
226 "}\n");
227 WriteFieldDocComment(printer, descriptor_);
228 printer->Print(variables_,
229 "$deprecation$public Builder set$capitalized_name$Value(int value) {\n"
230 " copyOnWrite();\n"
231 " instance.set$capitalized_name$Value(int value);\n"
232 " return this;\n"
233 "}\n");
234 }
235 WriteFieldDocComment(printer, descriptor_);
236 printer->Print(variables_,
237 "$deprecation$public $type$ get$capitalized_name$() {\n"
238 " return instance.get$capitalized_name$();\n"
239 "}\n");
240 WriteFieldDocComment(printer, descriptor_);
241 printer->Print(variables_,
242 "$deprecation$public Builder set$capitalized_name$($type$ value) {\n"
243 " copyOnWrite();\n"
244 " instance.set$capitalized_name$(value);\n"
245 " return this;\n"
246 "}\n");
247 WriteFieldDocComment(printer, descriptor_);
248 printer->Print(variables_,
249 "$deprecation$public Builder clear$capitalized_name$() {\n"
250 " copyOnWrite();\n"
251 " instance.clear$capitalized_name$();\n"
252 " return this;\n"
253 "}\n");
254}
255
256void ImmutableEnumFieldLiteGenerator::
257GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
258 // noop for enums
259}
260
261void ImmutableEnumFieldLiteGenerator::
262GenerateInitializationCode(io::Printer* printer) const {
263 printer->Print(variables_, "$name$_ = $default_number$;\n");
264}
265
266void ImmutableEnumFieldLiteGenerator::
267GenerateMergingCode(io::Printer* printer) const {
268 if (SupportFieldPresence(descriptor_->file())) {
269 printer->Print(variables_,
270 "if (other.has$capitalized_name$()) {\n"
271 " set$capitalized_name$(other.get$capitalized_name$());\n"
272 "}\n");
273 } else if (SupportUnknownEnumValue(descriptor_->file())) {
274 printer->Print(variables_,
275 "if (other.$name$_ != $default_number$) {\n"
276 " set$capitalized_name$Value(other.get$capitalized_name$Value());\n"
277 "}\n");
278 } else {
279 GOOGLE_LOG(FATAL) << "Can't reach here.";
280 }
281}
282
283void ImmutableEnumFieldLiteGenerator::
284GenerateDynamicMethodMakeImmutableCode(io::Printer* printer) const {
285 // noop for scalars
286}
287
288void ImmutableEnumFieldLiteGenerator::
289GenerateParsingCode(io::Printer* printer) const {
290 if (SupportUnknownEnumValue(descriptor_->file())) {
291 printer->Print(variables_,
292 "int rawValue = input.readEnum();\n"
293 "$set_has_field_bit_message$\n"
294 "$name$_ = rawValue;\n");
295 } else {
296 printer->Print(variables_,
297 "int rawValue = input.readEnum();\n"
298 "$type$ value = $type$.valueOf(rawValue);\n"
299 "if (value == null) {\n");
300 if (PreserveUnknownFields(descriptor_->containing_type())) {
301 printer->Print(variables_,
Jisi Liu46e8ff62015-10-05 11:59:43 -0700302 " super.mergeVarintField($number$, rawValue);\n");
Bo Yang5db21732015-05-21 14:28:59 -0700303 }
304 printer->Print(variables_,
305 "} else {\n"
306 " $set_has_field_bit_message$\n"
307 " $name$_ = rawValue;\n"
308 "}\n");
309 }
310}
311
312void ImmutableEnumFieldLiteGenerator::
313GenerateParsingDoneCode(io::Printer* printer) const {
314 // noop for enums
315}
316
317void ImmutableEnumFieldLiteGenerator::
318GenerateSerializationCode(io::Printer* printer) const {
319 printer->Print(variables_,
320 "if ($is_field_present_message$) {\n"
321 " output.writeEnum($number$, $name$_);\n"
322 "}\n");
323}
324
325void ImmutableEnumFieldLiteGenerator::
326GenerateSerializedSizeCode(io::Printer* printer) const {
327 printer->Print(variables_,
328 "if ($is_field_present_message$) {\n"
329 " size += com.google.protobuf.CodedOutputStream\n"
330 " .computeEnumSize($number$, $name$_);\n"
331 "}\n");
332}
333
334void ImmutableEnumFieldLiteGenerator::
335GenerateEqualsCode(io::Printer* printer) const {
336 printer->Print(variables_,
337 "result = result && $name$_ == other.$name$_;\n");
338}
339
340void ImmutableEnumFieldLiteGenerator::
341GenerateHashCode(io::Printer* printer) const {
342 printer->Print(variables_,
343 "hash = (37 * hash) + $constant_name$;\n"
344 "hash = (53 * hash) + $name$_;\n");
345}
346
347string ImmutableEnumFieldLiteGenerator::GetBoxedType() const {
348 return name_resolver_->GetImmutableClassName(descriptor_->enum_type());
349}
350
351// ===================================================================
352
353ImmutableEnumOneofFieldLiteGenerator::
354ImmutableEnumOneofFieldLiteGenerator(const FieldDescriptor* descriptor,
355 int messageBitIndex,
356 int builderBitIndex,
357 Context* context)
358 : ImmutableEnumFieldLiteGenerator(
359 descriptor, messageBitIndex, builderBitIndex, context) {
360 const OneofGeneratorInfo* info =
361 context->GetOneofGeneratorInfo(descriptor->containing_oneof());
362 SetCommonOneofVariables(descriptor, info, &variables_);
363}
364
365ImmutableEnumOneofFieldLiteGenerator::
366~ImmutableEnumOneofFieldLiteGenerator() {}
367
368void ImmutableEnumOneofFieldLiteGenerator::
369GenerateMembers(io::Printer* printer) const {
370 PrintExtraFieldInfo(variables_, printer);
371 if (SupportFieldPresence(descriptor_->file())) {
372 WriteFieldDocComment(printer, descriptor_);
373 printer->Print(variables_,
374 "$deprecation$public boolean has$capitalized_name$() {\n"
375 " return $has_oneof_case_message$;\n"
376 "}\n");
377 }
378 if (SupportUnknownEnumValue(descriptor_->file())) {
379 WriteFieldDocComment(printer, descriptor_);
380 printer->Print(variables_,
381 "$deprecation$public int get$capitalized_name$Value() {\n"
382 " if ($has_oneof_case_message$) {\n"
383 " return (java.lang.Integer) $oneof_name$_;\n"
384 " }\n"
385 " return $default_number$;\n"
386 "}\n");
387 }
388 WriteFieldDocComment(printer, descriptor_);
389 printer->Print(variables_,
390 "$deprecation$public $type$ get$capitalized_name$() {\n"
391 " if ($has_oneof_case_message$) {\n"
392 " $type$ result = $type$.valueOf((java.lang.Integer) $oneof_name$_);\n"
393 " return result == null ? $unknown$ : result;\n"
394 " }\n"
395 " return $default$;\n"
396 "}\n");
397
398 // Generate private setters for the builder to proxy into.
399 if (SupportUnknownEnumValue(descriptor_->file())) {
400 WriteFieldDocComment(printer, descriptor_);
401 printer->Print(variables_,
402 "private void set$capitalized_name$Value(int value) {\n"
403 " $set_oneof_case_message$;\n"
404 " $oneof_name$_ = value;\n"
405 "}\n");
406 }
407 WriteFieldDocComment(printer, descriptor_);
408 printer->Print(variables_,
409 "private void set$capitalized_name$($type$ value) {\n"
410 " if (value == null) {\n"
411 " throw new NullPointerException();\n"
412 " }\n"
413 " $set_oneof_case_message$;\n"
414 " $oneof_name$_ = value.getNumber();\n"
415 "}\n");
416 WriteFieldDocComment(printer, descriptor_);
417 printer->Print(variables_,
418 "private void clear$capitalized_name$() {\n"
419 " if ($has_oneof_case_message$) {\n"
420 " $clear_oneof_case_message$;\n"
421 " $oneof_name$_ = null;\n"
422 " }\n"
423 "}\n");
424}
425
426void ImmutableEnumOneofFieldLiteGenerator::
427GenerateBuilderMembers(io::Printer* printer) const {
428 if (SupportFieldPresence(descriptor_->file())) {
429 WriteFieldDocComment(printer, descriptor_);
430 printer->Print(variables_,
431 "$deprecation$public boolean has$capitalized_name$() {\n"
432 " return instance.has$capitalized_name$();\n"
433 "}\n");
434 }
435 if (SupportUnknownEnumValue(descriptor_->file())) {
436 WriteFieldDocComment(printer, descriptor_);
437 printer->Print(variables_,
438 "$deprecation$public int get$capitalized_name$Value() {\n"
439 " return instance.get$capitalized_name$Value();\n"
440 "}\n");
441 WriteFieldDocComment(printer, descriptor_);
442 printer->Print(variables_,
443 "$deprecation$public Builder set$capitalized_name$Value(int value) {\n"
444 " copyOnWrite();\n"
445 " instance.set$capitalized_name$Value(value);\n"
446 " return this;\n"
447 "}\n");
448 }
449 WriteFieldDocComment(printer, descriptor_);
450 printer->Print(variables_,
451 "$deprecation$public $type$ get$capitalized_name$() {\n"
452 " return instance.get$capitalized_name$();\n"
453 "}\n");
454 WriteFieldDocComment(printer, descriptor_);
455 printer->Print(variables_,
456 "$deprecation$public Builder set$capitalized_name$($type$ value) {\n"
457 " copyOnWrite();\n"
458 " instance.set$capitalized_name$(value);\n"
459 " return this;\n"
460 "}\n");
461 WriteFieldDocComment(printer, descriptor_);
462 printer->Print(variables_,
463 "$deprecation$public Builder clear$capitalized_name$() {\n"
464 " copyOnWrite();\n"
465 " instance.clear$capitalized_name$();\n"
466 " return this;\n"
467 "}\n");
468}
469
470void ImmutableEnumOneofFieldLiteGenerator::
471GenerateMergingCode(io::Printer* printer) const {
472 if (SupportUnknownEnumValue(descriptor_->file())) {
473 printer->Print(variables_,
474 "set$capitalized_name$Value(other.get$capitalized_name$Value());\n");
475 } else {
476 printer->Print(variables_,
477 "set$capitalized_name$(other.get$capitalized_name$());\n");
478 }
479}
480
481void ImmutableEnumOneofFieldLiteGenerator::
482GenerateParsingCode(io::Printer* printer) const {
483 if (SupportUnknownEnumValue(descriptor_->file())) {
484 printer->Print(variables_,
485 "int rawValue = input.readEnum();\n"
486 "$set_oneof_case_message$;\n"
487 "$oneof_name$_ = rawValue;\n");
488 } else {
489 printer->Print(variables_,
490 "int rawValue = input.readEnum();\n"
491 "$type$ value = $type$.valueOf(rawValue);\n"
492 "if (value == null) {\n");
493 if (PreserveUnknownFields(descriptor_->containing_type())) {
494 printer->Print(variables_,
Jisi Liu46e8ff62015-10-05 11:59:43 -0700495 " super.mergeVarintField($number$, rawValue);\n");
Bo Yang5db21732015-05-21 14:28:59 -0700496 }
497 printer->Print(variables_,
498 "} else {\n"
499 " $set_oneof_case_message$;\n"
500 " $oneof_name$_ = rawValue;\n"
501 "}\n");
502 }
503}
504
505void ImmutableEnumOneofFieldLiteGenerator::
506GenerateSerializationCode(io::Printer* printer) const {
507 printer->Print(variables_,
508 "if ($has_oneof_case_message$) {\n"
509 " output.writeEnum($number$, ((java.lang.Integer) $oneof_name$_));\n"
510 "}\n");
511}
512
513void ImmutableEnumOneofFieldLiteGenerator::
514GenerateSerializedSizeCode(io::Printer* printer) const {
515 printer->Print(variables_,
516 "if ($has_oneof_case_message$) {\n"
517 " size += com.google.protobuf.CodedOutputStream\n"
518 " .computeEnumSize($number$, ((java.lang.Integer) $oneof_name$_));\n"
519 "}\n");
520}
521
522void ImmutableEnumOneofFieldLiteGenerator::
523GenerateEqualsCode(io::Printer* printer) const {
524 if (SupportUnknownEnumValue(descriptor_->file())) {
525 printer->Print(variables_,
526 "result = result && get$capitalized_name$Value()\n"
527 " == other.get$capitalized_name$Value();\n");
528 } else {
529 printer->Print(variables_,
530 "result = result && get$capitalized_name$()\n"
531 " .equals(other.get$capitalized_name$());\n");
532 }
533}
534
535void ImmutableEnumOneofFieldLiteGenerator::
536GenerateHashCode(io::Printer* printer) const {
537 if (SupportUnknownEnumValue(descriptor_->file())) {
538 printer->Print(variables_,
539 "hash = (37 * hash) + $constant_name$;\n"
540 "hash = (53 * hash) + get$capitalized_name$Value();\n");
541 } else {
542 printer->Print(variables_,
543 "hash = (37 * hash) + $constant_name$;\n"
544 "hash = (53 * hash) + get$capitalized_name$().getNumber();\n");
545 }
546}
547
548// ===================================================================
549
550RepeatedImmutableEnumFieldLiteGenerator::
551RepeatedImmutableEnumFieldLiteGenerator(const FieldDescriptor* descriptor,
552 int messageBitIndex,
553 int builderBitIndex,
554 Context* context)
555 : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
556 builderBitIndex_(builderBitIndex), context_(context),
557 name_resolver_(context->GetNameResolver()) {
558 SetEnumVariables(descriptor, messageBitIndex, builderBitIndex,
559 context->GetFieldGeneratorInfo(descriptor),
560 name_resolver_, &variables_);
561}
562
563RepeatedImmutableEnumFieldLiteGenerator::
564~RepeatedImmutableEnumFieldLiteGenerator() {}
565
566int RepeatedImmutableEnumFieldLiteGenerator::GetNumBitsForMessage() const {
567 return 0;
568}
569
570int RepeatedImmutableEnumFieldLiteGenerator::GetNumBitsForBuilder() const {
571 return 0;
572}
573
574void RepeatedImmutableEnumFieldLiteGenerator::
575GenerateInterfaceMembers(io::Printer* printer) const {
576 WriteFieldDocComment(printer, descriptor_);
577 printer->Print(variables_,
578 "$deprecation$java.util.List<$type$> get$capitalized_name$List();\n");
579 WriteFieldDocComment(printer, descriptor_);
580 printer->Print(variables_,
581 "$deprecation$int get$capitalized_name$Count();\n");
582 WriteFieldDocComment(printer, descriptor_);
583 printer->Print(variables_,
584 "$deprecation$$type$ get$capitalized_name$(int index);\n");
585 if (SupportUnknownEnumValue(descriptor_->file())) {
586 WriteFieldDocComment(printer, descriptor_);
587 printer->Print(variables_,
588 "$deprecation$java.util.List<java.lang.Integer>\n"
589 "get$capitalized_name$ValueList();\n");
590 WriteFieldDocComment(printer, descriptor_);
591 printer->Print(variables_,
592 "$deprecation$int get$capitalized_name$Value(int index);\n");
593 }
594}
595
596void RepeatedImmutableEnumFieldLiteGenerator::
597GenerateMembers(io::Printer* printer) const {
598 printer->Print(variables_,
Feng Xiaoe841bac2015-12-11 17:09:20 -0800599 "private com.google.protobuf.Internal.IntList $name$_;\n"
Bo Yang5db21732015-05-21 14:28:59 -0700600 "private static final com.google.protobuf.Internal.ListAdapter.Converter<\n"
601 " java.lang.Integer, $type$> $name$_converter_ =\n"
602 " new com.google.protobuf.Internal.ListAdapter.Converter<\n"
603 " java.lang.Integer, $type$>() {\n"
604 " public $type$ convert(java.lang.Integer from) {\n"
605 " $type$ result = $type$.valueOf(from);\n"
606 " return result == null ? $unknown$ : result;\n"
607 " }\n"
608 " };\n");
609 PrintExtraFieldInfo(variables_, printer);
610 WriteFieldDocComment(printer, descriptor_);
611 printer->Print(variables_,
612 "$deprecation$public java.util.List<$type$> get$capitalized_name$List() {\n"
613 " return new com.google.protobuf.Internal.ListAdapter<\n"
614 " java.lang.Integer, $type$>($name$_, $name$_converter_);\n"
615 "}\n");
616 WriteFieldDocComment(printer, descriptor_);
617 printer->Print(variables_,
618 "$deprecation$public int get$capitalized_name$Count() {\n"
619 " return $name$_.size();\n"
620 "}\n");
621 WriteFieldDocComment(printer, descriptor_);
622 printer->Print(variables_,
623 "$deprecation$public $type$ get$capitalized_name$(int index) {\n"
Feng Xiaoe841bac2015-12-11 17:09:20 -0800624 " return $name$_converter_.convert($name$_.getInt(index));\n"
Bo Yang5db21732015-05-21 14:28:59 -0700625 "}\n");
626 if (SupportUnknownEnumValue(descriptor_->file())) {
627 WriteFieldDocComment(printer, descriptor_);
628 printer->Print(variables_,
629 "$deprecation$public java.util.List<java.lang.Integer>\n"
630 "get$capitalized_name$ValueList() {\n"
631 " return $name$_;\n"
632 "}\n");
633 WriteFieldDocComment(printer, descriptor_);
634 printer->Print(variables_,
635 "$deprecation$public int get$capitalized_name$Value(int index) {\n"
Feng Xiaoe841bac2015-12-11 17:09:20 -0800636 " return $name$_.getInt(index);\n"
Bo Yang5db21732015-05-21 14:28:59 -0700637 "}\n");
638 }
639
640 if (descriptor_->options().packed() &&
641 HasGeneratedMethods(descriptor_->containing_type())) {
642 printer->Print(variables_,
643 "private int $name$MemoizedSerializedSize;\n");
644 }
645
646 // Generate private setters for the builder to proxy into.
647 printer->Print(variables_,
648 "private void ensure$capitalized_name$IsMutable() {\n"
649 " if (!$is_mutable$) {\n"
Feng Xiaoe841bac2015-12-11 17:09:20 -0800650 " $name$_ = newIntList($name$_);\n"
Bo Yang5db21732015-05-21 14:28:59 -0700651 " }\n"
652 "}\n");
653 WriteFieldDocComment(printer, descriptor_);
654 printer->Print(variables_,
655 "private void set$capitalized_name$(\n"
656 " int index, $type$ value) {\n"
657 " if (value == null) {\n"
658 " throw new NullPointerException();\n"
659 " }\n"
660 " ensure$capitalized_name$IsMutable();\n"
Feng Xiaoe841bac2015-12-11 17:09:20 -0800661 " $name$_.setInt(index, value.getNumber());\n"
Bo Yang5db21732015-05-21 14:28:59 -0700662 "}\n");
663 WriteFieldDocComment(printer, descriptor_);
664 printer->Print(variables_,
665 "private void add$capitalized_name$($type$ value) {\n"
666 " if (value == null) {\n"
667 " throw new NullPointerException();\n"
668 " }\n"
669 " ensure$capitalized_name$IsMutable();\n"
Feng Xiaoe841bac2015-12-11 17:09:20 -0800670 " $name$_.addInt(value.getNumber());\n"
Bo Yang5db21732015-05-21 14:28:59 -0700671 "}\n");
672 WriteFieldDocComment(printer, descriptor_);
673 printer->Print(variables_,
674 "private void addAll$capitalized_name$(\n"
675 " java.lang.Iterable<? extends $type$> values) {\n"
676 " ensure$capitalized_name$IsMutable();\n"
677 " for ($type$ value : values) {\n"
Feng Xiaoe841bac2015-12-11 17:09:20 -0800678 " $name$_.addInt(value.getNumber());\n"
Bo Yang5db21732015-05-21 14:28:59 -0700679 " }\n"
680 "}\n");
681 WriteFieldDocComment(printer, descriptor_);
682 printer->Print(variables_,
683 "private void clear$capitalized_name$() {\n"
Feng Xiaoe841bac2015-12-11 17:09:20 -0800684 " $name$_ = emptyIntList();\n"
Bo Yang5db21732015-05-21 14:28:59 -0700685 "}\n");
686
687 if (SupportUnknownEnumValue(descriptor_->file())) {
688 WriteFieldDocComment(printer, descriptor_);
689 printer->Print(variables_,
690 "private void set$capitalized_name$Value(\n"
691 " int index, int value) {\n"
692 " ensure$capitalized_name$IsMutable();\n"
Feng Xiaoe841bac2015-12-11 17:09:20 -0800693 " $name$_.setInt(index, value);\n"
Bo Yang5db21732015-05-21 14:28:59 -0700694 "}\n");
695 WriteFieldDocComment(printer, descriptor_);
696 printer->Print(variables_,
697 "private void add$capitalized_name$Value(int value) {\n"
698 " ensure$capitalized_name$IsMutable();\n"
Feng Xiaoe841bac2015-12-11 17:09:20 -0800699 " $name$_.addInt(value);\n"
Bo Yang5db21732015-05-21 14:28:59 -0700700 "}\n");
701 WriteFieldDocComment(printer, descriptor_);
702 printer->Print(variables_,
703 "private void addAll$capitalized_name$Value(\n"
704 " java.lang.Iterable<java.lang.Integer> values) {\n"
705 " ensure$capitalized_name$IsMutable();\n"
706 " for (int value : values) {\n"
Feng Xiaoe841bac2015-12-11 17:09:20 -0800707 " $name$_.addInt(value);\n"
Bo Yang5db21732015-05-21 14:28:59 -0700708 " }\n"
709 "}\n");
710 }
711}
712
713void RepeatedImmutableEnumFieldLiteGenerator::
714GenerateBuilderMembers(io::Printer* printer) const {
715 WriteFieldDocComment(printer, descriptor_);
716 printer->Print(variables_,
717 "$deprecation$public java.util.List<$type$> get$capitalized_name$List() {\n"
718 " return instance.get$capitalized_name$List();\n"
719 "}\n");
720 WriteFieldDocComment(printer, descriptor_);
721 printer->Print(variables_,
722 "$deprecation$public int get$capitalized_name$Count() {\n"
723 " return instance.get$capitalized_name$Count();\n"
724 "}\n");
725 WriteFieldDocComment(printer, descriptor_);
726 printer->Print(variables_,
727 "$deprecation$public $type$ get$capitalized_name$(int index) {\n"
728 " return instance.get$capitalized_name$(index);\n"
729 "}\n");
730 WriteFieldDocComment(printer, descriptor_);
731 printer->Print(variables_,
732 "$deprecation$public Builder set$capitalized_name$(\n"
733 " int index, $type$ value) {\n"
734 " copyOnWrite();\n"
735 " instance.set$capitalized_name$(index, value);\n"
736 " return this;\n"
737 "}\n");
738 WriteFieldDocComment(printer, descriptor_);
739 printer->Print(variables_,
740 "$deprecation$public Builder add$capitalized_name$($type$ value) {\n"
741 " copyOnWrite();\n"
742 " instance.add$capitalized_name$(value);\n"
743 " return this;\n"
744 "}\n");
745 WriteFieldDocComment(printer, descriptor_);
746 printer->Print(variables_,
747 "$deprecation$public Builder addAll$capitalized_name$(\n"
748 " java.lang.Iterable<? extends $type$> values) {\n"
749 " copyOnWrite();\n"
750 " instance.addAll$capitalized_name$(values);"
751 " return this;\n"
752 "}\n");
753 WriteFieldDocComment(printer, descriptor_);
754 printer->Print(variables_,
755 "$deprecation$public Builder clear$capitalized_name$() {\n"
756 " copyOnWrite();\n"
757 " instance.clear$capitalized_name$();\n"
758 " return this;\n"
759 "}\n");
760
761 if (SupportUnknownEnumValue(descriptor_->file())) {
762 WriteFieldDocComment(printer, descriptor_);
763 printer->Print(variables_,
764 "$deprecation$public java.util.List<java.lang.Integer>\n"
765 "get$capitalized_name$ValueList() {\n"
766 " return java.util.Collections.unmodifiableList(\n"
767 " instance.get$capitalized_name$ValueList());\n"
768 "}\n");
769 WriteFieldDocComment(printer, descriptor_);
770 printer->Print(variables_,
771 "$deprecation$public int get$capitalized_name$Value(int index) {\n"
772 " return instance.get$capitalized_name$Value(index);\n"
773 "}\n");
774 WriteFieldDocComment(printer, descriptor_);
775 printer->Print(variables_,
776 "$deprecation$public Builder set$capitalized_name$Value(\n"
777 " int index, int value) {\n"
778 " copyOnWrite();\n"
779 " instance.set$capitalized_name$Value(index, value);\n"
780 " return this;\n"
781 "}\n");
782 WriteFieldDocComment(printer, descriptor_);
783 printer->Print(variables_,
784 "$deprecation$public Builder add$capitalized_name$Value(int value) {\n"
785 " instance.add$capitalized_name$Value(value);\n"
786 " return this;\n"
787 "}\n");
788 WriteFieldDocComment(printer, descriptor_);
789 printer->Print(variables_,
790 "$deprecation$public Builder addAll$capitalized_name$Value(\n"
791 " java.lang.Iterable<java.lang.Integer> values) {\n"
792 " copyOnWrite();\n"
793 " instance.addAll$capitalized_name$Value(values);\n"
794 " return this;\n"
795 "}\n");
796 }
797}
798
799void RepeatedImmutableEnumFieldLiteGenerator::
800GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
801 // noop for enums
802}
803
804void RepeatedImmutableEnumFieldLiteGenerator::
805GenerateInitializationCode(io::Printer* printer) const {
Feng Xiaoe841bac2015-12-11 17:09:20 -0800806 printer->Print(variables_, "$name$_ = emptyIntList();\n");
Bo Yang5db21732015-05-21 14:28:59 -0700807}
808
809void RepeatedImmutableEnumFieldLiteGenerator::
810GenerateMergingCode(io::Printer* printer) const {
811 // The code below does two optimizations:
812 // 1. If the other list is empty, there's nothing to do. This ensures we
813 // don't allocate a new array if we already have an immutable one.
814 // 2. If the other list is non-empty and our current list is empty, we can
815 // reuse the other list which is guaranteed to be immutable.
816 printer->Print(variables_,
817 "if (!other.$name$_.isEmpty()) {\n"
818 " if ($name$_.isEmpty()) {\n"
819 " $name$_ = other.$name$_;\n"
820 " } else {\n"
821 " ensure$capitalized_name$IsMutable();\n"
822 " $name$_.addAll(other.$name$_);\n"
823 " }\n"
824 " $on_changed$\n"
825 "}\n");
826}
827
828void RepeatedImmutableEnumFieldLiteGenerator::
829GenerateDynamicMethodMakeImmutableCode(io::Printer* printer) const {
830 printer->Print(variables_,
831 "$name$_.makeImmutable();\n");
832}
833
834void RepeatedImmutableEnumFieldLiteGenerator::
835GenerateParsingCode(io::Printer* printer) const {
836 // Read and store the enum
837 if (SupportUnknownEnumValue(descriptor_->file())) {
838 printer->Print(variables_,
839 "int rawValue = input.readEnum();\n"
840 "if (!$is_mutable$) {\n"
Feng Xiaoe841bac2015-12-11 17:09:20 -0800841 " $name$_ = newIntList();\n"
Bo Yang5db21732015-05-21 14:28:59 -0700842 "}\n"
Feng Xiaoe841bac2015-12-11 17:09:20 -0800843 "$name$_.addInt(rawValue);\n");
Bo Yang5db21732015-05-21 14:28:59 -0700844 } else {
845 printer->Print(variables_,
846 "int rawValue = input.readEnum();\n"
847 "$type$ value = $type$.valueOf(rawValue);\n"
848 "if (value == null) {\n");
849 if (PreserveUnknownFields(descriptor_->containing_type())) {
850 printer->Print(variables_,
Jisi Liu46e8ff62015-10-05 11:59:43 -0700851 " super.mergeVarintField($number$, rawValue);\n");
Bo Yang5db21732015-05-21 14:28:59 -0700852 }
853 printer->Print(variables_,
854 "} else {\n"
855 " if (!$is_mutable$) {\n"
Feng Xiaoe841bac2015-12-11 17:09:20 -0800856 " $name$_ = newIntList();\n"
Bo Yang5db21732015-05-21 14:28:59 -0700857 " }\n"
Feng Xiaoe841bac2015-12-11 17:09:20 -0800858 " $name$_.addInt(rawValue);\n"
Bo Yang5db21732015-05-21 14:28:59 -0700859 "}\n");
860 }
861}
862
863void RepeatedImmutableEnumFieldLiteGenerator::
864GenerateParsingCodeFromPacked(io::Printer* printer) const {
865 // Wrap GenerateParsingCode's contents with a while loop.
866
867 printer->Print(variables_,
868 "int length = input.readRawVarint32();\n"
869 "int oldLimit = input.pushLimit(length);\n"
870 "while(input.getBytesUntilLimit() > 0) {\n");
871 printer->Indent();
872
873 GenerateParsingCode(printer);
874
875 printer->Outdent();
876 printer->Print(variables_,
877 "}\n"
878 "input.popLimit(oldLimit);\n");
879}
880
881void RepeatedImmutableEnumFieldLiteGenerator::
882GenerateParsingDoneCode(io::Printer* printer) const {
883 printer->Print(variables_,
884 "if ($is_mutable$) {\n"
885 " $name$_.makeImmutable();\n"
886 "}\n");
887}
888
889void RepeatedImmutableEnumFieldLiteGenerator::
890GenerateSerializationCode(io::Printer* printer) const {
891 if (descriptor_->options().packed()) {
892 printer->Print(variables_,
893 "if (get$capitalized_name$List().size() > 0) {\n"
894 " output.writeRawVarint32($tag$);\n"
895 " output.writeRawVarint32($name$MemoizedSerializedSize);\n"
896 "}\n"
897 "for (int i = 0; i < $name$_.size(); i++) {\n"
Feng Xiaoe841bac2015-12-11 17:09:20 -0800898 " output.writeEnumNoTag($name$_.getInt(i));\n"
Bo Yang5db21732015-05-21 14:28:59 -0700899 "}\n");
900 } else {
901 printer->Print(variables_,
902 "for (int i = 0; i < $name$_.size(); i++) {\n"
Feng Xiaoe841bac2015-12-11 17:09:20 -0800903 " output.writeEnum($number$, $name$_.getInt(i));\n"
Bo Yang5db21732015-05-21 14:28:59 -0700904 "}\n");
905 }
906}
907
908void RepeatedImmutableEnumFieldLiteGenerator::
909GenerateSerializedSizeCode(io::Printer* printer) const {
910 printer->Print(variables_,
911 "{\n"
912 " int dataSize = 0;\n");
913 printer->Indent();
914
915 printer->Print(variables_,
916 "for (int i = 0; i < $name$_.size(); i++) {\n"
917 " dataSize += com.google.protobuf.CodedOutputStream\n"
Feng Xiaoe841bac2015-12-11 17:09:20 -0800918 " .computeEnumSizeNoTag($name$_.getInt(i));\n"
Bo Yang5db21732015-05-21 14:28:59 -0700919 "}\n");
920 printer->Print(
921 "size += dataSize;\n");
922 if (descriptor_->options().packed()) {
923 printer->Print(variables_,
924 "if (!get$capitalized_name$List().isEmpty()) {"
925 " size += $tag_size$;\n"
926 " size += com.google.protobuf.CodedOutputStream\n"
927 " .computeRawVarint32Size(dataSize);\n"
928 "}");
929 } else {
930 printer->Print(variables_,
931 "size += $tag_size$ * $name$_.size();\n");
932 }
933
934 // cache the data size for packed fields.
935 if (descriptor_->options().packed()) {
936 printer->Print(variables_,
937 "$name$MemoizedSerializedSize = dataSize;\n");
938 }
939
940 printer->Outdent();
941 printer->Print("}\n");
942}
943
944void RepeatedImmutableEnumFieldLiteGenerator::
945GenerateEqualsCode(io::Printer* printer) const {
946 printer->Print(variables_,
947 "result = result && $name$_.equals(other.$name$_);\n");
948}
949
950void RepeatedImmutableEnumFieldLiteGenerator::
951GenerateHashCode(io::Printer* printer) const {
952 printer->Print(variables_,
953 "if (get$capitalized_name$Count() > 0) {\n"
954 " hash = (37 * hash) + $constant_name$;\n"
955 " hash = (53 * hash) + $name$_.hashCode();\n"
956 "}\n");
957}
958
959string RepeatedImmutableEnumFieldLiteGenerator::GetBoxedType() const {
960 return name_resolver_->GetImmutableClassName(descriptor_->enum_type());
961}
962
963} // namespace java
964} // namespace compiler
965} // namespace protobuf
966} // namespace google