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