• 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 {
EnableExperimentalRuntimeForLite()55 bool EnableExperimentalRuntimeForLite() {
56 #ifdef PROTOBUF_EXPERIMENT
57   return PROTOBUF_EXPERIMENT;
58 #else   // PROTOBUF_EXPERIMENT
59   return false;
60 #endif  // !PROTOBUF_EXPERIMENT
61 }
62 
SetEnumVariables(const FieldDescriptor * descriptor,int messageBitIndex,int builderBitIndex,const FieldGeneratorInfo * info,ClassNameResolver * name_resolver,std::map<std::string,std::string> * variables)63 void SetEnumVariables(const FieldDescriptor* descriptor, int messageBitIndex,
64                       int builderBitIndex, const FieldGeneratorInfo* info,
65                       ClassNameResolver* name_resolver,
66                       std::map<std::string, std::string>* variables) {
67   SetCommonFieldVariables(descriptor, info, variables);
68 
69   (*variables)["type"] =
70       name_resolver->GetImmutableClassName(descriptor->enum_type());
71   (*variables)["mutable_type"] =
72       name_resolver->GetMutableClassName(descriptor->enum_type());
73   (*variables)["default"] = ImmutableDefaultValue(descriptor, name_resolver);
74   (*variables)["default_number"] =
75       StrCat(descriptor->default_value_enum()->number());
76   (*variables)["tag"] = StrCat(
77       static_cast<int32>(internal::WireFormat::MakeTag(descriptor)));
78   (*variables)["tag_size"] = StrCat(
79       internal::WireFormat::TagSize(descriptor->number(), GetType(descriptor)));
80   // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
81   // by the proto compiler
82   (*variables)["deprecation"] =
83       descriptor->options().deprecated() ? "@java.lang.Deprecated " : "";
84   (*variables)["required"] = descriptor->is_required() ? "true" : "false";
85 
86   if (SupportFieldPresence(descriptor)) {
87     // For singular messages and builders, one bit is used for the hasField bit.
88     (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
89 
90     // Note that these have a trailing ";".
91     (*variables)["set_has_field_bit_message"] =
92         GenerateSetBit(messageBitIndex) + ";";
93     (*variables)["clear_has_field_bit_message"] =
94         GenerateClearBit(messageBitIndex) + ";";
95 
96     (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex);
97   } else {
98     (*variables)["set_has_field_bit_message"] = "";
99     (*variables)["clear_has_field_bit_message"] = "";
100 
101     (*variables)["is_field_present_message"] =
102         (*variables)["name"] + "_ != " + (*variables)["default"] +
103         ".getNumber()";
104   }
105 
106   (*variables)["get_has_field_bit_from_local"] =
107       GenerateGetBitFromLocal(builderBitIndex);
108   (*variables)["set_has_field_bit_to_local"] =
109       GenerateSetBitToLocal(messageBitIndex);
110 
111   if (SupportUnknownEnumValue(descriptor->file())) {
112     (*variables)["unknown"] = (*variables)["type"] + ".UNRECOGNIZED";
113   } else {
114     (*variables)["unknown"] = (*variables)["default"];
115   }
116 
117   // We use `x.getClass()` as a null check because it generates less bytecode
118   // than an `if (x == null) { throw ... }` statement.
119   (*variables)["null_check"] = "value.getClass();\n";
120 }
121 
122 }  // namespace
123 
124 // ===================================================================
125 
ImmutableEnumFieldLiteGenerator(const FieldDescriptor * descriptor,int messageBitIndex,Context * context)126 ImmutableEnumFieldLiteGenerator::ImmutableEnumFieldLiteGenerator(
127     const FieldDescriptor* descriptor, int messageBitIndex, Context* context)
128     : descriptor_(descriptor),
129       messageBitIndex_(messageBitIndex),
130       context_(context),
131       name_resolver_(context->GetNameResolver()) {
132   SetEnumVariables(descriptor, messageBitIndex, 0,
133                    context->GetFieldGeneratorInfo(descriptor), name_resolver_,
134                    &variables_);
135 }
136 
~ImmutableEnumFieldLiteGenerator()137 ImmutableEnumFieldLiteGenerator::~ImmutableEnumFieldLiteGenerator() {}
138 
GetNumBitsForMessage() const139 int ImmutableEnumFieldLiteGenerator::GetNumBitsForMessage() const {
140   return SupportFieldPresence(descriptor_) ? 1 : 0;
141 }
142 
GenerateInterfaceMembers(io::Printer * printer) const143 void ImmutableEnumFieldLiteGenerator::GenerateInterfaceMembers(
144     io::Printer* printer) const {
145   if (SupportFieldPresence(descriptor_)) {
146     WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
147     printer->Print(variables_,
148                    "$deprecation$boolean has$capitalized_name$();\n");
149   }
150   if (SupportUnknownEnumValue(descriptor_->file())) {
151     WriteFieldEnumValueAccessorDocComment(printer, descriptor_, GETTER);
152     printer->Print(variables_,
153                    "$deprecation$int get$capitalized_name$Value();\n");
154   }
155   WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
156   printer->Print(variables_, "$deprecation$$type$ get$capitalized_name$();\n");
157 }
158 
GenerateMembers(io::Printer * printer) const159 void ImmutableEnumFieldLiteGenerator::GenerateMembers(
160     io::Printer* printer) const {
161   printer->Print(variables_, "private int $name$_;\n");
162   PrintExtraFieldInfo(variables_, printer);
163   if (SupportFieldPresence(descriptor_)) {
164     WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
165     printer->Print(
166         variables_,
167         "@java.lang.Override\n"
168         "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
169         "  return $get_has_field_bit_message$;\n"
170         "}\n");
171     printer->Annotate("{", "}", descriptor_);
172   }
173   if (SupportUnknownEnumValue(descriptor_->file())) {
174     WriteFieldEnumValueAccessorDocComment(printer, descriptor_, GETTER);
175     printer->Print(
176         variables_,
177         "@java.lang.Override\n"
178         "$deprecation$public int ${$get$capitalized_name$Value$}$() {\n"
179         "  return $name$_;\n"
180         "}\n");
181     printer->Annotate("{", "}", descriptor_);
182   }
183   WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
184   printer->Print(variables_,
185                  "@java.lang.Override\n"
186                  "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
187                  "  $type$ result = $type$.forNumber($name$_);\n"
188                  "  return result == null ? $unknown$ : result;\n"
189                  "}\n");
190   printer->Annotate("{", "}", descriptor_);
191 
192   // Generate private setters for the builder to proxy into.
193   if (SupportUnknownEnumValue(descriptor_->file())) {
194     WriteFieldEnumValueAccessorDocComment(printer, descriptor_, SETTER);
195     printer->Print(variables_,
196                    "private void set$capitalized_name$Value(int value) {\n"
197                    "  $set_has_field_bit_message$"
198                    "  $name$_ = value;\n"
199                    "}\n");
200   }
201   WriteFieldAccessorDocComment(printer, descriptor_, SETTER);
202   printer->Print(variables_,
203                  "private void set$capitalized_name$($type$ value) {\n"
204                  "  $name$_ = value.getNumber();\n"
205                  "  $set_has_field_bit_message$\n"
206                  "}\n");
207   WriteFieldAccessorDocComment(printer, descriptor_, CLEARER);
208   printer->Print(variables_,
209                  "private void clear$capitalized_name$() {\n"
210                  "  $clear_has_field_bit_message$\n"
211                  "  $name$_ = $default_number$;\n"
212                  "}\n");
213 }
214 
GenerateBuilderMembers(io::Printer * printer) const215 void ImmutableEnumFieldLiteGenerator::GenerateBuilderMembers(
216     io::Printer* printer) const {
217   if (SupportFieldPresence(descriptor_)) {
218     WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
219     printer->Print(
220         variables_,
221         "@java.lang.Override\n"
222         "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
223         "  return instance.has$capitalized_name$();\n"
224         "}\n");
225     printer->Annotate("{", "}", descriptor_);
226   }
227   if (SupportUnknownEnumValue(descriptor_->file())) {
228     WriteFieldEnumValueAccessorDocComment(printer, descriptor_, GETTER);
229     printer->Print(
230         variables_,
231         "@java.lang.Override\n"
232         "$deprecation$public int ${$get$capitalized_name$Value$}$() {\n"
233         "  return instance.get$capitalized_name$Value();\n"
234         "}\n");
235     printer->Annotate("{", "}", descriptor_);
236     WriteFieldAccessorDocComment(printer, descriptor_, SETTER,
237                                  /* builder */ true);
238     printer->Print(variables_,
239                    "$deprecation$public Builder "
240                    "${$set$capitalized_name$Value$}$(int value) {\n"
241                    "  copyOnWrite();\n"
242                    "  instance.set$capitalized_name$Value(value);\n"
243                    "  return this;\n"
244                    "}\n");
245     printer->Annotate("{", "}", descriptor_);
246   }
247   WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
248   printer->Print(variables_,
249                  "@java.lang.Override\n"
250                  "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
251                  "  return instance.get$capitalized_name$();\n"
252                  "}\n");
253   printer->Annotate("{", "}", descriptor_);
254   WriteFieldEnumValueAccessorDocComment(printer, descriptor_, SETTER,
255                                         /* builder */ true);
256   printer->Print(variables_,
257                  "$deprecation$public Builder "
258                  "${$set$capitalized_name$$}$($type$ value) {\n"
259                  "  copyOnWrite();\n"
260                  "  instance.set$capitalized_name$(value);\n"
261                  "  return this;\n"
262                  "}\n");
263   printer->Annotate("{", "}", descriptor_);
264   WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
265                                /* builder */ true);
266   printer->Print(
267       variables_,
268       "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
269       "  copyOnWrite();\n"
270       "  instance.clear$capitalized_name$();\n"
271       "  return this;\n"
272       "}\n");
273   printer->Annotate("{", "}", descriptor_);
274 }
275 
GenerateInitializationCode(io::Printer * printer) const276 void ImmutableEnumFieldLiteGenerator::GenerateInitializationCode(
277     io::Printer* printer) const {
278   if (!IsDefaultValueJavaDefault(descriptor_)) {
279     printer->Print(variables_, "$name$_ = $default_number$;\n");
280   }
281 }
282 
GenerateFieldInfo(io::Printer * printer,std::vector<uint16> * output) const283 void ImmutableEnumFieldLiteGenerator::GenerateFieldInfo(
284     io::Printer* printer, std::vector<uint16>* output) const {
285   WriteIntToUtf16CharSequence(descriptor_->number(), output);
286   WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_),
287                               output);
288   if (HasHasbit(descriptor_)) {
289     WriteIntToUtf16CharSequence(messageBitIndex_, output);
290   }
291   printer->Print(variables_, "\"$name$_\",\n");
292   if (!SupportUnknownEnumValue((descriptor_))) {
293     PrintEnumVerifierLogic(printer, descriptor_, variables_,
294                            /*var_name=*/"$type$",
295                            /*terminating_string=*/",\n",
296                            /*enforce_lite=*/context_->EnforceLite());
297   }
298 }
299 
GetBoxedType() const300 std::string ImmutableEnumFieldLiteGenerator::GetBoxedType() const {
301   return name_resolver_->GetImmutableClassName(descriptor_->enum_type());
302 }
303 
304 // ===================================================================
305 
ImmutableEnumOneofFieldLiteGenerator(const FieldDescriptor * descriptor,int messageBitIndex,Context * context)306 ImmutableEnumOneofFieldLiteGenerator::ImmutableEnumOneofFieldLiteGenerator(
307     const FieldDescriptor* descriptor, int messageBitIndex, Context* context)
308     : ImmutableEnumFieldLiteGenerator(descriptor, messageBitIndex, context) {
309   const OneofGeneratorInfo* info =
310       context->GetOneofGeneratorInfo(descriptor->containing_oneof());
311   SetCommonOneofVariables(descriptor, info, &variables_);
312 }
313 
~ImmutableEnumOneofFieldLiteGenerator()314 ImmutableEnumOneofFieldLiteGenerator::~ImmutableEnumOneofFieldLiteGenerator() {}
315 
GenerateMembers(io::Printer * printer) const316 void ImmutableEnumOneofFieldLiteGenerator::GenerateMembers(
317     io::Printer* printer) const {
318   PrintExtraFieldInfo(variables_, printer);
319   if (SupportFieldPresence(descriptor_)) {
320     WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
321     printer->Print(
322         variables_,
323         "@java.lang.Override\n"
324         "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
325         "  return $has_oneof_case_message$;\n"
326         "}\n");
327     printer->Annotate("{", "}", descriptor_);
328   }
329   if (SupportUnknownEnumValue(descriptor_->file())) {
330     WriteFieldEnumValueAccessorDocComment(printer, descriptor_, GETTER);
331     printer->Print(
332         variables_,
333         "@java.lang.Override\n"
334         "$deprecation$public int ${$get$capitalized_name$Value$}$() {\n"
335         "  if ($has_oneof_case_message$) {\n"
336         "    return (java.lang.Integer) $oneof_name$_;\n"
337         "  }\n"
338         "  return $default_number$;\n"
339         "}\n");
340     printer->Annotate("{", "}", descriptor_);
341   }
342   WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
343   printer->Print(variables_,
344                  "@java.lang.Override\n"
345                  "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
346                  "  if ($has_oneof_case_message$) {\n"
347                  "    $type$ result = $type$.forNumber((java.lang.Integer) "
348                  "$oneof_name$_);\n"
349                  "    return result == null ? $unknown$ : result;\n"
350                  "  }\n"
351                  "  return $default$;\n"
352                  "}\n");
353   printer->Annotate("{", "}", descriptor_);
354 
355   // Generate private setters for the builder to proxy into.
356   if (SupportUnknownEnumValue(descriptor_->file())) {
357     WriteFieldEnumValueAccessorDocComment(printer, descriptor_, SETTER);
358     printer->Print(variables_,
359                    "private void set$capitalized_name$Value(int value) {\n"
360                    "  $set_oneof_case_message$;\n"
361                    "  $oneof_name$_ = value;\n"
362                    "}\n");
363   }
364   WriteFieldAccessorDocComment(printer, descriptor_, SETTER);
365   printer->Print(variables_,
366                  "private void set$capitalized_name$($type$ value) {\n"
367                  "  $oneof_name$_ = value.getNumber();\n"
368                  "  $set_oneof_case_message$;\n"
369                  "}\n");
370   WriteFieldAccessorDocComment(printer, descriptor_, CLEARER);
371   printer->Print(variables_,
372                  "private void clear$capitalized_name$() {\n"
373                  "  if ($has_oneof_case_message$) {\n"
374                  "    $clear_oneof_case_message$;\n"
375                  "    $oneof_name$_ = null;\n"
376                  "  }\n"
377                  "}\n");
378 }
379 
GenerateFieldInfo(io::Printer * printer,std::vector<uint16> * output) const380 void ImmutableEnumOneofFieldLiteGenerator::GenerateFieldInfo(
381     io::Printer* printer, std::vector<uint16>* output) const {
382   WriteIntToUtf16CharSequence(descriptor_->number(), output);
383   WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_),
384                               output);
385   WriteIntToUtf16CharSequence(descriptor_->containing_oneof()->index(), output);
386   if (!SupportUnknownEnumValue(descriptor_)) {
387     PrintEnumVerifierLogic(printer, descriptor_, variables_,
388                            /*var_name=*/"$type$",
389                            /*terminating_string=*/",\n",
390                            /*enforce_lite=*/context_->EnforceLite());
391   }
392 }
393 
GenerateBuilderMembers(io::Printer * printer) const394 void ImmutableEnumOneofFieldLiteGenerator::GenerateBuilderMembers(
395     io::Printer* printer) const {
396   if (SupportFieldPresence(descriptor_)) {
397     WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
398     printer->Print(
399         variables_,
400         "@java.lang.Override\n"
401         "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
402         "  return instance.has$capitalized_name$();\n"
403         "}\n");
404     printer->Annotate("{", "}", descriptor_);
405   }
406   if (SupportUnknownEnumValue(descriptor_->file())) {
407     WriteFieldEnumValueAccessorDocComment(printer, descriptor_, GETTER);
408     printer->Print(
409         variables_,
410         "@java.lang.Override\n"
411         "$deprecation$public int ${$get$capitalized_name$Value$}$() {\n"
412         "  return instance.get$capitalized_name$Value();\n"
413         "}\n");
414     printer->Annotate("{", "}", descriptor_);
415     WriteFieldEnumValueAccessorDocComment(printer, descriptor_, SETTER,
416                                           /* builder */ true);
417     printer->Print(variables_,
418                    "$deprecation$public Builder "
419                    "${$set$capitalized_name$Value$}$(int value) {\n"
420                    "  copyOnWrite();\n"
421                    "  instance.set$capitalized_name$Value(value);\n"
422                    "  return this;\n"
423                    "}\n");
424     printer->Annotate("{", "}", descriptor_);
425   }
426   WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
427   printer->Print(variables_,
428                  "@java.lang.Override\n"
429                  "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
430                  "  return instance.get$capitalized_name$();\n"
431                  "}\n");
432   printer->Annotate("{", "}", descriptor_);
433   WriteFieldAccessorDocComment(printer, descriptor_, SETTER,
434                                /* builder */ true);
435   printer->Print(variables_,
436                  "$deprecation$public Builder "
437                  "${$set$capitalized_name$$}$($type$ value) {\n"
438                  "  copyOnWrite();\n"
439                  "  instance.set$capitalized_name$(value);\n"
440                  "  return this;\n"
441                  "}\n");
442   printer->Annotate("{", "}", descriptor_);
443   WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
444                                /* builder */ true);
445   printer->Print(
446       variables_,
447       "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
448       "  copyOnWrite();\n"
449       "  instance.clear$capitalized_name$();\n"
450       "  return this;\n"
451       "}\n");
452   printer->Annotate("{", "}", descriptor_);
453 }
454 
455 // ===================================================================
456 
457 RepeatedImmutableEnumFieldLiteGenerator::
RepeatedImmutableEnumFieldLiteGenerator(const FieldDescriptor * descriptor,int messageBitIndex,Context * context)458     RepeatedImmutableEnumFieldLiteGenerator(const FieldDescriptor* descriptor,
459                                             int messageBitIndex,
460                                             Context* context)
461     : descriptor_(descriptor),
462       context_(context),
463       name_resolver_(context->GetNameResolver()) {
464   SetEnumVariables(descriptor, messageBitIndex, 0,
465                    context->GetFieldGeneratorInfo(descriptor), name_resolver_,
466                    &variables_);
467 }
468 
469 RepeatedImmutableEnumFieldLiteGenerator::
~RepeatedImmutableEnumFieldLiteGenerator()470     ~RepeatedImmutableEnumFieldLiteGenerator() {}
471 
GetNumBitsForMessage() const472 int RepeatedImmutableEnumFieldLiteGenerator::GetNumBitsForMessage() const {
473   return 0;
474 }
475 
GenerateInterfaceMembers(io::Printer * printer) const476 void RepeatedImmutableEnumFieldLiteGenerator::GenerateInterfaceMembers(
477     io::Printer* printer) const {
478   WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER);
479   printer->Print(
480       variables_,
481       "$deprecation$java.util.List<$type$> get$capitalized_name$List();\n");
482   WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT);
483   printer->Print(variables_,
484                  "$deprecation$int get$capitalized_name$Count();\n");
485   WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER);
486   printer->Print(variables_,
487                  "$deprecation$$type$ get$capitalized_name$(int index);\n");
488   if (SupportUnknownEnumValue(descriptor_->file())) {
489     WriteFieldEnumValueAccessorDocComment(printer, descriptor_, LIST_GETTER);
490     printer->Print(variables_,
491                    "$deprecation$java.util.List<java.lang.Integer>\n"
492                    "get$capitalized_name$ValueList();\n");
493     WriteFieldEnumValueAccessorDocComment(printer, descriptor_,
494                                           LIST_INDEXED_GETTER);
495     printer->Print(variables_,
496                    "$deprecation$int get$capitalized_name$Value(int index);\n");
497   }
498 }
499 
GenerateMembers(io::Printer * printer) const500 void RepeatedImmutableEnumFieldLiteGenerator::GenerateMembers(
501     io::Printer* printer) const {
502   printer->Print(
503       variables_,
504       "private com.google.protobuf.Internal.IntList $name$_;\n"
505       "private static final "
506       "com.google.protobuf.Internal.ListAdapter.Converter<\n"
507       "    java.lang.Integer, $type$> $name$_converter_ =\n"
508       "        new com.google.protobuf.Internal.ListAdapter.Converter<\n"
509       "            java.lang.Integer, $type$>() {\n"
510       "          @java.lang.Override\n"
511       "          public $type$ convert(java.lang.Integer from) {\n"
512       "            $type$ result = $type$.forNumber(from);\n"
513       "            return result == null ? $unknown$ : result;\n"
514       "          }\n"
515       "        };\n");
516   PrintExtraFieldInfo(variables_, printer);
517   WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER);
518   printer->Print(
519       variables_,
520       "@java.lang.Override\n"
521       "$deprecation$public java.util.List<$type$> "
522       "${$get$capitalized_name$List$}$() {\n"
523       "  return new com.google.protobuf.Internal.ListAdapter<\n"
524       "      java.lang.Integer, $type$>($name$_, $name$_converter_);\n"
525       "}\n");
526   printer->Annotate("{", "}", descriptor_);
527   WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT);
528   printer->Print(
529       variables_,
530       "@java.lang.Override\n"
531       "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
532       "  return $name$_.size();\n"
533       "}\n");
534   printer->Annotate("{", "}", descriptor_);
535   WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER);
536   printer->Print(
537       variables_,
538       "@java.lang.Override\n"
539       "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n"
540       "  return $name$_converter_.convert($name$_.getInt(index));\n"
541       "}\n");
542   printer->Annotate("{", "}", descriptor_);
543   if (SupportUnknownEnumValue(descriptor_->file())) {
544     WriteFieldEnumValueAccessorDocComment(printer, descriptor_, LIST_GETTER);
545     printer->Print(variables_,
546                    "@java.lang.Override\n"
547                    "$deprecation$public java.util.List<java.lang.Integer>\n"
548                    "${$get$capitalized_name$ValueList$}$() {\n"
549                    "  return $name$_;\n"
550                    "}\n");
551     printer->Annotate("{", "}", descriptor_);
552     WriteFieldEnumValueAccessorDocComment(printer, descriptor_,
553                                           LIST_INDEXED_GETTER);
554     printer->Print(variables_,
555                    "@java.lang.Override\n"
556                    "$deprecation$public int "
557                    "${$get$capitalized_name$Value$}$(int index) {\n"
558                    "  return $name$_.getInt(index);\n"
559                    "}\n");
560     printer->Annotate("{", "}", descriptor_);
561   }
562 
563   if (!EnableExperimentalRuntimeForLite() && descriptor_->is_packed() &&
564       context_->HasGeneratedMethods(descriptor_->containing_type())) {
565     printer->Print(variables_, "private int $name$MemoizedSerializedSize;\n");
566   }
567 
568   // Generate private setters for the builder to proxy into.
569   printer->Print(
570       variables_,
571       "private void ensure$capitalized_name$IsMutable() {\n"
572       // Use a temporary to avoid a redundant iget-object.
573       "  com.google.protobuf.Internal.IntList tmp = $name$_;\n"
574       "  if (!tmp.isModifiable()) {\n"
575       "    $name$_ =\n"
576       "        com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);\n"
577       "  }\n"
578       "}\n");
579   WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER);
580   printer->Print(variables_,
581                  "private void set$capitalized_name$(\n"
582                  "    int index, $type$ value) {\n"
583                  "  $null_check$"
584                  "  ensure$capitalized_name$IsMutable();\n"
585                  "  $name$_.setInt(index, value.getNumber());\n"
586                  "}\n");
587   WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER);
588   printer->Print(variables_,
589                  "private void add$capitalized_name$($type$ value) {\n"
590                  "  $null_check$"
591                  "  ensure$capitalized_name$IsMutable();\n"
592                  "  $name$_.addInt(value.getNumber());\n"
593                  "}\n");
594   WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER);
595   printer->Print(variables_,
596                  "private void addAll$capitalized_name$(\n"
597                  "    java.lang.Iterable<? extends $type$> values) {\n"
598                  "  ensure$capitalized_name$IsMutable();\n"
599                  "  for ($type$ value : values) {\n"
600                  "    $name$_.addInt(value.getNumber());\n"
601                  "  }\n"
602                  "}\n");
603   WriteFieldAccessorDocComment(printer, descriptor_, CLEARER);
604   printer->Print(variables_,
605                  "private void clear$capitalized_name$() {\n"
606                  "  $name$_ = emptyIntList();\n"
607                  "}\n");
608 
609   if (SupportUnknownEnumValue(descriptor_->file())) {
610     WriteFieldEnumValueAccessorDocComment(printer, descriptor_, SETTER);
611     printer->Print(variables_,
612                    "private void set$capitalized_name$Value(\n"
613                    "    int index, int value) {\n"
614                    "  ensure$capitalized_name$IsMutable();\n"
615                    "  $name$_.setInt(index, value);\n"
616                    "}\n");
617     WriteFieldEnumValueAccessorDocComment(printer, descriptor_, LIST_ADDER);
618     printer->Print(variables_,
619                    "private void add$capitalized_name$Value(int value) {\n"
620                    "  ensure$capitalized_name$IsMutable();\n"
621                    "  $name$_.addInt(value);\n"
622                    "}\n");
623     WriteFieldEnumValueAccessorDocComment(printer, descriptor_,
624                                           LIST_MULTI_ADDER);
625     printer->Print(variables_,
626                    "private void addAll$capitalized_name$Value(\n"
627                    "    java.lang.Iterable<java.lang.Integer> values) {\n"
628                    "  ensure$capitalized_name$IsMutable();\n"
629                    "  for (int value : values) {\n"
630                    "    $name$_.addInt(value);\n"
631                    "  }\n"
632                    "}\n");
633   }
634 }
635 
GenerateFieldInfo(io::Printer * printer,std::vector<uint16> * output) const636 void RepeatedImmutableEnumFieldLiteGenerator::GenerateFieldInfo(
637     io::Printer* printer, std::vector<uint16>* output) const {
638   WriteIntToUtf16CharSequence(descriptor_->number(), output);
639   WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_),
640                               output);
641   printer->Print(variables_, "\"$name$_\",\n");
642   if (!SupportUnknownEnumValue(descriptor_->file())) {
643     PrintEnumVerifierLogic(printer, descriptor_, variables_,
644                            /*var_name=*/"$type$",
645                            /*terminating_string=*/",\n",
646                            /*enforce_lite=*/context_->EnforceLite());
647   }
648 }
649 
GenerateBuilderMembers(io::Printer * printer) const650 void RepeatedImmutableEnumFieldLiteGenerator::GenerateBuilderMembers(
651     io::Printer* printer) const {
652   WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER);
653   printer->Print(variables_,
654                  "@java.lang.Override\n"
655                  "$deprecation$public java.util.List<$type$> "
656                  "${$get$capitalized_name$List$}$() {\n"
657                  "  return instance.get$capitalized_name$List();\n"
658                  "}\n");
659   printer->Annotate("{", "}", descriptor_);
660   WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT);
661   printer->Print(
662       variables_,
663       "@java.lang.Override\n"
664       "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
665       "  return instance.get$capitalized_name$Count();\n"
666       "}\n");
667   printer->Annotate("{", "}", descriptor_);
668   WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER);
669   printer->Print(
670       variables_,
671       "@java.lang.Override\n"
672       "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n"
673       "  return instance.get$capitalized_name$(index);\n"
674       "}\n");
675   printer->Annotate("{", "}", descriptor_);
676   WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER,
677                                /* builder */ true);
678   printer->Print(variables_,
679                  "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
680                  "    int index, $type$ value) {\n"
681                  "  copyOnWrite();\n"
682                  "  instance.set$capitalized_name$(index, value);\n"
683                  "  return this;\n"
684                  "}\n");
685   printer->Annotate("{", "}", descriptor_);
686   WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER,
687                                /* builder */ true);
688   printer->Print(variables_,
689                  "$deprecation$public Builder "
690                  "${$add$capitalized_name$$}$($type$ value) {\n"
691                  "  copyOnWrite();\n"
692                  "  instance.add$capitalized_name$(value);\n"
693                  "  return this;\n"
694                  "}\n");
695   printer->Annotate("{", "}", descriptor_);
696   WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER,
697                                /* builder */ true);
698   printer->Print(variables_,
699                  "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n"
700                  "    java.lang.Iterable<? extends $type$> values) {\n"
701                  "  copyOnWrite();\n"
702                  "  instance.addAll$capitalized_name$(values);"
703                  "  return this;\n"
704                  "}\n");
705   printer->Annotate("{", "}", descriptor_);
706   WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
707                                /* builder */ true);
708   printer->Print(
709       variables_,
710       "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
711       "  copyOnWrite();\n"
712       "  instance.clear$capitalized_name$();\n"
713       "  return this;\n"
714       "}\n");
715   printer->Annotate("{", "}", descriptor_);
716 
717   if (SupportUnknownEnumValue(descriptor_->file())) {
718     WriteFieldEnumValueAccessorDocComment(printer, descriptor_, LIST_GETTER);
719     printer->Print(variables_,
720                    "@java.lang.Override\n"
721                    "$deprecation$public java.util.List<java.lang.Integer>\n"
722                    "${$get$capitalized_name$ValueList$}$() {\n"
723                    "  return java.util.Collections.unmodifiableList(\n"
724                    "      instance.get$capitalized_name$ValueList());\n"
725                    "}\n");
726     printer->Annotate("{", "}", descriptor_);
727     WriteFieldEnumValueAccessorDocComment(printer, descriptor_,
728                                           LIST_INDEXED_GETTER);
729     printer->Print(variables_,
730                    "@java.lang.Override\n"
731                    "$deprecation$public int "
732                    "${$get$capitalized_name$Value$}$(int index) {\n"
733                    "  return instance.get$capitalized_name$Value(index);\n"
734                    "}\n");
735     printer->Annotate("{", "}", descriptor_);
736     WriteFieldEnumValueAccessorDocComment(printer, descriptor_,
737                                           LIST_INDEXED_SETTER,
738                                           /* builder */ true);
739     printer->Print(
740         variables_,
741         "$deprecation$public Builder ${$set$capitalized_name$Value$}$(\n"
742         "    int index, int value) {\n"
743         "  copyOnWrite();\n"
744         "  instance.set$capitalized_name$Value(index, value);\n"
745         "  return this;\n"
746         "}\n");
747     printer->Annotate("{", "}", descriptor_);
748     WriteFieldEnumValueAccessorDocComment(printer, descriptor_, LIST_ADDER,
749                                           /* builder */ true);
750     printer->Print(variables_,
751                    "$deprecation$public Builder "
752                    "${$add$capitalized_name$Value$}$(int value) {\n"
753                    "  instance.add$capitalized_name$Value(value);\n"
754                    "  return this;\n"
755                    "}\n");
756     printer->Annotate("{", "}", descriptor_);
757     WriteFieldEnumValueAccessorDocComment(printer, descriptor_,
758                                           LIST_MULTI_ADDER,
759                                           /* builder */ true);
760     printer->Print(
761         variables_,
762         "$deprecation$public Builder ${$addAll$capitalized_name$Value$}$(\n"
763         "    java.lang.Iterable<java.lang.Integer> values) {\n"
764         "  copyOnWrite();\n"
765         "  instance.addAll$capitalized_name$Value(values);\n"
766         "  return this;\n"
767         "}\n");
768     printer->Annotate("{", "}", descriptor_);
769   }
770 }
771 
GenerateInitializationCode(io::Printer * printer) const772 void RepeatedImmutableEnumFieldLiteGenerator::GenerateInitializationCode(
773     io::Printer* printer) const {
774   printer->Print(variables_, "$name$_ = emptyIntList();\n");
775 }
776 
GetBoxedType() const777 std::string RepeatedImmutableEnumFieldLiteGenerator::GetBoxedType() const {
778   return name_resolver_->GetImmutableClassName(descriptor_->enum_type());
779 }
780 
781 }  // namespace java
782 }  // namespace compiler
783 }  // namespace protobuf
784 }  // namespace google
785