• 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 #include <google/protobuf/compiler/java/java_map_field.h>
32 
33 #include <google/protobuf/compiler/java/java_context.h>
34 #include <google/protobuf/compiler/java/java_doc_comment.h>
35 #include <google/protobuf/compiler/java/java_helpers.h>
36 #include <google/protobuf/compiler/java/java_name_resolver.h>
37 #include <google/protobuf/io/printer.h>
38 
39 namespace google {
40 namespace protobuf {
41 namespace compiler {
42 namespace java {
43 
44 namespace {
45 
KeyField(const FieldDescriptor * descriptor)46 const FieldDescriptor* KeyField(const FieldDescriptor* descriptor) {
47   GOOGLE_CHECK_EQ(FieldDescriptor::TYPE_MESSAGE, descriptor->type());
48   const Descriptor* message = descriptor->message_type();
49   GOOGLE_CHECK(message->options().map_entry());
50   return message->FindFieldByName("key");
51 }
52 
ValueField(const FieldDescriptor * descriptor)53 const FieldDescriptor* ValueField(const FieldDescriptor* descriptor) {
54   GOOGLE_CHECK_EQ(FieldDescriptor::TYPE_MESSAGE, descriptor->type());
55   const Descriptor* message = descriptor->message_type();
56   GOOGLE_CHECK(message->options().map_entry());
57   return message->FindFieldByName("value");
58 }
59 
TypeName(const FieldDescriptor * field,ClassNameResolver * name_resolver,bool boxed)60 std::string TypeName(const FieldDescriptor* field,
61                      ClassNameResolver* name_resolver, bool boxed) {
62   if (GetJavaType(field) == JAVATYPE_MESSAGE) {
63     return name_resolver->GetImmutableClassName(field->message_type());
64   } else if (GetJavaType(field) == JAVATYPE_ENUM) {
65     return name_resolver->GetImmutableClassName(field->enum_type());
66   } else {
67     return boxed ? BoxedPrimitiveTypeName(GetJavaType(field))
68                  : PrimitiveTypeName(GetJavaType(field));
69   }
70 }
71 
WireType(const FieldDescriptor * field)72 std::string WireType(const FieldDescriptor* field) {
73   return "com.google.protobuf.WireFormat.FieldType." +
74          std::string(FieldTypeName(field->type()));
75 }
76 
SetMessageVariables(const FieldDescriptor * descriptor,int messageBitIndex,int builderBitIndex,const FieldGeneratorInfo * info,Context * context,std::map<std::string,std::string> * variables)77 void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex,
78                          int builderBitIndex, const FieldGeneratorInfo* info,
79                          Context* context,
80                          std::map<std::string, std::string>* variables) {
81   SetCommonFieldVariables(descriptor, info, variables);
82   ClassNameResolver* name_resolver = context->GetNameResolver();
83 
84   (*variables)["type"] =
85       name_resolver->GetImmutableClassName(descriptor->message_type());
86   const FieldDescriptor* key = KeyField(descriptor);
87   const FieldDescriptor* value = ValueField(descriptor);
88   const JavaType keyJavaType = GetJavaType(key);
89   const JavaType valueJavaType = GetJavaType(value);
90 
91   (*variables)["key_type"] = TypeName(key, name_resolver, false);
92   std::string boxed_key_type = TypeName(key, name_resolver, true);
93   (*variables)["boxed_key_type"] = boxed_key_type;
94   // Used for calling the serialization function.
95   (*variables)["short_key_type"] =
96       boxed_key_type.substr(boxed_key_type.rfind('.') + 1);
97   (*variables)["key_wire_type"] = WireType(key);
98   (*variables)["key_default_value"] = DefaultValue(key, true, name_resolver);
99   (*variables)["key_null_check"] =
100       IsReferenceType(keyJavaType)
101           ? "if (key == null) { throw new java.lang.NullPointerException(); }"
102           : "";
103   (*variables)["value_null_check"] =
104       IsReferenceType(valueJavaType)
105           ? "if (value == null) { throw new java.lang.NullPointerException(); }"
106           : "";
107   if (valueJavaType == JAVATYPE_ENUM) {
108     // We store enums as Integers internally.
109     (*variables)["value_type"] = "int";
110     (*variables)["boxed_value_type"] = "java.lang.Integer";
111     (*variables)["value_wire_type"] = WireType(value);
112     (*variables)["value_default_value"] =
113         DefaultValue(value, true, name_resolver) + ".getNumber()";
114 
115     (*variables)["value_enum_type"] = TypeName(value, name_resolver, false);
116 
117     if (SupportUnknownEnumValue(descriptor->file())) {
118       // Map unknown values to a special UNRECOGNIZED value if supported.
119       (*variables)["unrecognized_value"] =
120           (*variables)["value_enum_type"] + ".UNRECOGNIZED";
121     } else {
122       // Map unknown values to the default value if we don't have UNRECOGNIZED.
123       (*variables)["unrecognized_value"] =
124           DefaultValue(value, true, name_resolver);
125     }
126   } else {
127     (*variables)["value_type"] = TypeName(value, name_resolver, false);
128     (*variables)["boxed_value_type"] = TypeName(value, name_resolver, true);
129     (*variables)["value_wire_type"] = WireType(value);
130     (*variables)["value_default_value"] =
131         DefaultValue(value, true, name_resolver);
132   }
133   (*variables)["type_parameters"] =
134       (*variables)["boxed_key_type"] + ", " + (*variables)["boxed_value_type"];
135   // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
136   // by the proto compiler
137   (*variables)["deprecation"] =
138       descriptor->options().deprecated() ? "@java.lang.Deprecated " : "";
139   (*variables)["on_changed"] = "onChanged();";
140 
141   (*variables)["default_entry"] =
142       (*variables)["capitalized_name"] + "DefaultEntryHolder.defaultEntry";
143   (*variables)["map_field_parameter"] = (*variables)["default_entry"];
144   (*variables)["descriptor"] =
145       name_resolver->GetImmutableClassName(descriptor->file()) + ".internal_" +
146       UniqueFileScopeIdentifier(descriptor->message_type()) + "_descriptor, ";
147   (*variables)["ver"] = GeneratedCodeVersionSuffix();
148 }
149 
150 }  // namespace
151 
ImmutableMapFieldGenerator(const FieldDescriptor * descriptor,int messageBitIndex,int builderBitIndex,Context * context)152 ImmutableMapFieldGenerator::ImmutableMapFieldGenerator(
153     const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex,
154     Context* context)
155     : descriptor_(descriptor), name_resolver_(context->GetNameResolver()) {
156   SetMessageVariables(descriptor, messageBitIndex, builderBitIndex,
157                       context->GetFieldGeneratorInfo(descriptor), context,
158                       &variables_);
159 }
160 
~ImmutableMapFieldGenerator()161 ImmutableMapFieldGenerator::~ImmutableMapFieldGenerator() {}
162 
GetNumBitsForMessage() const163 int ImmutableMapFieldGenerator::GetNumBitsForMessage() const { return 0; }
164 
GetNumBitsForBuilder() const165 int ImmutableMapFieldGenerator::GetNumBitsForBuilder() const { return 1; }
166 
GenerateInterfaceMembers(io::Printer * printer) const167 void ImmutableMapFieldGenerator::GenerateInterfaceMembers(
168     io::Printer* printer) const {
169   WriteFieldDocComment(printer, descriptor_);
170   printer->Print(variables_,
171                  "$deprecation$int ${$get$capitalized_name$Count$}$();\n");
172   printer->Annotate("{", "}", descriptor_);
173   WriteFieldDocComment(printer, descriptor_);
174   printer->Print(variables_,
175                  "$deprecation$boolean ${$contains$capitalized_name$$}$(\n"
176                  "    $key_type$ key);\n");
177   printer->Annotate("{", "}", descriptor_);
178   if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) {
179     printer->Print(variables_,
180                    "/**\n"
181                    " * Use {@link #get$capitalized_name$Map()} instead.\n"
182                    " */\n"
183                    "@java.lang.Deprecated\n"
184                    "java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
185                    "${$get$capitalized_name$$}$();\n");
186     printer->Annotate("{", "}", descriptor_);
187     WriteFieldDocComment(printer, descriptor_);
188     printer->Print(
189         variables_,
190         "$deprecation$java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
191         "${$get$capitalized_name$Map$}$();\n");
192     printer->Annotate("{", "}", descriptor_);
193     WriteFieldDocComment(printer, descriptor_);
194     printer->Print(
195         variables_,
196         "$deprecation$$value_enum_type$ ${$get$capitalized_name$OrDefault$}$(\n"
197         "    $key_type$ key,\n"
198         "    $value_enum_type$ defaultValue);\n");
199     printer->Annotate("{", "}", descriptor_);
200     WriteFieldDocComment(printer, descriptor_);
201     printer->Print(
202         variables_,
203         "$deprecation$$value_enum_type$ ${$get$capitalized_name$OrThrow$}$(\n"
204         "    $key_type$ key);\n");
205     printer->Annotate("{", "}", descriptor_);
206     if (SupportUnknownEnumValue(descriptor_->file())) {
207       printer->Print(
208           variables_,
209           "/**\n"
210           " * Use {@link #get$capitalized_name$ValueMap()} instead.\n"
211           " */\n"
212           "@java.lang.Deprecated\n"
213           "java.util.Map<$type_parameters$>\n"
214           "${$get$capitalized_name$Value$}$();\n");
215       printer->Annotate("{", "}", descriptor_);
216       WriteFieldDocComment(printer, descriptor_);
217       printer->Print(variables_,
218                      "$deprecation$java.util.Map<$type_parameters$>\n"
219                      "${$get$capitalized_name$ValueMap$}$();\n");
220       printer->Annotate("{", "}", descriptor_);
221       WriteFieldDocComment(printer, descriptor_);
222       printer->Print(variables_,
223                      "$deprecation$\n"
224                      "$value_type$ ${$get$capitalized_name$ValueOrDefault$}$(\n"
225                      "    $key_type$ key,\n"
226                      "    $value_type$ defaultValue);\n");
227       printer->Annotate("{", "}", descriptor_);
228       WriteFieldDocComment(printer, descriptor_);
229       printer->Print(variables_,
230                      "$deprecation$\n"
231                      "$value_type$ ${$get$capitalized_name$ValueOrThrow$}$(\n"
232                      "    $key_type$ key);\n");
233       printer->Annotate("{", "}", descriptor_);
234     }
235   } else {
236     printer->Print(variables_,
237                    "/**\n"
238                    " * Use {@link #get$capitalized_name$Map()} instead.\n"
239                    " */\n"
240                    "@java.lang.Deprecated\n"
241                    "java.util.Map<$type_parameters$>\n"
242                    "${$get$capitalized_name$$}$();\n");
243     printer->Annotate("{", "}", descriptor_);
244     WriteFieldDocComment(printer, descriptor_);
245     printer->Print(variables_,
246                    "$deprecation$java.util.Map<$type_parameters$>\n"
247                    "${$get$capitalized_name$Map$}$();\n");
248     printer->Annotate("{", "}", descriptor_);
249     WriteFieldDocComment(printer, descriptor_);
250     printer->Print(variables_,
251                    "$deprecation$\n"
252                    "$value_type$ ${$get$capitalized_name$OrDefault$}$(\n"
253                    "    $key_type$ key,\n"
254                    "    $value_type$ defaultValue);\n");
255     printer->Annotate("{", "}", descriptor_);
256     WriteFieldDocComment(printer, descriptor_);
257     printer->Print(variables_,
258                    "$deprecation$\n"
259                    "$value_type$ ${$get$capitalized_name$OrThrow$}$(\n"
260                    "    $key_type$ key);\n");
261     printer->Annotate("{", "}", descriptor_);
262   }
263 }
264 
GenerateMembers(io::Printer * printer) const265 void ImmutableMapFieldGenerator::GenerateMembers(io::Printer* printer) const {
266   printer->Print(
267       variables_,
268       "private static final class $capitalized_name$DefaultEntryHolder {\n"
269       "  static final com.google.protobuf.MapEntry<\n"
270       "      $type_parameters$> defaultEntry =\n"
271       "          com.google.protobuf.MapEntry\n"
272       "          .<$type_parameters$>newDefaultInstance(\n"
273       "              $descriptor$\n"
274       "              $key_wire_type$,\n"
275       "              $key_default_value$,\n"
276       "              $value_wire_type$,\n"
277       "              $value_default_value$);\n"
278       "}\n");
279   printer->Print(variables_,
280                  "private com.google.protobuf.MapField<\n"
281                  "    $type_parameters$> $name$_;\n"
282                  "private com.google.protobuf.MapField<$type_parameters$>\n"
283                  "internalGet$capitalized_name$() {\n"
284                  "  if ($name$_ == null) {\n"
285                  "    return com.google.protobuf.MapField.emptyMapField(\n"
286                  "        $map_field_parameter$);\n"
287                  "  }\n"
288                  "  return $name$_;\n"
289                  "}\n");
290   if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) {
291     printer->Print(
292         variables_,
293         "private static final\n"
294         "com.google.protobuf.Internal.MapAdapter.Converter<\n"
295         "    java.lang.Integer, $value_enum_type$> $name$ValueConverter =\n"
296         "        com.google.protobuf.Internal.MapAdapter.newEnumConverter(\n"
297         "            $value_enum_type$.internalGetValueMap(),\n"
298         "            $unrecognized_value$);\n");
299     printer->Print(
300         variables_,
301         "private static final java.util.Map<$boxed_key_type$, "
302         "$value_enum_type$>\n"
303         "internalGetAdapted$capitalized_name$Map(\n"
304         "    java.util.Map<$boxed_key_type$, $boxed_value_type$> map) {\n"
305         "  return new com.google.protobuf.Internal.MapAdapter<\n"
306         "      $boxed_key_type$, $value_enum_type$, java.lang.Integer>(\n"
307         "          map, $name$ValueConverter);\n"
308         "}\n");
309   }
310   GenerateMapGetters(printer);
311 }
312 
GenerateBuilderMembers(io::Printer * printer) const313 void ImmutableMapFieldGenerator::GenerateBuilderMembers(
314     io::Printer* printer) const {
315   printer->Print(variables_,
316                  "private com.google.protobuf.MapField<\n"
317                  "    $type_parameters$> $name$_;\n"
318                  "private com.google.protobuf.MapField<$type_parameters$>\n"
319                  "internalGet$capitalized_name$() {\n"
320                  "  if ($name$_ == null) {\n"
321                  "    return com.google.protobuf.MapField.emptyMapField(\n"
322                  "        $map_field_parameter$);\n"
323                  "  }\n"
324                  "  return $name$_;\n"
325                  "}\n"
326                  "private com.google.protobuf.MapField<$type_parameters$>\n"
327                  "internalGetMutable$capitalized_name$() {\n"
328                  "  $on_changed$;\n"
329                  "  if ($name$_ == null) {\n"
330                  "    $name$_ = com.google.protobuf.MapField.newMapField(\n"
331                  "        $map_field_parameter$);\n"
332                  "  }\n"
333                  "  if (!$name$_.isMutable()) {\n"
334                  "    $name$_ = $name$_.copy();\n"
335                  "  }\n"
336                  "  return $name$_;\n"
337                  "}\n");
338   GenerateMapGetters(printer);
339   printer->Print(variables_,
340                  "$deprecation$\n"
341                  "public Builder ${$clear$capitalized_name$$}$() {\n"
342                  "  internalGetMutable$capitalized_name$().getMutableMap()\n"
343                  "      .clear();\n"
344                  "  return this;\n"
345                  "}\n");
346   printer->Annotate("{", "}", descriptor_);
347   WriteFieldDocComment(printer, descriptor_);
348   printer->Print(variables_,
349                  "$deprecation$\n"
350                  "public Builder ${$remove$capitalized_name$$}$(\n"
351                  "    $key_type$ key) {\n"
352                  "  $key_null_check$\n"
353                  "  internalGetMutable$capitalized_name$().getMutableMap()\n"
354                  "      .remove(key);\n"
355                  "  return this;\n"
356                  "}\n");
357   printer->Annotate("{", "}", descriptor_);
358   if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) {
359     printer->Print(
360         variables_,
361         "/**\n"
362         " * Use alternate mutation accessors instead.\n"
363         " */\n"
364         "@java.lang.Deprecated\n"
365         "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
366         "${$getMutable$capitalized_name$$}$() {\n"
367         "  return internalGetAdapted$capitalized_name$Map(\n"
368         "       internalGetMutable$capitalized_name$().getMutableMap());\n"
369         "}\n");
370     printer->Annotate("{", "}", descriptor_);
371     WriteFieldDocComment(printer, descriptor_);
372     printer->Print(variables_,
373                    "$deprecation$public Builder ${$put$capitalized_name$$}$(\n"
374                    "    $key_type$ key,\n"
375                    "    $value_enum_type$ value) {\n"
376                    "  $key_null_check$\n"
377                    "  $value_null_check$\n"
378                    "  internalGetMutable$capitalized_name$().getMutableMap()\n"
379                    "      .put(key, $name$ValueConverter.doBackward(value));\n"
380                    "  return this;\n"
381                    "}\n");
382     printer->Annotate("{", "}", descriptor_);
383     WriteFieldDocComment(printer, descriptor_);
384     printer->Print(
385         variables_,
386         "$deprecation$public Builder ${$putAll$capitalized_name$$}$(\n"
387         "    java.util.Map<$boxed_key_type$, $value_enum_type$> values) {\n"
388         "  internalGetAdapted$capitalized_name$Map(\n"
389         "      internalGetMutable$capitalized_name$().getMutableMap())\n"
390         "          .putAll(values);\n"
391         "  return this;\n"
392         "}\n");
393     printer->Annotate("{", "}", descriptor_);
394     if (SupportUnknownEnumValue(descriptor_->file())) {
395       printer->Print(
396           variables_,
397           "/**\n"
398           " * Use alternate mutation accessors instead.\n"
399           " */\n"
400           "@java.lang.Deprecated\n"
401           "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n"
402           "${$getMutable$capitalized_name$Value$}$() {\n"
403           "  return internalGetMutable$capitalized_name$().getMutableMap();\n"
404           "}\n");
405       printer->Annotate("{", "}", descriptor_);
406       WriteFieldDocComment(printer, descriptor_);
407       printer->Print(
408           variables_,
409           "$deprecation$public Builder ${$put$capitalized_name$Value$}$(\n"
410           "    $key_type$ key,\n"
411           "    $value_type$ value) {\n"
412           "  $key_null_check$\n"
413           "  internalGetMutable$capitalized_name$().getMutableMap()\n"
414           "      .put(key, value);\n"
415           "  return this;\n"
416           "}\n");
417       printer->Annotate("{", "}", descriptor_);
418       WriteFieldDocComment(printer, descriptor_);
419       printer->Print(
420           variables_,
421           "$deprecation$public Builder ${$putAll$capitalized_name$Value$}$(\n"
422           "    java.util.Map<$boxed_key_type$, $boxed_value_type$> values) {\n"
423           "  internalGetMutable$capitalized_name$().getMutableMap()\n"
424           "      .putAll(values);\n"
425           "  return this;\n"
426           "}\n");
427       printer->Annotate("{", "}", descriptor_);
428     }
429   } else {
430     printer->Print(
431         variables_,
432         "/**\n"
433         " * Use alternate mutation accessors instead.\n"
434         " */\n"
435         "@java.lang.Deprecated\n"
436         "public java.util.Map<$type_parameters$>\n"
437         "${$getMutable$capitalized_name$$}$() {\n"
438         "  return internalGetMutable$capitalized_name$().getMutableMap();\n"
439         "}\n");
440     printer->Annotate("{", "}", descriptor_);
441     WriteFieldDocComment(printer, descriptor_);
442     printer->Print(variables_,
443                    "$deprecation$"
444                    "public Builder ${$put$capitalized_name$$}$(\n"
445                    "    $key_type$ key,\n"
446                    "    $value_type$ value) {\n"
447                    "  $key_null_check$\n"
448                    "  $value_null_check$\n"
449                    "  internalGetMutable$capitalized_name$().getMutableMap()\n"
450                    "      .put(key, value);\n"
451                    "  return this;\n"
452                    "}\n");
453     printer->Annotate("{", "}", descriptor_);
454     WriteFieldDocComment(printer, descriptor_);
455     printer->Print(variables_,
456                    "$deprecation$\n"
457                    "public Builder ${$putAll$capitalized_name$$}$(\n"
458                    "    java.util.Map<$type_parameters$> values) {\n"
459                    "  internalGetMutable$capitalized_name$().getMutableMap()\n"
460                    "      .putAll(values);\n"
461                    "  return this;\n"
462                    "}\n");
463     printer->Annotate("{", "}", descriptor_);
464   }
465 }
466 
GenerateMapGetters(io::Printer * printer) const467 void ImmutableMapFieldGenerator::GenerateMapGetters(
468     io::Printer* printer) const {
469   printer->Print(variables_,
470                  "$deprecation$\n"
471                  "public int ${$get$capitalized_name$Count$}$() {\n"
472                  "  return internalGet$capitalized_name$().getMap().size();\n"
473                  "}\n");
474   printer->Annotate("{", "}", descriptor_);
475   WriteFieldDocComment(printer, descriptor_);
476   printer->Print(
477       variables_,
478       "$deprecation$\n"
479       "@java.lang.Override\n"
480       "public boolean ${$contains$capitalized_name$$}$(\n"
481       "    $key_type$ key) {\n"
482       "  $key_null_check$\n"
483       "  return internalGet$capitalized_name$().getMap().containsKey(key);\n"
484       "}\n");
485   printer->Annotate("{", "}", descriptor_);
486   if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) {
487     printer->Print(variables_,
488                    "/**\n"
489                    " * Use {@link #get$capitalized_name$Map()} instead.\n"
490                    " */\n"
491                    "@java.lang.Override\n"
492                    "@java.lang.Deprecated\n"
493                    "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
494                    "${$get$capitalized_name$$}$() {\n"
495                    "  return get$capitalized_name$Map();\n"
496                    "}\n");
497     printer->Annotate("{", "}", descriptor_);
498     WriteFieldDocComment(printer, descriptor_);
499     printer->Print(variables_,
500                    "@java.lang.Override\n"
501                    "$deprecation$\n"
502                    "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
503                    "${$get$capitalized_name$Map$}$() {\n"
504                    "  return internalGetAdapted$capitalized_name$Map(\n"
505                    "      internalGet$capitalized_name$().getMap());"
506                    "}\n");
507     printer->Annotate("{", "}", descriptor_);
508     WriteFieldDocComment(printer, descriptor_);
509     printer->Print(
510         variables_,
511         "@java.lang.Override\n"
512         "$deprecation$\n"
513         "public $value_enum_type$ ${$get$capitalized_name$OrDefault$}$(\n"
514         "    $key_type$ key,\n"
515         "    $value_enum_type$ defaultValue) {\n"
516         "  $key_null_check$\n"
517         "  java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
518         "      internalGet$capitalized_name$().getMap();\n"
519         "  return map.containsKey(key)\n"
520         "         ? $name$ValueConverter.doForward(map.get(key))\n"
521         "         : defaultValue;\n"
522         "}\n");
523     printer->Annotate("{", "}", descriptor_);
524     WriteFieldDocComment(printer, descriptor_);
525     printer->Print(
526         variables_,
527         "@java.lang.Override\n"
528         "$deprecation$\n"
529         "public $value_enum_type$ ${$get$capitalized_name$OrThrow$}$(\n"
530         "    $key_type$ key) {\n"
531         "  $key_null_check$\n"
532         "  java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
533         "      internalGet$capitalized_name$().getMap();\n"
534         "  if (!map.containsKey(key)) {\n"
535         "    throw new java.lang.IllegalArgumentException();\n"
536         "  }\n"
537         "  return $name$ValueConverter.doForward(map.get(key));\n"
538         "}\n");
539     printer->Annotate("{", "}", descriptor_);
540     if (SupportUnknownEnumValue(descriptor_->file())) {
541       printer->Print(
542           variables_,
543           "/**\n"
544           " * Use {@link #get$capitalized_name$ValueMap()} instead.\n"
545           " */\n"
546           "@java.lang.Override\n"
547           "@java.lang.Deprecated\n"
548           "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n"
549           "${$get$capitalized_name$Value$}$() {\n"
550           "  return get$capitalized_name$ValueMap();\n"
551           "}\n");
552       printer->Annotate("{", "}", descriptor_);
553       WriteFieldDocComment(printer, descriptor_);
554       printer->Print(
555           variables_,
556           "@java.lang.Override\n"
557           "$deprecation$\n"
558           "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n"
559           "${$get$capitalized_name$ValueMap$}$() {\n"
560           "  return internalGet$capitalized_name$().getMap();\n"
561           "}\n");
562       printer->Annotate("{", "}", descriptor_);
563       WriteFieldDocComment(printer, descriptor_);
564       printer->Print(
565           variables_,
566           "@java.lang.Override\n"
567           "$deprecation$\n"
568           "public $value_type$ ${$get$capitalized_name$ValueOrDefault$}$(\n"
569           "    $key_type$ key,\n"
570           "    $value_type$ defaultValue) {\n"
571           "  $key_null_check$\n"
572           "  java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
573           "      internalGet$capitalized_name$().getMap();\n"
574           "  return map.containsKey(key) ? map.get(key) : defaultValue;\n"
575           "}\n");
576       printer->Annotate("{", "}", descriptor_);
577       WriteFieldDocComment(printer, descriptor_);
578       printer->Print(
579           variables_,
580           "@java.lang.Override\n"
581           "$deprecation$\n"
582           "public $value_type$ ${$get$capitalized_name$ValueOrThrow$}$(\n"
583           "    $key_type$ key) {\n"
584           "  $key_null_check$\n"
585           "  java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
586           "      internalGet$capitalized_name$().getMap();\n"
587           "  if (!map.containsKey(key)) {\n"
588           "    throw new java.lang.IllegalArgumentException();\n"
589           "  }\n"
590           "  return map.get(key);\n"
591           "}\n");
592       printer->Annotate("{", "}", descriptor_);
593     }
594   } else {
595     printer->Print(variables_,
596                    "/**\n"
597                    " * Use {@link #get$capitalized_name$Map()} instead.\n"
598                    " */\n"
599                    "@java.lang.Override\n"
600                    "@java.lang.Deprecated\n"
601                    "public java.util.Map<$type_parameters$> "
602                    "${$get$capitalized_name$$}$() {\n"
603                    "  return get$capitalized_name$Map();\n"
604                    "}\n");
605     printer->Annotate("{", "}", descriptor_);
606     WriteFieldDocComment(printer, descriptor_);
607     printer->Print(variables_,
608                    "@java.lang.Override\n"
609                    "$deprecation$\n"
610                    "public java.util.Map<$type_parameters$> "
611                    "${$get$capitalized_name$Map$}$() {\n"
612                    "  return internalGet$capitalized_name$().getMap();\n"
613                    "}\n");
614     printer->Annotate("{", "}", descriptor_);
615     WriteFieldDocComment(printer, descriptor_);
616     printer->Print(
617         variables_,
618         "@java.lang.Override\n"
619         "$deprecation$\n"
620         "public $value_type$ ${$get$capitalized_name$OrDefault$}$(\n"
621         "    $key_type$ key,\n"
622         "    $value_type$ defaultValue) {\n"
623         "  $key_null_check$\n"
624         "  java.util.Map<$type_parameters$> map =\n"
625         "      internalGet$capitalized_name$().getMap();\n"
626         "  return map.containsKey(key) ? map.get(key) : defaultValue;\n"
627         "}\n");
628     printer->Annotate("{", "}", descriptor_);
629     WriteFieldDocComment(printer, descriptor_);
630     printer->Print(variables_,
631                    "@java.lang.Override\n"
632                    "$deprecation$\n"
633                    "public $value_type$ ${$get$capitalized_name$OrThrow$}$(\n"
634                    "    $key_type$ key) {\n"
635                    "  $key_null_check$\n"
636                    "  java.util.Map<$type_parameters$> map =\n"
637                    "      internalGet$capitalized_name$().getMap();\n"
638                    "  if (!map.containsKey(key)) {\n"
639                    "    throw new java.lang.IllegalArgumentException();\n"
640                    "  }\n"
641                    "  return map.get(key);\n"
642                    "}\n");
643     printer->Annotate("{", "}", descriptor_);
644   }
645 }
646 
GenerateFieldBuilderInitializationCode(io::Printer * printer) const647 void ImmutableMapFieldGenerator::GenerateFieldBuilderInitializationCode(
648     io::Printer* printer) const {
649   // Nothing to initialize.
650 }
651 
GenerateInitializationCode(io::Printer * printer) const652 void ImmutableMapFieldGenerator::GenerateInitializationCode(
653     io::Printer* printer) const {
654   // Nothing to initialize.
655 }
656 
GenerateBuilderClearCode(io::Printer * printer) const657 void ImmutableMapFieldGenerator::GenerateBuilderClearCode(
658     io::Printer* printer) const {
659   printer->Print(variables_,
660                  "internalGetMutable$capitalized_name$().clear();\n");
661 }
662 
GenerateMergingCode(io::Printer * printer) const663 void ImmutableMapFieldGenerator::GenerateMergingCode(
664     io::Printer* printer) const {
665   printer->Print(variables_,
666                  "internalGetMutable$capitalized_name$().mergeFrom(\n"
667                  "    other.internalGet$capitalized_name$());\n");
668 }
669 
GenerateBuildingCode(io::Printer * printer) const670 void ImmutableMapFieldGenerator::GenerateBuildingCode(
671     io::Printer* printer) const {
672   printer->Print(variables_,
673                  "result.$name$_ = internalGet$capitalized_name$();\n"
674                  "result.$name$_.makeImmutable();\n");
675 }
676 
GenerateBuilderParsingCode(io::Printer * printer) const677 void ImmutableMapFieldGenerator::GenerateBuilderParsingCode(
678     io::Printer* printer) const {
679   if (!SupportUnknownEnumValue(descriptor_->file()) &&
680       GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) {
681     printer->Print(
682         variables_,
683         "com.google.protobuf.ByteString bytes = input.readBytes();\n"
684         "com.google.protobuf.MapEntry<$type_parameters$>\n"
685         "$name$__ = $default_entry$.getParserForType().parseFrom(bytes);\n"
686         "if ($value_enum_type$.forNumber($name$__.getValue()) == null) {\n"
687         "  mergeUnknownLengthDelimitedField($number$, bytes);\n"
688         "} else {\n"
689         "  internalGetMutable$capitalized_name$().getMutableMap().put(\n"
690         "      $name$__.getKey(), $name$__.getValue());\n"
691         "}\n");
692   } else {
693     printer->Print(
694         variables_,
695         "com.google.protobuf.MapEntry<$type_parameters$>\n"
696         "$name$__ = input.readMessage(\n"
697         "    $default_entry$.getParserForType(), extensionRegistry);\n"
698         "internalGetMutable$capitalized_name$().getMutableMap().put(\n"
699         "    $name$__.getKey(), $name$__.getValue());\n");
700   }
701 }
702 
GenerateSerializationCode(io::Printer * printer) const703 void ImmutableMapFieldGenerator::GenerateSerializationCode(
704     io::Printer* printer) const {
705   printer->Print(variables_,
706                  "com.google.protobuf.GeneratedMessage$ver$\n"
707                  "  .serialize$short_key_type$MapTo(\n"
708                  "    output,\n"
709                  "    internalGet$capitalized_name$(),\n"
710                  "    $default_entry$,\n"
711                  "    $number$);\n");
712 }
713 
GenerateSerializedSizeCode(io::Printer * printer) const714 void ImmutableMapFieldGenerator::GenerateSerializedSizeCode(
715     io::Printer* printer) const {
716   printer->Print(
717       variables_,
718       "for (java.util.Map.Entry<$type_parameters$> entry\n"
719       "     : internalGet$capitalized_name$().getMap().entrySet()) {\n"
720       "  com.google.protobuf.MapEntry<$type_parameters$>\n"
721       "  $name$__ = $default_entry$.newBuilderForType()\n"
722       "      .setKey(entry.getKey())\n"
723       "      .setValue(entry.getValue())\n"
724       "      .build();\n"
725       "  size += com.google.protobuf.CodedOutputStream\n"
726       "      .computeMessageSize($number$, $name$__);\n"
727       "}\n");
728 }
729 
GenerateEqualsCode(io::Printer * printer) const730 void ImmutableMapFieldGenerator::GenerateEqualsCode(
731     io::Printer* printer) const {
732   printer->Print(variables_,
733                  "if (!internalGet$capitalized_name$().equals(\n"
734                  "    other.internalGet$capitalized_name$())) return false;\n");
735 }
736 
GenerateHashCode(io::Printer * printer) const737 void ImmutableMapFieldGenerator::GenerateHashCode(io::Printer* printer) const {
738   printer->Print(
739       variables_,
740       "if (!internalGet$capitalized_name$().getMap().isEmpty()) {\n"
741       "  hash = (37 * hash) + $constant_name$;\n"
742       "  hash = (53 * hash) + internalGet$capitalized_name$().hashCode();\n"
743       "}\n");
744 }
745 
GetBoxedType() const746 std::string ImmutableMapFieldGenerator::GetBoxedType() const {
747   return name_resolver_->GetImmutableClassName(descriptor_->message_type());
748 }
749 
750 }  // namespace java
751 }  // namespace compiler
752 }  // namespace protobuf
753 }  // namespace google
754