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
44namespace google {
45namespace protobuf {
46namespace compiler {
47namespace java {
48
49namespace {
50
51const 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
58const 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
65std::string TypeName(const FieldDescriptor* field,
66 ClassNameResolver* name_resolver, bool boxed) {
67 if (GetJavaType(field) == JAVATYPE_MESSAGE) {
68 return name_resolver->GetImmutableClassName(descriptor: field->message_type());
69 } else if (GetJavaType(field) == JAVATYPE_ENUM) {
70 return name_resolver->GetImmutableClassName(descriptor: field->enum_type());
71 } else {
72 return boxed ? BoxedPrimitiveTypeName(type: GetJavaType(field))
73 : PrimitiveTypeName(type: GetJavaType(field));
74 }
75}
76
77std::string KotlinTypeName(const FieldDescriptor* field,
78 ClassNameResolver* name_resolver) {
79 if (GetJavaType(field) == JAVATYPE_MESSAGE) {
80 return name_resolver->GetImmutableClassName(descriptor: field->message_type());
81 } else if (GetJavaType(field) == JAVATYPE_ENUM) {
82 return name_resolver->GetImmutableClassName(descriptor: field->enum_type());
83 } else {
84 return KotlinTypeName(type: GetJavaType(field));
85 }
86}
87
88std::string WireType(const FieldDescriptor* field) {
89 return "com.google.protobuf.WireFormat.FieldType." +
90 std::string(FieldTypeName(field_type: field->type()));
91}
92
93void 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: descriptor->message_type());
102 const FieldDescriptor* key = KeyField(descriptor);
103 const FieldDescriptor* value = ValueField(descriptor);
104 const JavaType keyJavaType = GetJavaType(field: key);
105 const JavaType valueJavaType = GetJavaType(field: value);
106
107 std::string pass_through_nullness = "/* nullable */\n";
108
109 (*variables)["key_type"] = TypeName(field: key, name_resolver, boxed: false);
110 (*variables)["boxed_key_type"] = TypeName(field: key, name_resolver, boxed: true);
111 (*variables)["kt_key_type"] = KotlinTypeName(field: key, name_resolver);
112 (*variables)["kt_value_type"] = KotlinTypeName(field: value, name_resolver);
113 (*variables)["key_wire_type"] = WireType(field: key);
114 (*variables)["key_default_value"] = DefaultValue(field: key, immutable: 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(type: keyJavaType)
119 ? "java.lang.Class<?> keyClass = key.getClass();"
120 : "";
121 (*variables)["value_null_check"] =
122 IsReferenceType(type: valueJavaType)
123 ? "java.lang.Class<?> valueClass = value.getClass();"
124 : "";
125
126 if (GetJavaType(field: 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(field: value);
131 (*variables)["value_default_value"] =
132 DefaultValue(field: value, immutable: true, name_resolver) + ".getNumber()";
133
134 (*variables)["value_enum_type"] = TypeName(field: value, name_resolver, boxed: false);
135
136 (*variables)["value_enum_type_pass_through_nullness"] =
137 pass_through_nullness + (*variables)["value_enum_type"];
138
139 if (SupportUnknownEnumValue(descriptor: 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(field: value, immutable: true, name_resolver);
147 }
148 } else {
149 (*variables)["value_type"] = TypeName(field: value, name_resolver, boxed: false);
150
151 (*variables)["value_type_pass_through_nullness"] =
152 (IsReferenceType(type: valueJavaType) ? pass_through_nullness : "") +
153 (*variables)["value_type"];
154
155 (*variables)["boxed_value_type"] = TypeName(field: value, name_resolver, boxed: true);
156 (*variables)["value_wire_type"] = WireType(field: value);
157 (*variables)["value_default_value"] =
158 DefaultValue(field: value, immutable: 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
178ImmutableMapFieldLiteGenerator::ImmutableMapFieldLiteGenerator(
179 const FieldDescriptor* descriptor, int messageBitIndex, Context* context)
180 : descriptor_(descriptor),
181 context_(context),
182 name_resolver_(context->GetNameResolver()) {
183 SetMessageVariables(descriptor, messageBitIndex, builderBitIndex: 0,
184 info: context->GetFieldGeneratorInfo(field: descriptor), context,
185 variables: &variables_);
186}
187
188ImmutableMapFieldLiteGenerator::~ImmutableMapFieldLiteGenerator() {}
189
190int ImmutableMapFieldLiteGenerator::GetNumBitsForMessage() const { return 0; }
191
192void ImmutableMapFieldLiteGenerator::GenerateInterfaceMembers(
193 io::Printer* printer) const {
194 WriteFieldDocComment(printer, field: descriptor_);
195 printer->Print(variables: variables_,
196 text: "$deprecation$int ${$get$capitalized_name$Count$}$();\n");
197 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
198 WriteFieldDocComment(printer, field: descriptor_);
199 printer->Print(variables: variables_,
200 text: "$deprecation$boolean ${$contains$capitalized_name$$}$(\n"
201 " $key_type$ key);\n");
202 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
203 if (GetJavaType(field: ValueField(descriptor: descriptor_)) == JAVATYPE_ENUM) {
204 printer->Print(variables: variables_,
205 text: "/**\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(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
212 WriteFieldDocComment(printer, field: descriptor_);
213 printer->Print(
214 variables: variables_,
215 text: "$deprecation$java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
216 "${$get$capitalized_name$Map$}$();\n");
217 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
218 WriteFieldDocComment(printer, field: descriptor_);
219 printer->Print(variables: variables_,
220 text: "$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(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
226 WriteFieldDocComment(printer, field: descriptor_);
227 printer->Print(
228 variables: variables_,
229 text: "$deprecation$$value_enum_type$ ${$get$capitalized_name$OrThrow$}$(\n"
230 " $key_type$ key);\n");
231 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
232 if (SupportUnknownEnumValue(descriptor: descriptor_->file())) {
233 printer->Print(
234 variables: variables_,
235 text: "/**\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(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
242 WriteFieldDocComment(printer, field: descriptor_);
243 printer->Print(variables: variables_,
244 text: "$deprecation$java.util.Map<$type_parameters$>\n"
245 "${$get$capitalized_name$ValueMap$}$();\n");
246 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
247 WriteFieldDocComment(printer, field: descriptor_);
248 printer->Print(variables: variables_,
249 text: "$deprecation$\n"
250 "$value_type$ ${$get$capitalized_name$ValueOrDefault$}$(\n"
251 " $key_type$ key,\n"
252 " $value_type$ defaultValue);\n");
253 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
254 WriteFieldDocComment(printer, field: descriptor_);
255 printer->Print(variables: variables_,
256 text: "$deprecation$\n"
257 "$value_type$ ${$get$capitalized_name$ValueOrThrow$}$(\n"
258 " $key_type$ key);\n");
259 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
260 }
261 } else {
262 printer->Print(variables: variables_,
263 text: "/**\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(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
270 WriteFieldDocComment(printer, field: descriptor_);
271 printer->Print(variables: variables_,
272 text: "$deprecation$java.util.Map<$type_parameters$>\n"
273 "${$get$capitalized_name$Map$}$();\n");
274 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
275 WriteFieldDocComment(printer, field: descriptor_);
276 printer->Print(variables: variables_,
277 text: "$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(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
283 WriteFieldDocComment(printer, field: descriptor_);
284 printer->Print(variables: variables_,
285 text: "$deprecation$\n"
286 "$value_type$ ${$get$capitalized_name$OrThrow$}$(\n"
287 " $key_type$ key);\n");
288 printer->Annotate(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
289 }
290}
291
292void ImmutableMapFieldLiteGenerator::GenerateMembers(
293 io::Printer* printer) const {
294 printer->Print(
295 variables: variables_,
296 text: "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: variables_,
307 text: "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: variables_,
322 text: "@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(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
328 WriteFieldDocComment(printer, field: descriptor_);
329 printer->Print(variables: variables_,
330 text: "@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(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
338 if (GetJavaType(field: ValueField(descriptor: descriptor_)) == JAVATYPE_ENUM) {
339 printer->Print(
340 variables: variables_,
341 text: "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: variables_,
348 text: "/**\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(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
357 WriteFieldDocComment(printer, field: descriptor_);
358 printer->Print(
359 variables: variables_,
360 text: "@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(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
371 WriteFieldDocComment(printer, field: descriptor_);
372 printer->Print(
373 variables: variables_,
374 text: "@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(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
387 WriteFieldDocComment(printer, field: descriptor_);
388 printer->Print(
389 variables: variables_,
390 text: "@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(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
403 if (SupportUnknownEnumValue(descriptor: descriptor_->file())) {
404 printer->Print(
405 variables: variables_,
406 text: "/**\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(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
416 WriteFieldDocComment(printer, field: descriptor_);
417 printer->Print(
418 variables: variables_,
419 text: "@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(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
427 WriteFieldDocComment(printer, field: descriptor_);
428 printer->Print(
429 variables: variables_,
430 text: "@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(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
441 WriteFieldDocComment(printer, field: descriptor_);
442 printer->Print(
443 variables: variables_,
444 text: "@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(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
457 }
458 } else {
459 printer->Print(variables: variables_,
460 text: "/**\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(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
470 WriteFieldDocComment(printer, field: descriptor_);
471 printer->Print(variables: variables_,
472 text: "@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(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
480 WriteFieldDocComment(printer, field: descriptor_);
481 printer->Print(
482 variables: variables_,
483 text: "@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(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
494 WriteFieldDocComment(printer, field: descriptor_);
495 printer->Print(variables: variables_,
496 text: "@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(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
509 }
510
511 // Generate private setters for the builder to proxy into.
512 if (GetJavaType(field: ValueField(descriptor: descriptor_)) == JAVATYPE_ENUM) {
513 WriteFieldDocComment(printer, field: descriptor_);
514 printer->Print(
515 variables: variables_,
516 text: "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: descriptor_->file())) {
524 WriteFieldDocComment(printer, field: descriptor_);
525 printer->Print(
526 variables: variables_,
527 text: "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, field: descriptor_);
534 printer->Print(variables: variables_,
535 text: "private java.util.Map<$type_parameters$>\n"
536 "getMutable$capitalized_name$Map() {\n"
537 " return internalGetMutable$capitalized_name$();\n"
538 "}\n");
539 }
540}
541
542void ImmutableMapFieldLiteGenerator::GenerateFieldInfo(
543 io::Printer* printer, std::vector<uint16_t>* output) const {
544 WriteIntToUtf16CharSequence(value: descriptor_->number(), output);
545 WriteIntToUtf16CharSequence(value: GetExperimentalJavaFieldType(field: descriptor_),
546 output);
547 printer->Print(variables: variables_,
548 text: "\"$name$_\",\n"
549 "$default_entry$,\n");
550 if (!SupportUnknownEnumValue(field: descriptor_) &&
551 GetJavaType(field: ValueField(descriptor: descriptor_)) == JAVATYPE_ENUM) {
552 PrintEnumVerifierLogic(printer, descriptor: ValueField(descriptor: descriptor_), variables: variables_,
553 /*var_name=*/"$value_enum_type$",
554 /*terminating_string=*/",\n",
555 /*enforce_lite=*/context_->EnforceLite());
556 }
557}
558
559void ImmutableMapFieldLiteGenerator::GenerateBuilderMembers(
560 io::Printer* printer) const {
561 printer->Print(variables: variables_,
562 text: "@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(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
568 WriteFieldDocComment(printer, field: descriptor_);
569 printer->Print(
570 variables: variables_,
571 text: "@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(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
579 printer->Print(variables: variables_,
580 text: "$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(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
587 WriteFieldDocComment(printer, field: descriptor_);
588 printer->Print(variables: variables_,
589 text: "$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(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
598 if (GetJavaType(field: ValueField(descriptor: descriptor_)) == JAVATYPE_ENUM) {
599 printer->Print(variables: variables_,
600 text: "/**\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(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
609 WriteFieldDocComment(printer, field: descriptor_);
610 printer->Print(variables: variables_,
611 text: "@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(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
619 WriteFieldDocComment(printer, field: descriptor_);
620 printer->Print(
621 variables: variables_,
622 text: "@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(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
636 WriteFieldDocComment(printer, field: descriptor_);
637 printer->Print(
638 variables: variables_,
639 text: "@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(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
652 WriteFieldDocComment(printer, field: descriptor_);
653 printer->Print(
654 variables: variables_,
655 text: "$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(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
665 WriteFieldDocComment(printer, field: descriptor_);
666 printer->Print(
667 variables: variables_,
668 text: "$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(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
675 if (SupportUnknownEnumValue(descriptor: descriptor_->file())) {
676 printer->Print(
677 variables: variables_,
678 text: "/**\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(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
688 WriteFieldDocComment(printer, field: descriptor_);
689 printer->Print(
690 variables: variables_,
691 text: "@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(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
699 WriteFieldDocComment(printer, field: descriptor_);
700 printer->Print(
701 variables: variables_,
702 text: "@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(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
713 WriteFieldDocComment(printer, field: descriptor_);
714 printer->Print(
715 variables: variables_,
716 text: "@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(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
729 WriteFieldDocComment(printer, field: descriptor_);
730 printer->Print(
731 variables: variables_,
732 text: "$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(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
741 WriteFieldDocComment(printer, field: descriptor_);
742 printer->Print(
743 variables: variables_,
744 text: "$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(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
751 }
752 } else {
753 printer->Print(variables: variables_,
754 text: "/**\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(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
764 WriteFieldDocComment(printer, field: descriptor_);
765 printer->Print(variables: variables_,
766 text: "@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(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
774 WriteFieldDocComment(printer, field: descriptor_);
775 printer->Print(
776 variables: variables_,
777 text: "@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(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
788 WriteFieldDocComment(printer, field: descriptor_);
789 printer->Print(variables: variables_,
790 text: "@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(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
803 WriteFieldDocComment(printer, field: descriptor_);
804 printer->Print(
805 variables: variables_,
806 text: "$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(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
817 WriteFieldDocComment(printer, field: descriptor_);
818 printer->Print(
819 variables: variables_,
820 text: "$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(begin_varname: "{", end_varname: "}", descriptor: descriptor_);
828 }
829}
830
831void ImmutableMapFieldLiteGenerator::GenerateKotlinDslMembers(
832 io::Printer* printer) const {
833 printer->Print(
834 variables: variables_,
835 text: "/**\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 "class ${$$kt_capitalized_name$Proxy$}$ private constructor()"
842 " : com.google.protobuf.kotlin.DslProxy()\n");
843
844 WriteFieldDocComment(printer, field: descriptor_);
845 printer->Print(
846 variables: variables_,
847 text: "$kt_deprecation$ 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, field: descriptor_);
857 printer->Print(
858 variables: variables_,
859 text: "@JvmName(\"put$kt_capitalized_name$\")\n"
860 "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, field: descriptor_);
867 printer->Print(
868 variables: variables_,
869 text: "@kotlin.jvm.JvmSynthetic\n"
870 "@JvmName(\"set$kt_capitalized_name$\")\n"
871 "@Suppress(\"NOTHING_TO_INLINE\")\n"
872 "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, field: descriptor_);
879 printer->Print(
880 variables: variables_,
881 text: "@kotlin.jvm.JvmSynthetic\n"
882 "@JvmName(\"remove$kt_capitalized_name$\")\n"
883 "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, field: descriptor_);
890 printer->Print(
891 variables: variables_,
892 text: "@kotlin.jvm.JvmSynthetic\n"
893 "@JvmName(\"putAll$kt_capitalized_name$\")\n"
894 "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, field: descriptor_);
902 printer->Print(
903 variables: variables_,
904 text: "@kotlin.jvm.JvmSynthetic\n"
905 "@JvmName(\"clear$kt_capitalized_name$\")\n"
906 "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
913void ImmutableMapFieldLiteGenerator::GenerateInitializationCode(
914 io::Printer* printer) const {
915 // Nothing to initialize.
916}
917
918std::string ImmutableMapFieldLiteGenerator::GetBoxedType() const {
919 return name_resolver_->GetImmutableClassName(descriptor: 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