• 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_lite.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 
83   ClassNameResolver* name_resolver = context->GetNameResolver();
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   (*variables)["boxed_key_type"] = TypeName(key, name_resolver, true);
93   (*variables)["key_wire_type"] = WireType(key);
94   (*variables)["key_default_value"] = DefaultValue(key, true, name_resolver);
95   (*variables)["key_null_check"] =
96       IsReferenceType(keyJavaType)
97           ? "if (key == null) { throw new java.lang.NullPointerException(); }"
98           : "";
99   (*variables)["value_null_check"] =
100       IsReferenceType(valueJavaType)
101           ? "if (value == null) { throw new java.lang.NullPointerException(); }"
102           : "";
103 
104   if (GetJavaType(value) == JAVATYPE_ENUM) {
105     // We store enums as Integers internally.
106     (*variables)["value_type"] = "int";
107     (*variables)["boxed_value_type"] = "java.lang.Integer";
108     (*variables)["value_wire_type"] = WireType(value);
109     (*variables)["value_default_value"] =
110         DefaultValue(value, true, name_resolver) + ".getNumber()";
111 
112     (*variables)["value_enum_type"] = TypeName(value, name_resolver, false);
113 
114     if (SupportUnknownEnumValue(descriptor->file())) {
115       // Map unknown values to a special UNRECOGNIZED value if supported.
116       (*variables)["unrecognized_value"] =
117           (*variables)["value_enum_type"] + ".UNRECOGNIZED";
118     } else {
119       // Map unknown values to the default value if we don't have UNRECOGNIZED.
120       (*variables)["unrecognized_value"] =
121           DefaultValue(value, true, name_resolver);
122     }
123   } else {
124     (*variables)["value_type"] = TypeName(value, name_resolver, false);
125     (*variables)["boxed_value_type"] = TypeName(value, name_resolver, true);
126     (*variables)["value_wire_type"] = WireType(value);
127     (*variables)["value_default_value"] =
128         DefaultValue(value, true, name_resolver);
129   }
130   (*variables)["type_parameters"] =
131       (*variables)["boxed_key_type"] + ", " + (*variables)["boxed_value_type"];
132   // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
133   // by the proto compiler
134   (*variables)["deprecation"] =
135       descriptor->options().deprecated() ? "@java.lang.Deprecated " : "";
136 
137   (*variables)["default_entry"] =
138       (*variables)["capitalized_name"] + "DefaultEntryHolder.defaultEntry";
139 }
140 
141 }  // namespace
142 
ImmutableMapFieldLiteGenerator(const FieldDescriptor * descriptor,int messageBitIndex,Context * context)143 ImmutableMapFieldLiteGenerator::ImmutableMapFieldLiteGenerator(
144     const FieldDescriptor* descriptor, int messageBitIndex, Context* context)
145     : descriptor_(descriptor),
146       context_(context),
147       name_resolver_(context->GetNameResolver()) {
148   SetMessageVariables(descriptor, messageBitIndex, 0,
149                       context->GetFieldGeneratorInfo(descriptor), context,
150                       &variables_);
151 }
152 
~ImmutableMapFieldLiteGenerator()153 ImmutableMapFieldLiteGenerator::~ImmutableMapFieldLiteGenerator() {}
154 
GetNumBitsForMessage() const155 int ImmutableMapFieldLiteGenerator::GetNumBitsForMessage() const { return 0; }
156 
GenerateInterfaceMembers(io::Printer * printer) const157 void ImmutableMapFieldLiteGenerator::GenerateInterfaceMembers(
158     io::Printer* printer) const {
159   WriteFieldDocComment(printer, descriptor_);
160   printer->Print(variables_,
161                  "$deprecation$int ${$get$capitalized_name$Count$}$();\n");
162   printer->Annotate("{", "}", descriptor_);
163   WriteFieldDocComment(printer, descriptor_);
164   printer->Print(variables_,
165                  "$deprecation$boolean ${$contains$capitalized_name$$}$(\n"
166                  "    $key_type$ key);\n");
167   printer->Annotate("{", "}", descriptor_);
168   if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) {
169     printer->Print(variables_,
170                    "/**\n"
171                    " * Use {@link #get$capitalized_name$Map()} instead.\n"
172                    " */\n"
173                    "@java.lang.Deprecated\n"
174                    "java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
175                    "${$get$capitalized_name$$}$();\n");
176     printer->Annotate("{", "}", descriptor_);
177     WriteFieldDocComment(printer, descriptor_);
178     printer->Print(
179         variables_,
180         "$deprecation$java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
181         "${$get$capitalized_name$Map$}$();\n");
182     printer->Annotate("{", "}", descriptor_);
183     WriteFieldDocComment(printer, descriptor_);
184     printer->Print(
185         variables_,
186         "$deprecation$$value_enum_type$ ${$get$capitalized_name$OrDefault$}$(\n"
187         "    $key_type$ key,\n"
188         "    $value_enum_type$ defaultValue);\n");
189     printer->Annotate("{", "}", descriptor_);
190     WriteFieldDocComment(printer, descriptor_);
191     printer->Print(
192         variables_,
193         "$deprecation$$value_enum_type$ ${$get$capitalized_name$OrThrow$}$(\n"
194         "    $key_type$ key);\n");
195     printer->Annotate("{", "}", descriptor_);
196     if (SupportUnknownEnumValue(descriptor_->file())) {
197       printer->Print(
198           variables_,
199           "/**\n"
200           " * Use {@link #get$capitalized_name$ValueMap()} instead.\n"
201           " */\n"
202           "@java.lang.Deprecated\n"
203           "java.util.Map<$type_parameters$>\n"
204           "${$get$capitalized_name$Value$}$();\n");
205       printer->Annotate("{", "}", descriptor_);
206       WriteFieldDocComment(printer, descriptor_);
207       printer->Print(variables_,
208                      "$deprecation$java.util.Map<$type_parameters$>\n"
209                      "${$get$capitalized_name$ValueMap$}$();\n");
210       printer->Annotate("{", "}", descriptor_);
211       WriteFieldDocComment(printer, descriptor_);
212       printer->Print(variables_,
213                      "$deprecation$\n"
214                      "$value_type$ ${$get$capitalized_name$ValueOrDefault$}$(\n"
215                      "    $key_type$ key,\n"
216                      "    $value_type$ defaultValue);\n");
217       printer->Annotate("{", "}", descriptor_);
218       WriteFieldDocComment(printer, descriptor_);
219       printer->Print(variables_,
220                      "$deprecation$\n"
221                      "$value_type$ ${$get$capitalized_name$ValueOrThrow$}$(\n"
222                      "    $key_type$ key);\n");
223       printer->Annotate("{", "}", descriptor_);
224     }
225   } else {
226     printer->Print(variables_,
227                    "/**\n"
228                    " * Use {@link #get$capitalized_name$Map()} instead.\n"
229                    " */\n"
230                    "@java.lang.Deprecated\n"
231                    "java.util.Map<$type_parameters$>\n"
232                    "${$get$capitalized_name$$}$();\n");
233     printer->Annotate("{", "}", descriptor_);
234     WriteFieldDocComment(printer, descriptor_);
235     printer->Print(variables_,
236                    "$deprecation$java.util.Map<$type_parameters$>\n"
237                    "${$get$capitalized_name$Map$}$();\n");
238     printer->Annotate("{", "}", descriptor_);
239     WriteFieldDocComment(printer, descriptor_);
240     printer->Print(variables_,
241                    "$deprecation$\n"
242                    "$value_type$ ${$get$capitalized_name$OrDefault$}$(\n"
243                    "    $key_type$ key,\n"
244                    "    $value_type$ defaultValue);\n");
245     printer->Annotate("{", "}", descriptor_);
246     WriteFieldDocComment(printer, descriptor_);
247     printer->Print(variables_,
248                    "$deprecation$\n"
249                    "$value_type$ ${$get$capitalized_name$OrThrow$}$(\n"
250                    "    $key_type$ key);\n");
251     printer->Annotate("{", "}", descriptor_);
252   }
253 }
254 
GenerateMembers(io::Printer * printer) const255 void ImmutableMapFieldLiteGenerator::GenerateMembers(
256     io::Printer* printer) const {
257   printer->Print(
258       variables_,
259       "private static final class $capitalized_name$DefaultEntryHolder {\n"
260       "  static final com.google.protobuf.MapEntryLite<\n"
261       "      $type_parameters$> defaultEntry =\n"
262       "          com.google.protobuf.MapEntryLite\n"
263       "          .<$type_parameters$>newDefaultInstance(\n"
264       "              $key_wire_type$,\n"
265       "              $key_default_value$,\n"
266       "              $value_wire_type$,\n"
267       "              $value_default_value$);\n"
268       "}\n");
269   printer->Print(variables_,
270                  "private com.google.protobuf.MapFieldLite<\n"
271                  "    $type_parameters$> $name$_ =\n"
272                  "        com.google.protobuf.MapFieldLite.emptyMapField();\n"
273                  "private com.google.protobuf.MapFieldLite<$type_parameters$>\n"
274                  "internalGet$capitalized_name$() {\n"
275                  "  return $name$_;\n"
276                  "}\n"
277                  "private com.google.protobuf.MapFieldLite<$type_parameters$>\n"
278                  "internalGetMutable$capitalized_name$() {\n"
279                  "  if (!$name$_.isMutable()) {\n"
280                  "    $name$_ = $name$_.mutableCopy();\n"
281                  "  }\n"
282                  "  return $name$_;\n"
283                  "}\n");
284   printer->Print(variables_,
285                  "@java.lang.Override\n"
286                  "$deprecation$\n"
287                  "public int ${$get$capitalized_name$Count$}$() {\n"
288                  "  return internalGet$capitalized_name$().size();\n"
289                  "}\n");
290   printer->Annotate("{", "}", descriptor_);
291   WriteFieldDocComment(printer, descriptor_);
292   printer->Print(variables_,
293                  "@java.lang.Override\n"
294                  "$deprecation$\n"
295                  "public boolean ${$contains$capitalized_name$$}$(\n"
296                  "    $key_type$ key) {\n"
297                  "  $key_null_check$\n"
298                  "  return internalGet$capitalized_name$().containsKey(key);\n"
299                  "}\n");
300   printer->Annotate("{", "}", descriptor_);
301   if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) {
302     printer->Print(
303         variables_,
304         "private static final\n"
305         "com.google.protobuf.Internal.MapAdapter.Converter<\n"
306         "    java.lang.Integer, $value_enum_type$> $name$ValueConverter =\n"
307         "        com.google.protobuf.Internal.MapAdapter.newEnumConverter(\n"
308         "            $value_enum_type$.internalGetValueMap(),\n"
309         "            $unrecognized_value$);\n");
310     printer->Print(variables_,
311                    "/**\n"
312                    " * Use {@link #get$capitalized_name$Map()} instead.\n"
313                    " */\n"
314                    "@java.lang.Deprecated\n"
315                    "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
316                    "${$get$capitalized_name$$}$() {\n"
317                    "  return get$capitalized_name$Map();\n"
318                    "}\n");
319     printer->Annotate("{", "}", descriptor_);
320     WriteFieldDocComment(printer, descriptor_);
321     printer->Print(
322         variables_,
323         "@java.lang.Override\n"
324         "$deprecation$\n"
325         "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
326         "${$get$capitalized_name$Map$}$() {\n"
327         "  return java.util.Collections.unmodifiableMap(\n"
328         "      new com.google.protobuf.Internal.MapAdapter<\n"
329         "        $boxed_key_type$, $value_enum_type$, java.lang.Integer>(\n"
330         "            internalGet$capitalized_name$(),\n"
331         "            $name$ValueConverter));\n"
332         "}\n");
333     printer->Annotate("{", "}", descriptor_);
334     WriteFieldDocComment(printer, descriptor_);
335     printer->Print(
336         variables_,
337         "@java.lang.Override\n"
338         "$deprecation$\n"
339         "public $value_enum_type$ ${$get$capitalized_name$OrDefault$}$(\n"
340         "    $key_type$ key,\n"
341         "    $value_enum_type$ defaultValue) {\n"
342         "  $key_null_check$\n"
343         "  java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
344         "      internalGet$capitalized_name$();\n"
345         "  return map.containsKey(key)\n"
346         "         ? $name$ValueConverter.doForward(map.get(key))\n"
347         "         : defaultValue;\n"
348         "}\n");
349     printer->Annotate("{", "}", descriptor_);
350     WriteFieldDocComment(printer, descriptor_);
351     printer->Print(
352         variables_,
353         "@java.lang.Override\n"
354         "$deprecation$\n"
355         "public $value_enum_type$ ${$get$capitalized_name$OrThrow$}$(\n"
356         "    $key_type$ key) {\n"
357         "  $key_null_check$\n"
358         "  java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
359         "      internalGet$capitalized_name$();\n"
360         "  if (!map.containsKey(key)) {\n"
361         "    throw new java.lang.IllegalArgumentException();\n"
362         "  }\n"
363         "  return $name$ValueConverter.doForward(map.get(key));\n"
364         "}\n");
365     printer->Annotate("{", "}", descriptor_);
366     if (SupportUnknownEnumValue(descriptor_->file())) {
367       printer->Print(
368           variables_,
369           "/**\n"
370           " * Use {@link #get$capitalized_name$ValueMap()} instead.\n"
371           " */\n"
372           "@java.lang.Override\n"
373           "@java.lang.Deprecated\n"
374           "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n"
375           "${$get$capitalized_name$Value$}$() {\n"
376           "  return get$capitalized_name$ValueMap();\n"
377           "}\n");
378       printer->Annotate("{", "}", descriptor_);
379       WriteFieldDocComment(printer, descriptor_);
380       printer->Print(
381           variables_,
382           "@java.lang.Override\n"
383           "$deprecation$\n"
384           "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n"
385           "${$get$capitalized_name$ValueMap$}$() {\n"
386           "  return java.util.Collections.unmodifiableMap(\n"
387           "      internalGet$capitalized_name$());\n"
388           "}\n");
389       printer->Annotate("{", "}", descriptor_);
390       WriteFieldDocComment(printer, descriptor_);
391       printer->Print(
392           variables_,
393           "@java.lang.Override\n"
394           "$deprecation$\n"
395           "public $value_type$ ${$get$capitalized_name$ValueOrDefault$}$(\n"
396           "    $key_type$ key,\n"
397           "    $value_type$ defaultValue) {\n"
398           "  $key_null_check$\n"
399           "  java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
400           "      internalGet$capitalized_name$();\n"
401           "  return map.containsKey(key) ? map.get(key) : defaultValue;\n"
402           "}\n");
403       printer->Annotate("{", "}", descriptor_);
404       WriteFieldDocComment(printer, descriptor_);
405       printer->Print(
406           variables_,
407           "@java.lang.Override\n"
408           "$deprecation$\n"
409           "public $value_type$ ${$get$capitalized_name$ValueOrThrow$}$(\n"
410           "    $key_type$ key) {\n"
411           "  $key_null_check$\n"
412           "  java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
413           "      internalGet$capitalized_name$();\n"
414           "  if (!map.containsKey(key)) {\n"
415           "    throw new java.lang.IllegalArgumentException();\n"
416           "  }\n"
417           "  return map.get(key);\n"
418           "}\n");
419       printer->Annotate("{", "}", descriptor_);
420     }
421   } else {
422     printer->Print(variables_,
423                    "/**\n"
424                    " * Use {@link #get$capitalized_name$Map()} instead.\n"
425                    " */\n"
426                    "@java.lang.Override\n"
427                    "@java.lang.Deprecated\n"
428                    "public java.util.Map<$type_parameters$> "
429                    "${$get$capitalized_name$$}$() {\n"
430                    "  return get$capitalized_name$Map();\n"
431                    "}\n");
432     printer->Annotate("{", "}", descriptor_);
433     WriteFieldDocComment(printer, descriptor_);
434     printer->Print(variables_,
435                    "@java.lang.Override\n"
436                    "$deprecation$\n"
437                    "public java.util.Map<$type_parameters$> "
438                    "${$get$capitalized_name$Map$}$() {\n"
439                    "  return java.util.Collections.unmodifiableMap(\n"
440                    "      internalGet$capitalized_name$());\n"
441                    "}\n");
442     printer->Annotate("{", "}", descriptor_);
443     WriteFieldDocComment(printer, descriptor_);
444     printer->Print(
445         variables_,
446         "@java.lang.Override\n"
447         "$deprecation$\n"
448         "public $value_type$ ${$get$capitalized_name$OrDefault$}$(\n"
449         "    $key_type$ key,\n"
450         "    $value_type$ defaultValue) {\n"
451         "  $key_null_check$\n"
452         "  java.util.Map<$type_parameters$> map =\n"
453         "      internalGet$capitalized_name$();\n"
454         "  return map.containsKey(key) ? map.get(key) : defaultValue;\n"
455         "}\n");
456     printer->Annotate("{", "}", descriptor_);
457     WriteFieldDocComment(printer, descriptor_);
458     printer->Print(variables_,
459                    "@java.lang.Override\n"
460                    "$deprecation$\n"
461                    "public $value_type$ ${$get$capitalized_name$OrThrow$}$(\n"
462                    "    $key_type$ key) {\n"
463                    "  $key_null_check$\n"
464                    "  java.util.Map<$type_parameters$> map =\n"
465                    "      internalGet$capitalized_name$();\n"
466                    "  if (!map.containsKey(key)) {\n"
467                    "    throw new java.lang.IllegalArgumentException();\n"
468                    "  }\n"
469                    "  return map.get(key);\n"
470                    "}\n");
471     printer->Annotate("{", "}", descriptor_);
472   }
473 
474   // Generate private setters for the builder to proxy into.
475   if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) {
476     WriteFieldDocComment(printer, descriptor_);
477     printer->Print(
478         variables_,
479         "private java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
480         "getMutable$capitalized_name$Map() {\n"
481         "  return new com.google.protobuf.Internal.MapAdapter<\n"
482         "      $boxed_key_type$, $value_enum_type$, java.lang.Integer>(\n"
483         "          internalGetMutable$capitalized_name$(),\n"
484         "          $name$ValueConverter);\n"
485         "}\n");
486     if (SupportUnknownEnumValue(descriptor_->file())) {
487       WriteFieldDocComment(printer, descriptor_);
488       printer->Print(
489           variables_,
490           "private java.util.Map<$boxed_key_type$, $boxed_value_type$>\n"
491           "getMutable$capitalized_name$ValueMap() {\n"
492           "  return internalGetMutable$capitalized_name$();\n"
493           "}\n");
494     }
495   } else {
496     WriteFieldDocComment(printer, descriptor_);
497     printer->Print(variables_,
498                    "private java.util.Map<$type_parameters$>\n"
499                    "getMutable$capitalized_name$Map() {\n"
500                    "  return internalGetMutable$capitalized_name$();\n"
501                    "}\n");
502   }
503 }
504 
GenerateFieldInfo(io::Printer * printer,std::vector<uint16> * output) const505 void ImmutableMapFieldLiteGenerator::GenerateFieldInfo(
506     io::Printer* printer, std::vector<uint16>* output) const {
507   WriteIntToUtf16CharSequence(descriptor_->number(), output);
508   WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_),
509                               output);
510   printer->Print(variables_,
511                  "\"$name$_\",\n"
512                  "$default_entry$,\n");
513   if (SupportFieldPresence(descriptor_->file()) &&
514       GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) {
515     PrintEnumVerifierLogic(printer, ValueField(descriptor_), variables_,
516                            /*var_name=*/"$value_enum_type$",
517                            /*terminating_string=*/",\n",
518                            /*enforce_lite=*/context_->EnforceLite());
519   }
520 }
521 
GenerateBuilderMembers(io::Printer * printer) const522 void ImmutableMapFieldLiteGenerator::GenerateBuilderMembers(
523     io::Printer* printer) const {
524   printer->Print(variables_,
525                  "@java.lang.Override\n"
526                  "$deprecation$\n"
527                  "public int ${$get$capitalized_name$Count$}$() {\n"
528                  "  return instance.get$capitalized_name$Map().size();\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 boolean ${$contains$capitalized_name$$}$(\n"
537       "    $key_type$ key) {\n"
538       "  $key_null_check$\n"
539       "  return instance.get$capitalized_name$Map().containsKey(key);\n"
540       "}\n");
541   printer->Annotate("{", "}", descriptor_);
542   printer->Print(variables_,
543                  "$deprecation$\n"
544                  "public Builder ${$clear$capitalized_name$$}$() {\n"
545                  "  copyOnWrite();\n"
546                  "  instance.getMutable$capitalized_name$Map().clear();\n"
547                  "  return this;\n"
548                  "}\n");
549   printer->Annotate("{", "}", descriptor_);
550   WriteFieldDocComment(printer, descriptor_);
551   printer->Print(variables_,
552                  "$deprecation$\n"
553                  "public Builder ${$remove$capitalized_name$$}$(\n"
554                  "    $key_type$ key) {\n"
555                  "  $key_null_check$\n"
556                  "  copyOnWrite();\n"
557                  "  instance.getMutable$capitalized_name$Map().remove(key);\n"
558                  "  return this;\n"
559                  "}\n");
560   printer->Annotate("{", "}", descriptor_);
561   if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) {
562     printer->Print(variables_,
563                    "/**\n"
564                    " * Use {@link #get$capitalized_name$Map()} instead.\n"
565                    " */\n"
566                    "@java.lang.Deprecated\n"
567                    "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
568                    "${$get$capitalized_name$$}$() {\n"
569                    "  return get$capitalized_name$Map();\n"
570                    "}\n");
571     printer->Annotate("{", "}", descriptor_);
572     WriteFieldDocComment(printer, descriptor_);
573     printer->Print(variables_,
574                    "@java.lang.Override\n"
575                    "$deprecation$\n"
576                    "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
577                    "${$get$capitalized_name$Map$}$() {\n"
578                    "  return java.util.Collections.unmodifiableMap(\n"
579                    "      instance.get$capitalized_name$Map());\n"
580                    "}\n");
581     printer->Annotate("{", "}", descriptor_);
582     WriteFieldDocComment(printer, descriptor_);
583     printer->Print(
584         variables_,
585         "@java.lang.Override\n"
586         "$deprecation$\n"
587         "public $value_enum_type$ ${$get$capitalized_name$OrDefault$}$(\n"
588         "    $key_type$ key,\n"
589         "    $value_enum_type$ defaultValue) {\n"
590         "  $key_null_check$\n"
591         "  java.util.Map<$boxed_key_type$, $value_enum_type$> map =\n"
592         "      instance.get$capitalized_name$Map();\n"
593         "  return map.containsKey(key)\n"
594         "         ? map.get(key)\n"
595         "         : defaultValue;\n"
596         "}\n");
597     printer->Annotate("{", "}", descriptor_);
598     WriteFieldDocComment(printer, descriptor_);
599     printer->Print(
600         variables_,
601         "@java.lang.Override\n"
602         "$deprecation$\n"
603         "public $value_enum_type$ ${$get$capitalized_name$OrThrow$}$(\n"
604         "    $key_type$ key) {\n"
605         "  $key_null_check$\n"
606         "  java.util.Map<$boxed_key_type$, $value_enum_type$> map =\n"
607         "      instance.get$capitalized_name$Map();\n"
608         "  if (!map.containsKey(key)) {\n"
609         "    throw new java.lang.IllegalArgumentException();\n"
610         "  }\n"
611         "  return map.get(key);\n"
612         "}\n");
613     printer->Annotate("{", "}", descriptor_);
614     WriteFieldDocComment(printer, descriptor_);
615     printer->Print(
616         variables_,
617         "$deprecation$public Builder ${$put$capitalized_name$$}$(\n"
618         "    $key_type$ key,\n"
619         "    $value_enum_type$ value) {\n"
620         "  $key_null_check$\n"
621         "  $value_null_check$\n"
622         "  copyOnWrite();\n"
623         "  instance.getMutable$capitalized_name$Map().put(key, value);\n"
624         "  return this;\n"
625         "}\n");
626     printer->Annotate("{", "}", descriptor_);
627     WriteFieldDocComment(printer, descriptor_);
628     printer->Print(
629         variables_,
630         "$deprecation$public Builder ${$putAll$capitalized_name$$}$(\n"
631         "    java.util.Map<$boxed_key_type$, $value_enum_type$> values) {\n"
632         "  copyOnWrite();\n"
633         "  instance.getMutable$capitalized_name$Map().putAll(values);\n"
634         "  return this;\n"
635         "}\n");
636     printer->Annotate("{", "}", descriptor_);
637     if (SupportUnknownEnumValue(descriptor_->file())) {
638       printer->Print(
639           variables_,
640           "/**\n"
641           " * Use {@link #get$capitalized_name$ValueMap()} instead.\n"
642           " */\n"
643           "@java.lang.Override\n"
644           "@java.lang.Deprecated\n"
645           "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n"
646           "${$get$capitalized_name$Value$}$() {\n"
647           "  return get$capitalized_name$ValueMap();\n"
648           "}\n");
649       printer->Annotate("{", "}", descriptor_);
650       WriteFieldDocComment(printer, descriptor_);
651       printer->Print(
652           variables_,
653           "@java.lang.Override\n"
654           "$deprecation$\n"
655           "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n"
656           "${$get$capitalized_name$ValueMap$}$() {\n"
657           "  return java.util.Collections.unmodifiableMap(\n"
658           "      instance.get$capitalized_name$ValueMap());\n"
659           "}\n");
660       printer->Annotate("{", "}", descriptor_);
661       WriteFieldDocComment(printer, descriptor_);
662       printer->Print(
663           variables_,
664           "@java.lang.Override\n"
665           "$deprecation$\n"
666           "public $value_type$ ${$get$capitalized_name$ValueOrDefault$}$(\n"
667           "    $key_type$ key,\n"
668           "    $value_type$ defaultValue) {\n"
669           "  $key_null_check$\n"
670           "  java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
671           "      instance.get$capitalized_name$ValueMap();\n"
672           "  return map.containsKey(key) ? map.get(key) : defaultValue;\n"
673           "}\n");
674       printer->Annotate("{", "}", descriptor_);
675       WriteFieldDocComment(printer, descriptor_);
676       printer->Print(
677           variables_,
678           "@java.lang.Override\n"
679           "$deprecation$\n"
680           "public $value_type$ ${$get$capitalized_name$ValueOrThrow$}$(\n"
681           "    $key_type$ key) {\n"
682           "  $key_null_check$\n"
683           "  java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
684           "      instance.get$capitalized_name$ValueMap();\n"
685           "  if (!map.containsKey(key)) {\n"
686           "    throw new java.lang.IllegalArgumentException();\n"
687           "  }\n"
688           "  return map.get(key);\n"
689           "}\n");
690       printer->Annotate("{", "}", descriptor_);
691       WriteFieldDocComment(printer, descriptor_);
692       printer->Print(
693           variables_,
694           "$deprecation$public Builder ${$put$capitalized_name$Value$}$(\n"
695           "    $key_type$ key,\n"
696           "    $value_type$ value) {\n"
697           "  $key_null_check$\n"
698           "  copyOnWrite();\n"
699           "  instance.getMutable$capitalized_name$ValueMap().put(key, value);\n"
700           "  return this;\n"
701           "}\n");
702       printer->Annotate("{", "}", descriptor_);
703       WriteFieldDocComment(printer, descriptor_);
704       printer->Print(
705           variables_,
706           "$deprecation$public Builder ${$putAll$capitalized_name$Value$}$(\n"
707           "    java.util.Map<$boxed_key_type$, $boxed_value_type$> values) {\n"
708           "  copyOnWrite();\n"
709           "  instance.getMutable$capitalized_name$ValueMap().putAll(values);\n"
710           "  return this;\n"
711           "}\n");
712       printer->Annotate("{", "}", descriptor_);
713     }
714   } else {
715     printer->Print(variables_,
716                    "/**\n"
717                    " * Use {@link #get$capitalized_name$Map()} instead.\n"
718                    " */\n"
719                    "@java.lang.Override\n"
720                    "@java.lang.Deprecated\n"
721                    "public java.util.Map<$type_parameters$> "
722                    "${$get$capitalized_name$$}$() {\n"
723                    "  return get$capitalized_name$Map();\n"
724                    "}\n");
725     printer->Annotate("{", "}", descriptor_);
726     WriteFieldDocComment(printer, descriptor_);
727     printer->Print(variables_,
728                    "@java.lang.Override\n"
729                    "$deprecation$"
730                    "public java.util.Map<$type_parameters$> "
731                    "${$get$capitalized_name$Map$}$() {\n"
732                    "  return java.util.Collections.unmodifiableMap(\n"
733                    "      instance.get$capitalized_name$Map());\n"
734                    "}\n");
735     printer->Annotate("{", "}", descriptor_);
736     WriteFieldDocComment(printer, descriptor_);
737     printer->Print(
738         variables_,
739         "@java.lang.Override\n"
740         "$deprecation$\n"
741         "public $value_type$ ${$get$capitalized_name$OrDefault$}$(\n"
742         "    $key_type$ key,\n"
743         "    $value_type$ defaultValue) {\n"
744         "  $key_null_check$\n"
745         "  java.util.Map<$type_parameters$> map =\n"
746         "      instance.get$capitalized_name$Map();\n"
747         "  return map.containsKey(key) ? map.get(key) : defaultValue;\n"
748         "}\n");
749     printer->Annotate("{", "}", descriptor_);
750     WriteFieldDocComment(printer, descriptor_);
751     printer->Print(variables_,
752                    "@java.lang.Override\n"
753                    "$deprecation$\n"
754                    "public $value_type$ ${$get$capitalized_name$OrThrow$}$(\n"
755                    "    $key_type$ key) {\n"
756                    "  $key_null_check$\n"
757                    "  java.util.Map<$type_parameters$> map =\n"
758                    "      instance.get$capitalized_name$Map();\n"
759                    "  if (!map.containsKey(key)) {\n"
760                    "    throw new java.lang.IllegalArgumentException();\n"
761                    "  }\n"
762                    "  return map.get(key);\n"
763                    "}\n");
764     printer->Annotate("{", "}", descriptor_);
765     WriteFieldDocComment(printer, descriptor_);
766     printer->Print(
767         variables_,
768         "$deprecation$"
769         "public Builder ${$put$capitalized_name$$}$(\n"
770         "    $key_type$ key,\n"
771         "    $value_type$ value) {\n"
772         "  $key_null_check$\n"
773         "  $value_null_check$\n"
774         "  copyOnWrite();\n"
775         "  instance.getMutable$capitalized_name$Map().put(key, value);\n"
776         "  return this;\n"
777         "}\n");
778     printer->Annotate("{", "}", descriptor_);
779     WriteFieldDocComment(printer, descriptor_);
780     printer->Print(
781         variables_,
782         "$deprecation$"
783         "public Builder ${$putAll$capitalized_name$$}$(\n"
784         "    java.util.Map<$type_parameters$> values) {\n"
785         "  copyOnWrite();\n"
786         "  instance.getMutable$capitalized_name$Map().putAll(values);\n"
787         "  return this;\n"
788         "}\n");
789     printer->Annotate("{", "}", descriptor_);
790   }
791 }
792 
GenerateInitializationCode(io::Printer * printer) const793 void ImmutableMapFieldLiteGenerator::GenerateInitializationCode(
794     io::Printer* printer) const {
795   // Nothing to initialize.
796 }
797 
GetBoxedType() const798 std::string ImmutableMapFieldLiteGenerator::GetBoxedType() const {
799   return name_resolver_->GetImmutableClassName(descriptor_->message_type());
800 }
801 
802 }  // namespace java
803 }  // namespace compiler
804 }  // namespace protobuf
805 }  // namespace google
806