• 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       "public boolean ${$contains$capitalized_name$$}$(\n"
487       "    $key_type$ key) {\n"
488       "  $key_null_check$\n"
489       "  return internalGet$capitalized_name$().getMap().containsKey(key);\n"
490       "}\n");
491   printer->Annotate("{", "}", descriptor_);
492   if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) {
493     printer->Print(variables_,
494                    "/**\n"
495                    " * Use {@link #get$capitalized_name$Map()} instead.\n"
496                    " */\n"
497                    "@java.lang.Deprecated\n"
498                    "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
499                    "${$get$capitalized_name$$}$() {\n"
500                    "  return get$capitalized_name$Map();\n"
501                    "}\n");
502     printer->Annotate("{", "}", descriptor_);
503     WriteFieldDocComment(printer, descriptor_);
504     printer->Print(variables_,
505                    "$deprecation$\n"
506                    "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
507                    "${$get$capitalized_name$Map$}$() {\n"
508                    "  return internalGetAdapted$capitalized_name$Map(\n"
509                    "      internalGet$capitalized_name$().getMap());"
510                    "}\n");
511     printer->Annotate("{", "}", descriptor_);
512     WriteFieldDocComment(printer, descriptor_);
513     printer->Print(
514         variables_,
515         "$deprecation$\n"
516         "public $value_enum_type$ ${$get$capitalized_name$OrDefault$}$(\n"
517         "    $key_type$ key,\n"
518         "    $value_enum_type$ defaultValue) {\n"
519         "  $key_null_check$\n"
520         "  java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
521         "      internalGet$capitalized_name$().getMap();\n"
522         "  return map.containsKey(key)\n"
523         "         ? $name$ValueConverter.doForward(map.get(key))\n"
524         "         : defaultValue;\n"
525         "}\n");
526     printer->Annotate("{", "}", descriptor_);
527     WriteFieldDocComment(printer, descriptor_);
528     printer->Print(
529         variables_,
530         "$deprecation$\n"
531         "public $value_enum_type$ ${$get$capitalized_name$OrThrow$}$(\n"
532         "    $key_type$ key) {\n"
533         "  $key_null_check$\n"
534         "  java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
535         "      internalGet$capitalized_name$().getMap();\n"
536         "  if (!map.containsKey(key)) {\n"
537         "    throw new java.lang.IllegalArgumentException();\n"
538         "  }\n"
539         "  return $name$ValueConverter.doForward(map.get(key));\n"
540         "}\n");
541     printer->Annotate("{", "}", descriptor_);
542     if (SupportUnknownEnumValue(descriptor_->file())) {
543       printer->Print(
544           variables_,
545           "/**\n"
546           " * Use {@link #get$capitalized_name$ValueMap()} instead.\n"
547           " */\n"
548           "@java.lang.Deprecated\n"
549           "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n"
550           "${$get$capitalized_name$Value$}$() {\n"
551           "  return get$capitalized_name$ValueMap();\n"
552           "}\n");
553       printer->Annotate("{", "}", descriptor_);
554       WriteFieldDocComment(printer, descriptor_);
555       printer->Print(
556           variables_,
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           "$deprecation$\n"
567           "public $value_type$ ${$get$capitalized_name$ValueOrDefault$}$(\n"
568           "    $key_type$ key,\n"
569           "    $value_type$ defaultValue) {\n"
570           "  $key_null_check$\n"
571           "  java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
572           "      internalGet$capitalized_name$().getMap();\n"
573           "  return map.containsKey(key) ? map.get(key) : defaultValue;\n"
574           "}\n");
575       printer->Annotate("{", "}", descriptor_);
576       WriteFieldDocComment(printer, descriptor_);
577       printer->Print(
578           variables_,
579           "$deprecation$\n"
580           "public $value_type$ ${$get$capitalized_name$ValueOrThrow$}$(\n"
581           "    $key_type$ key) {\n"
582           "  $key_null_check$\n"
583           "  java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
584           "      internalGet$capitalized_name$().getMap();\n"
585           "  if (!map.containsKey(key)) {\n"
586           "    throw new java.lang.IllegalArgumentException();\n"
587           "  }\n"
588           "  return map.get(key);\n"
589           "}\n");
590       printer->Annotate("{", "}", descriptor_);
591     }
592   } else {
593     printer->Print(variables_,
594                    "/**\n"
595                    " * Use {@link #get$capitalized_name$Map()} instead.\n"
596                    " */\n"
597                    "@java.lang.Deprecated\n"
598                    "public java.util.Map<$type_parameters$> "
599                    "${$get$capitalized_name$$}$() {\n"
600                    "  return get$capitalized_name$Map();\n"
601                    "}\n");
602     printer->Annotate("{", "}", descriptor_);
603     WriteFieldDocComment(printer, descriptor_);
604     printer->Print(variables_,
605                    "$deprecation$\n"
606                    "public java.util.Map<$type_parameters$> "
607                    "${$get$capitalized_name$Map$}$() {\n"
608                    "  return internalGet$capitalized_name$().getMap();\n"
609                    "}\n");
610     printer->Annotate("{", "}", descriptor_);
611     WriteFieldDocComment(printer, descriptor_);
612     printer->Print(
613         variables_,
614         "$deprecation$\n"
615         "public $value_type$ ${$get$capitalized_name$OrDefault$}$(\n"
616         "    $key_type$ key,\n"
617         "    $value_type$ defaultValue) {\n"
618         "  $key_null_check$\n"
619         "  java.util.Map<$type_parameters$> map =\n"
620         "      internalGet$capitalized_name$().getMap();\n"
621         "  return map.containsKey(key) ? map.get(key) : defaultValue;\n"
622         "}\n");
623     printer->Annotate("{", "}", descriptor_);
624     WriteFieldDocComment(printer, descriptor_);
625     printer->Print(variables_,
626                    "$deprecation$\n"
627                    "public $value_type$ ${$get$capitalized_name$OrThrow$}$(\n"
628                    "    $key_type$ key) {\n"
629                    "  $key_null_check$\n"
630                    "  java.util.Map<$type_parameters$> map =\n"
631                    "      internalGet$capitalized_name$().getMap();\n"
632                    "  if (!map.containsKey(key)) {\n"
633                    "    throw new java.lang.IllegalArgumentException();\n"
634                    "  }\n"
635                    "  return map.get(key);\n"
636                    "}\n");
637     printer->Annotate("{", "}", descriptor_);
638   }
639 }
640 
GenerateFieldBuilderInitializationCode(io::Printer * printer) const641 void ImmutableMapFieldGenerator::GenerateFieldBuilderInitializationCode(
642     io::Printer* printer) const {
643   // Nothing to initialize.
644 }
645 
GenerateInitializationCode(io::Printer * printer) const646 void ImmutableMapFieldGenerator::GenerateInitializationCode(
647     io::Printer* printer) const {
648   // Nothing to initialize.
649 }
650 
GenerateBuilderClearCode(io::Printer * printer) const651 void ImmutableMapFieldGenerator::GenerateBuilderClearCode(
652     io::Printer* printer) const {
653   printer->Print(variables_,
654                  "internalGetMutable$capitalized_name$().clear();\n");
655 }
656 
GenerateMergingCode(io::Printer * printer) const657 void ImmutableMapFieldGenerator::GenerateMergingCode(
658     io::Printer* printer) const {
659   printer->Print(variables_,
660                  "internalGetMutable$capitalized_name$().mergeFrom(\n"
661                  "    other.internalGet$capitalized_name$());\n");
662 }
663 
GenerateBuildingCode(io::Printer * printer) const664 void ImmutableMapFieldGenerator::GenerateBuildingCode(
665     io::Printer* printer) const {
666   printer->Print(variables_,
667                  "result.$name$_ = internalGet$capitalized_name$();\n"
668                  "result.$name$_.makeImmutable();\n");
669 }
670 
GenerateParsingCode(io::Printer * printer) const671 void ImmutableMapFieldGenerator::GenerateParsingCode(
672     io::Printer* printer) const {
673   printer->Print(variables_,
674                  "if (!$get_mutable_bit_parser$) {\n"
675                  "  $name$_ = com.google.protobuf.MapField.newMapField(\n"
676                  "      $map_field_parameter$);\n"
677                  "  $set_mutable_bit_parser$;\n"
678                  "}\n");
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     printer->Print(
687         variables_,
688         "if ($value_enum_type$.forNumber($name$__.getValue()) == null) {\n"
689         "  unknownFields.mergeLengthDelimitedField($number$, bytes);\n"
690         "} else {\n"
691         "  $name$_.getMutableMap().put(\n"
692         "      $name$__.getKey(), $name$__.getValue());\n"
693         "}\n");
694   } else {
695     printer->Print(
696         variables_,
697         "com.google.protobuf.MapEntry<$type_parameters$>\n"
698         "$name$__ = input.readMessage(\n"
699         "    $default_entry$.getParserForType(), extensionRegistry);\n"
700         "$name$_.getMutableMap().put(\n"
701         "    $name$__.getKey(), $name$__.getValue());\n");
702   }
703 }
704 
GenerateParsingDoneCode(io::Printer * printer) const705 void ImmutableMapFieldGenerator::GenerateParsingDoneCode(
706     io::Printer* printer) const {
707   // Nothing to do here.
708 }
709 
GenerateSerializationCode(io::Printer * printer) const710 void ImmutableMapFieldGenerator::GenerateSerializationCode(
711     io::Printer* printer) const {
712   printer->Print(variables_,
713                  "com.google.protobuf.GeneratedMessage$ver$\n"
714                  "  .serialize$short_key_type$MapTo(\n"
715                  "    output,\n"
716                  "    internalGet$capitalized_name$(),\n"
717                  "    $default_entry$,\n"
718                  "    $number$);\n");
719 }
720 
GenerateSerializedSizeCode(io::Printer * printer) const721 void ImmutableMapFieldGenerator::GenerateSerializedSizeCode(
722     io::Printer* printer) const {
723   printer->Print(
724       variables_,
725       "for (java.util.Map.Entry<$type_parameters$> entry\n"
726       "     : internalGet$capitalized_name$().getMap().entrySet()) {\n"
727       "  com.google.protobuf.MapEntry<$type_parameters$>\n"
728       "  $name$__ = $default_entry$.newBuilderForType()\n"
729       "      .setKey(entry.getKey())\n"
730       "      .setValue(entry.getValue())\n"
731       "      .build();\n"
732       "  size += com.google.protobuf.CodedOutputStream\n"
733       "      .computeMessageSize($number$, $name$__);\n"
734       "}\n");
735 }
736 
GenerateEqualsCode(io::Printer * printer) const737 void ImmutableMapFieldGenerator::GenerateEqualsCode(
738     io::Printer* printer) const {
739   printer->Print(variables_,
740                  "if (!internalGet$capitalized_name$().equals(\n"
741                  "    other.internalGet$capitalized_name$())) return false;\n");
742 }
743 
GenerateHashCode(io::Printer * printer) const744 void ImmutableMapFieldGenerator::GenerateHashCode(io::Printer* printer) const {
745   printer->Print(
746       variables_,
747       "if (!internalGet$capitalized_name$().getMap().isEmpty()) {\n"
748       "  hash = (37 * hash) + $constant_name$;\n"
749       "  hash = (53 * hash) + internalGet$capitalized_name$().hashCode();\n"
750       "}\n");
751 }
752 
GetBoxedType() const753 std::string ImmutableMapFieldGenerator::GetBoxedType() const {
754   return name_resolver_->GetImmutableClassName(descriptor_->message_type());
755 }
756 
757 }  // namespace java
758 }  // namespace compiler
759 }  // namespace protobuf
760 }  // namespace google
761