• 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   // For repeated fields, one bit is used for whether the array is immutable
142   // in the parsing constructor.
143   (*variables)["get_mutable_bit_parser"] =
144       GenerateGetBitMutableLocal(builderBitIndex);
145   (*variables)["set_mutable_bit_parser"] =
146       GenerateSetBitMutableLocal(builderBitIndex);
147 
148   (*variables)["default_entry"] =
149       (*variables)["capitalized_name"] + "DefaultEntryHolder.defaultEntry";
150   (*variables)["map_field_parameter"] = (*variables)["default_entry"];
151   (*variables)["descriptor"] =
152       name_resolver->GetImmutableClassName(descriptor->file()) + ".internal_" +
153       UniqueFileScopeIdentifier(descriptor->message_type()) + "_descriptor, ";
154   (*variables)["ver"] = GeneratedCodeVersionSuffix();
155 }
156 
157 }  // namespace
158 
ImmutableMapFieldGenerator(const FieldDescriptor * descriptor,int messageBitIndex,int builderBitIndex,Context * context)159 ImmutableMapFieldGenerator::ImmutableMapFieldGenerator(
160     const FieldDescriptor* descriptor, int messageBitIndex, int builderBitIndex,
161     Context* context)
162     : descriptor_(descriptor), name_resolver_(context->GetNameResolver()) {
163   SetMessageVariables(descriptor, messageBitIndex, builderBitIndex,
164                       context->GetFieldGeneratorInfo(descriptor), context,
165                       &variables_);
166 }
167 
~ImmutableMapFieldGenerator()168 ImmutableMapFieldGenerator::~ImmutableMapFieldGenerator() {}
169 
GetNumBitsForMessage() const170 int ImmutableMapFieldGenerator::GetNumBitsForMessage() const { return 0; }
171 
GetNumBitsForBuilder() const172 int ImmutableMapFieldGenerator::GetNumBitsForBuilder() const { return 1; }
173 
GenerateInterfaceMembers(io::Printer * printer) const174 void ImmutableMapFieldGenerator::GenerateInterfaceMembers(
175     io::Printer* printer) const {
176   WriteFieldDocComment(printer, descriptor_);
177   printer->Print(variables_,
178                  "$deprecation$int ${$get$capitalized_name$Count$}$();\n");
179   printer->Annotate("{", "}", descriptor_);
180   WriteFieldDocComment(printer, descriptor_);
181   printer->Print(variables_,
182                  "$deprecation$boolean ${$contains$capitalized_name$$}$(\n"
183                  "    $key_type$ key);\n");
184   printer->Annotate("{", "}", descriptor_);
185   if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) {
186     printer->Print(variables_,
187                    "/**\n"
188                    " * Use {@link #get$capitalized_name$Map()} instead.\n"
189                    " */\n"
190                    "@java.lang.Deprecated\n"
191                    "java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
192                    "${$get$capitalized_name$$}$();\n");
193     printer->Annotate("{", "}", descriptor_);
194     WriteFieldDocComment(printer, descriptor_);
195     printer->Print(
196         variables_,
197         "$deprecation$java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
198         "${$get$capitalized_name$Map$}$();\n");
199     printer->Annotate("{", "}", descriptor_);
200     WriteFieldDocComment(printer, descriptor_);
201     printer->Print(
202         variables_,
203         "$deprecation$$value_enum_type$ ${$get$capitalized_name$OrDefault$}$(\n"
204         "    $key_type$ key,\n"
205         "    $value_enum_type$ defaultValue);\n");
206     printer->Annotate("{", "}", descriptor_);
207     WriteFieldDocComment(printer, descriptor_);
208     printer->Print(
209         variables_,
210         "$deprecation$$value_enum_type$ ${$get$capitalized_name$OrThrow$}$(\n"
211         "    $key_type$ key);\n");
212     printer->Annotate("{", "}", descriptor_);
213     if (SupportUnknownEnumValue(descriptor_->file())) {
214       printer->Print(
215           variables_,
216           "/**\n"
217           " * Use {@link #get$capitalized_name$ValueMap()} instead.\n"
218           " */\n"
219           "@java.lang.Deprecated\n"
220           "java.util.Map<$type_parameters$>\n"
221           "${$get$capitalized_name$Value$}$();\n");
222       printer->Annotate("{", "}", descriptor_);
223       WriteFieldDocComment(printer, descriptor_);
224       printer->Print(variables_,
225                      "$deprecation$java.util.Map<$type_parameters$>\n"
226                      "${$get$capitalized_name$ValueMap$}$();\n");
227       printer->Annotate("{", "}", descriptor_);
228       WriteFieldDocComment(printer, descriptor_);
229       printer->Print(variables_,
230                      "$deprecation$\n"
231                      "$value_type$ ${$get$capitalized_name$ValueOrDefault$}$(\n"
232                      "    $key_type$ key,\n"
233                      "    $value_type$ defaultValue);\n");
234       printer->Annotate("{", "}", descriptor_);
235       WriteFieldDocComment(printer, descriptor_);
236       printer->Print(variables_,
237                      "$deprecation$\n"
238                      "$value_type$ ${$get$capitalized_name$ValueOrThrow$}$(\n"
239                      "    $key_type$ key);\n");
240       printer->Annotate("{", "}", descriptor_);
241     }
242   } else {
243     printer->Print(variables_,
244                    "/**\n"
245                    " * Use {@link #get$capitalized_name$Map()} instead.\n"
246                    " */\n"
247                    "@java.lang.Deprecated\n"
248                    "java.util.Map<$type_parameters$>\n"
249                    "${$get$capitalized_name$$}$();\n");
250     printer->Annotate("{", "}", descriptor_);
251     WriteFieldDocComment(printer, descriptor_);
252     printer->Print(variables_,
253                    "$deprecation$java.util.Map<$type_parameters$>\n"
254                    "${$get$capitalized_name$Map$}$();\n");
255     printer->Annotate("{", "}", descriptor_);
256     WriteFieldDocComment(printer, descriptor_);
257     printer->Print(variables_,
258                    "$deprecation$\n"
259                    "$value_type$ ${$get$capitalized_name$OrDefault$}$(\n"
260                    "    $key_type$ key,\n"
261                    "    $value_type$ defaultValue);\n");
262     printer->Annotate("{", "}", descriptor_);
263     WriteFieldDocComment(printer, descriptor_);
264     printer->Print(variables_,
265                    "$deprecation$\n"
266                    "$value_type$ ${$get$capitalized_name$OrThrow$}$(\n"
267                    "    $key_type$ key);\n");
268     printer->Annotate("{", "}", descriptor_);
269   }
270 }
271 
GenerateMembers(io::Printer * printer) const272 void ImmutableMapFieldGenerator::GenerateMembers(io::Printer* printer) const {
273   printer->Print(
274       variables_,
275       "private static final class $capitalized_name$DefaultEntryHolder {\n"
276       "  static final com.google.protobuf.MapEntry<\n"
277       "      $type_parameters$> defaultEntry =\n"
278       "          com.google.protobuf.MapEntry\n"
279       "          .<$type_parameters$>newDefaultInstance(\n"
280       "              $descriptor$\n"
281       "              $key_wire_type$,\n"
282       "              $key_default_value$,\n"
283       "              $value_wire_type$,\n"
284       "              $value_default_value$);\n"
285       "}\n");
286   printer->Print(variables_,
287                  "private com.google.protobuf.MapField<\n"
288                  "    $type_parameters$> $name$_;\n"
289                  "private com.google.protobuf.MapField<$type_parameters$>\n"
290                  "internalGet$capitalized_name$() {\n"
291                  "  if ($name$_ == null) {\n"
292                  "    return com.google.protobuf.MapField.emptyMapField(\n"
293                  "        $map_field_parameter$);\n"
294                  "  }\n"
295                  "  return $name$_;\n"
296                  "}\n");
297   if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) {
298     printer->Print(
299         variables_,
300         "private static final\n"
301         "com.google.protobuf.Internal.MapAdapter.Converter<\n"
302         "    java.lang.Integer, $value_enum_type$> $name$ValueConverter =\n"
303         "        com.google.protobuf.Internal.MapAdapter.newEnumConverter(\n"
304         "            $value_enum_type$.internalGetValueMap(),\n"
305         "            $unrecognized_value$);\n");
306     printer->Print(
307         variables_,
308         "private static final java.util.Map<$boxed_key_type$, "
309         "$value_enum_type$>\n"
310         "internalGetAdapted$capitalized_name$Map(\n"
311         "    java.util.Map<$boxed_key_type$, $boxed_value_type$> map) {\n"
312         "  return new com.google.protobuf.Internal.MapAdapter<\n"
313         "      $boxed_key_type$, $value_enum_type$, java.lang.Integer>(\n"
314         "          map, $name$ValueConverter);\n"
315         "}\n");
316   }
317   GenerateMapGetters(printer);
318 }
319 
GenerateBuilderMembers(io::Printer * printer) const320 void ImmutableMapFieldGenerator::GenerateBuilderMembers(
321     io::Printer* printer) const {
322   printer->Print(variables_,
323                  "private com.google.protobuf.MapField<\n"
324                  "    $type_parameters$> $name$_;\n"
325                  "private com.google.protobuf.MapField<$type_parameters$>\n"
326                  "internalGet$capitalized_name$() {\n"
327                  "  if ($name$_ == null) {\n"
328                  "    return com.google.protobuf.MapField.emptyMapField(\n"
329                  "        $map_field_parameter$);\n"
330                  "  }\n"
331                  "  return $name$_;\n"
332                  "}\n"
333                  "private com.google.protobuf.MapField<$type_parameters$>\n"
334                  "internalGetMutable$capitalized_name$() {\n"
335                  "  $on_changed$;\n"
336                  "  if ($name$_ == null) {\n"
337                  "    $name$_ = com.google.protobuf.MapField.newMapField(\n"
338                  "        $map_field_parameter$);\n"
339                  "  }\n"
340                  "  if (!$name$_.isMutable()) {\n"
341                  "    $name$_ = $name$_.copy();\n"
342                  "  }\n"
343                  "  return $name$_;\n"
344                  "}\n");
345   GenerateMapGetters(printer);
346   printer->Print(variables_,
347                  "$deprecation$\n"
348                  "public Builder ${$clear$capitalized_name$$}$() {\n"
349                  "  internalGetMutable$capitalized_name$().getMutableMap()\n"
350                  "      .clear();\n"
351                  "  return this;\n"
352                  "}\n");
353   printer->Annotate("{", "}", descriptor_);
354   WriteFieldDocComment(printer, descriptor_);
355   printer->Print(variables_,
356                  "$deprecation$\n"
357                  "public Builder ${$remove$capitalized_name$$}$(\n"
358                  "    $key_type$ key) {\n"
359                  "  $key_null_check$\n"
360                  "  internalGetMutable$capitalized_name$().getMutableMap()\n"
361                  "      .remove(key);\n"
362                  "  return this;\n"
363                  "}\n");
364   printer->Annotate("{", "}", descriptor_);
365   if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) {
366     printer->Print(
367         variables_,
368         "/**\n"
369         " * Use alternate mutation accessors instead.\n"
370         " */\n"
371         "@java.lang.Deprecated\n"
372         "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
373         "${$getMutable$capitalized_name$$}$() {\n"
374         "  return internalGetAdapted$capitalized_name$Map(\n"
375         "       internalGetMutable$capitalized_name$().getMutableMap());\n"
376         "}\n");
377     printer->Annotate("{", "}", descriptor_);
378     WriteFieldDocComment(printer, descriptor_);
379     printer->Print(variables_,
380                    "$deprecation$public Builder ${$put$capitalized_name$$}$(\n"
381                    "    $key_type$ key,\n"
382                    "    $value_enum_type$ value) {\n"
383                    "  $key_null_check$\n"
384                    "  $value_null_check$\n"
385                    "  internalGetMutable$capitalized_name$().getMutableMap()\n"
386                    "      .put(key, $name$ValueConverter.doBackward(value));\n"
387                    "  return this;\n"
388                    "}\n");
389     printer->Annotate("{", "}", descriptor_);
390     WriteFieldDocComment(printer, descriptor_);
391     printer->Print(
392         variables_,
393         "$deprecation$public Builder ${$putAll$capitalized_name$$}$(\n"
394         "    java.util.Map<$boxed_key_type$, $value_enum_type$> values) {\n"
395         "  internalGetAdapted$capitalized_name$Map(\n"
396         "      internalGetMutable$capitalized_name$().getMutableMap())\n"
397         "          .putAll(values);\n"
398         "  return this;\n"
399         "}\n");
400     printer->Annotate("{", "}", descriptor_);
401     if (SupportUnknownEnumValue(descriptor_->file())) {
402       printer->Print(
403           variables_,
404           "/**\n"
405           " * Use alternate mutation accessors instead.\n"
406           " */\n"
407           "@java.lang.Deprecated\n"
408           "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n"
409           "${$getMutable$capitalized_name$Value$}$() {\n"
410           "  return internalGetMutable$capitalized_name$().getMutableMap();\n"
411           "}\n");
412       printer->Annotate("{", "}", descriptor_);
413       WriteFieldDocComment(printer, descriptor_);
414       printer->Print(
415           variables_,
416           "$deprecation$public Builder ${$put$capitalized_name$Value$}$(\n"
417           "    $key_type$ key,\n"
418           "    $value_type$ value) {\n"
419           "  $key_null_check$\n"
420           "  internalGetMutable$capitalized_name$().getMutableMap()\n"
421           "      .put(key, value);\n"
422           "  return this;\n"
423           "}\n");
424       printer->Annotate("{", "}", descriptor_);
425       WriteFieldDocComment(printer, descriptor_);
426       printer->Print(
427           variables_,
428           "$deprecation$public Builder ${$putAll$capitalized_name$Value$}$(\n"
429           "    java.util.Map<$boxed_key_type$, $boxed_value_type$> values) {\n"
430           "  internalGetMutable$capitalized_name$().getMutableMap()\n"
431           "      .putAll(values);\n"
432           "  return this;\n"
433           "}\n");
434       printer->Annotate("{", "}", descriptor_);
435     }
436   } else {
437     printer->Print(
438         variables_,
439         "/**\n"
440         " * Use alternate mutation accessors instead.\n"
441         " */\n"
442         "@java.lang.Deprecated\n"
443         "public java.util.Map<$type_parameters$>\n"
444         "${$getMutable$capitalized_name$$}$() {\n"
445         "  return internalGetMutable$capitalized_name$().getMutableMap();\n"
446         "}\n");
447     printer->Annotate("{", "}", descriptor_);
448     WriteFieldDocComment(printer, descriptor_);
449     printer->Print(variables_,
450                    "$deprecation$"
451                    "public Builder ${$put$capitalized_name$$}$(\n"
452                    "    $key_type$ key,\n"
453                    "    $value_type$ value) {\n"
454                    "  $key_null_check$\n"
455                    "  $value_null_check$\n"
456                    "  internalGetMutable$capitalized_name$().getMutableMap()\n"
457                    "      .put(key, value);\n"
458                    "  return this;\n"
459                    "}\n");
460     printer->Annotate("{", "}", descriptor_);
461     WriteFieldDocComment(printer, descriptor_);
462     printer->Print(variables_,
463                    "$deprecation$\n"
464                    "public Builder ${$putAll$capitalized_name$$}$(\n"
465                    "    java.util.Map<$type_parameters$> values) {\n"
466                    "  internalGetMutable$capitalized_name$().getMutableMap()\n"
467                    "      .putAll(values);\n"
468                    "  return this;\n"
469                    "}\n");
470     printer->Annotate("{", "}", descriptor_);
471   }
472 }
473 
GenerateMapGetters(io::Printer * printer) const474 void ImmutableMapFieldGenerator::GenerateMapGetters(
475     io::Printer* printer) const {
476   printer->Print(variables_,
477                  "$deprecation$\n"
478                  "public int ${$get$capitalized_name$Count$}$() {\n"
479                  "  return internalGet$capitalized_name$().getMap().size();\n"
480                  "}\n");
481   printer->Annotate("{", "}", descriptor_);
482   WriteFieldDocComment(printer, descriptor_);
483   printer->Print(
484       variables_,
485       "$deprecation$\n"
486       "@java.lang.Override\n"
487       "public boolean ${$contains$capitalized_name$$}$(\n"
488       "    $key_type$ key) {\n"
489       "  $key_null_check$\n"
490       "  return internalGet$capitalized_name$().getMap().containsKey(key);\n"
491       "}\n");
492   printer->Annotate("{", "}", descriptor_);
493   if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) {
494     printer->Print(variables_,
495                    "/**\n"
496                    " * Use {@link #get$capitalized_name$Map()} instead.\n"
497                    " */\n"
498                    "@java.lang.Override\n"
499                    "@java.lang.Deprecated\n"
500                    "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
501                    "${$get$capitalized_name$$}$() {\n"
502                    "  return get$capitalized_name$Map();\n"
503                    "}\n");
504     printer->Annotate("{", "}", descriptor_);
505     WriteFieldDocComment(printer, descriptor_);
506     printer->Print(variables_,
507                    "@java.lang.Override\n"
508                    "$deprecation$\n"
509                    "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
510                    "${$get$capitalized_name$Map$}$() {\n"
511                    "  return internalGetAdapted$capitalized_name$Map(\n"
512                    "      internalGet$capitalized_name$().getMap());"
513                    "}\n");
514     printer->Annotate("{", "}", descriptor_);
515     WriteFieldDocComment(printer, descriptor_);
516     printer->Print(
517         variables_,
518         "@java.lang.Override\n"
519         "$deprecation$\n"
520         "public $value_enum_type$ ${$get$capitalized_name$OrDefault$}$(\n"
521         "    $key_type$ key,\n"
522         "    $value_enum_type$ defaultValue) {\n"
523         "  $key_null_check$\n"
524         "  java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
525         "      internalGet$capitalized_name$().getMap();\n"
526         "  return map.containsKey(key)\n"
527         "         ? $name$ValueConverter.doForward(map.get(key))\n"
528         "         : defaultValue;\n"
529         "}\n");
530     printer->Annotate("{", "}", descriptor_);
531     WriteFieldDocComment(printer, descriptor_);
532     printer->Print(
533         variables_,
534         "@java.lang.Override\n"
535         "$deprecation$\n"
536         "public $value_enum_type$ ${$get$capitalized_name$OrThrow$}$(\n"
537         "    $key_type$ key) {\n"
538         "  $key_null_check$\n"
539         "  java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
540         "      internalGet$capitalized_name$().getMap();\n"
541         "  if (!map.containsKey(key)) {\n"
542         "    throw new java.lang.IllegalArgumentException();\n"
543         "  }\n"
544         "  return $name$ValueConverter.doForward(map.get(key));\n"
545         "}\n");
546     printer->Annotate("{", "}", descriptor_);
547     if (SupportUnknownEnumValue(descriptor_->file())) {
548       printer->Print(
549           variables_,
550           "/**\n"
551           " * Use {@link #get$capitalized_name$ValueMap()} instead.\n"
552           " */\n"
553           "@java.lang.Override\n"
554           "@java.lang.Deprecated\n"
555           "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n"
556           "${$get$capitalized_name$Value$}$() {\n"
557           "  return get$capitalized_name$ValueMap();\n"
558           "}\n");
559       printer->Annotate("{", "}", descriptor_);
560       WriteFieldDocComment(printer, descriptor_);
561       printer->Print(
562           variables_,
563           "@java.lang.Override\n"
564           "$deprecation$\n"
565           "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n"
566           "${$get$capitalized_name$ValueMap$}$() {\n"
567           "  return internalGet$capitalized_name$().getMap();\n"
568           "}\n");
569       printer->Annotate("{", "}", descriptor_);
570       WriteFieldDocComment(printer, descriptor_);
571       printer->Print(
572           variables_,
573           "@java.lang.Override\n"
574           "$deprecation$\n"
575           "public $value_type$ ${$get$capitalized_name$ValueOrDefault$}$(\n"
576           "    $key_type$ key,\n"
577           "    $value_type$ defaultValue) {\n"
578           "  $key_null_check$\n"
579           "  java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
580           "      internalGet$capitalized_name$().getMap();\n"
581           "  return map.containsKey(key) ? map.get(key) : defaultValue;\n"
582           "}\n");
583       printer->Annotate("{", "}", descriptor_);
584       WriteFieldDocComment(printer, descriptor_);
585       printer->Print(
586           variables_,
587           "@java.lang.Override\n"
588           "$deprecation$\n"
589           "public $value_type$ ${$get$capitalized_name$ValueOrThrow$}$(\n"
590           "    $key_type$ key) {\n"
591           "  $key_null_check$\n"
592           "  java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
593           "      internalGet$capitalized_name$().getMap();\n"
594           "  if (!map.containsKey(key)) {\n"
595           "    throw new java.lang.IllegalArgumentException();\n"
596           "  }\n"
597           "  return map.get(key);\n"
598           "}\n");
599       printer->Annotate("{", "}", descriptor_);
600     }
601   } else {
602     printer->Print(variables_,
603                    "/**\n"
604                    " * Use {@link #get$capitalized_name$Map()} instead.\n"
605                    " */\n"
606                    "@java.lang.Override\n"
607                    "@java.lang.Deprecated\n"
608                    "public java.util.Map<$type_parameters$> "
609                    "${$get$capitalized_name$$}$() {\n"
610                    "  return get$capitalized_name$Map();\n"
611                    "}\n");
612     printer->Annotate("{", "}", descriptor_);
613     WriteFieldDocComment(printer, descriptor_);
614     printer->Print(variables_,
615                    "@java.lang.Override\n"
616                    "$deprecation$\n"
617                    "public java.util.Map<$type_parameters$> "
618                    "${$get$capitalized_name$Map$}$() {\n"
619                    "  return internalGet$capitalized_name$().getMap();\n"
620                    "}\n");
621     printer->Annotate("{", "}", descriptor_);
622     WriteFieldDocComment(printer, descriptor_);
623     printer->Print(
624         variables_,
625         "@java.lang.Override\n"
626         "$deprecation$\n"
627         "public $value_type$ ${$get$capitalized_name$OrDefault$}$(\n"
628         "    $key_type$ key,\n"
629         "    $value_type$ defaultValue) {\n"
630         "  $key_null_check$\n"
631         "  java.util.Map<$type_parameters$> map =\n"
632         "      internalGet$capitalized_name$().getMap();\n"
633         "  return map.containsKey(key) ? map.get(key) : defaultValue;\n"
634         "}\n");
635     printer->Annotate("{", "}", descriptor_);
636     WriteFieldDocComment(printer, descriptor_);
637     printer->Print(variables_,
638                    "@java.lang.Override\n"
639                    "$deprecation$\n"
640                    "public $value_type$ ${$get$capitalized_name$OrThrow$}$(\n"
641                    "    $key_type$ key) {\n"
642                    "  $key_null_check$\n"
643                    "  java.util.Map<$type_parameters$> map =\n"
644                    "      internalGet$capitalized_name$().getMap();\n"
645                    "  if (!map.containsKey(key)) {\n"
646                    "    throw new java.lang.IllegalArgumentException();\n"
647                    "  }\n"
648                    "  return map.get(key);\n"
649                    "}\n");
650     printer->Annotate("{", "}", descriptor_);
651   }
652 }
653 
GenerateFieldBuilderInitializationCode(io::Printer * printer) const654 void ImmutableMapFieldGenerator::GenerateFieldBuilderInitializationCode(
655     io::Printer* printer) const {
656   // Nothing to initialize.
657 }
658 
GenerateInitializationCode(io::Printer * printer) const659 void ImmutableMapFieldGenerator::GenerateInitializationCode(
660     io::Printer* printer) const {
661   // Nothing to initialize.
662 }
663 
GenerateBuilderClearCode(io::Printer * printer) const664 void ImmutableMapFieldGenerator::GenerateBuilderClearCode(
665     io::Printer* printer) const {
666   printer->Print(variables_,
667                  "internalGetMutable$capitalized_name$().clear();\n");
668 }
669 
GenerateMergingCode(io::Printer * printer) const670 void ImmutableMapFieldGenerator::GenerateMergingCode(
671     io::Printer* printer) const {
672   printer->Print(variables_,
673                  "internalGetMutable$capitalized_name$().mergeFrom(\n"
674                  "    other.internalGet$capitalized_name$());\n");
675 }
676 
GenerateBuildingCode(io::Printer * printer) const677 void ImmutableMapFieldGenerator::GenerateBuildingCode(
678     io::Printer* printer) const {
679   printer->Print(variables_,
680                  "result.$name$_ = internalGet$capitalized_name$();\n"
681                  "result.$name$_.makeImmutable();\n");
682 }
683 
GenerateParsingCode(io::Printer * printer) const684 void ImmutableMapFieldGenerator::GenerateParsingCode(
685     io::Printer* printer) const {
686   printer->Print(variables_,
687                  "if (!$get_mutable_bit_parser$) {\n"
688                  "  $name$_ = com.google.protobuf.MapField.newMapField(\n"
689                  "      $map_field_parameter$);\n"
690                  "  $set_mutable_bit_parser$;\n"
691                  "}\n");
692   if (!SupportUnknownEnumValue(descriptor_->file()) &&
693       GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) {
694     printer->Print(
695         variables_,
696         "com.google.protobuf.ByteString bytes = input.readBytes();\n"
697         "com.google.protobuf.MapEntry<$type_parameters$>\n"
698         "$name$__ = $default_entry$.getParserForType().parseFrom(bytes);\n");
699     printer->Print(
700         variables_,
701         "if ($value_enum_type$.forNumber($name$__.getValue()) == null) {\n"
702         "  unknownFields.mergeLengthDelimitedField($number$, bytes);\n"
703         "} else {\n"
704         "  $name$_.getMutableMap().put(\n"
705         "      $name$__.getKey(), $name$__.getValue());\n"
706         "}\n");
707   } else {
708     printer->Print(
709         variables_,
710         "com.google.protobuf.MapEntry<$type_parameters$>\n"
711         "$name$__ = input.readMessage(\n"
712         "    $default_entry$.getParserForType(), extensionRegistry);\n"
713         "$name$_.getMutableMap().put(\n"
714         "    $name$__.getKey(), $name$__.getValue());\n");
715   }
716 }
717 
GenerateParsingDoneCode(io::Printer * printer) const718 void ImmutableMapFieldGenerator::GenerateParsingDoneCode(
719     io::Printer* printer) const {
720   // Nothing to do here.
721 }
722 
GenerateSerializationCode(io::Printer * printer) const723 void ImmutableMapFieldGenerator::GenerateSerializationCode(
724     io::Printer* printer) const {
725   printer->Print(variables_,
726                  "com.google.protobuf.GeneratedMessage$ver$\n"
727                  "  .serialize$short_key_type$MapTo(\n"
728                  "    output,\n"
729                  "    internalGet$capitalized_name$(),\n"
730                  "    $default_entry$,\n"
731                  "    $number$);\n");
732 }
733 
GenerateSerializedSizeCode(io::Printer * printer) const734 void ImmutableMapFieldGenerator::GenerateSerializedSizeCode(
735     io::Printer* printer) const {
736   printer->Print(
737       variables_,
738       "for (java.util.Map.Entry<$type_parameters$> entry\n"
739       "     : internalGet$capitalized_name$().getMap().entrySet()) {\n"
740       "  com.google.protobuf.MapEntry<$type_parameters$>\n"
741       "  $name$__ = $default_entry$.newBuilderForType()\n"
742       "      .setKey(entry.getKey())\n"
743       "      .setValue(entry.getValue())\n"
744       "      .build();\n"
745       "  size += com.google.protobuf.CodedOutputStream\n"
746       "      .computeMessageSize($number$, $name$__);\n"
747       "}\n");
748 }
749 
GenerateEqualsCode(io::Printer * printer) const750 void ImmutableMapFieldGenerator::GenerateEqualsCode(
751     io::Printer* printer) const {
752   printer->Print(variables_,
753                  "if (!internalGet$capitalized_name$().equals(\n"
754                  "    other.internalGet$capitalized_name$())) return false;\n");
755 }
756 
GenerateHashCode(io::Printer * printer) const757 void ImmutableMapFieldGenerator::GenerateHashCode(io::Printer* printer) const {
758   printer->Print(
759       variables_,
760       "if (!internalGet$capitalized_name$().getMap().isEmpty()) {\n"
761       "  hash = (37 * hash) + $constant_name$;\n"
762       "  hash = (53 * hash) + internalGet$capitalized_name$().hashCode();\n"
763       "}\n");
764 }
765 
GetBoxedType() const766 std::string ImmutableMapFieldGenerator::GetBoxedType() const {
767   return name_resolver_->GetImmutableClassName(descriptor_->message_type());
768 }
769 
770 }  // namespace java
771 }  // namespace compiler
772 }  // namespace protobuf
773 }  // namespace google
774