• 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_helpers.h>
43 #include <google/protobuf/compiler/java/java_name_resolver.h>
44 #include <google/protobuf/compiler/java/java_primitive_field.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 using internal::WireFormat;
55 using internal::WireFormatLite;
56 
57 namespace {
58 
SetPrimitiveVariables(const FieldDescriptor * descriptor,int messageBitIndex,int builderBitIndex,const FieldGeneratorInfo * info,ClassNameResolver * name_resolver,std::map<std::string,std::string> * variables)59 void SetPrimitiveVariables(const FieldDescriptor* descriptor,
60                            int messageBitIndex, int builderBitIndex,
61                            const FieldGeneratorInfo* info,
62                            ClassNameResolver* name_resolver,
63                            std::map<std::string, std::string>* variables) {
64   SetCommonFieldVariables(descriptor, info, variables);
65   JavaType javaType = GetJavaType(descriptor);
66 
67   (*variables)["type"] = PrimitiveTypeName(javaType);
68   (*variables)["boxed_type"] = BoxedPrimitiveTypeName(javaType);
69   (*variables)["field_type"] = (*variables)["type"];
70 
71   if (javaType == JAVATYPE_BOOLEAN || javaType == JAVATYPE_DOUBLE ||
72       javaType == JAVATYPE_FLOAT || javaType == JAVATYPE_INT ||
73       javaType == JAVATYPE_LONG) {
74     std::string capitalized_type = UnderscoresToCamelCase(
75         PrimitiveTypeName(javaType), /*cap_first_letter=*/true);
76     (*variables)["field_list_type"] =
77         "com.google.protobuf.Internal." + capitalized_type + "List";
78     (*variables)["empty_list"] = "empty" + capitalized_type + "List()";
79     (*variables)["create_list"] = "new" + capitalized_type + "List()";
80     (*variables)["mutable_copy_list"] =
81         "mutableCopy(" + (*variables)["name"] + "_)";
82     (*variables)["name_make_immutable"] =
83         (*variables)["name"] + "_.makeImmutable()";
84     (*variables)["repeated_get"] =
85         (*variables)["name"] + "_.get" + capitalized_type;
86     (*variables)["repeated_add"] =
87         (*variables)["name"] + "_.add" + capitalized_type;
88     (*variables)["repeated_set"] =
89         (*variables)["name"] + "_.set" + capitalized_type;
90   } else {
91     (*variables)["field_list_type"] =
92         "java.util.List<" + (*variables)["boxed_type"] + ">";
93     (*variables)["create_list"] =
94         "new java.util.ArrayList<" + (*variables)["boxed_type"] + ">()";
95     (*variables)["mutable_copy_list"] = "new java.util.ArrayList<" +
96                                         (*variables)["boxed_type"] + ">(" +
97                                         (*variables)["name"] + "_)";
98     (*variables)["empty_list"] = "java.util.Collections.emptyList()";
99     (*variables)["name_make_immutable"] =
100         (*variables)["name"] + "_ = java.util.Collections.unmodifiableList(" +
101         (*variables)["name"] + "_)";
102     (*variables)["repeated_get"] = (*variables)["name"] + "_.get";
103     (*variables)["repeated_add"] = (*variables)["name"] + "_.add";
104     (*variables)["repeated_set"] = (*variables)["name"] + "_.set";
105   }
106 
107   (*variables)["default"] = ImmutableDefaultValue(descriptor, name_resolver);
108   (*variables)["default_init"] =
109       IsDefaultValueJavaDefault(descriptor)
110           ? ""
111           : ("= " + ImmutableDefaultValue(descriptor, name_resolver));
112   (*variables)["capitalized_type"] =
113       GetCapitalizedType(descriptor, /* immutable = */ true);
114   (*variables)["tag"] =
115       StrCat(static_cast<int32>(WireFormat::MakeTag(descriptor)));
116   (*variables)["tag_size"] = StrCat(
117       WireFormat::TagSize(descriptor->number(), GetType(descriptor)));
118   if (IsReferenceType(GetJavaType(descriptor))) {
119     (*variables)["null_check"] =
120         "  if (value == null) {\n"
121         "    throw new NullPointerException();\n"
122         "  }\n";
123   } else {
124     (*variables)["null_check"] = "";
125   }
126   // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
127   // by the proto compiler
128   (*variables)["deprecation"] =
129       descriptor->options().deprecated() ? "@java.lang.Deprecated " : "";
130   int fixed_size = FixedSize(GetType(descriptor));
131   if (fixed_size != -1) {
132     (*variables)["fixed_size"] = StrCat(fixed_size);
133   }
134   (*variables)["on_changed"] = "onChanged();";
135 
136   if (SupportFieldPresence(descriptor)) {
137     // For singular messages and builders, one bit is used for the hasField bit.
138     (*variables)["get_has_field_bit_message"] = GenerateGetBit(messageBitIndex);
139     (*variables)["get_has_field_bit_builder"] = GenerateGetBit(builderBitIndex);
140 
141     // Note that these have a trailing ";".
142     (*variables)["set_has_field_bit_message"] =
143         GenerateSetBit(messageBitIndex) + ";";
144     (*variables)["set_has_field_bit_builder"] =
145         GenerateSetBit(builderBitIndex) + ";";
146     (*variables)["clear_has_field_bit_builder"] =
147         GenerateClearBit(builderBitIndex) + ";";
148 
149     (*variables)["is_field_present_message"] = GenerateGetBit(messageBitIndex);
150   } else {
151     (*variables)["set_has_field_bit_message"] = "";
152     (*variables)["set_has_field_bit_builder"] = "";
153     (*variables)["clear_has_field_bit_builder"] = "";
154 
155     if (descriptor->type() == FieldDescriptor::TYPE_BYTES) {
156       (*variables)["is_field_present_message"] =
157           "!" + (*variables)["name"] + "_.isEmpty()";
158     } else {
159       (*variables)["is_field_present_message"] =
160           (*variables)["name"] + "_ != " + (*variables)["default"];
161     }
162   }
163 
164   // For repeated builders, one bit is used for whether the array is immutable.
165   (*variables)["get_mutable_bit_builder"] = GenerateGetBit(builderBitIndex);
166   (*variables)["set_mutable_bit_builder"] = GenerateSetBit(builderBitIndex);
167   (*variables)["clear_mutable_bit_builder"] = GenerateClearBit(builderBitIndex);
168 
169   // For repeated fields, one bit is used for whether the array is immutable
170   // in the parsing constructor.
171   (*variables)["get_mutable_bit_parser"] =
172       GenerateGetBitMutableLocal(builderBitIndex);
173   (*variables)["set_mutable_bit_parser"] =
174       GenerateSetBitMutableLocal(builderBitIndex);
175 
176   (*variables)["get_has_field_bit_from_local"] =
177       GenerateGetBitFromLocal(builderBitIndex);
178   (*variables)["set_has_field_bit_to_local"] =
179       GenerateSetBitToLocal(messageBitIndex);
180 }
181 
182 }  // namespace
183 
184 // ===================================================================
185 
ImmutablePrimitiveFieldGenerator(const FieldDescriptor * descriptor,int messageBitIndex,int builderBitIndex,Context * context)186 ImmutablePrimitiveFieldGenerator::ImmutablePrimitiveFieldGenerator(
187     const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex,
188     Context* context)
189     : descriptor_(descriptor), name_resolver_(context->GetNameResolver()) {
190   SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex,
191                         context->GetFieldGeneratorInfo(descriptor),
192                         name_resolver_, &variables_);
193 }
194 
~ImmutablePrimitiveFieldGenerator()195 ImmutablePrimitiveFieldGenerator::~ImmutablePrimitiveFieldGenerator() {}
196 
GetNumBitsForMessage() const197 int ImmutablePrimitiveFieldGenerator::GetNumBitsForMessage() const {
198   return SupportFieldPresence(descriptor_) ? 1 : 0;
199 }
200 
GetNumBitsForBuilder() const201 int ImmutablePrimitiveFieldGenerator::GetNumBitsForBuilder() const {
202   return GetNumBitsForMessage();
203 }
204 
GenerateInterfaceMembers(io::Printer * printer) const205 void ImmutablePrimitiveFieldGenerator::GenerateInterfaceMembers(
206     io::Printer* printer) const {
207   if (SupportFieldPresence(descriptor_)) {
208     WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
209     printer->Print(variables_,
210                    "$deprecation$boolean has$capitalized_name$();\n");
211   }
212   WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
213   printer->Print(variables_, "$deprecation$$type$ get$capitalized_name$();\n");
214 }
215 
GenerateMembers(io::Printer * printer) const216 void ImmutablePrimitiveFieldGenerator::GenerateMembers(
217     io::Printer* printer) const {
218   printer->Print(variables_, "private $field_type$ $name$_;\n");
219   PrintExtraFieldInfo(variables_, printer);
220   if (SupportFieldPresence(descriptor_)) {
221     WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
222     printer->Print(
223         variables_,
224         "@java.lang.Override\n"
225         "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
226         "  return $get_has_field_bit_message$;\n"
227         "}\n");
228     printer->Annotate("{", "}", descriptor_);
229   }
230 
231   WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
232   printer->Print(variables_,
233                  "@java.lang.Override\n"
234                  "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
235                  "  return $name$_;\n"
236                  "}\n");
237   printer->Annotate("{", "}", descriptor_);
238 }
239 
GenerateBuilderMembers(io::Printer * printer) const240 void ImmutablePrimitiveFieldGenerator::GenerateBuilderMembers(
241     io::Printer* printer) const {
242   printer->Print(variables_, "private $field_type$ $name$_ $default_init$;\n");
243 
244   if (SupportFieldPresence(descriptor_)) {
245     WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
246     printer->Print(
247         variables_,
248         "@java.lang.Override\n"
249         "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
250         "  return $get_has_field_bit_builder$;\n"
251         "}\n");
252     printer->Annotate("{", "}", descriptor_);
253   }
254 
255   WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
256   printer->Print(variables_,
257                  "@java.lang.Override\n"
258                  "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
259                  "  return $name$_;\n"
260                  "}\n");
261   printer->Annotate("{", "}", descriptor_);
262 
263   WriteFieldAccessorDocComment(printer, descriptor_, SETTER,
264                                /* builder */ true);
265   printer->Print(variables_,
266                  "$deprecation$public Builder "
267                  "${$set$capitalized_name$$}$($type$ value) {\n"
268                  "$null_check$"
269                  "  $set_has_field_bit_builder$\n"
270                  "  $name$_ = value;\n"
271                  "  $on_changed$\n"
272                  "  return this;\n"
273                  "}\n");
274   printer->Annotate("{", "}", descriptor_);
275 
276   WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
277                                /* builder */ true);
278   printer->Print(
279       variables_,
280       "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
281       "  $clear_has_field_bit_builder$\n");
282   printer->Annotate("{", "}", descriptor_);
283   JavaType type = GetJavaType(descriptor_);
284   if (type == JAVATYPE_STRING || type == JAVATYPE_BYTES) {
285     // The default value is not a simple literal so we want to avoid executing
286     // it multiple times.  Instead, get the default out of the default instance.
287     printer->Print(
288         variables_,
289         "  $name$_ = getDefaultInstance().get$capitalized_name$();\n");
290   } else {
291     printer->Print(variables_, "  $name$_ = $default$;\n");
292   }
293   printer->Print(variables_,
294                  "  $on_changed$\n"
295                  "  return this;\n"
296                  "}\n");
297 }
298 
299 
GenerateFieldBuilderInitializationCode(io::Printer * printer) const300 void ImmutablePrimitiveFieldGenerator::GenerateFieldBuilderInitializationCode(
301     io::Printer* printer) const {
302   // noop for primitives
303 }
304 
GenerateInitializationCode(io::Printer * printer) const305 void ImmutablePrimitiveFieldGenerator::GenerateInitializationCode(
306     io::Printer* printer) const {
307   if (!IsDefaultValueJavaDefault(descriptor_)) {
308     printer->Print(variables_, "$name$_ = $default$;\n");
309   }
310 }
311 
GenerateBuilderClearCode(io::Printer * printer) const312 void ImmutablePrimitiveFieldGenerator::GenerateBuilderClearCode(
313     io::Printer* printer) const {
314   printer->Print(variables_,
315                  "$name$_ = $default$;\n"
316                  "$clear_has_field_bit_builder$\n");
317 }
318 
GenerateMergingCode(io::Printer * printer) const319 void ImmutablePrimitiveFieldGenerator::GenerateMergingCode(
320     io::Printer* printer) const {
321   if (SupportFieldPresence(descriptor_)) {
322     printer->Print(variables_,
323                    "if (other.has$capitalized_name$()) {\n"
324                    "  set$capitalized_name$(other.get$capitalized_name$());\n"
325                    "}\n");
326   } else {
327     printer->Print(variables_,
328                    "if (other.get$capitalized_name$() != $default$) {\n"
329                    "  set$capitalized_name$(other.get$capitalized_name$());\n"
330                    "}\n");
331   }
332 }
333 
GenerateBuildingCode(io::Printer * printer) const334 void ImmutablePrimitiveFieldGenerator::GenerateBuildingCode(
335     io::Printer* printer) const {
336   if (SupportFieldPresence(descriptor_)) {
337     if (IsDefaultValueJavaDefault(descriptor_)) {
338       printer->Print(variables_,
339                      "if ($get_has_field_bit_from_local$) {\n"
340                      "  result.$name$_ = $name$_;\n"
341                      "  $set_has_field_bit_to_local$;\n"
342                      "}\n");
343     } else {
344       printer->Print(variables_,
345                      "if ($get_has_field_bit_from_local$) {\n"
346                      "  $set_has_field_bit_to_local$;\n"
347                      "}\n"
348                      "result.$name$_ = $name$_;\n");
349     }
350   } else {
351     printer->Print(variables_, "result.$name$_ = $name$_;\n");
352   }
353 }
354 
GenerateParsingCode(io::Printer * printer) const355 void ImmutablePrimitiveFieldGenerator::GenerateParsingCode(
356     io::Printer* printer) const {
357   printer->Print(variables_,
358                  "$set_has_field_bit_message$\n"
359                  "$name$_ = input.read$capitalized_type$();\n");
360 }
361 
GenerateParsingDoneCode(io::Printer * printer) const362 void ImmutablePrimitiveFieldGenerator::GenerateParsingDoneCode(
363     io::Printer* printer) const {
364   // noop for primitives.
365 }
366 
GenerateSerializationCode(io::Printer * printer) const367 void ImmutablePrimitiveFieldGenerator::GenerateSerializationCode(
368     io::Printer* printer) const {
369   printer->Print(variables_,
370                  "if ($is_field_present_message$) {\n"
371                  "  output.write$capitalized_type$($number$, $name$_);\n"
372                  "}\n");
373 }
374 
GenerateSerializedSizeCode(io::Printer * printer) const375 void ImmutablePrimitiveFieldGenerator::GenerateSerializedSizeCode(
376     io::Printer* printer) const {
377   printer->Print(variables_,
378                  "if ($is_field_present_message$) {\n"
379                  "  size += com.google.protobuf.CodedOutputStream\n"
380                  "    .compute$capitalized_type$Size($number$, $name$_);\n"
381                  "}\n");
382 }
383 
GenerateEqualsCode(io::Printer * printer) const384 void ImmutablePrimitiveFieldGenerator::GenerateEqualsCode(
385     io::Printer* printer) const {
386   switch (GetJavaType(descriptor_)) {
387     case JAVATYPE_INT:
388     case JAVATYPE_LONG:
389     case JAVATYPE_BOOLEAN:
390       printer->Print(variables_,
391                      "if (get$capitalized_name$()\n"
392                      "    != other.get$capitalized_name$()) return false;\n");
393       break;
394 
395     case JAVATYPE_FLOAT:
396       printer->Print(
397           variables_,
398           "if (java.lang.Float.floatToIntBits(get$capitalized_name$())\n"
399           "    != java.lang.Float.floatToIntBits(\n"
400           "        other.get$capitalized_name$())) return false;\n");
401       break;
402 
403     case JAVATYPE_DOUBLE:
404       printer->Print(
405           variables_,
406           "if (java.lang.Double.doubleToLongBits(get$capitalized_name$())\n"
407           "    != java.lang.Double.doubleToLongBits(\n"
408           "        other.get$capitalized_name$())) return false;\n");
409       break;
410 
411     case JAVATYPE_STRING:
412     case JAVATYPE_BYTES:
413       printer->Print(
414           variables_,
415           "if (!get$capitalized_name$()\n"
416           "    .equals(other.get$capitalized_name$())) return false;\n");
417       break;
418 
419     case JAVATYPE_ENUM:
420     case JAVATYPE_MESSAGE:
421     default:
422       GOOGLE_LOG(FATAL) << "Can't get here.";
423       break;
424   }
425 }
426 
GenerateHashCode(io::Printer * printer) const427 void ImmutablePrimitiveFieldGenerator::GenerateHashCode(
428     io::Printer* printer) const {
429   printer->Print(variables_, "hash = (37 * hash) + $constant_name$;\n");
430   switch (GetJavaType(descriptor_)) {
431     case JAVATYPE_INT:
432       printer->Print(variables_,
433                      "hash = (53 * hash) + get$capitalized_name$();\n");
434       break;
435 
436     case JAVATYPE_LONG:
437       printer->Print(
438           variables_,
439           "hash = (53 * hash) + com.google.protobuf.Internal.hashLong(\n"
440           "    get$capitalized_name$());\n");
441       break;
442 
443     case JAVATYPE_BOOLEAN:
444       printer->Print(
445           variables_,
446           "hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(\n"
447           "    get$capitalized_name$());\n");
448       break;
449 
450     case JAVATYPE_FLOAT:
451       printer->Print(variables_,
452                      "hash = (53 * hash) + java.lang.Float.floatToIntBits(\n"
453                      "    get$capitalized_name$());\n");
454       break;
455 
456     case JAVATYPE_DOUBLE:
457       printer->Print(
458           variables_,
459           "hash = (53 * hash) + com.google.protobuf.Internal.hashLong(\n"
460           "    java.lang.Double.doubleToLongBits(get$capitalized_name$()));\n");
461       break;
462 
463     case JAVATYPE_STRING:
464     case JAVATYPE_BYTES:
465       printer->Print(
466           variables_,
467           "hash = (53 * hash) + get$capitalized_name$().hashCode();\n");
468       break;
469 
470     case JAVATYPE_ENUM:
471     case JAVATYPE_MESSAGE:
472     default:
473       GOOGLE_LOG(FATAL) << "Can't get here.";
474       break;
475   }
476 }
477 
GetBoxedType() const478 std::string ImmutablePrimitiveFieldGenerator::GetBoxedType() const {
479   return BoxedPrimitiveTypeName(GetJavaType(descriptor_));
480 }
481 
482 // ===================================================================
483 
ImmutablePrimitiveOneofFieldGenerator(const FieldDescriptor * descriptor,int messageBitIndex,int builderBitIndex,Context * context)484 ImmutablePrimitiveOneofFieldGenerator::ImmutablePrimitiveOneofFieldGenerator(
485     const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex,
486     Context* context)
487     : ImmutablePrimitiveFieldGenerator(descriptor, messageBitIndex,
488                                        builderBitIndex, context) {
489   const OneofGeneratorInfo* info =
490       context->GetOneofGeneratorInfo(descriptor->containing_oneof());
491   SetCommonOneofVariables(descriptor, info, &variables_);
492 }
493 
494 ImmutablePrimitiveOneofFieldGenerator::
~ImmutablePrimitiveOneofFieldGenerator()495     ~ImmutablePrimitiveOneofFieldGenerator() {}
496 
GenerateMembers(io::Printer * printer) const497 void ImmutablePrimitiveOneofFieldGenerator::GenerateMembers(
498     io::Printer* printer) const {
499   PrintExtraFieldInfo(variables_, printer);
500   if (SupportFieldPresence(descriptor_)) {
501     WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
502     printer->Print(
503         variables_,
504         "@java.lang.Override\n"
505         "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
506         "  return $has_oneof_case_message$;\n"
507         "}\n");
508     printer->Annotate("{", "}", descriptor_);
509   }
510 
511   WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
512   printer->Print(variables_,
513                  "@java.lang.Override\n"
514                  "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
515                  "  if ($has_oneof_case_message$) {\n"
516                  "    return ($boxed_type$) $oneof_name$_;\n"
517                  "  }\n"
518                  "  return $default$;\n"
519                  "}\n");
520   printer->Annotate("{", "}", descriptor_);
521 }
522 
GenerateBuilderMembers(io::Printer * printer) const523 void ImmutablePrimitiveOneofFieldGenerator::GenerateBuilderMembers(
524     io::Printer* printer) const {
525   if (SupportFieldPresence(descriptor_)) {
526     WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
527     printer->Print(
528         variables_,
529         "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
530         "  return $has_oneof_case_message$;\n"
531         "}\n");
532     printer->Annotate("{", "}", descriptor_);
533   }
534 
535   WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
536   printer->Print(variables_,
537                  "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
538                  "  if ($has_oneof_case_message$) {\n"
539                  "    return ($boxed_type$) $oneof_name$_;\n"
540                  "  }\n"
541                  "  return $default$;\n"
542                  "}\n");
543   printer->Annotate("{", "}", descriptor_);
544 
545   WriteFieldAccessorDocComment(printer, descriptor_, SETTER,
546                                /* builder */ true);
547   printer->Print(variables_,
548                  "$deprecation$public Builder "
549                  "${$set$capitalized_name$$}$($type$ value) {\n"
550                  "$null_check$"
551                  "  $set_oneof_case_message$;\n"
552                  "  $oneof_name$_ = value;\n"
553                  "  $on_changed$\n"
554                  "  return this;\n"
555                  "}\n");
556   printer->Annotate("{", "}", descriptor_);
557 
558   WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
559                                /* builder */ true);
560   printer->Print(
561       variables_,
562       "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
563       "  if ($has_oneof_case_message$) {\n"
564       "    $clear_oneof_case_message$;\n"
565       "    $oneof_name$_ = null;\n"
566       "    $on_changed$\n"
567       "  }\n"
568       "  return this;\n"
569       "}\n");
570   printer->Annotate("{", "}", descriptor_);
571 }
572 
GenerateBuildingCode(io::Printer * printer) const573 void ImmutablePrimitiveOneofFieldGenerator::GenerateBuildingCode(
574     io::Printer* printer) const {
575   printer->Print(variables_,
576                  "if ($has_oneof_case_message$) {\n"
577                  "  result.$oneof_name$_ = $oneof_name$_;\n"
578                  "}\n");
579 }
580 
GenerateMergingCode(io::Printer * printer) const581 void ImmutablePrimitiveOneofFieldGenerator::GenerateMergingCode(
582     io::Printer* printer) const {
583   printer->Print(variables_,
584                  "set$capitalized_name$(other.get$capitalized_name$());\n");
585 }
586 
GenerateParsingCode(io::Printer * printer) const587 void ImmutablePrimitiveOneofFieldGenerator::GenerateParsingCode(
588     io::Printer* printer) const {
589   printer->Print(variables_,
590                  "$set_oneof_case_message$;\n"
591                  "$oneof_name$_ = input.read$capitalized_type$();\n");
592 }
593 
GenerateSerializationCode(io::Printer * printer) const594 void ImmutablePrimitiveOneofFieldGenerator::GenerateSerializationCode(
595     io::Printer* printer) const {
596   printer->Print(variables_,
597                  "if ($has_oneof_case_message$) {\n"
598                  "  output.write$capitalized_type$(\n");
599   // $type$ and $boxed_type$ is the same for bytes fields so we don't need to
600   // do redundant casts.
601   if (GetJavaType(descriptor_) == JAVATYPE_BYTES) {
602     printer->Print(variables_, "      $number$, ($type$) $oneof_name$_);\n");
603   } else {
604     printer->Print(
605         variables_,
606         "      $number$, ($type$)(($boxed_type$) $oneof_name$_));\n");
607   }
608   printer->Print("}\n");
609 }
610 
GenerateSerializedSizeCode(io::Printer * printer) const611 void ImmutablePrimitiveOneofFieldGenerator::GenerateSerializedSizeCode(
612     io::Printer* printer) const {
613   printer->Print(variables_,
614                  "if ($has_oneof_case_message$) {\n"
615                  "  size += com.google.protobuf.CodedOutputStream\n"
616                  "    .compute$capitalized_type$Size(\n");
617   // $type$ and $boxed_type$ is the same for bytes fields so we don't need to
618   // do redundant casts.
619   if (GetJavaType(descriptor_) == JAVATYPE_BYTES) {
620     printer->Print(variables_, "        $number$, ($type$) $oneof_name$_);\n");
621   } else {
622     printer->Print(
623         variables_,
624         "        $number$, ($type$)(($boxed_type$) $oneof_name$_));\n");
625   }
626   printer->Print("}\n");
627 }
628 
629 // ===================================================================
630 
631 RepeatedImmutablePrimitiveFieldGenerator::
RepeatedImmutablePrimitiveFieldGenerator(const FieldDescriptor * descriptor,int messageBitIndex,int builderBitIndex,Context * context)632     RepeatedImmutablePrimitiveFieldGenerator(const FieldDescriptor* descriptor,
633                                              int messageBitIndex,
634                                              int builderBitIndex,
635                                              Context* context)
636     : descriptor_(descriptor), name_resolver_(context->GetNameResolver()) {
637   SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex,
638                         context->GetFieldGeneratorInfo(descriptor),
639                         name_resolver_, &variables_);
640 }
641 
642 RepeatedImmutablePrimitiveFieldGenerator::
~RepeatedImmutablePrimitiveFieldGenerator()643     ~RepeatedImmutablePrimitiveFieldGenerator() {}
644 
GetNumBitsForMessage() const645 int RepeatedImmutablePrimitiveFieldGenerator::GetNumBitsForMessage() const {
646   return 0;
647 }
648 
GetNumBitsForBuilder() const649 int RepeatedImmutablePrimitiveFieldGenerator::GetNumBitsForBuilder() const {
650   return 1;
651 }
652 
GenerateInterfaceMembers(io::Printer * printer) const653 void RepeatedImmutablePrimitiveFieldGenerator::GenerateInterfaceMembers(
654     io::Printer* printer) const {
655   WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER);
656   printer->Print(variables_,
657                  "$deprecation$java.util.List<$boxed_type$> "
658                  "get$capitalized_name$List();\n");
659   WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT);
660   printer->Print(variables_,
661                  "$deprecation$int get$capitalized_name$Count();\n");
662   WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER);
663   printer->Print(variables_,
664                  "$deprecation$$type$ get$capitalized_name$(int index);\n");
665 }
666 
GenerateMembers(io::Printer * printer) const667 void RepeatedImmutablePrimitiveFieldGenerator::GenerateMembers(
668     io::Printer* printer) const {
669   printer->Print(variables_, "private $field_list_type$ $name$_;\n");
670   PrintExtraFieldInfo(variables_, printer);
671   WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER);
672   printer->Print(variables_,
673                  "@java.lang.Override\n"
674                  "$deprecation$public java.util.List<$boxed_type$>\n"
675                  "    ${$get$capitalized_name$List$}$() {\n"
676                  "  return $name$_;\n"  // note:  unmodifiable list
677                  "}\n");
678   printer->Annotate("{", "}", descriptor_);
679   WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT);
680   printer->Print(
681       variables_,
682       "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
683       "  return $name$_.size();\n"
684       "}\n");
685   printer->Annotate("{", "}", descriptor_);
686   WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER);
687   printer->Print(
688       variables_,
689       "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n"
690       "  return $repeated_get$(index);\n"
691       "}\n");
692   printer->Annotate("{", "}", descriptor_);
693 
694   if (descriptor_->is_packed()) {
695     printer->Print(variables_,
696                    "private int $name$MemoizedSerializedSize = -1;\n");
697   }
698 }
699 
GenerateBuilderMembers(io::Printer * printer) const700 void RepeatedImmutablePrimitiveFieldGenerator::GenerateBuilderMembers(
701     io::Printer* printer) const {
702   // One field is the list and the bit field keeps track of whether the
703   // list is immutable. If it's immutable, the invariant is that it must
704   // either an instance of Collections.emptyList() or it's an ArrayList
705   // wrapped in a Collections.unmodifiableList() wrapper and nobody else has
706   // a refererence to the underlying ArrayList. This invariant allows us to
707   // share instances of lists between protocol buffers avoiding expensive
708   // memory allocations. Note, immutable is a strong guarantee here -- not
709   // just that the list cannot be modified via the reference but that the
710   // list can never be modified.
711   printer->Print(variables_,
712                  "private $field_list_type$ $name$_ = $empty_list$;\n");
713 
714   printer->Print(variables_,
715                  "private void ensure$capitalized_name$IsMutable() {\n"
716                  "  if (!$get_mutable_bit_builder$) {\n"
717                  "    $name$_ = $mutable_copy_list$;\n"
718                  "    $set_mutable_bit_builder$;\n"
719                  "   }\n"
720                  "}\n");
721 
722   // Note:  We return an unmodifiable list because otherwise the caller
723   //   could hold on to the returned list and modify it after the message
724   //   has been built, thus mutating the message which is supposed to be
725   //   immutable.
726   WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER);
727   printer->Print(
728       variables_,
729       "$deprecation$public java.util.List<$boxed_type$>\n"
730       "    ${$get$capitalized_name$List$}$() {\n"
731       "  return $get_mutable_bit_builder$ ?\n"
732       "           java.util.Collections.unmodifiableList($name$_) : $name$_;\n"
733       "}\n");
734   printer->Annotate("{", "}", descriptor_);
735   WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT);
736   printer->Print(
737       variables_,
738       "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
739       "  return $name$_.size();\n"
740       "}\n");
741   printer->Annotate("{", "}", descriptor_);
742   WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER);
743   printer->Print(
744       variables_,
745       "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n"
746       "  return $repeated_get$(index);\n"
747       "}\n");
748   printer->Annotate("{", "}", descriptor_);
749   WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER,
750                                /* builder */ true);
751   printer->Print(variables_,
752                  "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
753                  "    int index, $type$ value) {\n"
754                  "$null_check$"
755                  "  ensure$capitalized_name$IsMutable();\n"
756                  "  $repeated_set$(index, value);\n"
757                  "  $on_changed$\n"
758                  "  return this;\n"
759                  "}\n");
760   printer->Annotate("{", "}", descriptor_);
761   WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER,
762                                /* builder */ true);
763   printer->Print(variables_,
764                  "$deprecation$public Builder "
765                  "${$add$capitalized_name$$}$($type$ value) {\n"
766                  "$null_check$"
767                  "  ensure$capitalized_name$IsMutable();\n"
768                  "  $repeated_add$(value);\n"
769                  "  $on_changed$\n"
770                  "  return this;\n"
771                  "}\n");
772   printer->Annotate("{", "}", descriptor_);
773   WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER,
774                                /* builder */ true);
775   printer->Print(variables_,
776                  "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n"
777                  "    java.lang.Iterable<? extends $boxed_type$> values) {\n"
778                  "  ensure$capitalized_name$IsMutable();\n"
779                  "  com.google.protobuf.AbstractMessageLite.Builder.addAll(\n"
780                  "      values, $name$_);\n"
781                  "  $on_changed$\n"
782                  "  return this;\n"
783                  "}\n");
784   printer->Annotate("{", "}", descriptor_);
785   WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
786                                /* builder */ true);
787   printer->Print(
788       variables_,
789       "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
790       "  $name$_ = $empty_list$;\n"
791       "  $clear_mutable_bit_builder$;\n"
792       "  $on_changed$\n"
793       "  return this;\n"
794       "}\n");
795   printer->Annotate("{", "}", descriptor_);
796 }
797 
798 void RepeatedImmutablePrimitiveFieldGenerator::
GenerateFieldBuilderInitializationCode(io::Printer * printer) const799     GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
800   // noop for primitives
801 }
802 
GenerateInitializationCode(io::Printer * printer) const803 void RepeatedImmutablePrimitiveFieldGenerator::GenerateInitializationCode(
804     io::Printer* printer) const {
805   printer->Print(variables_, "$name$_ = $empty_list$;\n");
806 }
807 
GenerateBuilderClearCode(io::Printer * printer) const808 void RepeatedImmutablePrimitiveFieldGenerator::GenerateBuilderClearCode(
809     io::Printer* printer) const {
810   printer->Print(variables_,
811                  "$name$_ = $empty_list$;\n"
812                  "$clear_mutable_bit_builder$;\n");
813 }
814 
GenerateMergingCode(io::Printer * printer) const815 void RepeatedImmutablePrimitiveFieldGenerator::GenerateMergingCode(
816     io::Printer* printer) const {
817   // The code below does two optimizations:
818   //   1. If the other list is empty, there's nothing to do. This ensures we
819   //      don't allocate a new array if we already have an immutable one.
820   //   2. If the other list is non-empty and our current list is empty, we can
821   //      reuse the other list which is guaranteed to be immutable.
822   printer->Print(variables_,
823                  "if (!other.$name$_.isEmpty()) {\n"
824                  "  if ($name$_.isEmpty()) {\n"
825                  "    $name$_ = other.$name$_;\n"
826                  "    $clear_mutable_bit_builder$;\n"
827                  "  } else {\n"
828                  "    ensure$capitalized_name$IsMutable();\n"
829                  "    $name$_.addAll(other.$name$_);\n"
830                  "  }\n"
831                  "  $on_changed$\n"
832                  "}\n");
833 }
834 
GenerateBuildingCode(io::Printer * printer) const835 void RepeatedImmutablePrimitiveFieldGenerator::GenerateBuildingCode(
836     io::Printer* printer) const {
837   // The code below ensures that the result has an immutable list. If our
838   // list is immutable, we can just reuse it. If not, we make it immutable.
839   printer->Print(variables_,
840                  "if ($get_mutable_bit_builder$) {\n"
841                  "  $name_make_immutable$;\n"
842                  "  $clear_mutable_bit_builder$;\n"
843                  "}\n"
844                  "result.$name$_ = $name$_;\n");
845 }
846 
GenerateParsingCode(io::Printer * printer) const847 void RepeatedImmutablePrimitiveFieldGenerator::GenerateParsingCode(
848     io::Printer* printer) const {
849   printer->Print(variables_,
850                  "if (!$get_mutable_bit_parser$) {\n"
851                  "  $name$_ = $create_list$;\n"
852                  "  $set_mutable_bit_parser$;\n"
853                  "}\n"
854                  "$repeated_add$(input.read$capitalized_type$());\n");
855 }
856 
GenerateParsingCodeFromPacked(io::Printer * printer) const857 void RepeatedImmutablePrimitiveFieldGenerator::GenerateParsingCodeFromPacked(
858     io::Printer* printer) const {
859   printer->Print(
860       variables_,
861       "int length = input.readRawVarint32();\n"
862       "int limit = input.pushLimit(length);\n"
863       "if (!$get_mutable_bit_parser$ && input.getBytesUntilLimit() > 0) {\n"
864       "  $name$_ = $create_list$;\n"
865       "  $set_mutable_bit_parser$;\n"
866       "}\n"
867       "while (input.getBytesUntilLimit() > 0) {\n"
868       "  $repeated_add$(input.read$capitalized_type$());\n"
869       "}\n"
870       "input.popLimit(limit);\n");
871 }
872 
GenerateParsingDoneCode(io::Printer * printer) const873 void RepeatedImmutablePrimitiveFieldGenerator::GenerateParsingDoneCode(
874     io::Printer* printer) const {
875   printer->Print(variables_,
876                  "if ($get_mutable_bit_parser$) {\n"
877                  "  $name_make_immutable$; // C\n"
878                  "}\n");
879 }
880 
GenerateSerializationCode(io::Printer * printer) const881 void RepeatedImmutablePrimitiveFieldGenerator::GenerateSerializationCode(
882     io::Printer* printer) const {
883   if (descriptor_->is_packed()) {
884     // We invoke getSerializedSize in writeTo for messages that have packed
885     // fields in ImmutableMessageGenerator::GenerateMessageSerializationMethods.
886     // That makes it safe to rely on the memoized size here.
887     printer->Print(variables_,
888                    "if (get$capitalized_name$List().size() > 0) {\n"
889                    "  output.writeUInt32NoTag($tag$);\n"
890                    "  output.writeUInt32NoTag($name$MemoizedSerializedSize);\n"
891                    "}\n"
892                    "for (int i = 0; i < $name$_.size(); i++) {\n"
893                    "  output.write$capitalized_type$NoTag($repeated_get$(i));\n"
894                    "}\n");
895   } else {
896     printer->Print(
897         variables_,
898         "for (int i = 0; i < $name$_.size(); i++) {\n"
899         "  output.write$capitalized_type$($number$, $repeated_get$(i));\n"
900         "}\n");
901   }
902 }
903 
GenerateSerializedSizeCode(io::Printer * printer) const904 void RepeatedImmutablePrimitiveFieldGenerator::GenerateSerializedSizeCode(
905     io::Printer* printer) const {
906   printer->Print(variables_,
907                  "{\n"
908                  "  int dataSize = 0;\n");
909   printer->Indent();
910 
911   if (FixedSize(GetType(descriptor_)) == -1) {
912     printer->Print(
913         variables_,
914         "for (int i = 0; i < $name$_.size(); i++) {\n"
915         "  dataSize += com.google.protobuf.CodedOutputStream\n"
916         "    .compute$capitalized_type$SizeNoTag($repeated_get$(i));\n"
917         "}\n");
918   } else {
919     printer->Print(
920         variables_,
921         "dataSize = $fixed_size$ * get$capitalized_name$List().size();\n");
922   }
923 
924   printer->Print("size += dataSize;\n");
925 
926   if (descriptor_->is_packed()) {
927     printer->Print(variables_,
928                    "if (!get$capitalized_name$List().isEmpty()) {\n"
929                    "  size += $tag_size$;\n"
930                    "  size += com.google.protobuf.CodedOutputStream\n"
931                    "      .computeInt32SizeNoTag(dataSize);\n"
932                    "}\n");
933   } else {
934     printer->Print(
935         variables_,
936         "size += $tag_size$ * get$capitalized_name$List().size();\n");
937   }
938 
939   // cache the data size for packed fields.
940   if (descriptor_->is_packed()) {
941     printer->Print(variables_, "$name$MemoizedSerializedSize = dataSize;\n");
942   }
943 
944   printer->Outdent();
945   printer->Print("}\n");
946 }
947 
GenerateEqualsCode(io::Printer * printer) const948 void RepeatedImmutablePrimitiveFieldGenerator::GenerateEqualsCode(
949     io::Printer* printer) const {
950   printer->Print(
951       variables_,
952       "if (!get$capitalized_name$List()\n"
953       "    .equals(other.get$capitalized_name$List())) return false;\n");
954 }
955 
GenerateHashCode(io::Printer * printer) const956 void RepeatedImmutablePrimitiveFieldGenerator::GenerateHashCode(
957     io::Printer* printer) const {
958   printer->Print(
959       variables_,
960       "if (get$capitalized_name$Count() > 0) {\n"
961       "  hash = (37 * hash) + $constant_name$;\n"
962       "  hash = (53 * hash) + get$capitalized_name$List().hashCode();\n"
963       "}\n");
964 }
965 
GetBoxedType() const966 std::string RepeatedImmutablePrimitiveFieldGenerator::GetBoxedType() const {
967   return BoxedPrimitiveTypeName(GetJavaType(descriptor_));
968 }
969 
970 }  // namespace java
971 }  // namespace compiler
972 }  // namespace protobuf
973 }  // namespace google
974