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