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