• 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 <google/protobuf/compiler/java/java_primitive_field_lite.h>
36 
37 #include <cstdint>
38 #include <map>
39 #include <string>
40 
41 #include <google/protobuf/stubs/logging.h>
42 #include <google/protobuf/stubs/common.h>
43 #include <google/protobuf/io/printer.h>
44 #include <google/protobuf/wire_format.h>
45 #include <google/protobuf/stubs/strutil.h>
46 #include <google/protobuf/compiler/java/java_context.h>
47 #include <google/protobuf/compiler/java/java_doc_comment.h>
48 #include <google/protobuf/compiler/java/java_helpers.h>
49 #include <google/protobuf/compiler/java/java_name_resolver.h>
50 
51 namespace google {
52 namespace protobuf {
53 namespace compiler {
54 namespace java {
55 
56 using internal::WireFormat;
57 using internal::WireFormatLite;
58 
59 namespace {
EnableExperimentalRuntimeForLite()60 bool EnableExperimentalRuntimeForLite() {
61 #ifdef PROTOBUF_EXPERIMENT
62   return PROTOBUF_EXPERIMENT;
63 #else   // PROTOBUF_EXPERIMENT
64   return false;
65 #endif  // !PROTOBUF_EXPERIMENT
66 }
67 
SetPrimitiveVariables(const FieldDescriptor * descriptor,int messageBitIndex,int builderBitIndex,const FieldGeneratorInfo * info,ClassNameResolver * name_resolver,std::map<std::string,std::string> * variables)68 void SetPrimitiveVariables(const FieldDescriptor* descriptor,
69                            int messageBitIndex, int builderBitIndex,
70                            const FieldGeneratorInfo* info,
71                            ClassNameResolver* name_resolver,
72                            std::map<std::string, std::string>* variables) {
73   SetCommonFieldVariables(descriptor, info, variables);
74   JavaType javaType = GetJavaType(descriptor);
75   (*variables)["type"] = PrimitiveTypeName(javaType);
76   (*variables)["boxed_type"] = BoxedPrimitiveTypeName(javaType);
77   (*variables)["kt_type"] = KotlinTypeName(javaType);
78   (*variables)["field_type"] = (*variables)["type"];
79   (*variables)["default"] = ImmutableDefaultValue(descriptor, name_resolver);
80   (*variables)["capitalized_type"] =
81       GetCapitalizedType(descriptor, /* immutable = */ true);
82   (*variables)["tag"] =
83       StrCat(static_cast<int32_t>(WireFormat::MakeTag(descriptor)));
84   (*variables)["tag_size"] = StrCat(
85       WireFormat::TagSize(descriptor->number(), GetType(descriptor)));
86   (*variables)["required"] = descriptor->is_required() ? "true" : "false";
87 
88   std::string capitalized_type = UnderscoresToCamelCase(
89       PrimitiveTypeName(javaType), true /* cap_next_letter */);
90   switch (javaType) {
91     case JAVATYPE_INT:
92     case JAVATYPE_LONG:
93     case JAVATYPE_FLOAT:
94     case JAVATYPE_DOUBLE:
95     case JAVATYPE_BOOLEAN:
96       (*variables)["field_list_type"] =
97           "com.google.protobuf.Internal." + capitalized_type + "List";
98       (*variables)["empty_list"] = "empty" + capitalized_type + "List()";
99       (*variables)["make_name_unmodifiable"] =
100           (*variables)["name"] + "_.makeImmutable()";
101       (*variables)["repeated_get"] =
102           (*variables)["name"] + "_.get" + capitalized_type;
103       (*variables)["repeated_add"] =
104           (*variables)["name"] + "_.add" + capitalized_type;
105       (*variables)["repeated_set"] =
106           (*variables)["name"] + "_.set" + capitalized_type;
107       (*variables)["visit_type"] = capitalized_type;
108       (*variables)["visit_type_list"] = "visit" + capitalized_type + "List";
109       break;
110     default:
111       (*variables)["field_list_type"] =
112           "com.google.protobuf.Internal.ProtobufList<" +
113           (*variables)["boxed_type"] + ">";
114       (*variables)["empty_list"] = "emptyProtobufList()";
115       (*variables)["make_name_unmodifiable"] =
116           (*variables)["name"] + "_.makeImmutable()";
117       (*variables)["repeated_get"] = (*variables)["name"] + "_.get";
118       (*variables)["repeated_add"] = (*variables)["name"] + "_.add";
119       (*variables)["repeated_set"] = (*variables)["name"] + "_.set";
120       (*variables)["visit_type"] = "ByteString";
121       (*variables)["visit_type_list"] = "visitList";
122   }
123 
124   if (javaType == JAVATYPE_BYTES) {
125     (*variables)["bytes_default"] =
126         ToUpper((*variables)["name"]) + "_DEFAULT_VALUE";
127   }
128 
129   if (IsReferenceType(javaType)) {
130     // We use `x.getClass()` as a null check because it generates less bytecode
131     // than an `if (x == null) { throw ... }` statement.
132     (*variables)["null_check"] =
133         "  java.lang.Class<?> valueClass = value.getClass();\n";
134   } else {
135     (*variables)["null_check"] = "";
136   }
137   // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
138   // by the proto compiler
139   (*variables)["deprecation"] =
140       descriptor->options().deprecated() ? "@java.lang.Deprecated " : "";
141   (*variables)["kt_deprecation"] =
142       descriptor->options().deprecated()
143           ? "@kotlin.Deprecated(message = \"Field " + (*variables)["name"] +
144                 " is deprecated\") "
145           : "";
146   int fixed_size = FixedSize(GetType(descriptor));
147   if (fixed_size != -1) {
148     (*variables)["fixed_size"] = StrCat(fixed_size);
149   }
150 
151   if (HasHasbit(descriptor)) {
152     // For singular messages and builders, one bit is used for the hasField bit.
153     (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
154 
155     // Note that these have a trailing ";".
156     (*variables)["set_has_field_bit_message"] =
157         GenerateSetBit(messageBitIndex) + ";";
158     (*variables)["clear_has_field_bit_message"] =
159         GenerateClearBit(messageBitIndex) + ";";
160 
161     (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex);
162   } else {
163     (*variables)["set_has_field_bit_message"] = "";
164     (*variables)["clear_has_field_bit_message"] = "";
165 
166     switch (descriptor->type()) {
167       case FieldDescriptor::TYPE_BYTES:
168         (*variables)["is_field_present_message"] =
169             "!" + (*variables)["name"] + "_.isEmpty()";
170         break;
171       case FieldDescriptor::TYPE_FLOAT:
172         (*variables)["is_field_present_message"] =
173             "java.lang.Float.floatToRawIntBits(" + (*variables)["name"] +
174             "_) != 0";
175         break;
176       case FieldDescriptor::TYPE_DOUBLE:
177         (*variables)["is_field_present_message"] =
178             "java.lang.Double.doubleToRawLongBits(" + (*variables)["name"] +
179             "_) != 0";
180         break;
181       default:
182         (*variables)["is_field_present_message"] =
183             (*variables)["name"] + "_ != " + (*variables)["default"];
184         break;
185     }
186   }
187 
188   (*variables)["get_has_field_bit_from_local"] =
189       GenerateGetBitFromLocal(builderBitIndex);
190   (*variables)["set_has_field_bit_to_local"] =
191       GenerateSetBitToLocal(messageBitIndex);
192 }
193 
194 }  // namespace
195 
196 // ===================================================================
197 
ImmutablePrimitiveFieldLiteGenerator(const FieldDescriptor * descriptor,int messageBitIndex,Context * context)198 ImmutablePrimitiveFieldLiteGenerator::ImmutablePrimitiveFieldLiteGenerator(
199     const FieldDescriptor* descriptor, int messageBitIndex, Context* context)
200     : descriptor_(descriptor),
201       messageBitIndex_(messageBitIndex),
202       name_resolver_(context->GetNameResolver()) {
203   SetPrimitiveVariables(descriptor, messageBitIndex, 0,
204                         context->GetFieldGeneratorInfo(descriptor),
205                         name_resolver_, &variables_);
206 }
207 
~ImmutablePrimitiveFieldLiteGenerator()208 ImmutablePrimitiveFieldLiteGenerator::~ImmutablePrimitiveFieldLiteGenerator() {}
209 
GetNumBitsForMessage() const210 int ImmutablePrimitiveFieldLiteGenerator::GetNumBitsForMessage() const {
211   return HasHasbit(descriptor_) ? 1 : 0;
212 }
213 
GenerateInterfaceMembers(io::Printer * printer) const214 void ImmutablePrimitiveFieldLiteGenerator::GenerateInterfaceMembers(
215     io::Printer* printer) const {
216   if (HasHazzer(descriptor_)) {
217     WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
218     printer->Print(variables_,
219                    "$deprecation$boolean has$capitalized_name$();\n");
220   }
221   WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
222   printer->Print(variables_, "$deprecation$$type$ get$capitalized_name$();\n");
223 }
224 
GenerateMembers(io::Printer * printer) const225 void ImmutablePrimitiveFieldLiteGenerator::GenerateMembers(
226     io::Printer* printer) const {
227   if (IsByteStringWithCustomDefaultValue(descriptor_)) {
228     // allocate this once statically since we know ByteStrings are immutable
229     // values that can be reused.
230     printer->Print(
231         variables_,
232         "private static final $field_type$ $bytes_default$ = $default$;\n");
233   }
234   printer->Print(variables_, "private $field_type$ $name$_;\n");
235   PrintExtraFieldInfo(variables_, printer);
236   if (HasHazzer(descriptor_)) {
237     WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
238     printer->Print(
239         variables_,
240         "@java.lang.Override\n"
241         "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
242         "  return $get_has_field_bit_message$;\n"
243         "}\n");
244     printer->Annotate("{", "}", descriptor_);
245   }
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 $name$_;\n"
252                  "}\n");
253   printer->Annotate("{", "}", descriptor_);
254 
255   WriteFieldAccessorDocComment(printer, descriptor_, SETTER);
256   printer->Print(variables_,
257                  "private void set$capitalized_name$($type$ value) {\n"
258                  "$null_check$"
259                  "  $set_has_field_bit_message$\n"
260                  "  $name$_ = value;\n"
261                  "}\n");
262 
263   WriteFieldAccessorDocComment(printer, descriptor_, CLEARER);
264   printer->Print(variables_,
265                  "private void clear$capitalized_name$() {\n"
266                  "  $clear_has_field_bit_message$\n");
267   JavaType type = GetJavaType(descriptor_);
268   if (type == JAVATYPE_STRING || type == JAVATYPE_BYTES) {
269     // The default value is not a simple literal so we want to avoid executing
270     // it multiple times.  Instead, get the default out of the default instance.
271     printer->Print(
272         variables_,
273         "  $name$_ = getDefaultInstance().get$capitalized_name$();\n");
274   } else {
275     printer->Print(variables_, "  $name$_ = $default$;\n");
276   }
277   printer->Print(variables_, "}\n");
278 }
279 
GenerateBuilderMembers(io::Printer * printer) const280 void ImmutablePrimitiveFieldLiteGenerator::GenerateBuilderMembers(
281     io::Printer* printer) const {
282   if (HasHazzer(descriptor_)) {
283     WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
284     printer->Print(
285         variables_,
286         "@java.lang.Override\n"
287         "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
288         "  return instance.has$capitalized_name$();\n"
289         "}\n");
290     printer->Annotate("{", "}", descriptor_);
291   }
292 
293   WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
294   printer->Print(variables_,
295                  "@java.lang.Override\n"
296                  "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
297                  "  return instance.get$capitalized_name$();\n"
298                  "}\n");
299   printer->Annotate("{", "}", descriptor_);
300 
301   WriteFieldAccessorDocComment(printer, descriptor_, SETTER,
302                                /* builder */ true);
303   printer->Print(variables_,
304                  "$deprecation$public Builder "
305                  "${$set$capitalized_name$$}$($type$ value) {\n"
306                  "  copyOnWrite();\n"
307                  "  instance.set$capitalized_name$(value);\n"
308                  "  return this;\n"
309                  "}\n");
310   printer->Annotate("{", "}", descriptor_);
311 
312   WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
313                                /* builder */ true);
314   printer->Print(
315       variables_,
316       "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
317       "  copyOnWrite();\n"
318       "  instance.clear$capitalized_name$();\n"
319       "  return this;\n"
320       "}\n");
321   printer->Annotate("{", "}", descriptor_);
322 }
323 
GenerateKotlinDslMembers(io::Printer * printer) const324 void ImmutablePrimitiveFieldLiteGenerator::GenerateKotlinDslMembers(
325     io::Printer* printer) const {
326   WriteFieldDocComment(printer, descriptor_);
327   printer->Print(variables_,
328                  "$kt_deprecation$public var $kt_name$: $kt_type$\n"
329                  "  @JvmName(\"${$get$kt_capitalized_name$$}$\")\n"
330                  "  get() = $kt_dsl_builder$.${$get$capitalized_name$$}$()\n"
331                  "  @JvmName(\"${$set$kt_capitalized_name$$}$\")\n"
332                  "  set(value) {\n"
333                  "    $kt_dsl_builder$.${$set$capitalized_name$$}$(value)\n"
334                  "  }\n");
335 
336   WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
337                                /* builder */ false);
338   printer->Print(variables_,
339                  "public fun ${$clear$kt_capitalized_name$$}$() {\n"
340                  "  $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n"
341                  "}\n");
342 
343   if (HasHazzer(descriptor_)) {
344     WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
345     printer->Print(
346         variables_,
347         "public fun ${$has$kt_capitalized_name$$}$(): kotlin.Boolean {\n"
348         "  return $kt_dsl_builder$.${$has$capitalized_name$$}$()\n"
349         "}\n");
350   }
351 }
352 
GenerateFieldInfo(io::Printer * printer,std::vector<uint16_t> * output) const353 void ImmutablePrimitiveFieldLiteGenerator::GenerateFieldInfo(
354     io::Printer* printer, std::vector<uint16_t>* output) const {
355   WriteIntToUtf16CharSequence(descriptor_->number(), output);
356   WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_),
357                               output);
358   if (HasHasbit(descriptor_)) {
359     WriteIntToUtf16CharSequence(messageBitIndex_, output);
360   }
361   printer->Print(variables_, "\"$name$_\",\n");
362 }
363 
GenerateInitializationCode(io::Printer * printer) const364 void ImmutablePrimitiveFieldLiteGenerator::GenerateInitializationCode(
365     io::Printer* printer) const {
366   if (IsByteStringWithCustomDefaultValue(descriptor_)) {
367     printer->Print(variables_, "$name$_ = $bytes_default$;\n");
368   } else if (!IsDefaultValueJavaDefault(descriptor_)) {
369     printer->Print(variables_, "$name$_ = $default$;\n");
370   }
371 }
372 
GetBoxedType() const373 std::string ImmutablePrimitiveFieldLiteGenerator::GetBoxedType() const {
374   return BoxedPrimitiveTypeName(GetJavaType(descriptor_));
375 }
376 
377 // ===================================================================
378 
379 ImmutablePrimitiveOneofFieldLiteGenerator::
ImmutablePrimitiveOneofFieldLiteGenerator(const FieldDescriptor * descriptor,int messageBitIndex,Context * context)380     ImmutablePrimitiveOneofFieldLiteGenerator(const FieldDescriptor* descriptor,
381                                               int messageBitIndex,
382                                               Context* context)
383     : ImmutablePrimitiveFieldLiteGenerator(descriptor, messageBitIndex,
384                                            context) {
385   const OneofGeneratorInfo* info =
386       context->GetOneofGeneratorInfo(descriptor->containing_oneof());
387   SetCommonOneofVariables(descriptor, info, &variables_);
388 }
389 
390 ImmutablePrimitiveOneofFieldLiteGenerator::
~ImmutablePrimitiveOneofFieldLiteGenerator()391     ~ImmutablePrimitiveOneofFieldLiteGenerator() {}
392 
GenerateMembers(io::Printer * printer) const393 void ImmutablePrimitiveOneofFieldLiteGenerator::GenerateMembers(
394     io::Printer* printer) const {
395   PrintExtraFieldInfo(variables_, printer);
396   GOOGLE_DCHECK(HasHazzer(descriptor_));
397   WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
398   printer->Print(variables_,
399                  "@java.lang.Override\n"
400                  "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
401                  "  return $has_oneof_case_message$;\n"
402                  "}\n");
403   printer->Annotate("{", "}", descriptor_);
404 
405   WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
406   printer->Print(variables_,
407                  "@java.lang.Override\n"
408                  "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
409                  "  if ($has_oneof_case_message$) {\n"
410                  "    return ($boxed_type$) $oneof_name$_;\n"
411                  "  }\n"
412                  "  return $default$;\n"
413                  "}\n");
414   printer->Annotate("{", "}", descriptor_);
415 
416   WriteFieldAccessorDocComment(printer, descriptor_, SETTER);
417   printer->Print(variables_,
418                  "private void set$capitalized_name$($type$ value) {\n"
419                  "$null_check$"
420                  "  $set_oneof_case_message$;\n"
421                  "  $oneof_name$_ = value;\n"
422                  "}\n");
423 
424   WriteFieldAccessorDocComment(printer, descriptor_, CLEARER);
425   printer->Print(variables_,
426                  "private void clear$capitalized_name$() {\n"
427                  "  if ($has_oneof_case_message$) {\n"
428                  "    $clear_oneof_case_message$;\n"
429                  "    $oneof_name$_ = null;\n"
430                  "  }\n"
431                  "}\n");
432 }
433 
GenerateFieldInfo(io::Printer * printer,std::vector<uint16_t> * output) const434 void ImmutablePrimitiveOneofFieldLiteGenerator::GenerateFieldInfo(
435     io::Printer* printer, std::vector<uint16_t>* output) const {
436   WriteIntToUtf16CharSequence(descriptor_->number(), output);
437   WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_),
438                               output);
439   WriteIntToUtf16CharSequence(descriptor_->containing_oneof()->index(), output);
440 }
441 
GenerateBuilderMembers(io::Printer * printer) const442 void ImmutablePrimitiveOneofFieldLiteGenerator::GenerateBuilderMembers(
443     io::Printer* printer) const {
444   GOOGLE_DCHECK(HasHazzer(descriptor_));
445   WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
446   printer->Print(variables_,
447                  "@java.lang.Override\n"
448                  "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
449                  "  return instance.has$capitalized_name$();\n"
450                  "}\n");
451   printer->Annotate("{", "}", descriptor_);
452 
453   WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
454   printer->Print(variables_,
455                  "@java.lang.Override\n"
456                  "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
457                  "  return instance.get$capitalized_name$();\n"
458                  "}\n");
459   printer->Annotate("{", "}", descriptor_);
460 
461   WriteFieldAccessorDocComment(printer, descriptor_, SETTER,
462                                /* builder */ true);
463   printer->Print(variables_,
464                  "$deprecation$public Builder "
465                  "${$set$capitalized_name$$}$($type$ value) {\n"
466                  "  copyOnWrite();\n"
467                  "  instance.set$capitalized_name$(value);\n"
468                  "  return this;\n"
469                  "}\n");
470   printer->Annotate("{", "}", descriptor_);
471 
472   WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
473                                /* builder */ true);
474   printer->Print(
475       variables_,
476       "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
477       "  copyOnWrite();\n"
478       "  instance.clear$capitalized_name$();\n"
479       "  return this;\n"
480       "}\n");
481   printer->Annotate("{", "}", descriptor_);
482 }
483 
484 // ===================================================================
485 
486 RepeatedImmutablePrimitiveFieldLiteGenerator::
RepeatedImmutablePrimitiveFieldLiteGenerator(const FieldDescriptor * descriptor,int messageBitIndex,Context * context)487     RepeatedImmutablePrimitiveFieldLiteGenerator(
488         const FieldDescriptor* descriptor, int messageBitIndex,
489         Context* context)
490     : descriptor_(descriptor),
491       context_(context),
492       name_resolver_(context->GetNameResolver()) {
493   SetPrimitiveVariables(descriptor, messageBitIndex, 0,
494                         context->GetFieldGeneratorInfo(descriptor),
495                         name_resolver_, &variables_);
496 }
497 
498 RepeatedImmutablePrimitiveFieldLiteGenerator::
~RepeatedImmutablePrimitiveFieldLiteGenerator()499     ~RepeatedImmutablePrimitiveFieldLiteGenerator() {}
500 
GetNumBitsForMessage() const501 int RepeatedImmutablePrimitiveFieldLiteGenerator::GetNumBitsForMessage() const {
502   return 0;
503 }
504 
GenerateInterfaceMembers(io::Printer * printer) const505 void RepeatedImmutablePrimitiveFieldLiteGenerator::GenerateInterfaceMembers(
506     io::Printer* printer) const {
507   WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER);
508   printer->Print(variables_,
509                  "$deprecation$java.util.List<$boxed_type$> "
510                  "get$capitalized_name$List();\n");
511   WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT);
512   printer->Print(variables_,
513                  "$deprecation$int get$capitalized_name$Count();\n");
514   WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER);
515   printer->Print(variables_,
516                  "$deprecation$$type$ get$capitalized_name$(int index);\n");
517 }
518 
GenerateMembers(io::Printer * printer) const519 void RepeatedImmutablePrimitiveFieldLiteGenerator::GenerateMembers(
520     io::Printer* printer) const {
521   printer->Print(variables_, "private $field_list_type$ $name$_;\n");
522   PrintExtraFieldInfo(variables_, printer);
523   WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER);
524   printer->Print(variables_,
525                  "@java.lang.Override\n"
526                  "$deprecation$public java.util.List<$boxed_type$>\n"
527                  "    ${$get$capitalized_name$List$}$() {\n"
528                  "  return $name$_;\n"  // note:  unmodifiable list
529                  "}\n");
530   printer->Annotate("{", "}", descriptor_);
531   WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT);
532   printer->Print(
533       variables_,
534       "@java.lang.Override\n"
535       "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
536       "  return $name$_.size();\n"
537       "}\n");
538   printer->Annotate("{", "}", descriptor_);
539   WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER);
540   printer->Print(
541       variables_,
542       "@java.lang.Override\n"
543       "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n"
544       "  return $repeated_get$(index);\n"
545       "}\n");
546   printer->Annotate("{", "}", descriptor_);
547 
548   if (!EnableExperimentalRuntimeForLite() && descriptor_->is_packed() &&
549       context_->HasGeneratedMethods(descriptor_->containing_type())) {
550     printer->Print(variables_,
551                    "private int $name$MemoizedSerializedSize = -1;\n");
552   }
553 
554   printer->Print(
555       variables_,
556       "private void ensure$capitalized_name$IsMutable() {\n"
557       // Use a temporary to avoid a redundant iget-object.
558       "  $field_list_type$ tmp = $name$_;\n"
559       "  if (!tmp.isModifiable()) {\n"
560       "    $name$_ =\n"
561       "        com.google.protobuf.GeneratedMessageLite.mutableCopy(tmp);\n"
562       "   }\n"
563       "}\n");
564 
565   WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER);
566   printer->Print(variables_,
567                  "private void set$capitalized_name$(\n"
568                  "    int index, $type$ value) {\n"
569                  "$null_check$"
570                  "  ensure$capitalized_name$IsMutable();\n"
571                  "  $repeated_set$(index, value);\n"
572                  "}\n");
573   WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER);
574   printer->Print(variables_,
575                  "private void add$capitalized_name$($type$ value) {\n"
576                  "$null_check$"
577                  "  ensure$capitalized_name$IsMutable();\n"
578                  "  $repeated_add$(value);\n"
579                  "}\n");
580   WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER);
581   printer->Print(variables_,
582                  "private void addAll$capitalized_name$(\n"
583                  "    java.lang.Iterable<? extends $boxed_type$> values) {\n"
584                  "  ensure$capitalized_name$IsMutable();\n"
585                  "  com.google.protobuf.AbstractMessageLite.addAll(\n"
586                  "      values, $name$_);\n"
587                  "}\n");
588   WriteFieldAccessorDocComment(printer, descriptor_, CLEARER);
589   printer->Print(variables_,
590                  "private void clear$capitalized_name$() {\n"
591                  "  $name$_ = $empty_list$;\n"
592                  "}\n");
593 }
594 
GenerateBuilderMembers(io::Printer * printer) const595 void RepeatedImmutablePrimitiveFieldLiteGenerator::GenerateBuilderMembers(
596     io::Printer* printer) const {
597   WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER);
598   printer->Print(variables_,
599                  "@java.lang.Override\n"
600                  "$deprecation$public java.util.List<$boxed_type$>\n"
601                  "    ${$get$capitalized_name$List$}$() {\n"
602                  "  return java.util.Collections.unmodifiableList(\n"
603                  "      instance.get$capitalized_name$List());\n"
604                  "}\n");
605   printer->Annotate("{", "}", descriptor_);
606   WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT);
607   printer->Print(
608       variables_,
609       "@java.lang.Override\n"
610       "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
611       "  return instance.get$capitalized_name$Count();\n"
612       "}\n");
613   printer->Annotate("{", "}", descriptor_);
614   WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER);
615   printer->Print(
616       variables_,
617       "@java.lang.Override\n"
618       "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n"
619       "  return instance.get$capitalized_name$(index);\n"
620       "}\n");
621   printer->Annotate("{", "}", descriptor_);
622   WriteFieldAccessorDocComment(printer, descriptor_, SETTER,
623                                /* builder */ true);
624   printer->Print(variables_,
625                  "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
626                  "    int index, $type$ value) {\n"
627                  "  copyOnWrite();\n"
628                  "  instance.set$capitalized_name$(index, value);\n"
629                  "  return this;\n"
630                  "}\n");
631   printer->Annotate("{", "}", descriptor_);
632   WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER,
633                                /* builder */ true);
634   printer->Print(variables_,
635                  "$deprecation$public Builder "
636                  "${$add$capitalized_name$$}$($type$ value) {\n"
637                  "  copyOnWrite();\n"
638                  "  instance.add$capitalized_name$(value);\n"
639                  "  return this;\n"
640                  "}\n");
641   printer->Annotate("{", "}", descriptor_);
642   WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER,
643                                /* builder */ true);
644   printer->Print(variables_,
645                  "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n"
646                  "    java.lang.Iterable<? extends $boxed_type$> values) {\n"
647                  "  copyOnWrite();\n"
648                  "  instance.addAll$capitalized_name$(values);\n"
649                  "  return this;\n"
650                  "}\n");
651   printer->Annotate("{", "}", descriptor_);
652   WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
653                                /* builder */ true);
654   printer->Print(
655       variables_,
656       "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
657       "  copyOnWrite();\n"
658       "  instance.clear$capitalized_name$();\n"
659       "  return this;\n"
660       "}\n");
661   printer->Annotate("{", "}", descriptor_);
662 }
663 
GenerateKotlinDslMembers(io::Printer * printer) const664 void RepeatedImmutablePrimitiveFieldLiteGenerator::GenerateKotlinDslMembers(
665     io::Printer* printer) const {
666   printer->Print(
667       variables_,
668       "/**\n"
669       " * An uninstantiable, behaviorless type to represent the field in\n"
670       " * generics.\n"
671       " */\n"
672       "@kotlin.OptIn"
673       "(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)\n"
674       "public class ${$$kt_capitalized_name$Proxy$}$ private constructor()"
675       " : com.google.protobuf.kotlin.DslProxy()\n");
676 
677   WriteFieldDocComment(printer, descriptor_);
678   printer->Print(variables_,
679                  "$kt_deprecation$ public val $kt_name$: "
680                  "com.google.protobuf.kotlin.DslList"
681                  "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>\n"
682                  "  @kotlin.jvm.JvmSynthetic\n"
683                  "  get() = com.google.protobuf.kotlin.DslList(\n"
684                  "    $kt_dsl_builder$.${$get$capitalized_name$List$}$()\n"
685                  "  )\n");
686 
687   WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER,
688                                /* builder */ false);
689   printer->Print(variables_,
690                  "@kotlin.jvm.JvmSynthetic\n"
691                  "@kotlin.jvm.JvmName(\"add$kt_capitalized_name$\")\n"
692                  "public fun com.google.protobuf.kotlin.DslList"
693                  "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
694                  "add(value: $kt_type$) {\n"
695                  "  $kt_dsl_builder$.${$add$capitalized_name$$}$(value)\n"
696                  "}");
697 
698   WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER,
699                                /* builder */ false);
700   printer->Print(variables_,
701                  "@kotlin.jvm.JvmSynthetic\n"
702                  "@kotlin.jvm.JvmName(\"plusAssign$kt_capitalized_name$\")\n"
703                  "@Suppress(\"NOTHING_TO_INLINE\")\n"
704                  "public inline operator fun com.google.protobuf.kotlin.DslList"
705                  "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
706                  "plusAssign(value: $kt_type$) {\n"
707                  "  add(value)\n"
708                  "}");
709 
710   WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER,
711                                /* builder */ false);
712   printer->Print(variables_,
713                  "@kotlin.jvm.JvmSynthetic\n"
714                  "@kotlin.jvm.JvmName(\"addAll$kt_capitalized_name$\")\n"
715                  "public fun com.google.protobuf.kotlin.DslList"
716                  "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
717                  "addAll(values: kotlin.collections.Iterable<$kt_type$>) {\n"
718                  "  $kt_dsl_builder$.${$addAll$capitalized_name$$}$(values)\n"
719                  "}");
720 
721   WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER,
722                                /* builder */ false);
723   printer->Print(
724       variables_,
725       "@kotlin.jvm.JvmSynthetic\n"
726       "@kotlin.jvm.JvmName(\"plusAssignAll$kt_capitalized_name$\")\n"
727       "@Suppress(\"NOTHING_TO_INLINE\")\n"
728       "public inline operator fun com.google.protobuf.kotlin.DslList"
729       "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
730       "plusAssign(values: kotlin.collections.Iterable<$kt_type$>) {\n"
731       "  addAll(values)\n"
732       "}");
733 
734   WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER,
735                                /* builder */ false);
736   printer->Print(
737       variables_,
738       "@kotlin.jvm.JvmSynthetic\n"
739       "@kotlin.jvm.JvmName(\"set$kt_capitalized_name$\")\n"
740       "public operator fun com.google.protobuf.kotlin.DslList"
741       "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
742       "set(index: kotlin.Int, value: $kt_type$) {\n"
743       "  $kt_dsl_builder$.${$set$capitalized_name$$}$(index, value)\n"
744       "}");
745 
746   WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
747                                /* builder */ false);
748   printer->Print(variables_,
749                  "@kotlin.jvm.JvmSynthetic\n"
750                  "@kotlin.jvm.JvmName(\"clear$kt_capitalized_name$\")\n"
751                  "public fun com.google.protobuf.kotlin.DslList"
752                  "<$kt_type$, ${$$kt_capitalized_name$Proxy$}$>."
753                  "clear() {\n"
754                  "  $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n"
755                  "}");
756 }
757 
GenerateFieldInfo(io::Printer * printer,std::vector<uint16_t> * output) const758 void RepeatedImmutablePrimitiveFieldLiteGenerator::GenerateFieldInfo(
759     io::Printer* printer, std::vector<uint16_t>* output) const {
760   WriteIntToUtf16CharSequence(descriptor_->number(), output);
761   WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_),
762                               output);
763   printer->Print(variables_, "\"$name$_\",\n");
764 }
765 
GenerateInitializationCode(io::Printer * printer) const766 void RepeatedImmutablePrimitiveFieldLiteGenerator::GenerateInitializationCode(
767     io::Printer* printer) const {
768   printer->Print(variables_, "$name$_ = $empty_list$;\n");
769 }
770 
GetBoxedType() const771 std::string RepeatedImmutablePrimitiveFieldLiteGenerator::GetBoxedType() const {
772   return BoxedPrimitiveTypeName(GetJavaType(descriptor_));
773 }
774 
775 }  // namespace java
776 }  // namespace compiler
777 }  // namespace protobuf
778 }  // namespace google
779