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