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