• 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 
50 namespace google {
51 namespace protobuf {
52 namespace compiler {
53 namespace java {
54 
55 namespace {
EnableExperimentalRuntimeForLite()56 bool EnableExperimentalRuntimeForLite() {
57 #ifdef PROTOBUF_EXPERIMENT
58   return PROTOBUF_EXPERIMENT;
59 #else   // PROTOBUF_EXPERIMENT
60   return false;
61 #endif  // !PROTOBUF_EXPERIMENT
62 }
63 
SetEnumVariables(const FieldDescriptor * descriptor,int messageBitIndex,int builderBitIndex,const FieldGeneratorInfo * info,ClassNameResolver * name_resolver,std::map<std::string,std::string> * variables)64 void SetEnumVariables(const FieldDescriptor* descriptor, int messageBitIndex,
65                       int builderBitIndex, const FieldGeneratorInfo* info,
66                       ClassNameResolver* name_resolver,
67                       std::map<std::string, std::string>* variables) {
68   SetCommonFieldVariables(descriptor, info, variables);
69 
70   (*variables)["type"] =
71       name_resolver->GetImmutableClassName(descriptor->enum_type());
72   (*variables)["mutable_type"] =
73       name_resolver->GetMutableClassName(descriptor->enum_type());
74   (*variables)["default"] = ImmutableDefaultValue(descriptor, name_resolver);
75   (*variables)["default_number"] =
76       StrCat(descriptor->default_value_enum()->number());
77   (*variables)["tag"] = StrCat(
78       static_cast<int32>(internal::WireFormat::MakeTag(descriptor)));
79   (*variables)["tag_size"] = StrCat(
80       internal::WireFormat::TagSize(descriptor->number(), GetType(descriptor)));
81   // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
82   // by the proto compiler
83   (*variables)["deprecation"] =
84       descriptor->options().deprecated() ? "@java.lang.Deprecated " : "";
85   (*variables)["required"] = descriptor->is_required() ? "true" : "false";
86 
87   if (SupportFieldPresence(descriptor->file())) {
88     // For singular messages and builders, one bit is used for the hasField bit.
89     (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
90 
91     // Note that these have a trailing ";".
92     (*variables)["set_has_field_bit_message"] =
93         GenerateSetBit(messageBitIndex) + ";";
94     (*variables)["clear_has_field_bit_message"] =
95         GenerateClearBit(messageBitIndex) + ";";
96 
97     (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex);
98   } else {
99     (*variables)["set_has_field_bit_message"] = "";
100     (*variables)["clear_has_field_bit_message"] = "";
101 
102     (*variables)["is_field_present_message"] =
103         (*variables)["name"] + "_ != " + (*variables)["default"] +
104         ".getNumber()";
105   }
106 
107   // For repeated builders, the underlying list tracks mutability state.
108   (*variables)["is_mutable"] = (*variables)["name"] + "_.isModifiable()";
109 
110   (*variables)["get_has_field_bit_from_local"] =
111       GenerateGetBitFromLocal(builderBitIndex);
112   (*variables)["set_has_field_bit_to_local"] =
113       GenerateSetBitToLocal(messageBitIndex);
114 
115   if (SupportUnknownEnumValue(descriptor->file())) {
116     (*variables)["unknown"] = (*variables)["type"] + ".UNRECOGNIZED";
117   } else {
118     (*variables)["unknown"] = (*variables)["default"];
119   }
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_->file()) ? 1 : 0;
141 }
142 
GenerateInterfaceMembers(io::Printer * printer) const143 void ImmutableEnumFieldLiteGenerator::GenerateInterfaceMembers(
144     io::Printer* printer) const {
145   if (SupportFieldPresence(descriptor_->file())) {
146     WriteFieldDocComment(printer, descriptor_);
147     printer->Print(variables_,
148                    "$deprecation$boolean has$capitalized_name$();\n");
149   }
150   if (SupportUnknownEnumValue(descriptor_->file())) {
151     WriteFieldDocComment(printer, descriptor_);
152     printer->Print(variables_,
153                    "$deprecation$int get$capitalized_name$Value();\n");
154   }
155   WriteFieldDocComment(printer, descriptor_);
156   printer->Print(variables_, "$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_->file())) {
164     WriteFieldDocComment(printer, descriptor_);
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     WriteFieldDocComment(printer, descriptor_);
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   WriteFieldDocComment(printer, descriptor_);
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     WriteFieldDocComment(printer, descriptor_);
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   WriteFieldDocComment(printer, descriptor_);
202   printer->Print(variables_,
203                  "private void set$capitalized_name$($type$ value) {\n"
204                  "  if (value == null) {\n"
205                  "    throw new NullPointerException();\n"
206                  "  }\n"
207                  "  $set_has_field_bit_message$\n"
208                  "  $name$_ = value.getNumber();\n"
209                  "}\n");
210   WriteFieldDocComment(printer, descriptor_);
211   printer->Print(variables_,
212                  "private void clear$capitalized_name$() {\n"
213                  "  $clear_has_field_bit_message$\n"
214                  "  $name$_ = $default_number$;\n"
215                  "}\n");
216 }
217 
GenerateBuilderMembers(io::Printer * printer) const218 void ImmutableEnumFieldLiteGenerator::GenerateBuilderMembers(
219     io::Printer* printer) const {
220   if (SupportFieldPresence(descriptor_->file())) {
221     WriteFieldDocComment(printer, descriptor_);
222     printer->Print(
223         variables_,
224         "@java.lang.Override\n"
225         "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
226         "  return instance.has$capitalized_name$();\n"
227         "}\n");
228     printer->Annotate("{", "}", descriptor_);
229   }
230   if (SupportUnknownEnumValue(descriptor_->file())) {
231     WriteFieldDocComment(printer, descriptor_);
232     printer->Print(
233         variables_,
234         "@java.lang.Override\n"
235         "$deprecation$public int ${$get$capitalized_name$Value$}$() {\n"
236         "  return instance.get$capitalized_name$Value();\n"
237         "}\n");
238     printer->Annotate("{", "}", descriptor_);
239     WriteFieldDocComment(printer, descriptor_);
240     printer->Print(variables_,
241                    "$deprecation$public Builder "
242                    "${$set$capitalized_name$Value$}$(int value) {\n"
243                    "  copyOnWrite();\n"
244                    "  instance.set$capitalized_name$Value(value);\n"
245                    "  return this;\n"
246                    "}\n");
247     printer->Annotate("{", "}", descriptor_);
248   }
249   WriteFieldDocComment(printer, descriptor_);
250   printer->Print(variables_,
251                  "@java.lang.Override\n"
252                  "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
253                  "  return instance.get$capitalized_name$();\n"
254                  "}\n");
255   printer->Annotate("{", "}", descriptor_);
256   WriteFieldDocComment(printer, descriptor_);
257   printer->Print(variables_,
258                  "$deprecation$public Builder "
259                  "${$set$capitalized_name$$}$($type$ value) {\n"
260                  "  copyOnWrite();\n"
261                  "  instance.set$capitalized_name$(value);\n"
262                  "  return this;\n"
263                  "}\n");
264   printer->Annotate("{", "}", descriptor_);
265   WriteFieldDocComment(printer, descriptor_);
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 (SupportFieldPresence(descriptor_->file())) {
289     WriteIntToUtf16CharSequence(messageBitIndex_, output);
290   }
291   printer->Print(variables_, "\"$name$_\",\n");
292   if (SupportFieldPresence(descriptor_->file())) {
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_->file())) {
320     WriteFieldDocComment(printer, descriptor_);
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     WriteFieldDocComment(printer, descriptor_);
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   WriteFieldDocComment(printer, descriptor_);
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     WriteFieldDocComment(printer, descriptor_);
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   WriteFieldDocComment(printer, descriptor_);
365   printer->Print(variables_,
366                  "private void set$capitalized_name$($type$ value) {\n"
367                  "  if (value == null) {\n"
368                  "    throw new NullPointerException();\n"
369                  "  }\n"
370                  "  $set_oneof_case_message$;\n"
371                  "  $oneof_name$_ = value.getNumber();\n"
372                  "}\n");
373   WriteFieldDocComment(printer, descriptor_);
374   printer->Print(variables_,
375                  "private void clear$capitalized_name$() {\n"
376                  "  if ($has_oneof_case_message$) {\n"
377                  "    $clear_oneof_case_message$;\n"
378                  "    $oneof_name$_ = null;\n"
379                  "  }\n"
380                  "}\n");
381 }
382 
GenerateFieldInfo(io::Printer * printer,std::vector<uint16> * output) const383 void ImmutableEnumOneofFieldLiteGenerator::GenerateFieldInfo(
384     io::Printer* printer, std::vector<uint16>* output) const {
385   WriteIntToUtf16CharSequence(descriptor_->number(), output);
386   WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_),
387                               output);
388   WriteIntToUtf16CharSequence(descriptor_->containing_oneof()->index(), output);
389   if (SupportFieldPresence(descriptor_->file())) {
390     PrintEnumVerifierLogic(printer, descriptor_, variables_,
391                            /*var_name=*/"$type$",
392                            /*terminating_string=*/",\n",
393                            /*enforce_lite=*/context_->EnforceLite());
394   }
395 }
396 
GenerateBuilderMembers(io::Printer * printer) const397 void ImmutableEnumOneofFieldLiteGenerator::GenerateBuilderMembers(
398     io::Printer* printer) const {
399   if (SupportFieldPresence(descriptor_->file())) {
400     WriteFieldDocComment(printer, descriptor_);
401     printer->Print(
402         variables_,
403         "@java.lang.Override\n"
404         "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
405         "  return instance.has$capitalized_name$();\n"
406         "}\n");
407     printer->Annotate("{", "}", descriptor_);
408   }
409   if (SupportUnknownEnumValue(descriptor_->file())) {
410     WriteFieldDocComment(printer, descriptor_);
411     printer->Print(
412         variables_,
413         "@java.lang.Override\n"
414         "$deprecation$public int ${$get$capitalized_name$Value$}$() {\n"
415         "  return instance.get$capitalized_name$Value();\n"
416         "}\n");
417     printer->Annotate("{", "}", descriptor_);
418     WriteFieldDocComment(printer, descriptor_);
419     printer->Print(variables_,
420                    "$deprecation$public Builder "
421                    "${$set$capitalized_name$Value$}$(int value) {\n"
422                    "  copyOnWrite();\n"
423                    "  instance.set$capitalized_name$Value(value);\n"
424                    "  return this;\n"
425                    "}\n");
426     printer->Annotate("{", "}", descriptor_);
427   }
428   WriteFieldDocComment(printer, descriptor_);
429   printer->Print(variables_,
430                  "@java.lang.Override\n"
431                  "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
432                  "  return instance.get$capitalized_name$();\n"
433                  "}\n");
434   printer->Annotate("{", "}", descriptor_);
435   WriteFieldDocComment(printer, descriptor_);
436   printer->Print(variables_,
437                  "$deprecation$public Builder "
438                  "${$set$capitalized_name$$}$($type$ value) {\n"
439                  "  copyOnWrite();\n"
440                  "  instance.set$capitalized_name$(value);\n"
441                  "  return this;\n"
442                  "}\n");
443   printer->Annotate("{", "}", descriptor_);
444   WriteFieldDocComment(printer, descriptor_);
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   WriteFieldDocComment(printer, descriptor_);
479   printer->Print(
480       variables_,
481       "$deprecation$java.util.List<$type$> get$capitalized_name$List();\n");
482   WriteFieldDocComment(printer, descriptor_);
483   printer->Print(variables_,
484                  "$deprecation$int get$capitalized_name$Count();\n");
485   WriteFieldDocComment(printer, descriptor_);
486   printer->Print(variables_,
487                  "$deprecation$$type$ get$capitalized_name$(int index);\n");
488   if (SupportUnknownEnumValue(descriptor_->file())) {
489     WriteFieldDocComment(printer, descriptor_);
490     printer->Print(variables_,
491                    "$deprecation$java.util.List<java.lang.Integer>\n"
492                    "get$capitalized_name$ValueList();\n");
493     WriteFieldDocComment(printer, descriptor_);
494     printer->Print(variables_,
495                    "$deprecation$int get$capitalized_name$Value(int index);\n");
496   }
497 }
498 
GenerateMembers(io::Printer * printer) const499 void RepeatedImmutableEnumFieldLiteGenerator::GenerateMembers(
500     io::Printer* printer) const {
501   printer->Print(
502       variables_,
503       "private com.google.protobuf.Internal.IntList $name$_;\n"
504       "private static final "
505       "com.google.protobuf.Internal.ListAdapter.Converter<\n"
506       "    java.lang.Integer, $type$> $name$_converter_ =\n"
507       "        new com.google.protobuf.Internal.ListAdapter.Converter<\n"
508       "            java.lang.Integer, $type$>() {\n"
509       "          @java.lang.Override\n"
510       "          public $type$ convert(java.lang.Integer from) {\n"
511       "            $type$ result = $type$.forNumber(from);\n"
512       "            return result == null ? $unknown$ : result;\n"
513       "          }\n"
514       "        };\n");
515   PrintExtraFieldInfo(variables_, printer);
516   WriteFieldDocComment(printer, descriptor_);
517   printer->Print(
518       variables_,
519       "@java.lang.Override\n"
520       "$deprecation$public java.util.List<$type$> "
521       "${$get$capitalized_name$List$}$() {\n"
522       "  return new com.google.protobuf.Internal.ListAdapter<\n"
523       "      java.lang.Integer, $type$>($name$_, $name$_converter_);\n"
524       "}\n");
525   printer->Annotate("{", "}", descriptor_);
526   WriteFieldDocComment(printer, descriptor_);
527   printer->Print(
528       variables_,
529       "@java.lang.Override\n"
530       "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
531       "  return $name$_.size();\n"
532       "}\n");
533   printer->Annotate("{", "}", descriptor_);
534   WriteFieldDocComment(printer, descriptor_);
535   printer->Print(
536       variables_,
537       "@java.lang.Override\n"
538       "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n"
539       "  return $name$_converter_.convert($name$_.getInt(index));\n"
540       "}\n");
541   printer->Annotate("{", "}", descriptor_);
542   if (SupportUnknownEnumValue(descriptor_->file())) {
543     WriteFieldDocComment(printer, descriptor_);
544     printer->Print(variables_,
545                    "@java.lang.Override\n"
546                    "$deprecation$public java.util.List<java.lang.Integer>\n"
547                    "${$get$capitalized_name$ValueList$}$() {\n"
548                    "  return $name$_;\n"
549                    "}\n");
550     printer->Annotate("{", "}", descriptor_);
551     WriteFieldDocComment(printer, descriptor_);
552     printer->Print(variables_,
553                    "@java.lang.Override\n"
554                    "$deprecation$public int "
555                    "${$get$capitalized_name$Value$}$(int index) {\n"
556                    "  return $name$_.getInt(index);\n"
557                    "}\n");
558     printer->Annotate("{", "}", descriptor_);
559   }
560 
561   if (!EnableExperimentalRuntimeForLite() && descriptor_->is_packed() &&
562       context_->HasGeneratedMethods(descriptor_->containing_type())) {
563     printer->Print(variables_, "private int $name$MemoizedSerializedSize;\n");
564   }
565 
566   // Generate private setters for the builder to proxy into.
567   printer->Print(
568       variables_,
569       "private void ensure$capitalized_name$IsMutable() {\n"
570       "  if (!$is_mutable$) {\n"
571       "    $name$_ =\n"
572       "        com.google.protobuf.GeneratedMessageLite.mutableCopy($name$_);\n"
573       "  }\n"
574       "}\n");
575   WriteFieldDocComment(printer, descriptor_);
576   printer->Print(variables_,
577                  "private void set$capitalized_name$(\n"
578                  "    int index, $type$ value) {\n"
579                  "  if (value == null) {\n"
580                  "    throw new NullPointerException();\n"
581                  "  }\n"
582                  "  ensure$capitalized_name$IsMutable();\n"
583                  "  $name$_.setInt(index, value.getNumber());\n"
584                  "}\n");
585   WriteFieldDocComment(printer, descriptor_);
586   printer->Print(variables_,
587                  "private void add$capitalized_name$($type$ value) {\n"
588                  "  if (value == null) {\n"
589                  "    throw new NullPointerException();\n"
590                  "  }\n"
591                  "  ensure$capitalized_name$IsMutable();\n"
592                  "  $name$_.addInt(value.getNumber());\n"
593                  "}\n");
594   WriteFieldDocComment(printer, descriptor_);
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   WriteFieldDocComment(printer, descriptor_);
604   printer->Print(variables_,
605                  "private void clear$capitalized_name$() {\n"
606                  "  $name$_ = emptyIntList();\n"
607                  "}\n");
608 
609   if (SupportUnknownEnumValue(descriptor_->file())) {
610     WriteFieldDocComment(printer, descriptor_);
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     WriteFieldDocComment(printer, descriptor_);
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     WriteFieldDocComment(printer, descriptor_);
624     printer->Print(variables_,
625                    "private void addAll$capitalized_name$Value(\n"
626                    "    java.lang.Iterable<java.lang.Integer> values) {\n"
627                    "  ensure$capitalized_name$IsMutable();\n"
628                    "  for (int value : values) {\n"
629                    "    $name$_.addInt(value);\n"
630                    "  }\n"
631                    "}\n");
632   }
633 }
634 
GenerateFieldInfo(io::Printer * printer,std::vector<uint16> * output) const635 void RepeatedImmutableEnumFieldLiteGenerator::GenerateFieldInfo(
636     io::Printer* printer, std::vector<uint16>* output) const {
637   WriteIntToUtf16CharSequence(descriptor_->number(), output);
638   WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_),
639                               output);
640   printer->Print(variables_, "\"$name$_\",\n");
641   if (SupportFieldPresence(descriptor_->file())) {
642     PrintEnumVerifierLogic(printer, descriptor_, variables_,
643                            /*var_name=*/"$type$",
644                            /*terminating_string=*/",\n",
645                            /*enforce_lite=*/context_->EnforceLite());
646   }
647 }
648 
GenerateBuilderMembers(io::Printer * printer) const649 void RepeatedImmutableEnumFieldLiteGenerator::GenerateBuilderMembers(
650     io::Printer* printer) const {
651   WriteFieldDocComment(printer, descriptor_);
652   printer->Print(variables_,
653                  "@java.lang.Override\n"
654                  "$deprecation$public java.util.List<$type$> "
655                  "${$get$capitalized_name$List$}$() {\n"
656                  "  return instance.get$capitalized_name$List();\n"
657                  "}\n");
658   printer->Annotate("{", "}", descriptor_);
659   WriteFieldDocComment(printer, descriptor_);
660   printer->Print(
661       variables_,
662       "@java.lang.Override\n"
663       "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
664       "  return instance.get$capitalized_name$Count();\n"
665       "}\n");
666   printer->Annotate("{", "}", descriptor_);
667   WriteFieldDocComment(printer, descriptor_);
668   printer->Print(
669       variables_,
670       "@java.lang.Override\n"
671       "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n"
672       "  return instance.get$capitalized_name$(index);\n"
673       "}\n");
674   printer->Annotate("{", "}", descriptor_);
675   WriteFieldDocComment(printer, descriptor_);
676   printer->Print(variables_,
677                  "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
678                  "    int index, $type$ value) {\n"
679                  "  copyOnWrite();\n"
680                  "  instance.set$capitalized_name$(index, value);\n"
681                  "  return this;\n"
682                  "}\n");
683   printer->Annotate("{", "}", descriptor_);
684   WriteFieldDocComment(printer, descriptor_);
685   printer->Print(variables_,
686                  "$deprecation$public Builder "
687                  "${$add$capitalized_name$$}$($type$ value) {\n"
688                  "  copyOnWrite();\n"
689                  "  instance.add$capitalized_name$(value);\n"
690                  "  return this;\n"
691                  "}\n");
692   printer->Annotate("{", "}", descriptor_);
693   WriteFieldDocComment(printer, descriptor_);
694   printer->Print(variables_,
695                  "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n"
696                  "    java.lang.Iterable<? extends $type$> values) {\n"
697                  "  copyOnWrite();\n"
698                  "  instance.addAll$capitalized_name$(values);"
699                  "  return this;\n"
700                  "}\n");
701   printer->Annotate("{", "}", descriptor_);
702   WriteFieldDocComment(printer, descriptor_);
703   printer->Print(
704       variables_,
705       "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
706       "  copyOnWrite();\n"
707       "  instance.clear$capitalized_name$();\n"
708       "  return this;\n"
709       "}\n");
710   printer->Annotate("{", "}", descriptor_);
711 
712   if (SupportUnknownEnumValue(descriptor_->file())) {
713     WriteFieldDocComment(printer, descriptor_);
714     printer->Print(variables_,
715                    "@java.lang.Override\n"
716                    "$deprecation$public java.util.List<java.lang.Integer>\n"
717                    "${$get$capitalized_name$ValueList$}$() {\n"
718                    "  return java.util.Collections.unmodifiableList(\n"
719                    "      instance.get$capitalized_name$ValueList());\n"
720                    "}\n");
721     printer->Annotate("{", "}", descriptor_);
722     WriteFieldDocComment(printer, descriptor_);
723     printer->Print(variables_,
724                    "@java.lang.Override\n"
725                    "$deprecation$public int "
726                    "${$get$capitalized_name$Value$}$(int index) {\n"
727                    "  return instance.get$capitalized_name$Value(index);\n"
728                    "}\n");
729     printer->Annotate("{", "}", descriptor_);
730     WriteFieldDocComment(printer, descriptor_);
731     printer->Print(
732         variables_,
733         "$deprecation$public Builder ${$set$capitalized_name$Value$}$(\n"
734         "    int index, int value) {\n"
735         "  copyOnWrite();\n"
736         "  instance.set$capitalized_name$Value(index, value);\n"
737         "  return this;\n"
738         "}\n");
739     printer->Annotate("{", "}", descriptor_);
740     WriteFieldDocComment(printer, descriptor_);
741     printer->Print(variables_,
742                    "$deprecation$public Builder "
743                    "${$add$capitalized_name$Value$}$(int value) {\n"
744                    "  instance.add$capitalized_name$Value(value);\n"
745                    "  return this;\n"
746                    "}\n");
747     printer->Annotate("{", "}", descriptor_);
748     WriteFieldDocComment(printer, descriptor_);
749     printer->Print(
750         variables_,
751         "$deprecation$public Builder ${$addAll$capitalized_name$Value$}$(\n"
752         "    java.lang.Iterable<java.lang.Integer> values) {\n"
753         "  copyOnWrite();\n"
754         "  instance.addAll$capitalized_name$Value(values);\n"
755         "  return this;\n"
756         "}\n");
757     printer->Annotate("{", "}", descriptor_);
758   }
759 }
760 
GenerateInitializationCode(io::Printer * printer) const761 void RepeatedImmutableEnumFieldLiteGenerator::GenerateInitializationCode(
762     io::Printer* printer) const {
763   printer->Print(variables_, "$name$_ = emptyIntList();\n");
764 }
765 
GetBoxedType() const766 std::string RepeatedImmutableEnumFieldLiteGenerator::GetBoxedType() const {
767   return name_resolver_->GetImmutableClassName(descriptor_->enum_type());
768 }
769 
770 }  // namespace java
771 }  // namespace compiler
772 }  // namespace protobuf
773 }  // namespace google
774