Line data Source code
1 : // Protocol Buffers - Google's data interchange format
2 : // Copyright 2008 Google Inc. All rights reserved.
3 : // https://developers.google.com/protocol-buffers/
4 : //
5 : // Redistribution and use in source and binary forms, with or without
6 : // modification, are permitted provided that the following conditions are
7 : // met:
8 : //
9 : // * Redistributions of source code must retain the above copyright
10 : // notice, this list of conditions and the following disclaimer.
11 : // * Redistributions in binary form must reproduce the above
12 : // copyright notice, this list of conditions and the following disclaimer
13 : // in the documentation and/or other materials provided with the
14 : // distribution.
15 : // * Neither the name of Google Inc. nor the names of its
16 : // contributors may be used to endorse or promote products derived from
17 : // this software without specific prior written permission.
18 : //
19 : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 : // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 : // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 : // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 : // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 : // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 : // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 : // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 : // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 : // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 :
31 : // Author: kenton@google.com (Kenton Varda)
32 : // Based on original Protocol Buffers design by
33 : // Sanjay Ghemawat, Jeff Dean, and others.
34 :
35 : #include <map>
36 : #include <string>
37 :
38 : #include <google/protobuf/stubs/logging.h>
39 : #include <google/protobuf/stubs/common.h>
40 : #include <google/protobuf/compiler/java/java_context.h>
41 : #include <google/protobuf/compiler/java/java_doc_comment.h>
42 : #include <google/protobuf/compiler/java/java_enum_field_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 :
56 0 : void SetEnumVariables(const FieldDescriptor* descriptor,
57 : int messageBitIndex,
58 : int builderBitIndex,
59 : const FieldGeneratorInfo* info,
60 : ClassNameResolver* name_resolver,
61 : map<string, string>* variables) {
62 0 : SetCommonFieldVariables(descriptor, info, variables);
63 :
64 0 : (*variables)["type"] =
65 : name_resolver->GetImmutableClassName(descriptor->enum_type());
66 0 : (*variables)["mutable_type"] =
67 : name_resolver->GetMutableClassName(descriptor->enum_type());
68 0 : (*variables)["default"] = ImmutableDefaultValue(descriptor, name_resolver);
69 0 : (*variables)["default_number"] = SimpleItoa(
70 : descriptor->default_value_enum()->number());
71 0 : (*variables)["tag"] = SimpleItoa(internal::WireFormat::MakeTag(descriptor));
72 0 : (*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 0 : (*variables)["deprecation"] = descriptor->options().deprecated()
77 : ? "@java.lang.Deprecated " : "";
78 0 : (*variables)["on_changed"] =
79 0 : HasDescriptorMethods(descriptor->containing_type()) ? "onChanged();" : "";
80 :
81 0 : if (SupportFieldPresence(descriptor->file())) {
82 : // For singular messages and builders, one bit is used for the hasField bit.
83 0 : (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
84 :
85 : // Note that these have a trailing ";".
86 0 : (*variables)["set_has_field_bit_message"] =
87 0 : GenerateSetBit(messageBitIndex) + ";";
88 0 : (*variables)["clear_has_field_bit_message"] =
89 0 : GenerateClearBit(messageBitIndex) + ";";
90 :
91 0 : (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex);
92 : } else {
93 0 : (*variables)["set_has_field_bit_message"] = "";
94 0 : (*variables)["clear_has_field_bit_message"] = "";
95 :
96 0 : (*variables)["is_field_present_message"] =
97 0 : (*variables)["name"] + "_ != " +
98 0 : (*variables)["default"] + ".getNumber()";
99 : }
100 :
101 : // For repeated builders, the underlying list tracks mutability state.
102 0 : (*variables)["is_mutable"] = (*variables)["name"] + "_.isModifiable()";
103 :
104 0 : (*variables)["get_has_field_bit_from_local"] =
105 : GenerateGetBitFromLocal(builderBitIndex);
106 0 : (*variables)["set_has_field_bit_to_local"] =
107 : GenerateSetBitToLocal(messageBitIndex);
108 :
109 0 : if (SupportUnknownEnumValue(descriptor->file())) {
110 0 : (*variables)["unknown"] = (*variables)["type"] + ".UNRECOGNIZED";
111 : } else {
112 0 : (*variables)["unknown"] = (*variables)["default"];
113 : }
114 0 : }
115 :
116 : } // namespace
117 :
118 : // ===================================================================
119 :
120 0 : ImmutableEnumFieldLiteGenerator::
121 : ImmutableEnumFieldLiteGenerator(const FieldDescriptor* descriptor,
122 : int messageBitIndex,
123 : int builderBitIndex,
124 : Context* context)
125 : : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
126 : builderBitIndex_(builderBitIndex),
127 0 : name_resolver_(context->GetNameResolver()) {
128 : SetEnumVariables(descriptor, messageBitIndex, builderBitIndex,
129 : context->GetFieldGeneratorInfo(descriptor),
130 0 : name_resolver_, &variables_);
131 0 : }
132 :
133 0 : ImmutableEnumFieldLiteGenerator::~ImmutableEnumFieldLiteGenerator() {}
134 :
135 0 : int ImmutableEnumFieldLiteGenerator::GetNumBitsForMessage() const {
136 0 : return 1;
137 : }
138 :
139 0 : int ImmutableEnumFieldLiteGenerator::GetNumBitsForBuilder() const {
140 0 : return 0;
141 : }
142 :
143 0 : void ImmutableEnumFieldLiteGenerator::
144 : GenerateInterfaceMembers(io::Printer* printer) const {
145 0 : if (SupportFieldPresence(descriptor_->file())) {
146 0 : WriteFieldDocComment(printer, descriptor_);
147 : printer->Print(variables_,
148 0 : "$deprecation$boolean has$capitalized_name$();\n");
149 : }
150 0 : if (SupportUnknownEnumValue(descriptor_->file())) {
151 0 : WriteFieldDocComment(printer, descriptor_);
152 : printer->Print(variables_,
153 0 : "$deprecation$int get$capitalized_name$Value();\n");
154 : }
155 0 : WriteFieldDocComment(printer, descriptor_);
156 : printer->Print(variables_,
157 0 : "$deprecation$$type$ get$capitalized_name$();\n");
158 0 : }
159 :
160 0 : void ImmutableEnumFieldLiteGenerator::
161 : GenerateMembers(io::Printer* printer) const {
162 : printer->Print(variables_,
163 0 : "private int $name$_;\n");
164 0 : PrintExtraFieldInfo(variables_, printer);
165 0 : if (SupportFieldPresence(descriptor_->file())) {
166 0 : WriteFieldDocComment(printer, descriptor_);
167 : printer->Print(variables_,
168 : "$deprecation$public boolean has$capitalized_name$() {\n"
169 : " return $get_has_field_bit_message$;\n"
170 0 : "}\n");
171 : }
172 0 : if (SupportUnknownEnumValue(descriptor_->file())) {
173 0 : WriteFieldDocComment(printer, descriptor_);
174 : printer->Print(variables_,
175 : "$deprecation$public int get$capitalized_name$Value() {\n"
176 : " return $name$_;\n"
177 0 : "}\n");
178 : }
179 0 : 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 0 : "}\n");
185 :
186 : // Generate private setters for the builder to proxy into.
187 0 : if (SupportUnknownEnumValue(descriptor_->file())) {
188 0 : 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 0 : "}\n");
194 : }
195 0 : 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 0 : "}\n");
204 0 : 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 0 : "}\n");
210 0 : }
211 :
212 0 : void ImmutableEnumFieldLiteGenerator::
213 : GenerateBuilderMembers(io::Printer* printer) const {
214 0 : if (SupportFieldPresence(descriptor_->file())) {
215 0 : WriteFieldDocComment(printer, descriptor_);
216 : printer->Print(variables_,
217 : "$deprecation$public boolean has$capitalized_name$() {\n"
218 : " return instance.has$capitalized_name$();\n"
219 0 : "}\n");
220 : }
221 0 : if (SupportUnknownEnumValue(descriptor_->file())) {
222 0 : 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 0 : "}\n");
227 0 : 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 0 : "}\n");
234 : }
235 0 : WriteFieldDocComment(printer, descriptor_);
236 : printer->Print(variables_,
237 : "$deprecation$public $type$ get$capitalized_name$() {\n"
238 : " return instance.get$capitalized_name$();\n"
239 0 : "}\n");
240 0 : 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 0 : "}\n");
247 0 : 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 0 : "}\n");
254 0 : }
255 :
256 0 : void ImmutableEnumFieldLiteGenerator::
257 : GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
258 : // noop for enums
259 0 : }
260 :
261 0 : void ImmutableEnumFieldLiteGenerator::
262 : GenerateInitializationCode(io::Printer* printer) const {
263 0 : printer->Print(variables_, "$name$_ = $default_number$;\n");
264 0 : }
265 :
266 0 : void ImmutableEnumFieldLiteGenerator::
267 : GenerateMergingCode(io::Printer* printer) const {
268 0 : 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 0 : "}\n");
273 0 : } 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 0 : "}\n");
278 : } else {
279 0 : GOOGLE_LOG(FATAL) << "Can't reach here.";
280 : }
281 0 : }
282 :
283 0 : void ImmutableEnumFieldLiteGenerator::
284 : GenerateDynamicMethodMakeImmutableCode(io::Printer* printer) const {
285 : // noop for scalars
286 0 : }
287 :
288 0 : void ImmutableEnumFieldLiteGenerator::
289 : GenerateParsingCode(io::Printer* printer) const {
290 0 : if (SupportUnknownEnumValue(descriptor_->file())) {
291 : printer->Print(variables_,
292 : "int rawValue = input.readEnum();\n"
293 : "$set_has_field_bit_message$\n"
294 0 : "$name$_ = rawValue;\n");
295 : } else {
296 : printer->Print(variables_,
297 : "int rawValue = input.readEnum();\n"
298 : "$type$ value = $type$.valueOf(rawValue);\n"
299 0 : "if (value == null) {\n");
300 0 : if (PreserveUnknownFields(descriptor_->containing_type())) {
301 : printer->Print(variables_,
302 0 : " unknownFields.mergeVarintField($number$, rawValue);\n");
303 : }
304 : printer->Print(variables_,
305 : "} else {\n"
306 : " $set_has_field_bit_message$\n"
307 : " $name$_ = rawValue;\n"
308 0 : "}\n");
309 : }
310 0 : }
311 :
312 0 : void ImmutableEnumFieldLiteGenerator::
313 : GenerateParsingDoneCode(io::Printer* printer) const {
314 : // noop for enums
315 0 : }
316 :
317 0 : void ImmutableEnumFieldLiteGenerator::
318 : GenerateSerializationCode(io::Printer* printer) const {
319 : printer->Print(variables_,
320 : "if ($is_field_present_message$) {\n"
321 : " output.writeEnum($number$, $name$_);\n"
322 0 : "}\n");
323 0 : }
324 :
325 0 : void ImmutableEnumFieldLiteGenerator::
326 : GenerateSerializedSizeCode(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 0 : "}\n");
332 0 : }
333 :
334 0 : void ImmutableEnumFieldLiteGenerator::
335 : GenerateEqualsCode(io::Printer* printer) const {
336 : printer->Print(variables_,
337 0 : "result = result && $name$_ == other.$name$_;\n");
338 0 : }
339 :
340 0 : void ImmutableEnumFieldLiteGenerator::
341 : GenerateHashCode(io::Printer* printer) const {
342 : printer->Print(variables_,
343 : "hash = (37 * hash) + $constant_name$;\n"
344 0 : "hash = (53 * hash) + $name$_;\n");
345 0 : }
346 :
347 0 : string ImmutableEnumFieldLiteGenerator::GetBoxedType() const {
348 0 : return name_resolver_->GetImmutableClassName(descriptor_->enum_type());
349 : }
350 :
351 : // ===================================================================
352 :
353 0 : ImmutableEnumOneofFieldLiteGenerator::
354 0 : ImmutableEnumOneofFieldLiteGenerator(const FieldDescriptor* descriptor,
355 : int messageBitIndex,
356 : int builderBitIndex,
357 : Context* context)
358 : : ImmutableEnumFieldLiteGenerator(
359 0 : descriptor, messageBitIndex, builderBitIndex, context) {
360 : const OneofGeneratorInfo* info =
361 0 : context->GetOneofGeneratorInfo(descriptor->containing_oneof());
362 0 : SetCommonOneofVariables(descriptor, info, &variables_);
363 0 : }
364 :
365 0 : ImmutableEnumOneofFieldLiteGenerator::
366 0 : ~ImmutableEnumOneofFieldLiteGenerator() {}
367 :
368 0 : void ImmutableEnumOneofFieldLiteGenerator::
369 : GenerateMembers(io::Printer* printer) const {
370 0 : PrintExtraFieldInfo(variables_, printer);
371 0 : if (SupportFieldPresence(descriptor_->file())) {
372 0 : WriteFieldDocComment(printer, descriptor_);
373 : printer->Print(variables_,
374 : "$deprecation$public boolean has$capitalized_name$() {\n"
375 : " return $has_oneof_case_message$;\n"
376 0 : "}\n");
377 : }
378 0 : if (SupportUnknownEnumValue(descriptor_->file())) {
379 0 : 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 0 : "}\n");
387 : }
388 0 : 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 0 : "}\n");
397 :
398 : // Generate private setters for the builder to proxy into.
399 0 : if (SupportUnknownEnumValue(descriptor_->file())) {
400 0 : 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 0 : "}\n");
406 : }
407 0 : 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 0 : "}\n");
416 0 : 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 0 : "}\n");
424 0 : }
425 :
426 0 : void ImmutableEnumOneofFieldLiteGenerator::
427 : GenerateBuilderMembers(io::Printer* printer) const {
428 0 : if (SupportFieldPresence(descriptor_->file())) {
429 0 : WriteFieldDocComment(printer, descriptor_);
430 : printer->Print(variables_,
431 : "$deprecation$public boolean has$capitalized_name$() {\n"
432 : " return instance.has$capitalized_name$();\n"
433 0 : "}\n");
434 : }
435 0 : if (SupportUnknownEnumValue(descriptor_->file())) {
436 0 : 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 0 : "}\n");
441 0 : 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 0 : "}\n");
448 : }
449 0 : WriteFieldDocComment(printer, descriptor_);
450 : printer->Print(variables_,
451 : "$deprecation$public $type$ get$capitalized_name$() {\n"
452 : " return instance.get$capitalized_name$();\n"
453 0 : "}\n");
454 0 : 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 0 : "}\n");
461 0 : 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 0 : "}\n");
468 0 : }
469 :
470 0 : void ImmutableEnumOneofFieldLiteGenerator::
471 : GenerateMergingCode(io::Printer* printer) const {
472 0 : if (SupportUnknownEnumValue(descriptor_->file())) {
473 : printer->Print(variables_,
474 0 : "set$capitalized_name$Value(other.get$capitalized_name$Value());\n");
475 : } else {
476 : printer->Print(variables_,
477 0 : "set$capitalized_name$(other.get$capitalized_name$());\n");
478 : }
479 0 : }
480 :
481 0 : void ImmutableEnumOneofFieldLiteGenerator::
482 : GenerateParsingCode(io::Printer* printer) const {
483 0 : if (SupportUnknownEnumValue(descriptor_->file())) {
484 : printer->Print(variables_,
485 : "int rawValue = input.readEnum();\n"
486 : "$set_oneof_case_message$;\n"
487 0 : "$oneof_name$_ = rawValue;\n");
488 : } else {
489 : printer->Print(variables_,
490 : "int rawValue = input.readEnum();\n"
491 : "$type$ value = $type$.valueOf(rawValue);\n"
492 0 : "if (value == null) {\n");
493 0 : if (PreserveUnknownFields(descriptor_->containing_type())) {
494 : printer->Print(variables_,
495 0 : " unknownFields.mergeVarintField($number$, rawValue);\n");
496 : }
497 : printer->Print(variables_,
498 : "} else {\n"
499 : " $set_oneof_case_message$;\n"
500 : " $oneof_name$_ = rawValue;\n"
501 0 : "}\n");
502 : }
503 0 : }
504 :
505 0 : void ImmutableEnumOneofFieldLiteGenerator::
506 : GenerateSerializationCode(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 0 : "}\n");
511 0 : }
512 :
513 0 : void ImmutableEnumOneofFieldLiteGenerator::
514 : GenerateSerializedSizeCode(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 0 : "}\n");
520 0 : }
521 :
522 0 : void ImmutableEnumOneofFieldLiteGenerator::
523 : GenerateEqualsCode(io::Printer* printer) const {
524 0 : if (SupportUnknownEnumValue(descriptor_->file())) {
525 : printer->Print(variables_,
526 : "result = result && get$capitalized_name$Value()\n"
527 0 : " == other.get$capitalized_name$Value();\n");
528 : } else {
529 : printer->Print(variables_,
530 : "result = result && get$capitalized_name$()\n"
531 0 : " .equals(other.get$capitalized_name$());\n");
532 : }
533 0 : }
534 :
535 0 : void ImmutableEnumOneofFieldLiteGenerator::
536 : GenerateHashCode(io::Printer* printer) const {
537 0 : if (SupportUnknownEnumValue(descriptor_->file())) {
538 : printer->Print(variables_,
539 : "hash = (37 * hash) + $constant_name$;\n"
540 0 : "hash = (53 * hash) + get$capitalized_name$Value();\n");
541 : } else {
542 : printer->Print(variables_,
543 : "hash = (37 * hash) + $constant_name$;\n"
544 0 : "hash = (53 * hash) + get$capitalized_name$().getNumber();\n");
545 : }
546 0 : }
547 :
548 : // ===================================================================
549 :
550 0 : RepeatedImmutableEnumFieldLiteGenerator::
551 : RepeatedImmutableEnumFieldLiteGenerator(const FieldDescriptor* descriptor,
552 : int messageBitIndex,
553 : int builderBitIndex,
554 : Context* context)
555 : : descriptor_(descriptor), messageBitIndex_(messageBitIndex),
556 : builderBitIndex_(builderBitIndex), context_(context),
557 0 : name_resolver_(context->GetNameResolver()) {
558 : SetEnumVariables(descriptor, messageBitIndex, builderBitIndex,
559 : context->GetFieldGeneratorInfo(descriptor),
560 0 : name_resolver_, &variables_);
561 0 : }
562 :
563 0 : RepeatedImmutableEnumFieldLiteGenerator::
564 0 : ~RepeatedImmutableEnumFieldLiteGenerator() {}
565 :
566 0 : int RepeatedImmutableEnumFieldLiteGenerator::GetNumBitsForMessage() const {
567 0 : return 0;
568 : }
569 :
570 0 : int RepeatedImmutableEnumFieldLiteGenerator::GetNumBitsForBuilder() const {
571 0 : return 0;
572 : }
573 :
574 0 : void RepeatedImmutableEnumFieldLiteGenerator::
575 : GenerateInterfaceMembers(io::Printer* printer) const {
576 0 : WriteFieldDocComment(printer, descriptor_);
577 : printer->Print(variables_,
578 0 : "$deprecation$java.util.List<$type$> get$capitalized_name$List();\n");
579 0 : WriteFieldDocComment(printer, descriptor_);
580 : printer->Print(variables_,
581 0 : "$deprecation$int get$capitalized_name$Count();\n");
582 0 : WriteFieldDocComment(printer, descriptor_);
583 : printer->Print(variables_,
584 0 : "$deprecation$$type$ get$capitalized_name$(int index);\n");
585 0 : if (SupportUnknownEnumValue(descriptor_->file())) {
586 0 : WriteFieldDocComment(printer, descriptor_);
587 : printer->Print(variables_,
588 : "$deprecation$java.util.List<java.lang.Integer>\n"
589 0 : "get$capitalized_name$ValueList();\n");
590 0 : WriteFieldDocComment(printer, descriptor_);
591 : printer->Print(variables_,
592 0 : "$deprecation$int get$capitalized_name$Value(int index);\n");
593 : }
594 0 : }
595 :
596 0 : void RepeatedImmutableEnumFieldLiteGenerator::
597 : GenerateMembers(io::Printer* printer) const {
598 : printer->Print(variables_,
599 : // TODO(dweis): Switch to IntList?
600 : "private com.google.protobuf.Internal.ProtobufList<\n"
601 : " java.lang.Integer> $name$_;\n"
602 : "private static final com.google.protobuf.Internal.ListAdapter.Converter<\n"
603 : " java.lang.Integer, $type$> $name$_converter_ =\n"
604 : " new com.google.protobuf.Internal.ListAdapter.Converter<\n"
605 : " java.lang.Integer, $type$>() {\n"
606 : " public $type$ convert(java.lang.Integer from) {\n"
607 : " $type$ result = $type$.valueOf(from);\n"
608 : " return result == null ? $unknown$ : result;\n"
609 : " }\n"
610 0 : " };\n");
611 0 : PrintExtraFieldInfo(variables_, printer);
612 0 : WriteFieldDocComment(printer, descriptor_);
613 : printer->Print(variables_,
614 : "$deprecation$public java.util.List<$type$> get$capitalized_name$List() {\n"
615 : " return new com.google.protobuf.Internal.ListAdapter<\n"
616 : " java.lang.Integer, $type$>($name$_, $name$_converter_);\n"
617 0 : "}\n");
618 0 : WriteFieldDocComment(printer, descriptor_);
619 : printer->Print(variables_,
620 : "$deprecation$public int get$capitalized_name$Count() {\n"
621 : " return $name$_.size();\n"
622 0 : "}\n");
623 0 : WriteFieldDocComment(printer, descriptor_);
624 : printer->Print(variables_,
625 : "$deprecation$public $type$ get$capitalized_name$(int index) {\n"
626 : " return $name$_converter_.convert($name$_.get(index));\n"
627 0 : "}\n");
628 0 : if (SupportUnknownEnumValue(descriptor_->file())) {
629 0 : WriteFieldDocComment(printer, descriptor_);
630 : printer->Print(variables_,
631 : "$deprecation$public java.util.List<java.lang.Integer>\n"
632 : "get$capitalized_name$ValueList() {\n"
633 : " return $name$_;\n"
634 0 : "}\n");
635 0 : WriteFieldDocComment(printer, descriptor_);
636 : printer->Print(variables_,
637 : "$deprecation$public int get$capitalized_name$Value(int index) {\n"
638 : " return $name$_.get(index);\n"
639 0 : "}\n");
640 : }
641 :
642 0 : if (descriptor_->options().packed() &&
643 0 : HasGeneratedMethods(descriptor_->containing_type())) {
644 : printer->Print(variables_,
645 0 : "private int $name$MemoizedSerializedSize;\n");
646 : }
647 :
648 : // Generate private setters for the builder to proxy into.
649 : printer->Print(variables_,
650 : "private void ensure$capitalized_name$IsMutable() {\n"
651 : " if (!$is_mutable$) {\n"
652 : " $name$_ = newProtobufList($name$_);\n"
653 : " }\n"
654 0 : "}\n");
655 0 : WriteFieldDocComment(printer, descriptor_);
656 : printer->Print(variables_,
657 : "private void set$capitalized_name$(\n"
658 : " int index, $type$ value) {\n"
659 : " if (value == null) {\n"
660 : " throw new NullPointerException();\n"
661 : " }\n"
662 : " ensure$capitalized_name$IsMutable();\n"
663 : " $name$_.set(index, value.getNumber());\n"
664 0 : "}\n");
665 0 : WriteFieldDocComment(printer, descriptor_);
666 : printer->Print(variables_,
667 : "private void add$capitalized_name$($type$ value) {\n"
668 : " if (value == null) {\n"
669 : " throw new NullPointerException();\n"
670 : " }\n"
671 : " ensure$capitalized_name$IsMutable();\n"
672 : " $name$_.add(value.getNumber());\n"
673 0 : "}\n");
674 0 : WriteFieldDocComment(printer, descriptor_);
675 : printer->Print(variables_,
676 : "private void addAll$capitalized_name$(\n"
677 : " java.lang.Iterable<? extends $type$> values) {\n"
678 : " ensure$capitalized_name$IsMutable();\n"
679 : " for ($type$ value : values) {\n"
680 : " $name$_.add(value.getNumber());\n"
681 : " }\n"
682 0 : "}\n");
683 0 : WriteFieldDocComment(printer, descriptor_);
684 : printer->Print(variables_,
685 : "private void clear$capitalized_name$() {\n"
686 : " $name$_ = emptyProtobufList();\n"
687 0 : "}\n");
688 :
689 0 : if (SupportUnknownEnumValue(descriptor_->file())) {
690 0 : WriteFieldDocComment(printer, descriptor_);
691 : printer->Print(variables_,
692 : "private void set$capitalized_name$Value(\n"
693 : " int index, int value) {\n"
694 : " ensure$capitalized_name$IsMutable();\n"
695 : " $name$_.set(index, value);\n"
696 0 : "}\n");
697 0 : WriteFieldDocComment(printer, descriptor_);
698 : printer->Print(variables_,
699 : "private void add$capitalized_name$Value(int value) {\n"
700 : " ensure$capitalized_name$IsMutable();\n"
701 : " $name$_.add(value);\n"
702 0 : "}\n");
703 0 : WriteFieldDocComment(printer, descriptor_);
704 : printer->Print(variables_,
705 : "private void addAll$capitalized_name$Value(\n"
706 : " java.lang.Iterable<java.lang.Integer> values) {\n"
707 : " ensure$capitalized_name$IsMutable();\n"
708 : " for (int value : values) {\n"
709 : " $name$_.add(value);\n"
710 : " }\n"
711 0 : "}\n");
712 : }
713 0 : }
714 :
715 0 : void RepeatedImmutableEnumFieldLiteGenerator::
716 : GenerateBuilderMembers(io::Printer* printer) const {
717 0 : WriteFieldDocComment(printer, descriptor_);
718 : printer->Print(variables_,
719 : "$deprecation$public java.util.List<$type$> get$capitalized_name$List() {\n"
720 : " return instance.get$capitalized_name$List();\n"
721 0 : "}\n");
722 0 : WriteFieldDocComment(printer, descriptor_);
723 : printer->Print(variables_,
724 : "$deprecation$public int get$capitalized_name$Count() {\n"
725 : " return instance.get$capitalized_name$Count();\n"
726 0 : "}\n");
727 0 : WriteFieldDocComment(printer, descriptor_);
728 : printer->Print(variables_,
729 : "$deprecation$public $type$ get$capitalized_name$(int index) {\n"
730 : " return instance.get$capitalized_name$(index);\n"
731 0 : "}\n");
732 0 : WriteFieldDocComment(printer, descriptor_);
733 : printer->Print(variables_,
734 : "$deprecation$public Builder set$capitalized_name$(\n"
735 : " int index, $type$ value) {\n"
736 : " copyOnWrite();\n"
737 : " instance.set$capitalized_name$(index, value);\n"
738 : " return this;\n"
739 0 : "}\n");
740 0 : WriteFieldDocComment(printer, descriptor_);
741 : printer->Print(variables_,
742 : "$deprecation$public Builder add$capitalized_name$($type$ value) {\n"
743 : " copyOnWrite();\n"
744 : " instance.add$capitalized_name$(value);\n"
745 : " return this;\n"
746 0 : "}\n");
747 0 : WriteFieldDocComment(printer, descriptor_);
748 : printer->Print(variables_,
749 : "$deprecation$public Builder addAll$capitalized_name$(\n"
750 : " java.lang.Iterable<? extends $type$> values) {\n"
751 : " copyOnWrite();\n"
752 : " instance.addAll$capitalized_name$(values);"
753 : " return this;\n"
754 0 : "}\n");
755 0 : WriteFieldDocComment(printer, descriptor_);
756 : printer->Print(variables_,
757 : "$deprecation$public Builder clear$capitalized_name$() {\n"
758 : " copyOnWrite();\n"
759 : " instance.clear$capitalized_name$();\n"
760 : " return this;\n"
761 0 : "}\n");
762 :
763 0 : if (SupportUnknownEnumValue(descriptor_->file())) {
764 0 : WriteFieldDocComment(printer, descriptor_);
765 : printer->Print(variables_,
766 : "$deprecation$public java.util.List<java.lang.Integer>\n"
767 : "get$capitalized_name$ValueList() {\n"
768 : " return java.util.Collections.unmodifiableList(\n"
769 : " instance.get$capitalized_name$ValueList());\n"
770 0 : "}\n");
771 0 : WriteFieldDocComment(printer, descriptor_);
772 : printer->Print(variables_,
773 : "$deprecation$public int get$capitalized_name$Value(int index) {\n"
774 : " return instance.get$capitalized_name$Value(index);\n"
775 0 : "}\n");
776 0 : WriteFieldDocComment(printer, descriptor_);
777 : printer->Print(variables_,
778 : "$deprecation$public Builder set$capitalized_name$Value(\n"
779 : " int index, int value) {\n"
780 : " copyOnWrite();\n"
781 : " instance.set$capitalized_name$Value(index, value);\n"
782 : " return this;\n"
783 0 : "}\n");
784 0 : WriteFieldDocComment(printer, descriptor_);
785 : printer->Print(variables_,
786 : "$deprecation$public Builder add$capitalized_name$Value(int value) {\n"
787 : " instance.add$capitalized_name$Value(value);\n"
788 : " return this;\n"
789 0 : "}\n");
790 0 : WriteFieldDocComment(printer, descriptor_);
791 : printer->Print(variables_,
792 : "$deprecation$public Builder addAll$capitalized_name$Value(\n"
793 : " java.lang.Iterable<java.lang.Integer> values) {\n"
794 : " copyOnWrite();\n"
795 : " instance.addAll$capitalized_name$Value(values);\n"
796 : " return this;\n"
797 0 : "}\n");
798 : }
799 0 : }
800 :
801 0 : void RepeatedImmutableEnumFieldLiteGenerator::
802 : GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
803 : // noop for enums
804 0 : }
805 :
806 0 : void RepeatedImmutableEnumFieldLiteGenerator::
807 : GenerateInitializationCode(io::Printer* printer) const {
808 0 : printer->Print(variables_, "$name$_ = emptyProtobufList();\n");
809 0 : }
810 :
811 0 : void RepeatedImmutableEnumFieldLiteGenerator::
812 : GenerateMergingCode(io::Printer* printer) const {
813 : // The code below does two optimizations:
814 : // 1. If the other list is empty, there's nothing to do. This ensures we
815 : // don't allocate a new array if we already have an immutable one.
816 : // 2. If the other list is non-empty and our current list is empty, we can
817 : // reuse the other list which is guaranteed to be immutable.
818 : printer->Print(variables_,
819 : "if (!other.$name$_.isEmpty()) {\n"
820 : " if ($name$_.isEmpty()) {\n"
821 : " $name$_ = other.$name$_;\n"
822 : " } else {\n"
823 : " ensure$capitalized_name$IsMutable();\n"
824 : " $name$_.addAll(other.$name$_);\n"
825 : " }\n"
826 : " $on_changed$\n"
827 0 : "}\n");
828 0 : }
829 :
830 0 : void RepeatedImmutableEnumFieldLiteGenerator::
831 : GenerateDynamicMethodMakeImmutableCode(io::Printer* printer) const {
832 : printer->Print(variables_,
833 0 : "$name$_.makeImmutable();\n");
834 0 : }
835 :
836 0 : void RepeatedImmutableEnumFieldLiteGenerator::
837 : GenerateParsingCode(io::Printer* printer) const {
838 : // Read and store the enum
839 0 : if (SupportUnknownEnumValue(descriptor_->file())) {
840 : printer->Print(variables_,
841 : "int rawValue = input.readEnum();\n"
842 : "if (!$is_mutable$) {\n"
843 : " $name$_ = newProtobufList();\n"
844 : "}\n"
845 0 : "$name$_.add(rawValue);\n");
846 : } else {
847 : printer->Print(variables_,
848 : "int rawValue = input.readEnum();\n"
849 : "$type$ value = $type$.valueOf(rawValue);\n"
850 0 : "if (value == null) {\n");
851 0 : if (PreserveUnknownFields(descriptor_->containing_type())) {
852 : printer->Print(variables_,
853 0 : " unknownFields.mergeVarintField($number$, rawValue);\n");
854 : }
855 : printer->Print(variables_,
856 : "} else {\n"
857 : " if (!$is_mutable$) {\n"
858 : " $name$_ = newProtobufList();\n"
859 : " }\n"
860 : " $name$_.add(rawValue);\n"
861 0 : "}\n");
862 : }
863 0 : }
864 :
865 0 : void RepeatedImmutableEnumFieldLiteGenerator::
866 : GenerateParsingCodeFromPacked(io::Printer* printer) const {
867 : // Wrap GenerateParsingCode's contents with a while loop.
868 :
869 : printer->Print(variables_,
870 : "int length = input.readRawVarint32();\n"
871 : "int oldLimit = input.pushLimit(length);\n"
872 0 : "while(input.getBytesUntilLimit() > 0) {\n");
873 0 : printer->Indent();
874 :
875 0 : GenerateParsingCode(printer);
876 :
877 0 : printer->Outdent();
878 : printer->Print(variables_,
879 : "}\n"
880 0 : "input.popLimit(oldLimit);\n");
881 0 : }
882 :
883 0 : void RepeatedImmutableEnumFieldLiteGenerator::
884 : GenerateParsingDoneCode(io::Printer* printer) const {
885 : printer->Print(variables_,
886 : "if ($is_mutable$) {\n"
887 : " $name$_.makeImmutable();\n"
888 0 : "}\n");
889 0 : }
890 :
891 0 : void RepeatedImmutableEnumFieldLiteGenerator::
892 : GenerateSerializationCode(io::Printer* printer) const {
893 0 : if (descriptor_->options().packed()) {
894 : printer->Print(variables_,
895 : "if (get$capitalized_name$List().size() > 0) {\n"
896 : " output.writeRawVarint32($tag$);\n"
897 : " output.writeRawVarint32($name$MemoizedSerializedSize);\n"
898 : "}\n"
899 : "for (int i = 0; i < $name$_.size(); i++) {\n"
900 : " output.writeEnumNoTag($name$_.get(i));\n"
901 0 : "}\n");
902 : } else {
903 : printer->Print(variables_,
904 : "for (int i = 0; i < $name$_.size(); i++) {\n"
905 : " output.writeEnum($number$, $name$_.get(i));\n"
906 0 : "}\n");
907 : }
908 0 : }
909 :
910 0 : void RepeatedImmutableEnumFieldLiteGenerator::
911 : GenerateSerializedSizeCode(io::Printer* printer) const {
912 : printer->Print(variables_,
913 : "{\n"
914 0 : " int dataSize = 0;\n");
915 0 : printer->Indent();
916 :
917 : printer->Print(variables_,
918 : "for (int i = 0; i < $name$_.size(); i++) {\n"
919 : " dataSize += com.google.protobuf.CodedOutputStream\n"
920 : " .computeEnumSizeNoTag($name$_.get(i));\n"
921 0 : "}\n");
922 : printer->Print(
923 0 : "size += dataSize;\n");
924 0 : if (descriptor_->options().packed()) {
925 : printer->Print(variables_,
926 : "if (!get$capitalized_name$List().isEmpty()) {"
927 : " size += $tag_size$;\n"
928 : " size += com.google.protobuf.CodedOutputStream\n"
929 : " .computeRawVarint32Size(dataSize);\n"
930 0 : "}");
931 : } else {
932 : printer->Print(variables_,
933 0 : "size += $tag_size$ * $name$_.size();\n");
934 : }
935 :
936 : // cache the data size for packed fields.
937 0 : if (descriptor_->options().packed()) {
938 : printer->Print(variables_,
939 0 : "$name$MemoizedSerializedSize = dataSize;\n");
940 : }
941 :
942 0 : printer->Outdent();
943 0 : printer->Print("}\n");
944 0 : }
945 :
946 0 : void RepeatedImmutableEnumFieldLiteGenerator::
947 : GenerateEqualsCode(io::Printer* printer) const {
948 : printer->Print(variables_,
949 0 : "result = result && $name$_.equals(other.$name$_);\n");
950 0 : }
951 :
952 0 : void RepeatedImmutableEnumFieldLiteGenerator::
953 : GenerateHashCode(io::Printer* printer) const {
954 : printer->Print(variables_,
955 : "if (get$capitalized_name$Count() > 0) {\n"
956 : " hash = (37 * hash) + $constant_name$;\n"
957 : " hash = (53 * hash) + $name$_.hashCode();\n"
958 0 : "}\n");
959 0 : }
960 :
961 0 : string RepeatedImmutableEnumFieldLiteGenerator::GetBoxedType() const {
962 0 : return name_resolver_->GetImmutableClassName(descriptor_->enum_type());
963 : }
964 :
965 : } // namespace java
966 : } // namespace compiler
967 : } // namespace protobuf
968 : } // namespace google
|