• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.  All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file or at
6 // https://developers.google.com/open-source/licenses/bsd
7 
8 #include "google/protobuf/compiler/java/full/map_field.h"
9 
10 #include <string>
11 
12 #include "absl/strings/str_cat.h"
13 #include "absl/strings/str_join.h"
14 #include "google/protobuf/compiler/java/context.h"
15 #include "google/protobuf/compiler/java/doc_comment.h"
16 #include "google/protobuf/compiler/java/field_common.h"
17 #include "google/protobuf/compiler/java/helpers.h"
18 #include "google/protobuf/compiler/java/internal_helpers.h"
19 #include "google/protobuf/compiler/java/name_resolver.h"
20 #include "google/protobuf/io/printer.h"
21 
22 // Must be last.
23 #include "google/protobuf/port_def.inc"
24 
25 namespace google {
26 namespace protobuf {
27 namespace compiler {
28 namespace java {
29 
30 namespace {
31 using Semantic = ::google::protobuf::io::AnnotationCollector::Semantic;
32 
TypeName(const FieldDescriptor * field,ClassNameResolver * name_resolver,bool boxed)33 std::string TypeName(const FieldDescriptor* field,
34                      ClassNameResolver* name_resolver, bool boxed) {
35   if (GetJavaType(field) == JAVATYPE_MESSAGE) {
36     return name_resolver->GetImmutableClassName(field->message_type());
37   } else if (GetJavaType(field) == JAVATYPE_ENUM) {
38     return name_resolver->GetImmutableClassName(field->enum_type());
39   } else {
40     return std::string(boxed ? BoxedPrimitiveTypeName(GetJavaType(field))
41                              : PrimitiveTypeName(GetJavaType(field)));
42   }
43 }
44 
KotlinTypeName(const FieldDescriptor * field,ClassNameResolver * name_resolver)45 std::string KotlinTypeName(const FieldDescriptor* field,
46                            ClassNameResolver* name_resolver) {
47   if (GetJavaType(field) == JAVATYPE_MESSAGE) {
48     return name_resolver->GetImmutableClassName(field->message_type());
49   } else if (GetJavaType(field) == JAVATYPE_ENUM) {
50     return name_resolver->GetImmutableClassName(field->enum_type());
51   } else {
52     return std::string(KotlinTypeName(GetJavaType(field)));
53   }
54 }
55 
WireType(const FieldDescriptor * field)56 std::string WireType(const FieldDescriptor* field) {
57   return absl::StrCat("com.google.protobuf.WireFormat.FieldType.",
58                       FieldTypeName(field->type()));
59 }
60 
61 }  // namespace
62 
ImmutableMapFieldGenerator(const FieldDescriptor * descriptor,int messageBitIndex,int builderBitIndex,Context * context)63 ImmutableMapFieldGenerator::ImmutableMapFieldGenerator(
64     const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex,
65     Context* context)
66     : descriptor_(descriptor),
67       message_bit_index_(messageBitIndex),
68       builder_bit_index_(builderBitIndex),
69       name_resolver_(context->GetNameResolver()),
70       context_(context) {
71   SetMessageVariables(context->GetFieldGeneratorInfo(descriptor));
72 }
73 
SetMessageVariables(const FieldGeneratorInfo * info)74 void ImmutableMapFieldGenerator::SetMessageVariables(
75     const FieldGeneratorInfo* info) {
76   SetCommonFieldVariables(descriptor_, info, &variables_);
77   ClassNameResolver* name_resolver = context_->GetNameResolver();
78 
79   variables_["type"] =
80       name_resolver->GetImmutableClassName(descriptor_->message_type());
81   const FieldDescriptor* key = MapKeyField(descriptor_);
82   const FieldDescriptor* value = MapValueField(descriptor_);
83   const JavaType keyJavaType = GetJavaType(key);
84   const JavaType valueJavaType = GetJavaType(value);
85 
86   // The code that generates the open-source version appears not to understand
87   // #else, so we have an #ifndef instead.
88   std::string pass_through_nullness =
89       context_->options().opensource_runtime
90           ? "/* nullable */\n"
91           : "@com.google.protobuf.Internal.ProtoPassThroughNullness ";
92 
93   variables_["key_type"] = TypeName(key, name_resolver, false);
94   std::string boxed_key_type = TypeName(key, name_resolver, true);
95   variables_["boxed_key_type"] = boxed_key_type;
96   variables_["kt_key_type"] = KotlinTypeName(key, name_resolver);
97   variables_["kt_value_type"] = KotlinTypeName(value, name_resolver);
98   // Used for calling the serialization function.
99   variables_["short_key_type"] =
100       boxed_key_type.substr(boxed_key_type.rfind('.') + 1);
101   variables_["key_wire_type"] = WireType(key);
102   variables_["key_default_value"] =
103       DefaultValue(key, true, name_resolver, context_->options());
104   variables_["key_null_check"] =
105       IsReferenceType(keyJavaType)
106           ? "if (key == null) { throw new NullPointerException(\"map key\"); }"
107           : "";
108   variables_["value_null_check"] =
109       valueJavaType != JAVATYPE_ENUM && IsReferenceType(valueJavaType)
110           ? "if (value == null) { "
111             "throw new NullPointerException(\"map value\"); }"
112           : "";
113   if (valueJavaType == JAVATYPE_ENUM) {
114     // We store enums as Integers internally.
115     variables_["value_type"] = "int";
116     variables_.insert(
117         {"value_type_pass_through_nullness", variables_["value_type"]});
118     variables_["boxed_value_type"] = "java.lang.Integer";
119     variables_["value_wire_type"] = WireType(value);
120     variables_["value_default_value"] =
121         DefaultValue(value, true, name_resolver, context_->options()) +
122         ".getNumber()";
123 
124     variables_["value_enum_type"] = TypeName(value, name_resolver, false);
125 
126     variables_.insert(
127         {"value_enum_type_pass_through_nullness",
128          absl::StrCat(pass_through_nullness, variables_["value_enum_type"])});
129 
130     if (SupportUnknownEnumValue(value)) {
131       // Map unknown values to a special UNRECOGNIZED value if supported.
132       variables_.insert(
133           {"unrecognized_value",
134            absl::StrCat(variables_["value_enum_type"], ".UNRECOGNIZED")});
135     } else {
136       // Map unknown values to the default value if we don't have UNRECOGNIZED.
137       variables_["unrecognized_value"] =
138           DefaultValue(value, true, name_resolver, context_->options());
139     }
140   } else {
141     variables_["value_type"] = TypeName(value, name_resolver, false);
142 
143     variables_.insert(
144         {"value_type_pass_through_nullness",
145          absl::StrCat(
146              (IsReferenceType(valueJavaType) ? pass_through_nullness : ""),
147              variables_["value_type"])});
148 
149     variables_["boxed_value_type"] = TypeName(value, name_resolver, true);
150     variables_["value_wire_type"] = WireType(value);
151     variables_["value_default_value"] =
152         DefaultValue(value, true, name_resolver, context_->options());
153   }
154 
155   variables_.insert(
156       {"type_parameters", absl::StrCat(variables_["boxed_key_type"], ", ",
157                                        variables_["boxed_value_type"])});
158 
159   if (valueJavaType == JAVATYPE_MESSAGE) {
160     variables_["value_interface_type"] =
161         absl::StrCat(variables_["boxed_value_type"], "OrBuilder");
162     variables_["value_builder_type"] =
163         absl::StrCat(variables_["boxed_value_type"], ".Builder");
164     variables_["builder_type_parameters"] = absl::StrJoin(
165         {variables_["boxed_key_type"], variables_["value_interface_type"],
166          variables_["boxed_value_type"], variables_["value_builder_type"]},
167         ", ");
168   }
169   // TODO: Add @deprecated javadoc when generating javadoc is supported
170   // by the proto compiler
171   variables_["deprecation"] =
172       descriptor_->options().deprecated() ? "@java.lang.Deprecated " : "";
173   variables_.insert(
174       {"kt_deprecation",
175        descriptor_->options().deprecated()
176            ? absl::StrCat("@kotlin.Deprecated(message = \"Field ",
177                           variables_["name"], " is deprecated\") ")
178            : ""});
179   variables_["on_changed"] = "onChanged();";
180 
181   variables_.insert(
182       {"default_entry", absl::StrCat(variables_["capitalized_name"],
183                                      "DefaultEntryHolder.defaultEntry")});
184   variables_.insert({"map_field_parameter", variables_["default_entry"]});
185   variables_["descriptor"] = absl::StrCat(
186       name_resolver->GetImmutableClassName(descriptor_->file()), ".internal_",
187       UniqueFileScopeIdentifier(descriptor_->message_type()), "_descriptor, ");
188   variables_["get_has_field_bit_builder"] = GenerateGetBit(builder_bit_index_);
189   variables_["get_has_field_bit_from_local"] =
190       GenerateGetBitFromLocal(builder_bit_index_);
191   variables_["set_has_field_bit_builder"] =
192       absl::StrCat(GenerateSetBit(builder_bit_index_), ";");
193   variables_["clear_has_field_bit_builder"] =
194       absl::StrCat(GenerateClearBit(builder_bit_index_), ";");
195 }
196 
GetMessageBitIndex() const197 int ImmutableMapFieldGenerator::GetMessageBitIndex() const {
198   return message_bit_index_;
199 }
200 
GetBuilderBitIndex() const201 int ImmutableMapFieldGenerator::GetBuilderBitIndex() const {
202   return builder_bit_index_;
203 }
204 
GetNumBitsForMessage() const205 int ImmutableMapFieldGenerator::GetNumBitsForMessage() const { return 0; }
206 
GetNumBitsForBuilder() const207 int ImmutableMapFieldGenerator::GetNumBitsForBuilder() const { return 1; }
208 
GenerateInterfaceMembers(io::Printer * printer) const209 void ImmutableMapFieldGenerator::GenerateInterfaceMembers(
210     io::Printer* printer) const {
211   WriteFieldDocComment(printer, descriptor_, context_->options());
212   printer->Print(variables_,
213                  "$deprecation$int ${$get$capitalized_name$Count$}$();\n");
214   printer->Annotate("{", "}", descriptor_);
215   WriteFieldDocComment(printer, descriptor_, context_->options());
216   printer->Print(variables_,
217                  "$deprecation$boolean ${$contains$capitalized_name$$}$(\n"
218                  "    $key_type$ key);\n");
219   printer->Annotate("{", "}", descriptor_);
220 
221   const FieldDescriptor* value = MapValueField(descriptor_);
222   if (GetJavaType(value) == JAVATYPE_ENUM) {
223     if (context_->options().opensource_runtime) {
224       printer->Print(variables_,
225                      "/**\n"
226                      " * Use {@link #get$capitalized_name$Map()} instead.\n"
227                      " */\n"
228                      "@java.lang.Deprecated\n"
229                      "java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
230                      "${$get$capitalized_name$$}$();\n");
231       printer->Annotate("{", "}", descriptor_);
232     }
233     WriteFieldDocComment(printer, descriptor_, context_->options());
234     printer->Print(
235         variables_,
236         "$deprecation$java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
237         "${$get$capitalized_name$Map$}$();\n");
238     printer->Annotate("{", "}", descriptor_);
239     WriteFieldDocComment(printer, descriptor_, context_->options());
240     printer->Print(variables_,
241                    "$deprecation$$value_enum_type_pass_through_nullness$ "
242                    "${$get$capitalized_name$OrDefault$}$(\n"
243                    "    $key_type$ key,\n"
244                    "    $value_enum_type_pass_through_nullness$ "
245                    "        defaultValue);\n");
246     printer->Annotate("{", "}", descriptor_);
247     WriteFieldDocComment(printer, descriptor_, context_->options());
248     printer->Print(
249         variables_,
250         "$deprecation$$value_enum_type$ ${$get$capitalized_name$OrThrow$}$(\n"
251         "    $key_type$ key);\n");
252     printer->Annotate("{", "}", descriptor_);
253     if (SupportUnknownEnumValue(value)) {
254       printer->Print(
255           variables_,
256           "/**\n"
257           " * Use {@link #get$capitalized_name$ValueMap()} instead.\n"
258           " */\n"
259           "@java.lang.Deprecated\n"
260           "java.util.Map<$type_parameters$>\n"
261           "${$get$capitalized_name$Value$}$();\n");
262       printer->Annotate("{", "}", descriptor_);
263       WriteFieldDocComment(printer, descriptor_, context_->options());
264       printer->Print(variables_,
265                      "$deprecation$java.util.Map<$type_parameters$>\n"
266                      "${$get$capitalized_name$ValueMap$}$();\n");
267       printer->Annotate("{", "}", descriptor_);
268       WriteFieldDocComment(printer, descriptor_, context_->options());
269       printer->Print(variables_,
270                      "$deprecation$$value_type_pass_through_nullness$ "
271                      "${$get$capitalized_name$ValueOrDefault$}$(\n"
272                      "    $key_type$ key,\n"
273                      "    $value_type_pass_through_nullness$ defaultValue);\n");
274       printer->Annotate("{", "}", descriptor_);
275       WriteFieldDocComment(printer, descriptor_, context_->options());
276       printer->Print(
277           variables_,
278           "$deprecation$$value_type$ ${$get$capitalized_name$ValueOrThrow$}$(\n"
279           "    $key_type$ key);\n");
280       printer->Annotate("{", "}", descriptor_);
281     }
282   } else {
283     if (context_->options().opensource_runtime) {
284       printer->Print(variables_,
285                      "/**\n"
286                      " * Use {@link #get$capitalized_name$Map()} instead.\n"
287                      " */\n"
288                      "@java.lang.Deprecated\n"
289                      "java.util.Map<$type_parameters$>\n"
290                      "${$get$capitalized_name$$}$();\n");
291       printer->Annotate("{", "}", descriptor_);
292     }
293     WriteFieldDocComment(printer, descriptor_, context_->options());
294     printer->Print(variables_,
295                    "$deprecation$java.util.Map<$type_parameters$>\n"
296                    "${$get$capitalized_name$Map$}$();\n");
297     printer->Annotate("{", "}", descriptor_);
298     WriteFieldDocComment(printer, descriptor_, context_->options());
299     printer->Print(variables_,
300                    "$deprecation$$value_type_pass_through_nullness$ "
301                    "${$get$capitalized_name$OrDefault$}$(\n"
302                    "    $key_type$ key,\n"
303                    "    $value_type_pass_through_nullness$ defaultValue);\n");
304     printer->Annotate("{", "}", descriptor_);
305     WriteFieldDocComment(printer, descriptor_, context_->options());
306     printer->Print(
307         variables_,
308         "$deprecation$$value_type$ ${$get$capitalized_name$OrThrow$}$(\n"
309         "    $key_type$ key);\n");
310     printer->Annotate("{", "}", descriptor_);
311   }
312 }
313 
GenerateMembers(io::Printer * printer) const314 void ImmutableMapFieldGenerator::GenerateMembers(io::Printer* printer) const {
315   printer->Print(
316       variables_,
317       "private static final class $capitalized_name$DefaultEntryHolder {\n"
318       "  static final com.google.protobuf.MapEntry<\n"
319       "      $type_parameters$> defaultEntry =\n"
320       "          com.google.protobuf.MapEntry\n"
321       "          .<$type_parameters$>newDefaultInstance(\n"
322       "              $descriptor$\n"
323       "              $key_wire_type$,\n"
324       "              $key_default_value$,\n"
325       "              $value_wire_type$,\n"
326       "              $value_default_value$);\n"
327       "}\n");
328   printer->Print(variables_,
329                  "@SuppressWarnings(\"serial\")\n"
330                  "private com.google.protobuf.MapField<\n"
331                  "    $type_parameters$> $name$_;\n"
332                  "private com.google.protobuf.MapField<$type_parameters$>\n"
333                  "internalGet$capitalized_name$() {\n"
334                  "  if ($name$_ == null) {\n"
335                  "    return com.google.protobuf.MapField.emptyMapField(\n"
336                  "        $map_field_parameter$);\n"
337                  "  }\n"
338                  "  return $name$_;\n"
339                  "}\n");
340   if (GetJavaType(MapValueField(descriptor_)) == JAVATYPE_ENUM) {
341     printer->Print(
342         variables_,
343         "private static final\n"
344         "com.google.protobuf.Internal.MapAdapter.Converter<\n"
345         "    java.lang.Integer, $value_enum_type$> $name$ValueConverter =\n"
346         "        com.google.protobuf.Internal.MapAdapter.newEnumConverter(\n"
347         "            $value_enum_type$.internalGetValueMap(),\n"
348         "            $unrecognized_value$);\n");
349     printer->Print(
350         variables_,
351         "private static final java.util.Map<$boxed_key_type$, "
352         "$value_enum_type$>\n"
353         "internalGetAdapted$capitalized_name$Map(\n"
354         "    java.util.Map<$boxed_key_type$, $boxed_value_type$> map) {\n"
355         "  return new com.google.protobuf.Internal.MapAdapter<\n"
356         "      $boxed_key_type$, $value_enum_type$, java.lang.Integer>(\n"
357         "          map, $name$ValueConverter);\n"
358         "}\n");
359   }
360   GenerateMapGetters(printer);
361 }
362 
GenerateBuilderMembers(io::Printer * printer) const363 void ImmutableMapFieldGenerator::GenerateBuilderMembers(
364     io::Printer* printer) const {
365   if (GetJavaType(MapValueField(descriptor_)) == JAVATYPE_MESSAGE) {
366     return GenerateMessageMapBuilderMembers(printer);
367   }
368   printer->Print(
369       variables_,
370       "private com.google.protobuf.MapField<\n"
371       "    $type_parameters$> $name$_;\n"
372       "$deprecation$private com.google.protobuf.MapField<$type_parameters$>\n"
373       "    internalGet$capitalized_name$() {\n"
374       "  if ($name$_ == null) {\n"
375       "    return com.google.protobuf.MapField.emptyMapField(\n"
376       "        $map_field_parameter$);\n"
377       "  }\n"
378       "  return $name$_;\n"
379       "}\n"
380       "$deprecation$private com.google.protobuf.MapField<$type_parameters$>\n"
381       "    internalGetMutable$capitalized_name$() {\n"
382       "  if ($name$_ == null) {\n"
383       "    $name$_ = com.google.protobuf.MapField.newMapField(\n"
384       "        $map_field_parameter$);\n"
385       "  }\n"
386       "  if (!$name$_.isMutable()) {\n"
387       "    $name$_ = $name$_.copy();\n"
388       "  }\n"
389       "  $set_has_field_bit_builder$\n"
390       "  $on_changed$\n"
391       "  return $name$_;\n"
392       "}\n");
393   GenerateMapGetters(printer);
394   printer->Print(
395       variables_,
396       "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
397       "  $clear_has_field_bit_builder$\n"
398       "  internalGetMutable$capitalized_name$().getMutableMap()\n"
399       "      .clear();\n"
400       "  return this;\n"
401       "}\n");
402   printer->Annotate("{", "}", descriptor_, Semantic::kSet);
403 
404   WriteFieldDocComment(printer, descriptor_, context_->options());
405   printer->Print(variables_,
406                  "$deprecation$public Builder ${$remove$capitalized_name$$}$(\n"
407                  "    $key_type$ key) {\n"
408                  "  $key_null_check$\n"
409                  "  internalGetMutable$capitalized_name$().getMutableMap()\n"
410                  "      .remove(key);\n"
411                  "  return this;\n"
412                  "}\n");
413   printer->Annotate("{", "}", descriptor_, Semantic::kSet);
414 
415   const FieldDescriptor* value = MapValueField(descriptor_);
416   if (GetJavaType(value) == JAVATYPE_ENUM) {
417     if (context_->options().opensource_runtime) {
418       printer->Print(
419           variables_,
420           "/**\n"
421           " * Use alternate mutation accessors instead.\n"
422           " */\n"
423           "@java.lang.Deprecated\n"
424           "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
425           "    ${$getMutable$capitalized_name$$}$() {\n"
426           "  $set_has_field_bit_builder$\n"
427           "  return internalGetAdapted$capitalized_name$Map(\n"
428           "       internalGetMutable$capitalized_name$().getMutableMap());\n"
429           "}\n");
430       printer->Annotate("{", "}", descriptor_);
431     }
432 
433     WriteFieldDocComment(printer, descriptor_, context_->options());
434     printer->Print(variables_,
435                    "$deprecation$public Builder ${$put$capitalized_name$$}$(\n"
436                    "    $key_type$ key,\n"
437                    "    $value_enum_type$ value) {\n"
438                    "  $key_null_check$\n"
439                    "  $value_null_check$\n"
440                    "  internalGetMutable$capitalized_name$().getMutableMap()\n"
441                    "      .put(key, $name$ValueConverter.doBackward(value));\n"
442                    "  $set_has_field_bit_builder$\n"
443                    "  return this;\n"
444                    "}\n");
445     printer->Annotate("{", "}", descriptor_, Semantic::kSet);
446 
447     WriteFieldDocComment(printer, descriptor_, context_->options());
448     printer->Print(
449         variables_,
450         "$deprecation$public Builder ${$putAll$capitalized_name$$}$(\n"
451         "    java.util.Map<$boxed_key_type$, $value_enum_type$> values) {\n"
452         "  internalGetAdapted$capitalized_name$Map(\n"
453         "      internalGetMutable$capitalized_name$().getMutableMap())\n"
454         "          .putAll(values);\n"
455         "  $set_has_field_bit_builder$\n"
456         "  return this;\n"
457         "}\n");
458     printer->Annotate("{", "}", descriptor_, Semantic::kSet);
459 
460     if (SupportUnknownEnumValue(value)) {
461       if (context_->options().opensource_runtime) {
462         printer->Print(
463             variables_,
464             "/**\n"
465             " * Use alternate mutation accessors instead.\n"
466             " */\n"
467             "@java.lang.Deprecated\n"
468             "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n"
469             "${$getMutable$capitalized_name$Value$}$() {\n"
470             "  $set_has_field_bit_builder$\n"
471             "  return internalGetMutable$capitalized_name$().getMutableMap();\n"
472             "}\n");
473         printer->Annotate("{", "}", descriptor_);
474       }
475 
476       WriteFieldDocComment(printer, descriptor_, context_->options());
477       printer->Print(
478           variables_,
479           "$deprecation$public Builder ${$put$capitalized_name$Value$}$(\n"
480           "    $key_type$ key,\n"
481           "    $value_type$ value) {\n"
482           "  $key_null_check$\n"
483           "  $value_null_check$\n"
484           "  internalGetMutable$capitalized_name$().getMutableMap()\n"
485           "      .put(key, value);\n"
486           "  $set_has_field_bit_builder$\n"
487           "  return this;\n"
488           "}\n");
489       printer->Annotate("{", "}", descriptor_, Semantic::kSet);
490 
491       WriteFieldDocComment(printer, descriptor_, context_->options());
492       printer->Print(
493           variables_,
494           "$deprecation$public Builder ${$putAll$capitalized_name$Value$}$(\n"
495           "    java.util.Map<$boxed_key_type$, $boxed_value_type$> values) {\n"
496           "  internalGetMutable$capitalized_name$().getMutableMap()\n"
497           "      .putAll(values);\n"
498           "  $set_has_field_bit_builder$\n"
499           "  return this;\n"
500           "}\n");
501       printer->Annotate("{", "}", descriptor_, Semantic::kSet);
502     }
503   } else {
504     if (context_->options().opensource_runtime) {
505       printer->Print(
506           variables_,
507           "/**\n"
508           " * Use alternate mutation accessors instead.\n"
509           " */\n"
510           "@java.lang.Deprecated\n"
511           "public java.util.Map<$type_parameters$>\n"
512           "    ${$getMutable$capitalized_name$$}$() {\n"
513           "  $set_has_field_bit_builder$\n"
514           "  return internalGetMutable$capitalized_name$().getMutableMap();\n"
515           "}\n");
516       printer->Annotate("{", "}", descriptor_);
517     }
518 
519     WriteFieldDocComment(printer, descriptor_, context_->options());
520     printer->Print(variables_,
521                    "$deprecation$public Builder ${$put$capitalized_name$$}$(\n"
522                    "    $key_type$ key,\n"
523                    "    $value_type$ value) {\n"
524                    "  $key_null_check$\n"
525                    "  $value_null_check$\n"
526                    "  internalGetMutable$capitalized_name$().getMutableMap()\n"
527                    "      .put(key, value);\n"
528                    "  $set_has_field_bit_builder$\n"
529                    "  return this;\n"
530                    "}\n");
531     printer->Annotate("{", "}", descriptor_, Semantic::kSet);
532 
533     WriteFieldDocComment(printer, descriptor_, context_->options());
534     printer->Print(
535         variables_,
536         "$deprecation$public Builder ${$putAll$capitalized_name$$}$(\n"
537         "    java.util.Map<$type_parameters$> values) {\n"
538         "  internalGetMutable$capitalized_name$().getMutableMap()\n"
539         "      .putAll(values);\n"
540         "  $set_has_field_bit_builder$\n"
541         "  return this;\n"
542         "}\n");
543     printer->Annotate("{", "}", descriptor_, Semantic::kSet);
544   }
545 }
546 
GenerateMapGetters(io::Printer * printer) const547 void ImmutableMapFieldGenerator::GenerateMapGetters(
548     io::Printer* printer) const {
549   printer->Print(
550       variables_,
551       "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
552       "  return internalGet$capitalized_name$().getMap().size();\n"
553       "}\n");
554   printer->Annotate("{", "}", descriptor_);
555 
556   WriteFieldDocComment(printer, descriptor_, context_->options());
557   printer->Print(
558       variables_,
559       "@java.lang.Override\n"
560       "$deprecation$public boolean ${$contains$capitalized_name$$}$(\n"
561       "    $key_type$ key) {\n"
562       "  $key_null_check$\n"
563       "  return internalGet$capitalized_name$().getMap().containsKey(key);\n"
564       "}\n");
565   printer->Annotate("{", "}", descriptor_);
566 
567   const FieldDescriptor* value = MapValueField(descriptor_);
568   if (GetJavaType(value) == JAVATYPE_ENUM) {
569     if (context_->options().opensource_runtime) {
570       printer->Print(
571           variables_,
572           "/**\n"
573           " * Use {@link #get$capitalized_name$Map()} instead.\n"
574           " */\n"
575           "@java.lang.Override\n"
576           "@java.lang.Deprecated\n"
577           "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
578           "${$get$capitalized_name$$}$() {\n"
579           "  return get$capitalized_name$Map();\n"
580           "}\n");
581       printer->Annotate("{", "}", descriptor_);
582     }
583 
584     WriteFieldDocComment(printer, descriptor_, context_->options());
585     printer->Print(variables_,
586                    "@java.lang.Override\n"
587                    "$deprecation$public java.util.Map<$boxed_key_type$, "
588                    "$value_enum_type$>\n"
589                    "${$get$capitalized_name$Map$}$() {\n"
590                    "  return internalGetAdapted$capitalized_name$Map(\n"
591                    "      internalGet$capitalized_name$().getMap());"
592                    "}\n");
593     printer->Annotate("{", "}", descriptor_);
594 
595     WriteFieldDocComment(printer, descriptor_, context_->options());
596     printer->Print(
597         variables_,
598         "@java.lang.Override\n"
599         "$deprecation$public $value_enum_type_pass_through_nullness$ "
600         "${$get$capitalized_name$OrDefault$}$(\n"
601         "    $key_type$ key,\n"
602         "    $value_enum_type_pass_through_nullness$ defaultValue) {\n"
603         "  $key_null_check$\n"
604         "  java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
605         "      internalGet$capitalized_name$().getMap();\n"
606         "  return map.containsKey(key)\n"
607         "         ? $name$ValueConverter.doForward(map.get(key))\n"
608         "         : defaultValue;\n"
609         "}\n");
610     printer->Annotate("{", "}", descriptor_);
611 
612     WriteFieldDocComment(printer, descriptor_, context_->options());
613     printer->Print(
614         variables_,
615         "@java.lang.Override\n"
616         "$deprecation$public $value_enum_type$ "
617         "${$get$capitalized_name$OrThrow$}$(\n"
618         "    $key_type$ key) {\n"
619         "  $key_null_check$\n"
620         "  java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
621         "      internalGet$capitalized_name$().getMap();\n"
622         "  if (!map.containsKey(key)) {\n"
623         "    throw new java.lang.IllegalArgumentException();\n"
624         "  }\n"
625         "  return $name$ValueConverter.doForward(map.get(key));\n"
626         "}\n");
627     printer->Annotate("{", "}", descriptor_);
628 
629     if (SupportUnknownEnumValue(value)) {
630       printer->Print(
631           variables_,
632           "/**\n"
633           " * Use {@link #get$capitalized_name$ValueMap()} instead.\n"
634           " */\n"
635           "@java.lang.Override\n"
636           "@java.lang.Deprecated\n"
637           "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n"
638           "${$get$capitalized_name$Value$}$() {\n"
639           "  return get$capitalized_name$ValueMap();\n"
640           "}\n");
641       printer->Annotate("{", "}", descriptor_);
642       WriteFieldDocComment(printer, descriptor_, context_->options());
643       printer->Print(variables_,
644                      "@java.lang.Override\n"
645                      "$deprecation$public java.util.Map<$boxed_key_type$, "
646                      "$boxed_value_type$>\n"
647                      "${$get$capitalized_name$ValueMap$}$() {\n"
648                      "  return internalGet$capitalized_name$().getMap();\n"
649                      "}\n");
650       printer->Annotate("{", "}", descriptor_);
651       WriteFieldDocComment(printer, descriptor_, context_->options());
652       printer->Print(
653           variables_,
654           "@java.lang.Override\n"
655           "$deprecation$public $value_type_pass_through_nullness$ "
656           "${$get$capitalized_name$ValueOrDefault$}$(\n"
657           "    $key_type$ key,\n"
658           "    $value_type_pass_through_nullness$ defaultValue) {\n"
659           "  $key_null_check$\n"
660           "  java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
661           "      internalGet$capitalized_name$().getMap();\n"
662           "  return map.containsKey(key) ? map.get(key) : defaultValue;\n"
663           "}\n");
664       printer->Annotate("{", "}", descriptor_);
665       WriteFieldDocComment(printer, descriptor_, context_->options());
666       printer->Print(
667           variables_,
668           "@java.lang.Override\n"
669           "$deprecation$public $value_type$ "
670           "${$get$capitalized_name$ValueOrThrow$}$(\n"
671           "    $key_type$ key) {\n"
672           "  $key_null_check$\n"
673           "  java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
674           "      internalGet$capitalized_name$().getMap();\n"
675           "  if (!map.containsKey(key)) {\n"
676           "    throw new java.lang.IllegalArgumentException();\n"
677           "  }\n"
678           "  return map.get(key);\n"
679           "}\n");
680       printer->Annotate("{", "}", descriptor_);
681     }
682   } else {
683     if (context_->options().opensource_runtime) {
684       printer->Print(variables_,
685                      "/**\n"
686                      " * Use {@link #get$capitalized_name$Map()} instead.\n"
687                      " */\n"
688                      "@java.lang.Override\n"
689                      "@java.lang.Deprecated\n"
690                      "public java.util.Map<$type_parameters$> "
691                      "${$get$capitalized_name$$}$() {\n"
692                      "  return get$capitalized_name$Map();\n"
693                      "}\n");
694       printer->Annotate("{", "}", descriptor_);
695     }
696     WriteFieldDocComment(printer, descriptor_, context_->options());
697     printer->Print(variables_,
698                    "@java.lang.Override\n"
699                    "$deprecation$public java.util.Map<$type_parameters$> "
700                    "${$get$capitalized_name$Map$}$() {\n"
701                    "  return internalGet$capitalized_name$().getMap();\n"
702                    "}\n");
703     printer->Annotate("{", "}", descriptor_);
704     WriteFieldDocComment(printer, descriptor_, context_->options());
705     printer->Print(
706         variables_,
707         "@java.lang.Override\n"
708         "$deprecation$public $value_type_pass_through_nullness$ "
709         "${$get$capitalized_name$OrDefault$}$(\n"
710         "    $key_type$ key,\n"
711         "    $value_type_pass_through_nullness$ defaultValue) {\n"
712         "  $key_null_check$\n"
713         "  java.util.Map<$type_parameters$> map =\n"
714         "      internalGet$capitalized_name$().getMap();\n"
715         "  return map.containsKey(key) ? map.get(key) : defaultValue;\n"
716         "}\n");
717     printer->Annotate("{", "}", descriptor_);
718     WriteFieldDocComment(printer, descriptor_, context_->options());
719     printer->Print(
720         variables_,
721         "@java.lang.Override\n"
722         "$deprecation$public $value_type$ ${$get$capitalized_name$OrThrow$}$(\n"
723         "    $key_type$ key) {\n"
724         "  $key_null_check$\n"
725         "  java.util.Map<$type_parameters$> map =\n"
726         "      internalGet$capitalized_name$().getMap();\n"
727         "  if (!map.containsKey(key)) {\n"
728         "    throw new java.lang.IllegalArgumentException();\n"
729         "  }\n"
730         "  return map.get(key);\n"
731         "}\n");
732     printer->Annotate("{", "}", descriptor_);
733   }
734 }
735 
GenerateMessageMapBuilderMembers(io::Printer * printer) const736 void ImmutableMapFieldGenerator::GenerateMessageMapBuilderMembers(
737     io::Printer* printer) const {
738   printer->Print(
739       variables_,
740       "private static final class $capitalized_name$Converter implements "
741       "com.google.protobuf.MapFieldBuilder.Converter<$boxed_key_type$, "
742       "$value_interface_type$, $boxed_value_type$> "
743       "{\n");
744   {
745     auto i1 = printer->WithIndent();
746     printer->Print("@java.lang.Override\n");
747     printer->Print(
748         variables_,
749         "public $boxed_value_type$ build($value_interface_type$ val) {\n");
750     {
751       auto i2 = printer->WithIndent();
752       printer->Print(variables_,
753                      "if (val instanceof $boxed_value_type$) {"
754                      " return ($boxed_value_type$) val; }\n");
755       printer->Print(variables_,
756                      "return (($value_builder_type$) val).build();\n");
757     }
758     printer->Print("}\n\n");
759 
760     printer->Print("@java.lang.Override\n");
761     printer->Print(variables_,
762                    "public com.google.protobuf.MapEntry<$boxed_key_type$, "
763                    "$boxed_value_type$> defaultEntry() {\n");
764     {
765       auto i2 = printer->WithIndent();
766       printer->Print(
767           variables_,
768           "return $capitalized_name$DefaultEntryHolder.defaultEntry;\n");
769     }
770     printer->Print("}\n");
771   }
772   printer->Print("};\n");
773   printer->Print(variables_,
774                  "private static final $capitalized_name$Converter "
775                  "$name$Converter = new $capitalized_name$Converter();\n\n");
776 
777   printer->Print(
778       variables_,
779       "private com.google.protobuf.MapFieldBuilder<\n"
780       "    $builder_type_parameters$> $name$_;\n"
781       "$deprecation$private "
782       "com.google.protobuf.MapFieldBuilder<$builder_type_parameters$>\n"
783       "    internalGet$capitalized_name$() {\n"
784       "  if ($name$_ == null) {\n"
785       "    return new com.google.protobuf.MapFieldBuilder<>($name$Converter);\n"
786       "  }\n"
787       "  return $name$_;\n"
788       "}\n"
789       "$deprecation$private "
790       "com.google.protobuf.MapFieldBuilder<$builder_type_parameters$>\n"
791       "    internalGetMutable$capitalized_name$() {\n"
792       "  if ($name$_ == null) {\n"
793       "    $name$_ = new "
794       "com.google.protobuf.MapFieldBuilder<>($name$Converter);\n"
795       "  }\n"
796       "  $set_has_field_bit_builder$\n"
797       "  $on_changed$\n"
798       "  return $name$_;\n"
799       "}\n");
800   GenerateMessageMapGetters(printer);
801   printer->Print(
802       variables_,
803       "$deprecation$public Builder ${$clear$capitalized_name$$}$() {\n"
804       "  $clear_has_field_bit_builder$\n"
805       "  internalGetMutable$capitalized_name$().clear();\n"
806       "  return this;\n"
807       "}\n");
808   printer->Annotate("{", "}", descriptor_, Semantic::kSet);
809 
810   WriteFieldDocComment(printer, descriptor_, context_->options());
811   printer->Print(variables_,
812                  "$deprecation$public Builder ${$remove$capitalized_name$$}$(\n"
813                  "    $key_type$ key) {\n"
814                  "  $key_null_check$\n"
815                  "  internalGetMutable$capitalized_name$().ensureBuilderMap()\n"
816                  "      .remove(key);\n"
817                  "  return this;\n"
818                  "}\n");
819   printer->Annotate("{", "}", descriptor_, Semantic::kSet);
820 
821   if (context_->options().opensource_runtime) {
822     printer->Print(
823         variables_,
824         "/**\n"
825         " * Use alternate mutation accessors instead.\n"
826         " */\n"
827         "@java.lang.Deprecated\n"
828         "public java.util.Map<$type_parameters$>\n"
829         "    ${$getMutable$capitalized_name$$}$() {\n"
830         "  $set_has_field_bit_builder$\n"
831         "  return internalGetMutable$capitalized_name$().ensureMessageMap();\n"
832         "}\n");
833     printer->Annotate("{", "}", descriptor_);
834   }
835 
836   WriteFieldDocComment(printer, descriptor_, context_->options());
837   printer->Print(variables_,
838                  "$deprecation$public Builder ${$put$capitalized_name$$}$(\n"
839                  "    $key_type$ key,\n"
840                  "    $value_type$ value) {\n"
841                  "  $key_null_check$\n"
842                  "  $value_null_check$\n"
843                  "  internalGetMutable$capitalized_name$().ensureBuilderMap()\n"
844                  "      .put(key, value);\n"
845                  "  $set_has_field_bit_builder$\n"
846                  "  return this;\n"
847                  "}\n");
848   printer->Annotate("{", "}", descriptor_, Semantic::kSet);
849 
850   WriteFieldDocComment(printer, descriptor_, context_->options());
851   printer->Print(
852       variables_,
853       "$deprecation$public Builder ${$putAll$capitalized_name$$}$(\n"
854       "    java.util.Map<$type_parameters$> values) {\n"
855       "  for (java.util.Map.Entry<$type_parameters$> e : values.entrySet()) {\n"
856       "    if (e.getKey() == null || e.getValue() == null) {\n"
857       "      throw new NullPointerException();\n"
858       "    }\n"
859       "  }\n"
860       "  internalGetMutable$capitalized_name$().ensureBuilderMap()\n"
861       "      .putAll(values);\n"
862       "  $set_has_field_bit_builder$\n"
863       "  return this;\n"
864       "}\n");
865   printer->Annotate("{", "}", descriptor_, Semantic::kSet);
866 
867   WriteFieldDocComment(printer, descriptor_, context_->options());
868   printer->Print(
869       variables_,
870       "$deprecation$public $value_builder_type$ "
871       "${$put$capitalized_name$BuilderIfAbsent$}$(\n"
872       "    $key_type$ key) {\n"
873       "  java.util.Map<$boxed_key_type$, $value_interface_type$> builderMap = "
874       "internalGetMutable$capitalized_name$().ensureBuilderMap();\n"
875       "  $value_interface_type$ entry = builderMap.get(key);\n"
876       "  if (entry == null) {\n"
877       "    entry = $value_type$.newBuilder();\n"
878       "    builderMap.put(key, entry);\n"
879       "  }\n"
880       "  if (entry instanceof $value_type$) {\n"
881       "    entry = (($value_type$) entry).toBuilder();\n"
882       "    builderMap.put(key, entry);\n"
883       "  }\n"
884       "  return ($value_builder_type$) entry;\n"
885       "}\n");
886   printer->Annotate("{", "}", descriptor_, Semantic::kSet);
887 }
888 
GenerateMessageMapGetters(io::Printer * printer) const889 void ImmutableMapFieldGenerator::GenerateMessageMapGetters(
890     io::Printer* printer) const {
891   printer->Print(
892       variables_,
893       "$deprecation$public int ${$get$capitalized_name$Count$}$() {\n"
894       "  return internalGet$capitalized_name$().ensureBuilderMap().size();\n"
895       "}\n");
896   printer->Annotate("{", "}", descriptor_);
897 
898   WriteFieldDocComment(printer, descriptor_, context_->options());
899   printer->Print(
900       variables_,
901       "@java.lang.Override\n"
902       "$deprecation$public boolean ${$contains$capitalized_name$$}$(\n"
903       "    $key_type$ key) {\n"
904       "  $key_null_check$\n"
905       "  return "
906       "internalGet$capitalized_name$().ensureBuilderMap().containsKey(key);\n"
907       "}\n");
908   printer->Annotate("{", "}", descriptor_);
909   if (context_->options().opensource_runtime) {
910     printer->Print(variables_,
911                    "/**\n"
912                    " * Use {@link #get$capitalized_name$Map()} instead.\n"
913                    " */\n"
914                    "@java.lang.Override\n"
915                    "@java.lang.Deprecated\n"
916                    "public java.util.Map<$type_parameters$> "
917                    "${$get$capitalized_name$$}$() {\n"
918                    "  return get$capitalized_name$Map();\n"
919                    "}\n");
920     printer->Annotate("{", "}", descriptor_);
921   }
922   WriteFieldDocComment(printer, descriptor_, context_->options());
923   printer->Print(variables_,
924                  "@java.lang.Override\n"
925                  "$deprecation$public java.util.Map<$type_parameters$> "
926                  "${$get$capitalized_name$Map$}$() {\n"
927                  "  return internalGet$capitalized_name$().getImmutableMap();\n"
928                  "}\n");
929   printer->Annotate("{", "}", descriptor_);
930   WriteFieldDocComment(printer, descriptor_, context_->options());
931   printer->Print(
932       variables_,
933       "@java.lang.Override\n"
934       "$deprecation$public $value_type_pass_through_nullness$ "
935       "${$get$capitalized_name$OrDefault$}$(\n"
936       "    $key_type$ key,\n"
937       "    $value_type_pass_through_nullness$ defaultValue) {\n"
938       "  $key_null_check$\n"
939       "  java.util.Map<$boxed_key_type$, $value_interface_type$> map = "
940       "internalGetMutable$capitalized_name$().ensureBuilderMap();\n"
941       "  return map.containsKey(key) ? $name$Converter.build(map.get(key)) : "
942       "defaultValue;\n"
943       "}\n");
944   printer->Annotate("{", "}", descriptor_);
945   WriteFieldDocComment(printer, descriptor_, context_->options());
946   printer->Print(
947       variables_,
948       "@java.lang.Override\n"
949       "$deprecation$public $value_type$ ${$get$capitalized_name$OrThrow$}$(\n"
950       "    $key_type$ key) {\n"
951       "  $key_null_check$\n"
952       "  java.util.Map<$boxed_key_type$, $value_interface_type$> map = "
953       "internalGetMutable$capitalized_name$().ensureBuilderMap();\n"
954       "  if (!map.containsKey(key)) {\n"
955       "    throw new java.lang.IllegalArgumentException();\n"
956       "  }\n"
957       "  return $name$Converter.build(map.get(key));\n"
958       "}\n");
959   printer->Annotate("{", "}", descriptor_);
960 }
961 
GenerateKotlinDslMembers(io::Printer * printer) const962 void ImmutableMapFieldGenerator::GenerateKotlinDslMembers(
963     io::Printer* printer) const {
964   printer->Print(
965       variables_,
966       "/**\n"
967       " * An uninstantiable, behaviorless type to represent the field in\n"
968       " * generics.\n"
969       " */\n"
970       "@kotlin.OptIn"
971       "(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)\n"
972       "public class ${$$kt_capitalized_name$Proxy$}$ private constructor()"
973       " : com.google.protobuf.kotlin.DslProxy()\n");
974 
975   WriteFieldDocComment(printer, descriptor_, context_->options(),
976                        /* kdoc */ true);
977   printer->Print(
978       variables_,
979       "$kt_deprecation$ public val $kt_name$: "
980       "com.google.protobuf.kotlin.DslMap"
981       "<$kt_key_type$, $kt_value_type$, ${$$kt_capitalized_name$Proxy$}$>\n"
982       "  @kotlin.jvm.JvmSynthetic\n"
983       "  @JvmName(\"get$kt_capitalized_name$Map\")\n"
984       "  get() = com.google.protobuf.kotlin.DslMap(\n"
985       "    $kt_dsl_builder$.${$$kt_property_name$Map$}$\n"
986       "  )\n");
987 
988   WriteFieldDocComment(printer, descriptor_, context_->options(),
989                        /* kdoc */ true);
990   printer->Print(
991       variables_,
992       "@JvmName(\"put$kt_capitalized_name$\")\n"
993       "public fun com.google.protobuf.kotlin.DslMap"
994       "<$kt_key_type$, $kt_value_type$, ${$$kt_capitalized_name$Proxy$}$>\n"
995       "  .put(key: $kt_key_type$, value: $kt_value_type$) {\n"
996       "     $kt_dsl_builder$.${$put$capitalized_name$$}$(key, value)\n"
997       "   }\n");
998 
999   WriteFieldDocComment(printer, descriptor_, context_->options(),
1000                        /* kdoc */ true);
1001   printer->Print(
1002       variables_,
1003       "@kotlin.jvm.JvmSynthetic\n"
1004       "@JvmName(\"set$kt_capitalized_name$\")\n"
1005       "@Suppress(\"NOTHING_TO_INLINE\")\n"
1006       "public inline operator fun com.google.protobuf.kotlin.DslMap"
1007       "<$kt_key_type$, $kt_value_type$, ${$$kt_capitalized_name$Proxy$}$>\n"
1008       "  .set(key: $kt_key_type$, value: $kt_value_type$) {\n"
1009       "     put(key, value)\n"
1010       "   }\n");
1011 
1012   WriteFieldDocComment(printer, descriptor_, context_->options(),
1013                        /* kdoc */ true);
1014   printer->Print(
1015       variables_,
1016       "@kotlin.jvm.JvmSynthetic\n"
1017       "@JvmName(\"remove$kt_capitalized_name$\")\n"
1018       "public fun com.google.protobuf.kotlin.DslMap"
1019       "<$kt_key_type$, $kt_value_type$, ${$$kt_capitalized_name$Proxy$}$>\n"
1020       "  .remove(key: $kt_key_type$) {\n"
1021       "     $kt_dsl_builder$.${$remove$capitalized_name$$}$(key)\n"
1022       "   }\n");
1023 
1024   WriteFieldDocComment(printer, descriptor_, context_->options(),
1025                        /* kdoc */ true);
1026   printer->Print(
1027       variables_,
1028       "@kotlin.jvm.JvmSynthetic\n"
1029       "@JvmName(\"putAll$kt_capitalized_name$\")\n"
1030       "public fun com.google.protobuf.kotlin.DslMap"
1031       "<$kt_key_type$, $kt_value_type$, ${$$kt_capitalized_name$Proxy$}$>\n"
1032       "  .putAll(map: kotlin.collections.Map<$kt_key_type$, "
1033       "$kt_value_type$>) "
1034       "{\n"
1035       "     $kt_dsl_builder$.${$putAll$capitalized_name$$}$(map)\n"
1036       "   }\n");
1037 
1038   WriteFieldDocComment(printer, descriptor_, context_->options(),
1039                        /* kdoc */ true);
1040   printer->Print(
1041       variables_,
1042       "@kotlin.jvm.JvmSynthetic\n"
1043       "@JvmName(\"clear$kt_capitalized_name$\")\n"
1044       "public fun com.google.protobuf.kotlin.DslMap"
1045       "<$kt_key_type$, $kt_value_type$, ${$$kt_capitalized_name$Proxy$}$>\n"
1046       "  .clear() {\n"
1047       "     $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n"
1048       "   }\n");
1049 }
1050 
GenerateFieldBuilderInitializationCode(io::Printer * printer) const1051 void ImmutableMapFieldGenerator::GenerateFieldBuilderInitializationCode(
1052     io::Printer* printer) const {
1053   // Nothing to initialize.
1054 }
1055 
GenerateInitializationCode(io::Printer * printer) const1056 void ImmutableMapFieldGenerator::GenerateInitializationCode(
1057     io::Printer* printer) const {
1058   // Nothing to initialize.
1059 }
1060 
GenerateBuilderClearCode(io::Printer * printer) const1061 void ImmutableMapFieldGenerator::GenerateBuilderClearCode(
1062     io::Printer* printer) const {
1063   // No need to clear the has-bit since we clear the bitField ints all at once.
1064   printer->Print(variables_,
1065                  "internalGetMutable$capitalized_name$().clear();\n");
1066 }
1067 
GenerateMergingCode(io::Printer * printer) const1068 void ImmutableMapFieldGenerator::GenerateMergingCode(
1069     io::Printer* printer) const {
1070   printer->Print(variables_,
1071                  "internalGetMutable$capitalized_name$().mergeFrom(\n"
1072                  "    other.internalGet$capitalized_name$());\n"
1073                  "$set_has_field_bit_builder$\n");
1074 }
1075 
GenerateBuildingCode(io::Printer * printer) const1076 void ImmutableMapFieldGenerator::GenerateBuildingCode(
1077     io::Printer* printer) const {
1078   if (GetJavaType(MapValueField(descriptor_)) == JAVATYPE_MESSAGE) {
1079     printer->Print(
1080         variables_,
1081         "if ($get_has_field_bit_from_local$) {\n"
1082         "  result.$name$_ = "
1083         "internalGet$capitalized_name$().build($map_field_parameter$);\n"
1084         "}\n");
1085     return;
1086   }
1087   printer->Print(variables_,
1088                  "if ($get_has_field_bit_from_local$) {\n"
1089                  "  result.$name$_ = internalGet$capitalized_name$();\n"
1090                  "  result.$name$_.makeImmutable();\n"
1091                  "}\n");
1092 }
1093 
GenerateBuilderParsingCode(io::Printer * printer) const1094 void ImmutableMapFieldGenerator::GenerateBuilderParsingCode(
1095     io::Printer* printer) const {
1096   const FieldDescriptor* value = MapValueField(descriptor_);
1097   const JavaType type = GetJavaType(value);
1098   if (type == JAVATYPE_MESSAGE) {
1099     printer->Print(
1100         variables_,
1101         "com.google.protobuf.MapEntry<$type_parameters$>\n"
1102         "$name$__ = input.readMessage(\n"
1103         "    $default_entry$.getParserForType(), extensionRegistry);\n"
1104         "internalGetMutable$capitalized_name$().ensureBuilderMap().put(\n"
1105         "    $name$__.getKey(), $name$__.getValue());\n"
1106         "$set_has_field_bit_builder$\n");
1107     return;
1108   }
1109   if (!SupportUnknownEnumValue(value) && type == JAVATYPE_ENUM) {
1110     printer->Print(
1111         variables_,
1112         "com.google.protobuf.ByteString bytes = input.readBytes();\n"
1113         "com.google.protobuf.MapEntry<$type_parameters$>\n"
1114         "$name$__ = $default_entry$.getParserForType().parseFrom(bytes);\n"
1115         "if ($value_enum_type$.forNumber($name$__.getValue()) == null) {\n"
1116         "  mergeUnknownLengthDelimitedField($number$, bytes);\n"
1117         "} else {\n"
1118         "  internalGetMutable$capitalized_name$().getMutableMap().put(\n"
1119         "      $name$__.getKey(), $name$__.getValue());\n"
1120         "  $set_has_field_bit_builder$\n"
1121         "}\n");
1122     return;
1123   }
1124   printer->Print(variables_,
1125                  "com.google.protobuf.MapEntry<$type_parameters$>\n"
1126                  "$name$__ = input.readMessage(\n"
1127                  "    $default_entry$.getParserForType(), extensionRegistry);\n"
1128                  "internalGetMutable$capitalized_name$().getMutableMap().put(\n"
1129                  "    $name$__.getKey(), $name$__.getValue());\n"
1130                  "$set_has_field_bit_builder$\n");
1131 }
GenerateSerializationCode(io::Printer * printer) const1132 void ImmutableMapFieldGenerator::GenerateSerializationCode(
1133     io::Printer* printer) const {
1134   printer->Print(variables_,
1135                  "com.google.protobuf.GeneratedMessage\n"
1136                  "  .serialize$short_key_type$MapTo(\n"
1137                  "    output,\n"
1138                  "    internalGet$capitalized_name$(),\n"
1139                  "    $default_entry$,\n"
1140                  "    $number$);\n");
1141 }
1142 
GenerateSerializedSizeCode(io::Printer * printer) const1143 void ImmutableMapFieldGenerator::GenerateSerializedSizeCode(
1144     io::Printer* printer) const {
1145   printer->Print(
1146       variables_,
1147       "for (java.util.Map.Entry<$type_parameters$> entry\n"
1148       "     : internalGet$capitalized_name$().getMap().entrySet()) {\n"
1149       "  com.google.protobuf.MapEntry<$type_parameters$>\n"
1150       "  $name$__ = $default_entry$.newBuilderForType()\n"
1151       "      .setKey(entry.getKey())\n"
1152       "      .setValue(entry.getValue())\n"
1153       "      .build();\n"
1154       "  size += com.google.protobuf.CodedOutputStream\n"
1155       "      .computeMessageSize($number$, $name$__);\n"
1156       "}\n");
1157 }
1158 
GenerateEqualsCode(io::Printer * printer) const1159 void ImmutableMapFieldGenerator::GenerateEqualsCode(
1160     io::Printer* printer) const {
1161   printer->Print(variables_,
1162                  "if (!internalGet$capitalized_name$().equals(\n"
1163                  "    other.internalGet$capitalized_name$())) return false;\n");
1164 }
1165 
GenerateHashCode(io::Printer * printer) const1166 void ImmutableMapFieldGenerator::GenerateHashCode(io::Printer* printer) const {
1167   printer->Print(
1168       variables_,
1169       "if (!internalGet$capitalized_name$().getMap().isEmpty()) {\n"
1170       "  hash = (37 * hash) + $constant_name$;\n"
1171       "  hash = (53 * hash) + internalGet$capitalized_name$().hashCode();\n"
1172       "}\n");
1173 }
1174 
GetBoxedType() const1175 std::string ImmutableMapFieldGenerator::GetBoxedType() const {
1176   return name_resolver_->GetImmutableClassName(descriptor_->message_type());
1177 }
1178 
1179 }  // namespace java
1180 }  // namespace compiler
1181 }  // namespace protobuf
1182 }  // namespace google
1183 
1184 #include "google/protobuf/port_undef.inc"
1185