• 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 (HasHasbit(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   (*variables)["get_has_field_bit_from_local"] =
170       GenerateGetBitFromLocal(builderBitIndex);
171   (*variables)["set_has_field_bit_to_local"] =
172       GenerateSetBitToLocal(messageBitIndex);
173 }
174 
175 }  // namespace
176 
177 // ===================================================================
178 
ImmutablePrimitiveFieldGenerator(const FieldDescriptor * descriptor,int messageBitIndex,int builderBitIndex,Context * context)179 ImmutablePrimitiveFieldGenerator::ImmutablePrimitiveFieldGenerator(
180     const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex,
181     Context* context)
182     : descriptor_(descriptor), name_resolver_(context->GetNameResolver()) {
183   SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex,
184                         context->GetFieldGeneratorInfo(descriptor),
185                         name_resolver_, &variables_);
186 }
187 
~ImmutablePrimitiveFieldGenerator()188 ImmutablePrimitiveFieldGenerator::~ImmutablePrimitiveFieldGenerator() {}
189 
GetNumBitsForMessage() const190 int ImmutablePrimitiveFieldGenerator::GetNumBitsForMessage() const {
191   return HasHasbit(descriptor_) ? 1 : 0;
192 }
193 
GetNumBitsForBuilder() const194 int ImmutablePrimitiveFieldGenerator::GetNumBitsForBuilder() const {
195   return GetNumBitsForMessage();
196 }
197 
GenerateInterfaceMembers(io::Printer * printer) const198 void ImmutablePrimitiveFieldGenerator::GenerateInterfaceMembers(
199     io::Printer* printer) const {
200   if (SupportFieldPresence(descriptor_)) {
201     WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
202     printer->Print(variables_,
203                    "$deprecation$boolean has$capitalized_name$();\n");
204   }
205   WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
206   printer->Print(variables_, "$deprecation$$type$ get$capitalized_name$();\n");
207 }
208 
GenerateMembers(io::Printer * printer) const209 void ImmutablePrimitiveFieldGenerator::GenerateMembers(
210     io::Printer* printer) const {
211   printer->Print(variables_, "private $field_type$ $name$_;\n");
212   PrintExtraFieldInfo(variables_, printer);
213   if (SupportFieldPresence(descriptor_)) {
214     WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
215     printer->Print(
216         variables_,
217         "@java.lang.Override\n"
218         "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
219         "  return $get_has_field_bit_message$;\n"
220         "}\n");
221     printer->Annotate("{", "}", descriptor_);
222   }
223 
224   WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
225   printer->Print(variables_,
226                  "@java.lang.Override\n"
227                  "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
228                  "  return $name$_;\n"
229                  "}\n");
230   printer->Annotate("{", "}", descriptor_);
231 }
232 
GenerateBuilderMembers(io::Printer * printer) const233 void ImmutablePrimitiveFieldGenerator::GenerateBuilderMembers(
234     io::Printer* printer) const {
235   printer->Print(variables_, "private $field_type$ $name$_ $default_init$;\n");
236 
237   if (SupportFieldPresence(descriptor_)) {
238     WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
239     printer->Print(
240         variables_,
241         "@java.lang.Override\n"
242         "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
243         "  return $get_has_field_bit_builder$;\n"
244         "}\n");
245     printer->Annotate("{", "}", descriptor_);
246   }
247 
248   WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
249   printer->Print(variables_,
250                  "@java.lang.Override\n"
251                  "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
252                  "  return $name$_;\n"
253                  "}\n");
254   printer->Annotate("{", "}", descriptor_);
255 
256   WriteFieldAccessorDocComment(printer, descriptor_, SETTER,
257                                /* builder */ true);
258   printer->Print(variables_,
259                  "$deprecation$public Builder "
260                  "${$set$capitalized_name$$}$($type$ value) {\n"
261                  "$null_check$"
262                  "  $set_has_field_bit_builder$\n"
263                  "  $name$_ = value;\n"
264                  "  $on_changed$\n"
265                  "  return this;\n"
266                  "}\n");
267   printer->Annotate("{", "}", descriptor_);
268 
269   WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
270                                /* builder */ true);
271   printer->Print(
272       variables_,
273       "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
274       "  $clear_has_field_bit_builder$\n");
275   printer->Annotate("{", "}", descriptor_);
276   JavaType type = GetJavaType(descriptor_);
277   if (type == JAVATYPE_STRING || type == JAVATYPE_BYTES) {
278     // The default value is not a simple literal so we want to avoid executing
279     // it multiple times.  Instead, get the default out of the default instance.
280     printer->Print(
281         variables_,
282         "  $name$_ = getDefaultInstance().get$capitalized_name$();\n");
283   } else {
284     printer->Print(variables_, "  $name$_ = $default$;\n");
285   }
286   printer->Print(variables_,
287                  "  $on_changed$\n"
288                  "  return this;\n"
289                  "}\n");
290 }
291 
292 
GenerateFieldBuilderInitializationCode(io::Printer * printer) const293 void ImmutablePrimitiveFieldGenerator::GenerateFieldBuilderInitializationCode(
294     io::Printer* printer) const {
295   // noop for primitives
296 }
297 
GenerateInitializationCode(io::Printer * printer) const298 void ImmutablePrimitiveFieldGenerator::GenerateInitializationCode(
299     io::Printer* printer) const {
300   if (!IsDefaultValueJavaDefault(descriptor_)) {
301     printer->Print(variables_, "$name$_ = $default$;\n");
302   }
303 }
304 
GenerateBuilderClearCode(io::Printer * printer) const305 void ImmutablePrimitiveFieldGenerator::GenerateBuilderClearCode(
306     io::Printer* printer) const {
307   printer->Print(variables_,
308                  "$name$_ = $default$;\n"
309                  "$clear_has_field_bit_builder$\n");
310 }
311 
GenerateMergingCode(io::Printer * printer) const312 void ImmutablePrimitiveFieldGenerator::GenerateMergingCode(
313     io::Printer* printer) const {
314   if (SupportFieldPresence(descriptor_)) {
315     printer->Print(variables_,
316                    "if (other.has$capitalized_name$()) {\n"
317                    "  set$capitalized_name$(other.get$capitalized_name$());\n"
318                    "}\n");
319   } else {
320     printer->Print(variables_,
321                    "if (other.get$capitalized_name$() != $default$) {\n"
322                    "  set$capitalized_name$(other.get$capitalized_name$());\n"
323                    "}\n");
324   }
325 }
326 
GenerateBuildingCode(io::Printer * printer) const327 void ImmutablePrimitiveFieldGenerator::GenerateBuildingCode(
328     io::Printer* printer) const {
329   if (SupportFieldPresence(descriptor_)) {
330     if (IsDefaultValueJavaDefault(descriptor_)) {
331       printer->Print(variables_,
332                      "if ($get_has_field_bit_from_local$) {\n"
333                      "  result.$name$_ = $name$_;\n"
334                      "  $set_has_field_bit_to_local$;\n"
335                      "}\n");
336     } else {
337       printer->Print(variables_,
338                      "if ($get_has_field_bit_from_local$) {\n"
339                      "  $set_has_field_bit_to_local$;\n"
340                      "}\n"
341                      "result.$name$_ = $name$_;\n");
342     }
343   } else {
344     printer->Print(variables_, "result.$name$_ = $name$_;\n");
345   }
346 }
347 
GenerateBuilderParsingCode(io::Printer * printer) const348 void ImmutablePrimitiveFieldGenerator::GenerateBuilderParsingCode(
349     io::Printer* printer) const {
350   printer->Print(variables_,
351                  "$name$_ = input.read$capitalized_type$();\n"
352                  "$set_has_field_bit_builder$\n");
353 }
354 
GenerateSerializationCode(io::Printer * printer) const355 void ImmutablePrimitiveFieldGenerator::GenerateSerializationCode(
356     io::Printer* printer) const {
357   printer->Print(variables_,
358                  "if ($is_field_present_message$) {\n"
359                  "  output.write$capitalized_type$($number$, $name$_);\n"
360                  "}\n");
361 }
362 
GenerateSerializedSizeCode(io::Printer * printer) const363 void ImmutablePrimitiveFieldGenerator::GenerateSerializedSizeCode(
364     io::Printer* printer) const {
365   printer->Print(variables_,
366                  "if ($is_field_present_message$) {\n"
367                  "  size += com.google.protobuf.CodedOutputStream\n"
368                  "    .compute$capitalized_type$Size($number$, $name$_);\n"
369                  "}\n");
370 }
371 
GenerateEqualsCode(io::Printer * printer) const372 void ImmutablePrimitiveFieldGenerator::GenerateEqualsCode(
373     io::Printer* printer) const {
374   switch (GetJavaType(descriptor_)) {
375     case JAVATYPE_INT:
376     case JAVATYPE_LONG:
377     case JAVATYPE_BOOLEAN:
378       printer->Print(variables_,
379                      "if (get$capitalized_name$()\n"
380                      "    != other.get$capitalized_name$()) return false;\n");
381       break;
382 
383     case JAVATYPE_FLOAT:
384       printer->Print(
385           variables_,
386           "if (java.lang.Float.floatToIntBits(get$capitalized_name$())\n"
387           "    != java.lang.Float.floatToIntBits(\n"
388           "        other.get$capitalized_name$())) return false;\n");
389       break;
390 
391     case JAVATYPE_DOUBLE:
392       printer->Print(
393           variables_,
394           "if (java.lang.Double.doubleToLongBits(get$capitalized_name$())\n"
395           "    != java.lang.Double.doubleToLongBits(\n"
396           "        other.get$capitalized_name$())) return false;\n");
397       break;
398 
399     case JAVATYPE_STRING:
400     case JAVATYPE_BYTES:
401       printer->Print(
402           variables_,
403           "if (!get$capitalized_name$()\n"
404           "    .equals(other.get$capitalized_name$())) return false;\n");
405       break;
406 
407     case JAVATYPE_ENUM:
408     case JAVATYPE_MESSAGE:
409     default:
410       GOOGLE_LOG(FATAL) << "Can't get here.";
411       break;
412   }
413 }
414 
GenerateHashCode(io::Printer * printer) const415 void ImmutablePrimitiveFieldGenerator::GenerateHashCode(
416     io::Printer* printer) const {
417   printer->Print(variables_, "hash = (37 * hash) + $constant_name$;\n");
418   switch (GetJavaType(descriptor_)) {
419     case JAVATYPE_INT:
420       printer->Print(variables_,
421                      "hash = (53 * hash) + get$capitalized_name$();\n");
422       break;
423 
424     case JAVATYPE_LONG:
425       printer->Print(
426           variables_,
427           "hash = (53 * hash) + com.google.protobuf.Internal.hashLong(\n"
428           "    get$capitalized_name$());\n");
429       break;
430 
431     case JAVATYPE_BOOLEAN:
432       printer->Print(
433           variables_,
434           "hash = (53 * hash) + com.google.protobuf.Internal.hashBoolean(\n"
435           "    get$capitalized_name$());\n");
436       break;
437 
438     case JAVATYPE_FLOAT:
439       printer->Print(variables_,
440                      "hash = (53 * hash) + java.lang.Float.floatToIntBits(\n"
441                      "    get$capitalized_name$());\n");
442       break;
443 
444     case JAVATYPE_DOUBLE:
445       printer->Print(
446           variables_,
447           "hash = (53 * hash) + com.google.protobuf.Internal.hashLong(\n"
448           "    java.lang.Double.doubleToLongBits(get$capitalized_name$()));\n");
449       break;
450 
451     case JAVATYPE_STRING:
452     case JAVATYPE_BYTES:
453       printer->Print(
454           variables_,
455           "hash = (53 * hash) + get$capitalized_name$().hashCode();\n");
456       break;
457 
458     case JAVATYPE_ENUM:
459     case JAVATYPE_MESSAGE:
460     default:
461       GOOGLE_LOG(FATAL) << "Can't get here.";
462       break;
463   }
464 }
465 
GetBoxedType() const466 std::string ImmutablePrimitiveFieldGenerator::GetBoxedType() const {
467   return BoxedPrimitiveTypeName(GetJavaType(descriptor_));
468 }
469 
470 // ===================================================================
471 
ImmutablePrimitiveOneofFieldGenerator(const FieldDescriptor * descriptor,int messageBitIndex,int builderBitIndex,Context * context)472 ImmutablePrimitiveOneofFieldGenerator::ImmutablePrimitiveOneofFieldGenerator(
473     const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex,
474     Context* context)
475     : ImmutablePrimitiveFieldGenerator(descriptor, messageBitIndex,
476                                        builderBitIndex, context) {
477   const OneofGeneratorInfo* info =
478       context->GetOneofGeneratorInfo(descriptor->containing_oneof());
479   SetCommonOneofVariables(descriptor, info, &variables_);
480 }
481 
482 ImmutablePrimitiveOneofFieldGenerator::
~ImmutablePrimitiveOneofFieldGenerator()483     ~ImmutablePrimitiveOneofFieldGenerator() {}
484 
GenerateMembers(io::Printer * printer) const485 void ImmutablePrimitiveOneofFieldGenerator::GenerateMembers(
486     io::Printer* printer) const {
487   PrintExtraFieldInfo(variables_, printer);
488   if (SupportFieldPresence(descriptor_)) {
489     WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
490     printer->Print(
491         variables_,
492         "@java.lang.Override\n"
493         "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
494         "  return $has_oneof_case_message$;\n"
495         "}\n");
496     printer->Annotate("{", "}", descriptor_);
497   }
498 
499   WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
500   printer->Print(variables_,
501                  "@java.lang.Override\n"
502                  "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
503                  "  if ($has_oneof_case_message$) {\n"
504                  "    return ($boxed_type$) $oneof_name$_;\n"
505                  "  }\n"
506                  "  return $default$;\n"
507                  "}\n");
508   printer->Annotate("{", "}", descriptor_);
509 }
510 
GenerateBuilderMembers(io::Printer * printer) const511 void ImmutablePrimitiveOneofFieldGenerator::GenerateBuilderMembers(
512     io::Printer* printer) const {
513   if (SupportFieldPresence(descriptor_)) {
514     WriteFieldAccessorDocComment(printer, descriptor_, HAZZER);
515     printer->Print(
516         variables_,
517         "$deprecation$public boolean ${$has$capitalized_name$$}$() {\n"
518         "  return $has_oneof_case_message$;\n"
519         "}\n");
520     printer->Annotate("{", "}", descriptor_);
521   }
522 
523   WriteFieldAccessorDocComment(printer, descriptor_, GETTER);
524   printer->Print(variables_,
525                  "$deprecation$public $type$ ${$get$capitalized_name$$}$() {\n"
526                  "  if ($has_oneof_case_message$) {\n"
527                  "    return ($boxed_type$) $oneof_name$_;\n"
528                  "  }\n"
529                  "  return $default$;\n"
530                  "}\n");
531   printer->Annotate("{", "}", descriptor_);
532 
533   WriteFieldAccessorDocComment(printer, descriptor_, SETTER,
534                                /* builder */ true);
535   printer->Print(variables_,
536                  "$deprecation$public Builder "
537                  "${$set$capitalized_name$$}$($type$ value) {\n"
538                  "$null_check$"
539                  "  $set_oneof_case_message$;\n"
540                  "  $oneof_name$_ = value;\n"
541                  "  $on_changed$\n"
542                  "  return this;\n"
543                  "}\n");
544   printer->Annotate("{", "}", descriptor_);
545 
546   WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
547                                /* builder */ true);
548   printer->Print(
549       variables_,
550       "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
551       "  if ($has_oneof_case_message$) {\n"
552       "    $clear_oneof_case_message$;\n"
553       "    $oneof_name$_ = null;\n"
554       "    $on_changed$\n"
555       "  }\n"
556       "  return this;\n"
557       "}\n");
558   printer->Annotate("{", "}", descriptor_);
559 }
560 
GenerateBuilderClearCode(io::Printer * printer) const561 void ImmutablePrimitiveOneofFieldGenerator::GenerateBuilderClearCode(
562     io::Printer* printer) const {
563   // No-Op: When a primitive field is in a oneof, clearing the oneof clears that
564   // field.
565 }
566 
GenerateBuildingCode(io::Printer * printer) const567 void ImmutablePrimitiveOneofFieldGenerator::GenerateBuildingCode(
568     io::Printer* printer) const {
569   printer->Print(variables_,
570                  "if ($has_oneof_case_message$) {\n"
571                  "  result.$oneof_name$_ = $oneof_name$_;\n"
572                  "}\n");
573 }
574 
GenerateMergingCode(io::Printer * printer) const575 void ImmutablePrimitiveOneofFieldGenerator::GenerateMergingCode(
576     io::Printer* printer) const {
577   printer->Print(variables_,
578                  "set$capitalized_name$(other.get$capitalized_name$());\n");
579 }
580 
GenerateBuilderParsingCode(io::Printer * printer) const581 void ImmutablePrimitiveOneofFieldGenerator::GenerateBuilderParsingCode(
582     io::Printer* printer) const {
583   printer->Print(variables_,
584                  "$set_oneof_case_message$;\n"
585                  "$oneof_name$_ = input.read$capitalized_type$();\n");
586 }
587 
GenerateSerializationCode(io::Printer * printer) const588 void ImmutablePrimitiveOneofFieldGenerator::GenerateSerializationCode(
589     io::Printer* printer) const {
590   printer->Print(variables_,
591                  "if ($has_oneof_case_message$) {\n"
592                  "  output.write$capitalized_type$(\n");
593   // $type$ and $boxed_type$ is the same for bytes fields so we don't need to
594   // do redundant casts.
595   if (GetJavaType(descriptor_) == JAVATYPE_BYTES) {
596     printer->Print(variables_, "      $number$, ($type$) $oneof_name$_);\n");
597   } else {
598     printer->Print(
599         variables_,
600         "      $number$, ($type$)(($boxed_type$) $oneof_name$_));\n");
601   }
602   printer->Print("}\n");
603 }
604 
GenerateSerializedSizeCode(io::Printer * printer) const605 void ImmutablePrimitiveOneofFieldGenerator::GenerateSerializedSizeCode(
606     io::Printer* printer) const {
607   printer->Print(variables_,
608                  "if ($has_oneof_case_message$) {\n"
609                  "  size += com.google.protobuf.CodedOutputStream\n"
610                  "    .compute$capitalized_type$Size(\n");
611   // $type$ and $boxed_type$ is the same for bytes fields so we don't need to
612   // do redundant casts.
613   if (GetJavaType(descriptor_) == JAVATYPE_BYTES) {
614     printer->Print(variables_, "        $number$, ($type$) $oneof_name$_);\n");
615   } else {
616     printer->Print(
617         variables_,
618         "        $number$, ($type$)(($boxed_type$) $oneof_name$_));\n");
619   }
620   printer->Print("}\n");
621 }
622 
623 // ===================================================================
624 
625 RepeatedImmutablePrimitiveFieldGenerator::
RepeatedImmutablePrimitiveFieldGenerator(const FieldDescriptor * descriptor,int messageBitIndex,int builderBitIndex,Context * context)626     RepeatedImmutablePrimitiveFieldGenerator(const FieldDescriptor* descriptor,
627                                              int messageBitIndex,
628                                              int builderBitIndex,
629                                              Context* context)
630     : descriptor_(descriptor), name_resolver_(context->GetNameResolver()) {
631   SetPrimitiveVariables(descriptor, messageBitIndex, builderBitIndex,
632                         context->GetFieldGeneratorInfo(descriptor),
633                         name_resolver_, &variables_);
634 }
635 
636 RepeatedImmutablePrimitiveFieldGenerator::
~RepeatedImmutablePrimitiveFieldGenerator()637     ~RepeatedImmutablePrimitiveFieldGenerator() {}
638 
GetNumBitsForMessage() const639 int RepeatedImmutablePrimitiveFieldGenerator::GetNumBitsForMessage() const {
640   return 0;
641 }
642 
GetNumBitsForBuilder() const643 int RepeatedImmutablePrimitiveFieldGenerator::GetNumBitsForBuilder() const {
644   return 1;
645 }
646 
GenerateInterfaceMembers(io::Printer * printer) const647 void RepeatedImmutablePrimitiveFieldGenerator::GenerateInterfaceMembers(
648     io::Printer* printer) const {
649   WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER);
650   printer->Print(variables_,
651                  "$deprecation$java.util.List<$boxed_type$> "
652                  "get$capitalized_name$List();\n");
653   WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT);
654   printer->Print(variables_,
655                  "$deprecation$int get$capitalized_name$Count();\n");
656   WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER);
657   printer->Print(variables_,
658                  "$deprecation$$type$ get$capitalized_name$(int index);\n");
659 }
660 
GenerateMembers(io::Printer * printer) const661 void RepeatedImmutablePrimitiveFieldGenerator::GenerateMembers(
662     io::Printer* printer) const {
663   printer->Print(variables_, "private $field_list_type$ $name$_;\n");
664   PrintExtraFieldInfo(variables_, printer);
665   WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER);
666   printer->Print(variables_,
667                  "@java.lang.Override\n"
668                  "$deprecation$public java.util.List<$boxed_type$>\n"
669                  "    ${$get$capitalized_name$List$}$() {\n"
670                  "  return $name$_;\n"  // note:  unmodifiable list
671                  "}\n");
672   printer->Annotate("{", "}", descriptor_);
673   WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT);
674   printer->Print(
675       variables_,
676       "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
677       "  return $name$_.size();\n"
678       "}\n");
679   printer->Annotate("{", "}", descriptor_);
680   WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER);
681   printer->Print(
682       variables_,
683       "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n"
684       "  return $repeated_get$(index);\n"
685       "}\n");
686   printer->Annotate("{", "}", descriptor_);
687 
688   if (descriptor_->is_packed()) {
689     printer->Print(variables_,
690                    "private int $name$MemoizedSerializedSize = -1;\n");
691   }
692 }
693 
GenerateBuilderMembers(io::Printer * printer) const694 void RepeatedImmutablePrimitiveFieldGenerator::GenerateBuilderMembers(
695     io::Printer* printer) const {
696   // One field is the list and the bit field keeps track of whether the
697   // list is immutable. If it's immutable, the invariant is that it must
698   // either an instance of Collections.emptyList() or it's an ArrayList
699   // wrapped in a Collections.unmodifiableList() wrapper and nobody else has
700   // a reference to the underlying ArrayList. This invariant allows us to
701   // share instances of lists between protocol buffers avoiding expensive
702   // memory allocations. Note, immutable is a strong guarantee here -- not
703   // just that the list cannot be modified via the reference but that the
704   // list can never be modified.
705   printer->Print(variables_,
706                  "private $field_list_type$ $name$_ = $empty_list$;\n");
707 
708   printer->Print(variables_,
709                  "private void ensure$capitalized_name$IsMutable() {\n"
710                  "  if (!$get_mutable_bit_builder$) {\n"
711                  "    $name$_ = $mutable_copy_list$;\n"
712                  "    $set_mutable_bit_builder$;\n"
713                  "   }\n"
714                  "}\n");
715 
716   // Note:  We return an unmodifiable list because otherwise the caller
717   //   could hold on to the returned list and modify it after the message
718   //   has been built, thus mutating the message which is supposed to be
719   //   immutable.
720   WriteFieldAccessorDocComment(printer, descriptor_, LIST_GETTER);
721   printer->Print(
722       variables_,
723       "$deprecation$public java.util.List<$boxed_type$>\n"
724       "    ${$get$capitalized_name$List$}$() {\n"
725       "  return $get_mutable_bit_builder$ ?\n"
726       "           java.util.Collections.unmodifiableList($name$_) : $name$_;\n"
727       "}\n");
728   printer->Annotate("{", "}", descriptor_);
729   WriteFieldAccessorDocComment(printer, descriptor_, LIST_COUNT);
730   printer->Print(
731       variables_,
732       "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
733       "  return $name$_.size();\n"
734       "}\n");
735   printer->Annotate("{", "}", descriptor_);
736   WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_GETTER);
737   printer->Print(
738       variables_,
739       "$deprecation$public $type$ ${$get$capitalized_name$$}$(int index) {\n"
740       "  return $repeated_get$(index);\n"
741       "}\n");
742   printer->Annotate("{", "}", descriptor_);
743   WriteFieldAccessorDocComment(printer, descriptor_, LIST_INDEXED_SETTER,
744                                /* builder */ true);
745   printer->Print(variables_,
746                  "$deprecation$public Builder ${$set$capitalized_name$$}$(\n"
747                  "    int index, $type$ value) {\n"
748                  "$null_check$"
749                  "  ensure$capitalized_name$IsMutable();\n"
750                  "  $repeated_set$(index, value);\n"
751                  "  $on_changed$\n"
752                  "  return this;\n"
753                  "}\n");
754   printer->Annotate("{", "}", descriptor_);
755   WriteFieldAccessorDocComment(printer, descriptor_, LIST_ADDER,
756                                /* builder */ true);
757   printer->Print(variables_,
758                  "$deprecation$public Builder "
759                  "${$add$capitalized_name$$}$($type$ value) {\n"
760                  "$null_check$"
761                  "  ensure$capitalized_name$IsMutable();\n"
762                  "  $repeated_add$(value);\n"
763                  "  $on_changed$\n"
764                  "  return this;\n"
765                  "}\n");
766   printer->Annotate("{", "}", descriptor_);
767   WriteFieldAccessorDocComment(printer, descriptor_, LIST_MULTI_ADDER,
768                                /* builder */ true);
769   printer->Print(variables_,
770                  "$deprecation$public Builder ${$addAll$capitalized_name$$}$(\n"
771                  "    java.lang.Iterable<? extends $boxed_type$> values) {\n"
772                  "  ensure$capitalized_name$IsMutable();\n"
773                  "  com.google.protobuf.AbstractMessageLite.Builder.addAll(\n"
774                  "      values, $name$_);\n"
775                  "  $on_changed$\n"
776                  "  return this;\n"
777                  "}\n");
778   printer->Annotate("{", "}", descriptor_);
779   WriteFieldAccessorDocComment(printer, descriptor_, CLEARER,
780                                /* builder */ true);
781   printer->Print(
782       variables_,
783       "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
784       "  $name$_ = $empty_list$;\n"
785       "  $clear_mutable_bit_builder$;\n"
786       "  $on_changed$\n"
787       "  return this;\n"
788       "}\n");
789   printer->Annotate("{", "}", descriptor_);
790 }
791 
792 void RepeatedImmutablePrimitiveFieldGenerator::
GenerateFieldBuilderInitializationCode(io::Printer * printer) const793     GenerateFieldBuilderInitializationCode(io::Printer* printer) const {
794   // noop for primitives
795 }
796 
GenerateInitializationCode(io::Printer * printer) const797 void RepeatedImmutablePrimitiveFieldGenerator::GenerateInitializationCode(
798     io::Printer* printer) const {
799   printer->Print(variables_, "$name$_ = $empty_list$;\n");
800 }
801 
GenerateBuilderClearCode(io::Printer * printer) const802 void RepeatedImmutablePrimitiveFieldGenerator::GenerateBuilderClearCode(
803     io::Printer* printer) const {
804   printer->Print(variables_,
805                  "$name$_ = $empty_list$;\n"
806                  "$clear_mutable_bit_builder$;\n");
807 }
808 
GenerateMergingCode(io::Printer * printer) const809 void RepeatedImmutablePrimitiveFieldGenerator::GenerateMergingCode(
810     io::Printer* printer) const {
811   // The code below does two optimizations:
812   //   1. If the other list is empty, there's nothing to do. This ensures we
813   //      don't allocate a new array if we already have an immutable one.
814   //   2. If the other list is non-empty and our current list is empty, we can
815   //      reuse the other list which is guaranteed to be immutable.
816   printer->Print(variables_,
817                  "if (!other.$name$_.isEmpty()) {\n"
818                  "  if ($name$_.isEmpty()) {\n"
819                  "    $name$_ = other.$name$_;\n"
820                  "    $clear_mutable_bit_builder$;\n"
821                  "  } else {\n"
822                  "    ensure$capitalized_name$IsMutable();\n"
823                  "    $name$_.addAll(other.$name$_);\n"
824                  "  }\n"
825                  "  $on_changed$\n"
826                  "}\n");
827 }
828 
GenerateBuildingCode(io::Printer * printer) const829 void RepeatedImmutablePrimitiveFieldGenerator::GenerateBuildingCode(
830     io::Printer* printer) const {
831   // The code below ensures that the result has an immutable list. If our
832   // list is immutable, we can just reuse it. If not, we make it immutable.
833   printer->Print(variables_,
834                  "if ($get_mutable_bit_builder$) {\n"
835                  "  $name_make_immutable$;\n"
836                  "  $clear_mutable_bit_builder$;\n"
837                  "}\n"
838                  "result.$name$_ = $name$_;\n");
839 }
840 
GenerateBuilderParsingCode(io::Printer * printer) const841 void RepeatedImmutablePrimitiveFieldGenerator::GenerateBuilderParsingCode(
842     io::Printer* printer) const {
843   printer->Print(variables_,
844                  "$type$ v = input.read$capitalized_type$();\n"
845                  "ensure$capitalized_name$IsMutable();\n"
846                  "$repeated_add$(v);\n");
847 }
848 
849 void RepeatedImmutablePrimitiveFieldGenerator::
GenerateBuilderParsingCodeFromPacked(io::Printer * printer) const850     GenerateBuilderParsingCodeFromPacked(io::Printer* printer) const {
851   printer->Print(variables_,
852                  "int length = input.readRawVarint32();\n"
853                  "int limit = input.pushLimit(length);\n"
854                  "ensure$capitalized_name$IsMutable();\n"
855                  "while (input.getBytesUntilLimit() > 0) {\n"
856                  "  $repeated_add$(input.read$capitalized_type$());\n"
857                  "}\n"
858                  "input.popLimit(limit);\n");
859 }
860 
GenerateSerializationCode(io::Printer * printer) const861 void RepeatedImmutablePrimitiveFieldGenerator::GenerateSerializationCode(
862     io::Printer* printer) const {
863   if (descriptor_->is_packed()) {
864     // We invoke getSerializedSize in writeTo for messages that have packed
865     // fields in ImmutableMessageGenerator::GenerateMessageSerializationMethods.
866     // That makes it safe to rely on the memoized size here.
867     printer->Print(variables_,
868                    "if (get$capitalized_name$List().size() > 0) {\n"
869                    "  output.writeUInt32NoTag($tag$);\n"
870                    "  output.writeUInt32NoTag($name$MemoizedSerializedSize);\n"
871                    "}\n"
872                    "for (int i = 0; i < $name$_.size(); i++) {\n"
873                    "  output.write$capitalized_type$NoTag($repeated_get$(i));\n"
874                    "}\n");
875   } else {
876     printer->Print(
877         variables_,
878         "for (int i = 0; i < $name$_.size(); i++) {\n"
879         "  output.write$capitalized_type$($number$, $repeated_get$(i));\n"
880         "}\n");
881   }
882 }
883 
GenerateSerializedSizeCode(io::Printer * printer) const884 void RepeatedImmutablePrimitiveFieldGenerator::GenerateSerializedSizeCode(
885     io::Printer* printer) const {
886   printer->Print(variables_,
887                  "{\n"
888                  "  int dataSize = 0;\n");
889   printer->Indent();
890 
891   if (FixedSize(GetType(descriptor_)) == -1) {
892     printer->Print(
893         variables_,
894         "for (int i = 0; i < $name$_.size(); i++) {\n"
895         "  dataSize += com.google.protobuf.CodedOutputStream\n"
896         "    .compute$capitalized_type$SizeNoTag($repeated_get$(i));\n"
897         "}\n");
898   } else {
899     printer->Print(
900         variables_,
901         "dataSize = $fixed_size$ * get$capitalized_name$List().size();\n");
902   }
903 
904   printer->Print("size += dataSize;\n");
905 
906   if (descriptor_->is_packed()) {
907     printer->Print(variables_,
908                    "if (!get$capitalized_name$List().isEmpty()) {\n"
909                    "  size += $tag_size$;\n"
910                    "  size += com.google.protobuf.CodedOutputStream\n"
911                    "      .computeInt32SizeNoTag(dataSize);\n"
912                    "}\n");
913   } else {
914     printer->Print(
915         variables_,
916         "size += $tag_size$ * get$capitalized_name$List().size();\n");
917   }
918 
919   // cache the data size for packed fields.
920   if (descriptor_->is_packed()) {
921     printer->Print(variables_, "$name$MemoizedSerializedSize = dataSize;\n");
922   }
923 
924   printer->Outdent();
925   printer->Print("}\n");
926 }
927 
GenerateEqualsCode(io::Printer * printer) const928 void RepeatedImmutablePrimitiveFieldGenerator::GenerateEqualsCode(
929     io::Printer* printer) const {
930   printer->Print(
931       variables_,
932       "if (!get$capitalized_name$List()\n"
933       "    .equals(other.get$capitalized_name$List())) return false;\n");
934 }
935 
GenerateHashCode(io::Printer * printer) const936 void RepeatedImmutablePrimitiveFieldGenerator::GenerateHashCode(
937     io::Printer* printer) const {
938   printer->Print(
939       variables_,
940       "if (get$capitalized_name$Count() > 0) {\n"
941       "  hash = (37 * hash) + $constant_name$;\n"
942       "  hash = (53 * hash) + get$capitalized_name$List().hashCode();\n"
943       "}\n");
944 }
945 
GetBoxedType() const946 std::string RepeatedImmutablePrimitiveFieldGenerator::GetBoxedType() const {
947   return BoxedPrimitiveTypeName(GetJavaType(descriptor_));
948 }
949 
950 }  // namespace java
951 }  // namespace compiler
952 }  // namespace protobuf
953 }  // namespace google
954