xref: /aosp_15_r20/external/cronet/third_party/protobuf/src/google/protobuf/compiler/java/map_field_lite.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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/map_field_lite.h>
32 
33 #include <cstdint>
34 
35 #include <google/protobuf/io/printer.h>
36 #include <google/protobuf/compiler/java/context.h>
37 #include <google/protobuf/compiler/java/doc_comment.h>
38 #include <google/protobuf/compiler/java/helpers.h>
39 #include <google/protobuf/compiler/java/name_resolver.h>
40 
41 // Must be last.
42 #include <google/protobuf/port_def.inc>
43 
44 namespace google {
45 namespace protobuf {
46 namespace compiler {
47 namespace java {
48 
49 namespace {
50 
KeyField(const FieldDescriptor * descriptor)51 const FieldDescriptor* KeyField(const FieldDescriptor* descriptor) {
52   GOOGLE_CHECK_EQ(FieldDescriptor::TYPE_MESSAGE, descriptor->type());
53   const Descriptor* message = descriptor->message_type();
54   GOOGLE_CHECK(message->options().map_entry());
55   return message->map_key();
56 }
57 
ValueField(const FieldDescriptor * descriptor)58 const FieldDescriptor* ValueField(const FieldDescriptor* descriptor) {
59   GOOGLE_CHECK_EQ(FieldDescriptor::TYPE_MESSAGE, descriptor->type());
60   const Descriptor* message = descriptor->message_type();
61   GOOGLE_CHECK(message->options().map_entry());
62   return message->map_value();
63 }
64 
TypeName(const FieldDescriptor * field,ClassNameResolver * name_resolver,bool boxed)65 std::string TypeName(const FieldDescriptor* field,
66                      ClassNameResolver* name_resolver, bool boxed) {
67   if (GetJavaType(field) == JAVATYPE_MESSAGE) {
68     return name_resolver->GetImmutableClassName(field->message_type());
69   } else if (GetJavaType(field) == JAVATYPE_ENUM) {
70     return name_resolver->GetImmutableClassName(field->enum_type());
71   } else {
72     return boxed ? BoxedPrimitiveTypeName(GetJavaType(field))
73                  : PrimitiveTypeName(GetJavaType(field));
74   }
75 }
76 
KotlinTypeName(const FieldDescriptor * field,ClassNameResolver * name_resolver)77 std::string KotlinTypeName(const FieldDescriptor* field,
78                            ClassNameResolver* name_resolver) {
79   if (GetJavaType(field) == JAVATYPE_MESSAGE) {
80     return name_resolver->GetImmutableClassName(field->message_type());
81   } else if (GetJavaType(field) == JAVATYPE_ENUM) {
82     return name_resolver->GetImmutableClassName(field->enum_type());
83   } else {
84     return KotlinTypeName(GetJavaType(field));
85   }
86 }
87 
WireType(const FieldDescriptor * field)88 std::string WireType(const FieldDescriptor* field) {
89   return "com.google.protobuf.WireFormat.FieldType." +
90          std::string(FieldTypeName(field->type()));
91 }
92 
SetMessageVariables(const FieldDescriptor * descriptor,int messageBitIndex,int builderBitIndex,const FieldGeneratorInfo * info,Context * context,std::map<std::string,std::string> * variables)93 void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex,
94                          int builderBitIndex, const FieldGeneratorInfo* info,
95                          Context* context,
96                          std::map<std::string, std::string>* variables) {
97   SetCommonFieldVariables(descriptor, info, variables);
98 
99   ClassNameResolver* name_resolver = context->GetNameResolver();
100   (*variables)["type"] =
101       name_resolver->GetImmutableClassName(descriptor->message_type());
102   const FieldDescriptor* key = KeyField(descriptor);
103   const FieldDescriptor* value = ValueField(descriptor);
104   const JavaType keyJavaType = GetJavaType(key);
105   const JavaType valueJavaType = GetJavaType(value);
106 
107   std::string pass_through_nullness = "/* nullable */\n";
108 
109   (*variables)["key_type"] = TypeName(key, name_resolver, false);
110   (*variables)["boxed_key_type"] = TypeName(key, name_resolver, true);
111   (*variables)["kt_key_type"] = KotlinTypeName(key, name_resolver);
112   (*variables)["kt_value_type"] = KotlinTypeName(value, name_resolver);
113   (*variables)["key_wire_type"] = WireType(key);
114   (*variables)["key_default_value"] = DefaultValue(key, true, name_resolver);
115   // We use `x.getClass()` as a null check because it generates less bytecode
116   // than an `if (x == null) { throw ... }` statement.
117   (*variables)["key_null_check"] =
118       IsReferenceType(keyJavaType)
119           ? "java.lang.Class<?> keyClass = key.getClass();"
120           : "";
121   (*variables)["value_null_check"] =
122       IsReferenceType(valueJavaType)
123           ? "java.lang.Class<?> valueClass = value.getClass();"
124           : "";
125 
126   if (GetJavaType(value) == JAVATYPE_ENUM) {
127     // We store enums as Integers internally.
128     (*variables)["value_type"] = "int";
129     (*variables)["boxed_value_type"] = "java.lang.Integer";
130     (*variables)["value_wire_type"] = WireType(value);
131     (*variables)["value_default_value"] =
132         DefaultValue(value, true, name_resolver) + ".getNumber()";
133 
134     (*variables)["value_enum_type"] = TypeName(value, name_resolver, false);
135 
136     (*variables)["value_enum_type_pass_through_nullness"] =
137         pass_through_nullness + (*variables)["value_enum_type"];
138 
139     if (SupportUnknownEnumValue(descriptor->file())) {
140       // Map unknown values to a special UNRECOGNIZED value if supported.
141       (*variables)["unrecognized_value"] =
142           (*variables)["value_enum_type"] + ".UNRECOGNIZED";
143     } else {
144       // Map unknown values to the default value if we don't have UNRECOGNIZED.
145       (*variables)["unrecognized_value"] =
146           DefaultValue(value, true, name_resolver);
147     }
148   } else {
149     (*variables)["value_type"] = TypeName(value, name_resolver, false);
150 
151     (*variables)["value_type_pass_through_nullness"] =
152         (IsReferenceType(valueJavaType) ? pass_through_nullness : "") +
153         (*variables)["value_type"];
154 
155     (*variables)["boxed_value_type"] = TypeName(value, name_resolver, true);
156     (*variables)["value_wire_type"] = WireType(value);
157     (*variables)["value_default_value"] =
158         DefaultValue(value, true, name_resolver);
159   }
160   (*variables)["type_parameters"] =
161       (*variables)["boxed_key_type"] + ", " + (*variables)["boxed_value_type"];
162   // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
163   // by the proto compiler
164   (*variables)["deprecation"] =
165       descriptor->options().deprecated() ? "@java.lang.Deprecated " : "";
166   (*variables)["kt_deprecation"] =
167       descriptor->options().deprecated()
168           ? "@kotlin.Deprecated(message = \"Field " + (*variables)["name"] +
169                 " is deprecated\") "
170           : "";
171 
172   (*variables)["default_entry"] =
173       (*variables)["capitalized_name"] + "DefaultEntryHolder.defaultEntry";
174 }
175 
176 }  // namespace
177 
ImmutableMapFieldLiteGenerator(const FieldDescriptor * descriptor,int messageBitIndex,Context * context)178 ImmutableMapFieldLiteGenerator::ImmutableMapFieldLiteGenerator(
179     const FieldDescriptor* descriptor, int messageBitIndex, Context* context)
180     : descriptor_(descriptor),
181       context_(context),
182       name_resolver_(context->GetNameResolver()) {
183   SetMessageVariables(descriptor, messageBitIndex, 0,
184                       context->GetFieldGeneratorInfo(descriptor), context,
185                       &variables_);
186 }
187 
~ImmutableMapFieldLiteGenerator()188 ImmutableMapFieldLiteGenerator::~ImmutableMapFieldLiteGenerator() {}
189 
GetNumBitsForMessage() const190 int ImmutableMapFieldLiteGenerator::GetNumBitsForMessage() const { return 0; }
191 
GenerateInterfaceMembers(io::Printer * printer) const192 void ImmutableMapFieldLiteGenerator::GenerateInterfaceMembers(
193     io::Printer* printer) const {
194   WriteFieldDocComment(printer, descriptor_);
195   printer->Print(variables_,
196                  "$deprecation$int ${$get$capitalized_name$Count$}$();\n");
197   printer->Annotate("{", "}", descriptor_);
198   WriteFieldDocComment(printer, descriptor_);
199   printer->Print(variables_,
200                  "$deprecation$boolean ${$contains$capitalized_name$$}$(\n"
201                  "    $key_type$ key);\n");
202   printer->Annotate("{", "}", descriptor_);
203   if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) {
204     printer->Print(variables_,
205                    "/**\n"
206                    " * Use {@link #get$capitalized_name$Map()} instead.\n"
207                    " */\n"
208                    "@java.lang.Deprecated\n"
209                    "java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
210                    "${$get$capitalized_name$$}$();\n");
211     printer->Annotate("{", "}", descriptor_);
212     WriteFieldDocComment(printer, descriptor_);
213     printer->Print(
214         variables_,
215         "$deprecation$java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
216         "${$get$capitalized_name$Map$}$();\n");
217     printer->Annotate("{", "}", descriptor_);
218     WriteFieldDocComment(printer, descriptor_);
219     printer->Print(variables_,
220                    "$deprecation$$value_enum_type_pass_through_nullness$ "
221                    "${$get$capitalized_name$OrDefault$}$(\n"
222                    "    $key_type$ key,\n"
223                    "    $value_enum_type_pass_through_nullness$ "
224                    "        defaultValue);\n");
225     printer->Annotate("{", "}", descriptor_);
226     WriteFieldDocComment(printer, descriptor_);
227     printer->Print(
228         variables_,
229         "$deprecation$$value_enum_type$ ${$get$capitalized_name$OrThrow$}$(\n"
230         "    $key_type$ key);\n");
231     printer->Annotate("{", "}", descriptor_);
232     if (SupportUnknownEnumValue(descriptor_->file())) {
233       printer->Print(
234           variables_,
235           "/**\n"
236           " * Use {@link #get$capitalized_name$ValueMap()} instead.\n"
237           " */\n"
238           "@java.lang.Deprecated\n"
239           "java.util.Map<$type_parameters$>\n"
240           "${$get$capitalized_name$Value$}$();\n");
241       printer->Annotate("{", "}", descriptor_);
242       WriteFieldDocComment(printer, descriptor_);
243       printer->Print(variables_,
244                      "$deprecation$java.util.Map<$type_parameters$>\n"
245                      "${$get$capitalized_name$ValueMap$}$();\n");
246       printer->Annotate("{", "}", descriptor_);
247       WriteFieldDocComment(printer, descriptor_);
248       printer->Print(variables_,
249                      "$deprecation$\n"
250                      "$value_type$ ${$get$capitalized_name$ValueOrDefault$}$(\n"
251                      "    $key_type$ key,\n"
252                      "    $value_type$ defaultValue);\n");
253       printer->Annotate("{", "}", descriptor_);
254       WriteFieldDocComment(printer, descriptor_);
255       printer->Print(variables_,
256                      "$deprecation$\n"
257                      "$value_type$ ${$get$capitalized_name$ValueOrThrow$}$(\n"
258                      "    $key_type$ key);\n");
259       printer->Annotate("{", "}", descriptor_);
260     }
261   } else {
262     printer->Print(variables_,
263                    "/**\n"
264                    " * Use {@link #get$capitalized_name$Map()} instead.\n"
265                    " */\n"
266                    "@java.lang.Deprecated\n"
267                    "java.util.Map<$type_parameters$>\n"
268                    "${$get$capitalized_name$$}$();\n");
269     printer->Annotate("{", "}", descriptor_);
270     WriteFieldDocComment(printer, descriptor_);
271     printer->Print(variables_,
272                    "$deprecation$java.util.Map<$type_parameters$>\n"
273                    "${$get$capitalized_name$Map$}$();\n");
274     printer->Annotate("{", "}", descriptor_);
275     WriteFieldDocComment(printer, descriptor_);
276     printer->Print(variables_,
277                    "$deprecation$\n"
278                    "$value_type_pass_through_nullness$ "
279                    "${$get$capitalized_name$OrDefault$}$(\n"
280                    "    $key_type$ key,\n"
281                    "    $value_type_pass_through_nullness$ defaultValue);\n");
282     printer->Annotate("{", "}", descriptor_);
283     WriteFieldDocComment(printer, descriptor_);
284     printer->Print(variables_,
285                    "$deprecation$\n"
286                    "$value_type$ ${$get$capitalized_name$OrThrow$}$(\n"
287                    "    $key_type$ key);\n");
288     printer->Annotate("{", "}", descriptor_);
289   }
290 }
291 
GenerateMembers(io::Printer * printer) const292 void ImmutableMapFieldLiteGenerator::GenerateMembers(
293     io::Printer* printer) const {
294   printer->Print(
295       variables_,
296       "private static final class $capitalized_name$DefaultEntryHolder {\n"
297       "  static final com.google.protobuf.MapEntryLite<\n"
298       "      $type_parameters$> defaultEntry =\n"
299       "          com.google.protobuf.MapEntryLite\n"
300       "          .<$type_parameters$>newDefaultInstance(\n"
301       "              $key_wire_type$,\n"
302       "              $key_default_value$,\n"
303       "              $value_wire_type$,\n"
304       "              $value_default_value$);\n"
305       "}\n");
306   printer->Print(variables_,
307                  "private com.google.protobuf.MapFieldLite<\n"
308                  "    $type_parameters$> $name$_ =\n"
309                  "        com.google.protobuf.MapFieldLite.emptyMapField();\n"
310                  "private com.google.protobuf.MapFieldLite<$type_parameters$>\n"
311                  "internalGet$capitalized_name$() {\n"
312                  "  return $name$_;\n"
313                  "}\n"
314                  "private com.google.protobuf.MapFieldLite<$type_parameters$>\n"
315                  "internalGetMutable$capitalized_name$() {\n"
316                  "  if (!$name$_.isMutable()) {\n"
317                  "    $name$_ = $name$_.mutableCopy();\n"
318                  "  }\n"
319                  "  return $name$_;\n"
320                  "}\n");
321   printer->Print(variables_,
322                  "@java.lang.Override\n"
323                  "$deprecation$\n"
324                  "public int ${$get$capitalized_name$Count$}$() {\n"
325                  "  return internalGet$capitalized_name$().size();\n"
326                  "}\n");
327   printer->Annotate("{", "}", descriptor_);
328   WriteFieldDocComment(printer, descriptor_);
329   printer->Print(variables_,
330                  "@java.lang.Override\n"
331                  "$deprecation$\n"
332                  "public boolean ${$contains$capitalized_name$$}$(\n"
333                  "    $key_type$ key) {\n"
334                  "  $key_null_check$\n"
335                  "  return internalGet$capitalized_name$().containsKey(key);\n"
336                  "}\n");
337   printer->Annotate("{", "}", descriptor_);
338   if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) {
339     printer->Print(
340         variables_,
341         "private static final\n"
342         "com.google.protobuf.Internal.MapAdapter.Converter<\n"
343         "    java.lang.Integer, $value_enum_type$> $name$ValueConverter =\n"
344         "        com.google.protobuf.Internal.MapAdapter.newEnumConverter(\n"
345         "            $value_enum_type$.internalGetValueMap(),\n"
346         "            $unrecognized_value$);\n");
347     printer->Print(variables_,
348                    "/**\n"
349                    " * Use {@link #get$capitalized_name$Map()} instead.\n"
350                    " */\n"
351                    "@java.lang.Deprecated\n"
352                    "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
353                    "${$get$capitalized_name$$}$() {\n"
354                    "  return get$capitalized_name$Map();\n"
355                    "}\n");
356     printer->Annotate("{", "}", descriptor_);
357     WriteFieldDocComment(printer, descriptor_);
358     printer->Print(
359         variables_,
360         "@java.lang.Override\n"
361         "$deprecation$\n"
362         "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
363         "${$get$capitalized_name$Map$}$() {\n"
364         "  return java.util.Collections.unmodifiableMap(\n"
365         "      new com.google.protobuf.Internal.MapAdapter<\n"
366         "        $boxed_key_type$, $value_enum_type$, java.lang.Integer>(\n"
367         "            internalGet$capitalized_name$(),\n"
368         "            $name$ValueConverter));\n"
369         "}\n");
370     printer->Annotate("{", "}", descriptor_);
371     WriteFieldDocComment(printer, descriptor_);
372     printer->Print(
373         variables_,
374         "@java.lang.Override\n"
375         "$deprecation$\n"
376         "public $value_enum_type$ ${$get$capitalized_name$OrDefault$}$(\n"
377         "    $key_type$ key,\n"
378         "    $value_enum_type$ defaultValue) {\n"
379         "  $key_null_check$\n"
380         "  java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
381         "      internalGet$capitalized_name$();\n"
382         "  return map.containsKey(key)\n"
383         "         ? $name$ValueConverter.doForward(map.get(key))\n"
384         "         : defaultValue;\n"
385         "}\n");
386     printer->Annotate("{", "}", descriptor_);
387     WriteFieldDocComment(printer, descriptor_);
388     printer->Print(
389         variables_,
390         "@java.lang.Override\n"
391         "$deprecation$\n"
392         "public $value_enum_type$ ${$get$capitalized_name$OrThrow$}$(\n"
393         "    $key_type$ key) {\n"
394         "  $key_null_check$\n"
395         "  java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
396         "      internalGet$capitalized_name$();\n"
397         "  if (!map.containsKey(key)) {\n"
398         "    throw new java.lang.IllegalArgumentException();\n"
399         "  }\n"
400         "  return $name$ValueConverter.doForward(map.get(key));\n"
401         "}\n");
402     printer->Annotate("{", "}", descriptor_);
403     if (SupportUnknownEnumValue(descriptor_->file())) {
404       printer->Print(
405           variables_,
406           "/**\n"
407           " * Use {@link #get$capitalized_name$ValueMap()} instead.\n"
408           " */\n"
409           "@java.lang.Override\n"
410           "@java.lang.Deprecated\n"
411           "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n"
412           "${$get$capitalized_name$Value$}$() {\n"
413           "  return get$capitalized_name$ValueMap();\n"
414           "}\n");
415       printer->Annotate("{", "}", descriptor_);
416       WriteFieldDocComment(printer, descriptor_);
417       printer->Print(
418           variables_,
419           "@java.lang.Override\n"
420           "$deprecation$\n"
421           "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n"
422           "${$get$capitalized_name$ValueMap$}$() {\n"
423           "  return java.util.Collections.unmodifiableMap(\n"
424           "      internalGet$capitalized_name$());\n"
425           "}\n");
426       printer->Annotate("{", "}", descriptor_);
427       WriteFieldDocComment(printer, descriptor_);
428       printer->Print(
429           variables_,
430           "@java.lang.Override\n"
431           "$deprecation$\n"
432           "public $value_type$ ${$get$capitalized_name$ValueOrDefault$}$(\n"
433           "    $key_type$ key,\n"
434           "    $value_type$ defaultValue) {\n"
435           "  $key_null_check$\n"
436           "  java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
437           "      internalGet$capitalized_name$();\n"
438           "  return map.containsKey(key) ? map.get(key) : defaultValue;\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$ValueOrThrow$}$(\n"
447           "    $key_type$ key) {\n"
448           "  $key_null_check$\n"
449           "  java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
450           "      internalGet$capitalized_name$();\n"
451           "  if (!map.containsKey(key)) {\n"
452           "    throw new java.lang.IllegalArgumentException();\n"
453           "  }\n"
454           "  return map.get(key);\n"
455           "}\n");
456       printer->Annotate("{", "}", descriptor_);
457     }
458   } else {
459     printer->Print(variables_,
460                    "/**\n"
461                    " * Use {@link #get$capitalized_name$Map()} instead.\n"
462                    " */\n"
463                    "@java.lang.Override\n"
464                    "@java.lang.Deprecated\n"
465                    "public java.util.Map<$type_parameters$> "
466                    "${$get$capitalized_name$$}$() {\n"
467                    "  return get$capitalized_name$Map();\n"
468                    "}\n");
469     printer->Annotate("{", "}", descriptor_);
470     WriteFieldDocComment(printer, descriptor_);
471     printer->Print(variables_,
472                    "@java.lang.Override\n"
473                    "$deprecation$\n"
474                    "public java.util.Map<$type_parameters$> "
475                    "${$get$capitalized_name$Map$}$() {\n"
476                    "  return java.util.Collections.unmodifiableMap(\n"
477                    "      internalGet$capitalized_name$());\n"
478                    "}\n");
479     printer->Annotate("{", "}", descriptor_);
480     WriteFieldDocComment(printer, descriptor_);
481     printer->Print(
482         variables_,
483         "@java.lang.Override\n"
484         "$deprecation$\n"
485         "public $value_type$ ${$get$capitalized_name$OrDefault$}$(\n"
486         "    $key_type$ key,\n"
487         "    $value_type$ defaultValue) {\n"
488         "  $key_null_check$\n"
489         "  java.util.Map<$type_parameters$> map =\n"
490         "      internalGet$capitalized_name$();\n"
491         "  return map.containsKey(key) ? map.get(key) : defaultValue;\n"
492         "}\n");
493     printer->Annotate("{", "}", descriptor_);
494     WriteFieldDocComment(printer, descriptor_);
495     printer->Print(variables_,
496                    "@java.lang.Override\n"
497                    "$deprecation$\n"
498                    "public $value_type$ ${$get$capitalized_name$OrThrow$}$(\n"
499                    "    $key_type$ key) {\n"
500                    "  $key_null_check$\n"
501                    "  java.util.Map<$type_parameters$> map =\n"
502                    "      internalGet$capitalized_name$();\n"
503                    "  if (!map.containsKey(key)) {\n"
504                    "    throw new java.lang.IllegalArgumentException();\n"
505                    "  }\n"
506                    "  return map.get(key);\n"
507                    "}\n");
508     printer->Annotate("{", "}", descriptor_);
509   }
510 
511   // Generate private setters for the builder to proxy into.
512   if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) {
513     WriteFieldDocComment(printer, descriptor_);
514     printer->Print(
515         variables_,
516         "private java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
517         "getMutable$capitalized_name$Map() {\n"
518         "  return new com.google.protobuf.Internal.MapAdapter<\n"
519         "      $boxed_key_type$, $value_enum_type$, java.lang.Integer>(\n"
520         "          internalGetMutable$capitalized_name$(),\n"
521         "          $name$ValueConverter);\n"
522         "}\n");
523     if (SupportUnknownEnumValue(descriptor_->file())) {
524       WriteFieldDocComment(printer, descriptor_);
525       printer->Print(
526           variables_,
527           "private java.util.Map<$boxed_key_type$, $boxed_value_type$>\n"
528           "getMutable$capitalized_name$ValueMap() {\n"
529           "  return internalGetMutable$capitalized_name$();\n"
530           "}\n");
531     }
532   } else {
533     WriteFieldDocComment(printer, descriptor_);
534     printer->Print(variables_,
535                    "private java.util.Map<$type_parameters$>\n"
536                    "getMutable$capitalized_name$Map() {\n"
537                    "  return internalGetMutable$capitalized_name$();\n"
538                    "}\n");
539   }
540 }
541 
GenerateFieldInfo(io::Printer * printer,std::vector<uint16_t> * output) const542 void ImmutableMapFieldLiteGenerator::GenerateFieldInfo(
543     io::Printer* printer, std::vector<uint16_t>* output) const {
544   WriteIntToUtf16CharSequence(descriptor_->number(), output);
545   WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_),
546                               output);
547   printer->Print(variables_,
548                  "\"$name$_\",\n"
549                  "$default_entry$,\n");
550   if (!SupportUnknownEnumValue(descriptor_) &&
551       GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) {
552     PrintEnumVerifierLogic(printer, ValueField(descriptor_), variables_,
553                            /*var_name=*/"$value_enum_type$",
554                            /*terminating_string=*/",\n",
555                            /*enforce_lite=*/context_->EnforceLite());
556   }
557 }
558 
GenerateBuilderMembers(io::Printer * printer) const559 void ImmutableMapFieldLiteGenerator::GenerateBuilderMembers(
560     io::Printer* printer) const {
561   printer->Print(variables_,
562                  "@java.lang.Override\n"
563                  "$deprecation$\n"
564                  "public int ${$get$capitalized_name$Count$}$() {\n"
565                  "  return instance.get$capitalized_name$Map().size();\n"
566                  "}\n");
567   printer->Annotate("{", "}", descriptor_);
568   WriteFieldDocComment(printer, descriptor_);
569   printer->Print(
570       variables_,
571       "@java.lang.Override\n"
572       "$deprecation$\n"
573       "public boolean ${$contains$capitalized_name$$}$(\n"
574       "    $key_type$ key) {\n"
575       "  $key_null_check$\n"
576       "  return instance.get$capitalized_name$Map().containsKey(key);\n"
577       "}\n");
578   printer->Annotate("{", "}", descriptor_);
579   printer->Print(variables_,
580                  "$deprecation$\n"
581                  "public Builder ${$clear$capitalized_name$$}$() {\n"
582                  "  copyOnWrite();\n"
583                  "  instance.getMutable$capitalized_name$Map().clear();\n"
584                  "  return this;\n"
585                  "}\n");
586   printer->Annotate("{", "}", descriptor_);
587   WriteFieldDocComment(printer, descriptor_);
588   printer->Print(variables_,
589                  "$deprecation$\n"
590                  "public Builder ${$remove$capitalized_name$$}$(\n"
591                  "    $key_type$ key) {\n"
592                  "  $key_null_check$\n"
593                  "  copyOnWrite();\n"
594                  "  instance.getMutable$capitalized_name$Map().remove(key);\n"
595                  "  return this;\n"
596                  "}\n");
597   printer->Annotate("{", "}", descriptor_);
598   if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) {
599     printer->Print(variables_,
600                    "/**\n"
601                    " * Use {@link #get$capitalized_name$Map()} instead.\n"
602                    " */\n"
603                    "@java.lang.Deprecated\n"
604                    "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
605                    "${$get$capitalized_name$$}$() {\n"
606                    "  return get$capitalized_name$Map();\n"
607                    "}\n");
608     printer->Annotate("{", "}", descriptor_);
609     WriteFieldDocComment(printer, descriptor_);
610     printer->Print(variables_,
611                    "@java.lang.Override\n"
612                    "$deprecation$\n"
613                    "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
614                    "${$get$capitalized_name$Map$}$() {\n"
615                    "  return java.util.Collections.unmodifiableMap(\n"
616                    "      instance.get$capitalized_name$Map());\n"
617                    "}\n");
618     printer->Annotate("{", "}", descriptor_);
619     WriteFieldDocComment(printer, descriptor_);
620     printer->Print(
621         variables_,
622         "@java.lang.Override\n"
623         "$deprecation$\n"
624         "public $value_enum_type_pass_through_nullness$ "
625         "${$get$capitalized_name$OrDefault$}$(\n"
626         "    $key_type$ key,\n"
627         "    $value_enum_type_pass_through_nullness$ defaultValue) {\n"
628         "  $key_null_check$\n"
629         "  java.util.Map<$boxed_key_type$, $value_enum_type$> map =\n"
630         "      instance.get$capitalized_name$Map();\n"
631         "  return map.containsKey(key)\n"
632         "         ? map.get(key)\n"
633         "         : defaultValue;\n"
634         "}\n");
635     printer->Annotate("{", "}", descriptor_);
636     WriteFieldDocComment(printer, descriptor_);
637     printer->Print(
638         variables_,
639         "@java.lang.Override\n"
640         "$deprecation$\n"
641         "public $value_enum_type$ ${$get$capitalized_name$OrThrow$}$(\n"
642         "    $key_type$ key) {\n"
643         "  $key_null_check$\n"
644         "  java.util.Map<$boxed_key_type$, $value_enum_type$> map =\n"
645         "      instance.get$capitalized_name$Map();\n"
646         "  if (!map.containsKey(key)) {\n"
647         "    throw new java.lang.IllegalArgumentException();\n"
648         "  }\n"
649         "  return map.get(key);\n"
650         "}\n");
651     printer->Annotate("{", "}", descriptor_);
652     WriteFieldDocComment(printer, descriptor_);
653     printer->Print(
654         variables_,
655         "$deprecation$public Builder ${$put$capitalized_name$$}$(\n"
656         "    $key_type$ key,\n"
657         "    $value_enum_type$ value) {\n"
658         "  $key_null_check$\n"
659         "  $value_null_check$\n"
660         "  copyOnWrite();\n"
661         "  instance.getMutable$capitalized_name$Map().put(key, value);\n"
662         "  return this;\n"
663         "}\n");
664     printer->Annotate("{", "}", descriptor_);
665     WriteFieldDocComment(printer, descriptor_);
666     printer->Print(
667         variables_,
668         "$deprecation$public Builder ${$putAll$capitalized_name$$}$(\n"
669         "    java.util.Map<$boxed_key_type$, $value_enum_type$> values) {\n"
670         "  copyOnWrite();\n"
671         "  instance.getMutable$capitalized_name$Map().putAll(values);\n"
672         "  return this;\n"
673         "}\n");
674     printer->Annotate("{", "}", descriptor_);
675     if (SupportUnknownEnumValue(descriptor_->file())) {
676       printer->Print(
677           variables_,
678           "/**\n"
679           " * Use {@link #get$capitalized_name$ValueMap()} instead.\n"
680           " */\n"
681           "@java.lang.Override\n"
682           "@java.lang.Deprecated\n"
683           "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n"
684           "${$get$capitalized_name$Value$}$() {\n"
685           "  return get$capitalized_name$ValueMap();\n"
686           "}\n");
687       printer->Annotate("{", "}", descriptor_);
688       WriteFieldDocComment(printer, descriptor_);
689       printer->Print(
690           variables_,
691           "@java.lang.Override\n"
692           "$deprecation$\n"
693           "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n"
694           "${$get$capitalized_name$ValueMap$}$() {\n"
695           "  return java.util.Collections.unmodifiableMap(\n"
696           "      instance.get$capitalized_name$ValueMap());\n"
697           "}\n");
698       printer->Annotate("{", "}", descriptor_);
699       WriteFieldDocComment(printer, descriptor_);
700       printer->Print(
701           variables_,
702           "@java.lang.Override\n"
703           "$deprecation$\n"
704           "public $value_type$ ${$get$capitalized_name$ValueOrDefault$}$(\n"
705           "    $key_type$ key,\n"
706           "    $value_type$ defaultValue) {\n"
707           "  $key_null_check$\n"
708           "  java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
709           "      instance.get$capitalized_name$ValueMap();\n"
710           "  return map.containsKey(key) ? map.get(key) : defaultValue;\n"
711           "}\n");
712       printer->Annotate("{", "}", descriptor_);
713       WriteFieldDocComment(printer, descriptor_);
714       printer->Print(
715           variables_,
716           "@java.lang.Override\n"
717           "$deprecation$\n"
718           "public $value_type$ ${$get$capitalized_name$ValueOrThrow$}$(\n"
719           "    $key_type$ key) {\n"
720           "  $key_null_check$\n"
721           "  java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
722           "      instance.get$capitalized_name$ValueMap();\n"
723           "  if (!map.containsKey(key)) {\n"
724           "    throw new java.lang.IllegalArgumentException();\n"
725           "  }\n"
726           "  return map.get(key);\n"
727           "}\n");
728       printer->Annotate("{", "}", descriptor_);
729       WriteFieldDocComment(printer, descriptor_);
730       printer->Print(
731           variables_,
732           "$deprecation$public Builder ${$put$capitalized_name$Value$}$(\n"
733           "    $key_type$ key,\n"
734           "    $value_type$ value) {\n"
735           "  $key_null_check$\n"
736           "  copyOnWrite();\n"
737           "  instance.getMutable$capitalized_name$ValueMap().put(key, value);\n"
738           "  return this;\n"
739           "}\n");
740       printer->Annotate("{", "}", descriptor_);
741       WriteFieldDocComment(printer, descriptor_);
742       printer->Print(
743           variables_,
744           "$deprecation$public Builder ${$putAll$capitalized_name$Value$}$(\n"
745           "    java.util.Map<$boxed_key_type$, $boxed_value_type$> values) {\n"
746           "  copyOnWrite();\n"
747           "  instance.getMutable$capitalized_name$ValueMap().putAll(values);\n"
748           "  return this;\n"
749           "}\n");
750       printer->Annotate("{", "}", descriptor_);
751     }
752   } else {
753     printer->Print(variables_,
754                    "/**\n"
755                    " * Use {@link #get$capitalized_name$Map()} instead.\n"
756                    " */\n"
757                    "@java.lang.Override\n"
758                    "@java.lang.Deprecated\n"
759                    "public java.util.Map<$type_parameters$> "
760                    "${$get$capitalized_name$$}$() {\n"
761                    "  return get$capitalized_name$Map();\n"
762                    "}\n");
763     printer->Annotate("{", "}", descriptor_);
764     WriteFieldDocComment(printer, descriptor_);
765     printer->Print(variables_,
766                    "@java.lang.Override\n"
767                    "$deprecation$"
768                    "public java.util.Map<$type_parameters$> "
769                    "${$get$capitalized_name$Map$}$() {\n"
770                    "  return java.util.Collections.unmodifiableMap(\n"
771                    "      instance.get$capitalized_name$Map());\n"
772                    "}\n");
773     printer->Annotate("{", "}", descriptor_);
774     WriteFieldDocComment(printer, descriptor_);
775     printer->Print(
776         variables_,
777         "@java.lang.Override\n"
778         "$deprecation$\n"
779         "public $value_type$ ${$get$capitalized_name$OrDefault$}$(\n"
780         "    $key_type$ key,\n"
781         "    $value_type$ defaultValue) {\n"
782         "  $key_null_check$\n"
783         "  java.util.Map<$type_parameters$> map =\n"
784         "      instance.get$capitalized_name$Map();\n"
785         "  return map.containsKey(key) ? map.get(key) : defaultValue;\n"
786         "}\n");
787     printer->Annotate("{", "}", descriptor_);
788     WriteFieldDocComment(printer, descriptor_);
789     printer->Print(variables_,
790                    "@java.lang.Override\n"
791                    "$deprecation$\n"
792                    "public $value_type$ ${$get$capitalized_name$OrThrow$}$(\n"
793                    "    $key_type$ key) {\n"
794                    "  $key_null_check$\n"
795                    "  java.util.Map<$type_parameters$> map =\n"
796                    "      instance.get$capitalized_name$Map();\n"
797                    "  if (!map.containsKey(key)) {\n"
798                    "    throw new java.lang.IllegalArgumentException();\n"
799                    "  }\n"
800                    "  return map.get(key);\n"
801                    "}\n");
802     printer->Annotate("{", "}", descriptor_);
803     WriteFieldDocComment(printer, descriptor_);
804     printer->Print(
805         variables_,
806         "$deprecation$"
807         "public Builder ${$put$capitalized_name$$}$(\n"
808         "    $key_type$ key,\n"
809         "    $value_type$ value) {\n"
810         "  $key_null_check$\n"
811         "  $value_null_check$\n"
812         "  copyOnWrite();\n"
813         "  instance.getMutable$capitalized_name$Map().put(key, value);\n"
814         "  return this;\n"
815         "}\n");
816     printer->Annotate("{", "}", descriptor_);
817     WriteFieldDocComment(printer, descriptor_);
818     printer->Print(
819         variables_,
820         "$deprecation$"
821         "public Builder ${$putAll$capitalized_name$$}$(\n"
822         "    java.util.Map<$type_parameters$> values) {\n"
823         "  copyOnWrite();\n"
824         "  instance.getMutable$capitalized_name$Map().putAll(values);\n"
825         "  return this;\n"
826         "}\n");
827     printer->Annotate("{", "}", descriptor_);
828   }
829 }
830 
GenerateKotlinDslMembers(io::Printer * printer) const831 void ImmutableMapFieldLiteGenerator::GenerateKotlinDslMembers(
832     io::Printer* printer) const {
833   printer->Print(
834       variables_,
835       "/**\n"
836       " * An uninstantiable, behaviorless type to represent the field in\n"
837       " * generics.\n"
838       " */\n"
839       "@kotlin.OptIn"
840       "(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)\n"
841       "public class ${$$kt_capitalized_name$Proxy$}$ private constructor()"
842       " : com.google.protobuf.kotlin.DslProxy()\n");
843 
844   WriteFieldDocComment(printer, descriptor_);
845   printer->Print(
846       variables_,
847       "$kt_deprecation$ public val $kt_name$: "
848       "com.google.protobuf.kotlin.DslMap"
849       "<$kt_key_type$, $kt_value_type$, ${$$kt_capitalized_name$Proxy$}$>\n"
850       "  @kotlin.jvm.JvmSynthetic\n"
851       "  @JvmName(\"get$kt_capitalized_name$Map\")\n"
852       "  get() = com.google.protobuf.kotlin.DslMap(\n"
853       "    $kt_dsl_builder$.${$get$capitalized_name$Map$}$()\n"
854       "  )\n");
855 
856   WriteFieldDocComment(printer, descriptor_);
857   printer->Print(
858       variables_,
859       "@JvmName(\"put$kt_capitalized_name$\")\n"
860       "public fun com.google.protobuf.kotlin.DslMap"
861       "<$kt_key_type$, $kt_value_type$, ${$$kt_capitalized_name$Proxy$}$>\n"
862       "  .put(key: $kt_key_type$, value: $kt_value_type$) {\n"
863       "     $kt_dsl_builder$.${$put$capitalized_name$$}$(key, value)\n"
864       "   }\n");
865 
866   WriteFieldDocComment(printer, descriptor_);
867   printer->Print(
868       variables_,
869       "@kotlin.jvm.JvmSynthetic\n"
870       "@JvmName(\"set$kt_capitalized_name$\")\n"
871       "@Suppress(\"NOTHING_TO_INLINE\")\n"
872       "public inline operator fun com.google.protobuf.kotlin.DslMap"
873       "<$kt_key_type$, $kt_value_type$, ${$$kt_capitalized_name$Proxy$}$>\n"
874       "  .set(key: $kt_key_type$, value: $kt_value_type$) {\n"
875       "     put(key, value)\n"
876       "   }\n");
877 
878   WriteFieldDocComment(printer, descriptor_);
879   printer->Print(
880       variables_,
881       "@kotlin.jvm.JvmSynthetic\n"
882       "@JvmName(\"remove$kt_capitalized_name$\")\n"
883       "public fun com.google.protobuf.kotlin.DslMap"
884       "<$kt_key_type$, $kt_value_type$, ${$$kt_capitalized_name$Proxy$}$>\n"
885       "  .remove(key: $kt_key_type$) {\n"
886       "     $kt_dsl_builder$.${$remove$capitalized_name$$}$(key)\n"
887       "   }\n");
888 
889   WriteFieldDocComment(printer, descriptor_);
890   printer->Print(
891       variables_,
892       "@kotlin.jvm.JvmSynthetic\n"
893       "@JvmName(\"putAll$kt_capitalized_name$\")\n"
894       "public fun com.google.protobuf.kotlin.DslMap"
895       "<$kt_key_type$, $kt_value_type$, ${$$kt_capitalized_name$Proxy$}$>\n"
896       "  .putAll(map: kotlin.collections.Map<$kt_key_type$, $kt_value_type$>) "
897       "{\n"
898       "     $kt_dsl_builder$.${$putAll$capitalized_name$$}$(map)\n"
899       "   }\n");
900 
901   WriteFieldDocComment(printer, descriptor_);
902   printer->Print(
903       variables_,
904       "@kotlin.jvm.JvmSynthetic\n"
905       "@JvmName(\"clear$kt_capitalized_name$\")\n"
906       "public fun com.google.protobuf.kotlin.DslMap"
907       "<$kt_key_type$, $kt_value_type$, ${$$kt_capitalized_name$Proxy$}$>\n"
908       "  .clear() {\n"
909       "     $kt_dsl_builder$.${$clear$capitalized_name$$}$()\n"
910       "   }\n");
911 }
912 
GenerateInitializationCode(io::Printer * printer) const913 void ImmutableMapFieldLiteGenerator::GenerateInitializationCode(
914     io::Printer* printer) const {
915   // Nothing to initialize.
916 }
917 
GetBoxedType() const918 std::string ImmutableMapFieldLiteGenerator::GetBoxedType() const {
919   return name_resolver_->GetImmutableClassName(descriptor_->message_type());
920 }
921 
922 }  // namespace java
923 }  // namespace compiler
924 }  // namespace protobuf
925 }  // namespace google
926 
927 #include <google/protobuf/port_undef.inc>
928