1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 // * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 // * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31 #include <google/protobuf/compiler/java/java_map_field_lite.h>
32
33 #include <google/protobuf/compiler/java/java_context.h>
34 #include <google/protobuf/compiler/java/java_doc_comment.h>
35 #include <google/protobuf/compiler/java/java_helpers.h>
36 #include <google/protobuf/compiler/java/java_name_resolver.h>
37 #include <google/protobuf/io/printer.h>
38
39 namespace google {
40 namespace protobuf {
41 namespace compiler {
42 namespace java {
43
44 namespace {
45
KeyField(const FieldDescriptor * descriptor)46 const FieldDescriptor* KeyField(const FieldDescriptor* descriptor) {
47 GOOGLE_CHECK_EQ(FieldDescriptor::TYPE_MESSAGE, descriptor->type());
48 const Descriptor* message = descriptor->message_type();
49 GOOGLE_CHECK(message->options().map_entry());
50 return message->FindFieldByName("key");
51 }
52
ValueField(const FieldDescriptor * descriptor)53 const FieldDescriptor* ValueField(const FieldDescriptor* descriptor) {
54 GOOGLE_CHECK_EQ(FieldDescriptor::TYPE_MESSAGE, descriptor->type());
55 const Descriptor* message = descriptor->message_type();
56 GOOGLE_CHECK(message->options().map_entry());
57 return message->FindFieldByName("value");
58 }
59
TypeName(const FieldDescriptor * field,ClassNameResolver * name_resolver,bool boxed)60 std::string TypeName(const FieldDescriptor* field,
61 ClassNameResolver* name_resolver, bool boxed) {
62 if (GetJavaType(field) == JAVATYPE_MESSAGE) {
63 return name_resolver->GetImmutableClassName(field->message_type());
64 } else if (GetJavaType(field) == JAVATYPE_ENUM) {
65 return name_resolver->GetImmutableClassName(field->enum_type());
66 } else {
67 return boxed ? BoxedPrimitiveTypeName(GetJavaType(field))
68 : PrimitiveTypeName(GetJavaType(field));
69 }
70 }
71
WireType(const FieldDescriptor * field)72 std::string WireType(const FieldDescriptor* field) {
73 return "com.google.protobuf.WireFormat.FieldType." +
74 std::string(FieldTypeName(field->type()));
75 }
76
SetMessageVariables(const FieldDescriptor * descriptor,int messageBitIndex,int builderBitIndex,const FieldGeneratorInfo * info,Context * context,std::map<std::string,std::string> * variables)77 void SetMessageVariables(const FieldDescriptor* descriptor, int messageBitIndex,
78 int builderBitIndex, const FieldGeneratorInfo* info,
79 Context* context,
80 std::map<std::string, std::string>* variables) {
81 SetCommonFieldVariables(descriptor, info, variables);
82
83 ClassNameResolver* name_resolver = context->GetNameResolver();
84 (*variables)["type"] =
85 name_resolver->GetImmutableClassName(descriptor->message_type());
86 const FieldDescriptor* key = KeyField(descriptor);
87 const FieldDescriptor* value = ValueField(descriptor);
88 const JavaType keyJavaType = GetJavaType(key);
89 const JavaType valueJavaType = GetJavaType(value);
90
91 (*variables)["key_type"] = TypeName(key, name_resolver, false);
92 (*variables)["boxed_key_type"] = TypeName(key, name_resolver, true);
93 (*variables)["key_wire_type"] = WireType(key);
94 (*variables)["key_default_value"] = DefaultValue(key, true, name_resolver);
95 (*variables)["key_null_check"] =
96 IsReferenceType(keyJavaType)
97 ? "if (key == null) { throw new java.lang.NullPointerException(); }"
98 : "";
99 (*variables)["value_null_check"] =
100 IsReferenceType(valueJavaType)
101 ? "if (value == null) { throw new java.lang.NullPointerException(); }"
102 : "";
103
104 if (GetJavaType(value) == JAVATYPE_ENUM) {
105 // We store enums as Integers internally.
106 (*variables)["value_type"] = "int";
107 (*variables)["boxed_value_type"] = "java.lang.Integer";
108 (*variables)["value_wire_type"] = WireType(value);
109 (*variables)["value_default_value"] =
110 DefaultValue(value, true, name_resolver) + ".getNumber()";
111
112 (*variables)["value_enum_type"] = TypeName(value, name_resolver, false);
113
114 if (SupportUnknownEnumValue(descriptor->file())) {
115 // Map unknown values to a special UNRECOGNIZED value if supported.
116 (*variables)["unrecognized_value"] =
117 (*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);
122 }
123 } else {
124 (*variables)["value_type"] = TypeName(value, name_resolver, false);
125 (*variables)["boxed_value_type"] = TypeName(value, name_resolver, true);
126 (*variables)["value_wire_type"] = WireType(value);
127 (*variables)["value_default_value"] =
128 DefaultValue(value, true, name_resolver);
129 }
130 (*variables)["type_parameters"] =
131 (*variables)["boxed_key_type"] + ", " + (*variables)["boxed_value_type"];
132 // TODO(birdo): Add @deprecated javadoc when generating javadoc is supported
133 // by the proto compiler
134 (*variables)["deprecation"] =
135 descriptor->options().deprecated() ? "@java.lang.Deprecated " : "";
136
137 (*variables)["default_entry"] =
138 (*variables)["capitalized_name"] + "DefaultEntryHolder.defaultEntry";
139 }
140
141 } // namespace
142
ImmutableMapFieldLiteGenerator(const FieldDescriptor * descriptor,int messageBitIndex,Context * context)143 ImmutableMapFieldLiteGenerator::ImmutableMapFieldLiteGenerator(
144 const FieldDescriptor* descriptor, int messageBitIndex, Context* context)
145 : descriptor_(descriptor),
146 context_(context),
147 name_resolver_(context->GetNameResolver()) {
148 SetMessageVariables(descriptor, messageBitIndex, 0,
149 context->GetFieldGeneratorInfo(descriptor), context,
150 &variables_);
151 }
152
~ImmutableMapFieldLiteGenerator()153 ImmutableMapFieldLiteGenerator::~ImmutableMapFieldLiteGenerator() {}
154
GetNumBitsForMessage() const155 int ImmutableMapFieldLiteGenerator::GetNumBitsForMessage() const { return 0; }
156
GenerateInterfaceMembers(io::Printer * printer) const157 void ImmutableMapFieldLiteGenerator::GenerateInterfaceMembers(
158 io::Printer* printer) const {
159 WriteFieldDocComment(printer, descriptor_);
160 printer->Print(variables_,
161 "$deprecation$int ${$get$capitalized_name$Count$}$();\n");
162 printer->Annotate("{", "}", descriptor_);
163 WriteFieldDocComment(printer, descriptor_);
164 printer->Print(variables_,
165 "$deprecation$boolean ${$contains$capitalized_name$$}$(\n"
166 " $key_type$ key);\n");
167 printer->Annotate("{", "}", descriptor_);
168 if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) {
169 printer->Print(variables_,
170 "/**\n"
171 " * Use {@link #get$capitalized_name$Map()} instead.\n"
172 " */\n"
173 "@java.lang.Deprecated\n"
174 "java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
175 "${$get$capitalized_name$$}$();\n");
176 printer->Annotate("{", "}", descriptor_);
177 WriteFieldDocComment(printer, descriptor_);
178 printer->Print(
179 variables_,
180 "$deprecation$java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
181 "${$get$capitalized_name$Map$}$();\n");
182 printer->Annotate("{", "}", descriptor_);
183 WriteFieldDocComment(printer, descriptor_);
184 printer->Print(
185 variables_,
186 "$deprecation$$value_enum_type$ ${$get$capitalized_name$OrDefault$}$(\n"
187 " $key_type$ key,\n"
188 " $value_enum_type$ defaultValue);\n");
189 printer->Annotate("{", "}", descriptor_);
190 WriteFieldDocComment(printer, descriptor_);
191 printer->Print(
192 variables_,
193 "$deprecation$$value_enum_type$ ${$get$capitalized_name$OrThrow$}$(\n"
194 " $key_type$ key);\n");
195 printer->Annotate("{", "}", descriptor_);
196 if (SupportUnknownEnumValue(descriptor_->file())) {
197 printer->Print(
198 variables_,
199 "/**\n"
200 " * Use {@link #get$capitalized_name$ValueMap()} instead.\n"
201 " */\n"
202 "@java.lang.Deprecated\n"
203 "java.util.Map<$type_parameters$>\n"
204 "${$get$capitalized_name$Value$}$();\n");
205 printer->Annotate("{", "}", descriptor_);
206 WriteFieldDocComment(printer, descriptor_);
207 printer->Print(variables_,
208 "$deprecation$java.util.Map<$type_parameters$>\n"
209 "${$get$capitalized_name$ValueMap$}$();\n");
210 printer->Annotate("{", "}", descriptor_);
211 WriteFieldDocComment(printer, descriptor_);
212 printer->Print(variables_,
213 "$deprecation$\n"
214 "$value_type$ ${$get$capitalized_name$ValueOrDefault$}$(\n"
215 " $key_type$ key,\n"
216 " $value_type$ defaultValue);\n");
217 printer->Annotate("{", "}", descriptor_);
218 WriteFieldDocComment(printer, descriptor_);
219 printer->Print(variables_,
220 "$deprecation$\n"
221 "$value_type$ ${$get$capitalized_name$ValueOrThrow$}$(\n"
222 " $key_type$ key);\n");
223 printer->Annotate("{", "}", descriptor_);
224 }
225 } else {
226 printer->Print(variables_,
227 "/**\n"
228 " * Use {@link #get$capitalized_name$Map()} instead.\n"
229 " */\n"
230 "@java.lang.Deprecated\n"
231 "java.util.Map<$type_parameters$>\n"
232 "${$get$capitalized_name$$}$();\n");
233 printer->Annotate("{", "}", descriptor_);
234 WriteFieldDocComment(printer, descriptor_);
235 printer->Print(variables_,
236 "$deprecation$java.util.Map<$type_parameters$>\n"
237 "${$get$capitalized_name$Map$}$();\n");
238 printer->Annotate("{", "}", descriptor_);
239 WriteFieldDocComment(printer, descriptor_);
240 printer->Print(variables_,
241 "$deprecation$\n"
242 "$value_type$ ${$get$capitalized_name$OrDefault$}$(\n"
243 " $key_type$ key,\n"
244 " $value_type$ defaultValue);\n");
245 printer->Annotate("{", "}", descriptor_);
246 WriteFieldDocComment(printer, descriptor_);
247 printer->Print(variables_,
248 "$deprecation$\n"
249 "$value_type$ ${$get$capitalized_name$OrThrow$}$(\n"
250 " $key_type$ key);\n");
251 printer->Annotate("{", "}", descriptor_);
252 }
253 }
254
GenerateMembers(io::Printer * printer) const255 void ImmutableMapFieldLiteGenerator::GenerateMembers(
256 io::Printer* printer) const {
257 printer->Print(
258 variables_,
259 "private static final class $capitalized_name$DefaultEntryHolder {\n"
260 " static final com.google.protobuf.MapEntryLite<\n"
261 " $type_parameters$> defaultEntry =\n"
262 " com.google.protobuf.MapEntryLite\n"
263 " .<$type_parameters$>newDefaultInstance(\n"
264 " $key_wire_type$,\n"
265 " $key_default_value$,\n"
266 " $value_wire_type$,\n"
267 " $value_default_value$);\n"
268 "}\n");
269 printer->Print(variables_,
270 "private com.google.protobuf.MapFieldLite<\n"
271 " $type_parameters$> $name$_ =\n"
272 " com.google.protobuf.MapFieldLite.emptyMapField();\n"
273 "private com.google.protobuf.MapFieldLite<$type_parameters$>\n"
274 "internalGet$capitalized_name$() {\n"
275 " return $name$_;\n"
276 "}\n"
277 "private com.google.protobuf.MapFieldLite<$type_parameters$>\n"
278 "internalGetMutable$capitalized_name$() {\n"
279 " if (!$name$_.isMutable()) {\n"
280 " $name$_ = $name$_.mutableCopy();\n"
281 " }\n"
282 " return $name$_;\n"
283 "}\n");
284 printer->Print(variables_,
285 "@java.lang.Override\n"
286 "$deprecation$\n"
287 "public int ${$get$capitalized_name$Count$}$() {\n"
288 " return internalGet$capitalized_name$().size();\n"
289 "}\n");
290 printer->Annotate("{", "}", descriptor_);
291 WriteFieldDocComment(printer, descriptor_);
292 printer->Print(variables_,
293 "@java.lang.Override\n"
294 "$deprecation$\n"
295 "public boolean ${$contains$capitalized_name$$}$(\n"
296 " $key_type$ key) {\n"
297 " $key_null_check$\n"
298 " return internalGet$capitalized_name$().containsKey(key);\n"
299 "}\n");
300 printer->Annotate("{", "}", descriptor_);
301 if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) {
302 printer->Print(
303 variables_,
304 "private static final\n"
305 "com.google.protobuf.Internal.MapAdapter.Converter<\n"
306 " java.lang.Integer, $value_enum_type$> $name$ValueConverter =\n"
307 " com.google.protobuf.Internal.MapAdapter.newEnumConverter(\n"
308 " $value_enum_type$.internalGetValueMap(),\n"
309 " $unrecognized_value$);\n");
310 printer->Print(variables_,
311 "/**\n"
312 " * Use {@link #get$capitalized_name$Map()} instead.\n"
313 " */\n"
314 "@java.lang.Deprecated\n"
315 "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
316 "${$get$capitalized_name$$}$() {\n"
317 " return get$capitalized_name$Map();\n"
318 "}\n");
319 printer->Annotate("{", "}", descriptor_);
320 WriteFieldDocComment(printer, descriptor_);
321 printer->Print(
322 variables_,
323 "@java.lang.Override\n"
324 "$deprecation$\n"
325 "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
326 "${$get$capitalized_name$Map$}$() {\n"
327 " return java.util.Collections.unmodifiableMap(\n"
328 " new com.google.protobuf.Internal.MapAdapter<\n"
329 " $boxed_key_type$, $value_enum_type$, java.lang.Integer>(\n"
330 " internalGet$capitalized_name$(),\n"
331 " $name$ValueConverter));\n"
332 "}\n");
333 printer->Annotate("{", "}", descriptor_);
334 WriteFieldDocComment(printer, descriptor_);
335 printer->Print(
336 variables_,
337 "@java.lang.Override\n"
338 "$deprecation$\n"
339 "public $value_enum_type$ ${$get$capitalized_name$OrDefault$}$(\n"
340 " $key_type$ key,\n"
341 " $value_enum_type$ defaultValue) {\n"
342 " $key_null_check$\n"
343 " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
344 " internalGet$capitalized_name$();\n"
345 " return map.containsKey(key)\n"
346 " ? $name$ValueConverter.doForward(map.get(key))\n"
347 " : defaultValue;\n"
348 "}\n");
349 printer->Annotate("{", "}", descriptor_);
350 WriteFieldDocComment(printer, descriptor_);
351 printer->Print(
352 variables_,
353 "@java.lang.Override\n"
354 "$deprecation$\n"
355 "public $value_enum_type$ ${$get$capitalized_name$OrThrow$}$(\n"
356 " $key_type$ key) {\n"
357 " $key_null_check$\n"
358 " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
359 " internalGet$capitalized_name$();\n"
360 " if (!map.containsKey(key)) {\n"
361 " throw new java.lang.IllegalArgumentException();\n"
362 " }\n"
363 " return $name$ValueConverter.doForward(map.get(key));\n"
364 "}\n");
365 printer->Annotate("{", "}", descriptor_);
366 if (SupportUnknownEnumValue(descriptor_->file())) {
367 printer->Print(
368 variables_,
369 "/**\n"
370 " * Use {@link #get$capitalized_name$ValueMap()} instead.\n"
371 " */\n"
372 "@java.lang.Override\n"
373 "@java.lang.Deprecated\n"
374 "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n"
375 "${$get$capitalized_name$Value$}$() {\n"
376 " return get$capitalized_name$ValueMap();\n"
377 "}\n");
378 printer->Annotate("{", "}", descriptor_);
379 WriteFieldDocComment(printer, descriptor_);
380 printer->Print(
381 variables_,
382 "@java.lang.Override\n"
383 "$deprecation$\n"
384 "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n"
385 "${$get$capitalized_name$ValueMap$}$() {\n"
386 " return java.util.Collections.unmodifiableMap(\n"
387 " internalGet$capitalized_name$());\n"
388 "}\n");
389 printer->Annotate("{", "}", descriptor_);
390 WriteFieldDocComment(printer, descriptor_);
391 printer->Print(
392 variables_,
393 "@java.lang.Override\n"
394 "$deprecation$\n"
395 "public $value_type$ ${$get$capitalized_name$ValueOrDefault$}$(\n"
396 " $key_type$ key,\n"
397 " $value_type$ defaultValue) {\n"
398 " $key_null_check$\n"
399 " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
400 " internalGet$capitalized_name$();\n"
401 " return map.containsKey(key) ? map.get(key) : defaultValue;\n"
402 "}\n");
403 printer->Annotate("{", "}", descriptor_);
404 WriteFieldDocComment(printer, descriptor_);
405 printer->Print(
406 variables_,
407 "@java.lang.Override\n"
408 "$deprecation$\n"
409 "public $value_type$ ${$get$capitalized_name$ValueOrThrow$}$(\n"
410 " $key_type$ key) {\n"
411 " $key_null_check$\n"
412 " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
413 " internalGet$capitalized_name$();\n"
414 " if (!map.containsKey(key)) {\n"
415 " throw new java.lang.IllegalArgumentException();\n"
416 " }\n"
417 " return map.get(key);\n"
418 "}\n");
419 printer->Annotate("{", "}", descriptor_);
420 }
421 } else {
422 printer->Print(variables_,
423 "/**\n"
424 " * Use {@link #get$capitalized_name$Map()} instead.\n"
425 " */\n"
426 "@java.lang.Override\n"
427 "@java.lang.Deprecated\n"
428 "public java.util.Map<$type_parameters$> "
429 "${$get$capitalized_name$$}$() {\n"
430 " return get$capitalized_name$Map();\n"
431 "}\n");
432 printer->Annotate("{", "}", descriptor_);
433 WriteFieldDocComment(printer, descriptor_);
434 printer->Print(variables_,
435 "@java.lang.Override\n"
436 "$deprecation$\n"
437 "public java.util.Map<$type_parameters$> "
438 "${$get$capitalized_name$Map$}$() {\n"
439 " return java.util.Collections.unmodifiableMap(\n"
440 " internalGet$capitalized_name$());\n"
441 "}\n");
442 printer->Annotate("{", "}", descriptor_);
443 WriteFieldDocComment(printer, descriptor_);
444 printer->Print(
445 variables_,
446 "@java.lang.Override\n"
447 "$deprecation$\n"
448 "public $value_type$ ${$get$capitalized_name$OrDefault$}$(\n"
449 " $key_type$ key,\n"
450 " $value_type$ defaultValue) {\n"
451 " $key_null_check$\n"
452 " java.util.Map<$type_parameters$> map =\n"
453 " internalGet$capitalized_name$();\n"
454 " return map.containsKey(key) ? map.get(key) : defaultValue;\n"
455 "}\n");
456 printer->Annotate("{", "}", descriptor_);
457 WriteFieldDocComment(printer, descriptor_);
458 printer->Print(variables_,
459 "@java.lang.Override\n"
460 "$deprecation$\n"
461 "public $value_type$ ${$get$capitalized_name$OrThrow$}$(\n"
462 " $key_type$ key) {\n"
463 " $key_null_check$\n"
464 " java.util.Map<$type_parameters$> map =\n"
465 " internalGet$capitalized_name$();\n"
466 " if (!map.containsKey(key)) {\n"
467 " throw new java.lang.IllegalArgumentException();\n"
468 " }\n"
469 " return map.get(key);\n"
470 "}\n");
471 printer->Annotate("{", "}", descriptor_);
472 }
473
474 // Generate private setters for the builder to proxy into.
475 if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) {
476 WriteFieldDocComment(printer, descriptor_);
477 printer->Print(
478 variables_,
479 "private java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
480 "getMutable$capitalized_name$Map() {\n"
481 " return new com.google.protobuf.Internal.MapAdapter<\n"
482 " $boxed_key_type$, $value_enum_type$, java.lang.Integer>(\n"
483 " internalGetMutable$capitalized_name$(),\n"
484 " $name$ValueConverter);\n"
485 "}\n");
486 if (SupportUnknownEnumValue(descriptor_->file())) {
487 WriteFieldDocComment(printer, descriptor_);
488 printer->Print(
489 variables_,
490 "private java.util.Map<$boxed_key_type$, $boxed_value_type$>\n"
491 "getMutable$capitalized_name$ValueMap() {\n"
492 " return internalGetMutable$capitalized_name$();\n"
493 "}\n");
494 }
495 } else {
496 WriteFieldDocComment(printer, descriptor_);
497 printer->Print(variables_,
498 "private java.util.Map<$type_parameters$>\n"
499 "getMutable$capitalized_name$Map() {\n"
500 " return internalGetMutable$capitalized_name$();\n"
501 "}\n");
502 }
503 }
504
GenerateFieldInfo(io::Printer * printer,std::vector<uint16> * output) const505 void ImmutableMapFieldLiteGenerator::GenerateFieldInfo(
506 io::Printer* printer, std::vector<uint16>* output) const {
507 WriteIntToUtf16CharSequence(descriptor_->number(), output);
508 WriteIntToUtf16CharSequence(GetExperimentalJavaFieldType(descriptor_),
509 output);
510 printer->Print(variables_,
511 "\"$name$_\",\n"
512 "$default_entry$,\n");
513 if (SupportFieldPresence(descriptor_->file()) &&
514 GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) {
515 PrintEnumVerifierLogic(printer, ValueField(descriptor_), variables_,
516 /*var_name=*/"$value_enum_type$",
517 /*terminating_string=*/",\n",
518 /*enforce_lite=*/context_->EnforceLite());
519 }
520 }
521
GenerateBuilderMembers(io::Printer * printer) const522 void ImmutableMapFieldLiteGenerator::GenerateBuilderMembers(
523 io::Printer* printer) const {
524 printer->Print(variables_,
525 "@java.lang.Override\n"
526 "$deprecation$\n"
527 "public int ${$get$capitalized_name$Count$}$() {\n"
528 " return instance.get$capitalized_name$Map().size();\n"
529 "}\n");
530 printer->Annotate("{", "}", descriptor_);
531 WriteFieldDocComment(printer, descriptor_);
532 printer->Print(
533 variables_,
534 "@java.lang.Override\n"
535 "$deprecation$\n"
536 "public boolean ${$contains$capitalized_name$$}$(\n"
537 " $key_type$ key) {\n"
538 " $key_null_check$\n"
539 " return instance.get$capitalized_name$Map().containsKey(key);\n"
540 "}\n");
541 printer->Annotate("{", "}", descriptor_);
542 printer->Print(variables_,
543 "$deprecation$\n"
544 "public Builder ${$clear$capitalized_name$$}$() {\n"
545 " copyOnWrite();\n"
546 " instance.getMutable$capitalized_name$Map().clear();\n"
547 " return this;\n"
548 "}\n");
549 printer->Annotate("{", "}", descriptor_);
550 WriteFieldDocComment(printer, descriptor_);
551 printer->Print(variables_,
552 "$deprecation$\n"
553 "public Builder ${$remove$capitalized_name$$}$(\n"
554 " $key_type$ key) {\n"
555 " $key_null_check$\n"
556 " copyOnWrite();\n"
557 " instance.getMutable$capitalized_name$Map().remove(key);\n"
558 " return this;\n"
559 "}\n");
560 printer->Annotate("{", "}", descriptor_);
561 if (GetJavaType(ValueField(descriptor_)) == JAVATYPE_ENUM) {
562 printer->Print(variables_,
563 "/**\n"
564 " * Use {@link #get$capitalized_name$Map()} instead.\n"
565 " */\n"
566 "@java.lang.Deprecated\n"
567 "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
568 "${$get$capitalized_name$$}$() {\n"
569 " return get$capitalized_name$Map();\n"
570 "}\n");
571 printer->Annotate("{", "}", descriptor_);
572 WriteFieldDocComment(printer, descriptor_);
573 printer->Print(variables_,
574 "@java.lang.Override\n"
575 "$deprecation$\n"
576 "public java.util.Map<$boxed_key_type$, $value_enum_type$>\n"
577 "${$get$capitalized_name$Map$}$() {\n"
578 " return java.util.Collections.unmodifiableMap(\n"
579 " instance.get$capitalized_name$Map());\n"
580 "}\n");
581 printer->Annotate("{", "}", descriptor_);
582 WriteFieldDocComment(printer, descriptor_);
583 printer->Print(
584 variables_,
585 "@java.lang.Override\n"
586 "$deprecation$\n"
587 "public $value_enum_type$ ${$get$capitalized_name$OrDefault$}$(\n"
588 " $key_type$ key,\n"
589 " $value_enum_type$ defaultValue) {\n"
590 " $key_null_check$\n"
591 " java.util.Map<$boxed_key_type$, $value_enum_type$> map =\n"
592 " instance.get$capitalized_name$Map();\n"
593 " return map.containsKey(key)\n"
594 " ? map.get(key)\n"
595 " : defaultValue;\n"
596 "}\n");
597 printer->Annotate("{", "}", descriptor_);
598 WriteFieldDocComment(printer, descriptor_);
599 printer->Print(
600 variables_,
601 "@java.lang.Override\n"
602 "$deprecation$\n"
603 "public $value_enum_type$ ${$get$capitalized_name$OrThrow$}$(\n"
604 " $key_type$ key) {\n"
605 " $key_null_check$\n"
606 " java.util.Map<$boxed_key_type$, $value_enum_type$> map =\n"
607 " instance.get$capitalized_name$Map();\n"
608 " if (!map.containsKey(key)) {\n"
609 " throw new java.lang.IllegalArgumentException();\n"
610 " }\n"
611 " return map.get(key);\n"
612 "}\n");
613 printer->Annotate("{", "}", descriptor_);
614 WriteFieldDocComment(printer, descriptor_);
615 printer->Print(
616 variables_,
617 "$deprecation$public Builder ${$put$capitalized_name$$}$(\n"
618 " $key_type$ key,\n"
619 " $value_enum_type$ value) {\n"
620 " $key_null_check$\n"
621 " $value_null_check$\n"
622 " copyOnWrite();\n"
623 " instance.getMutable$capitalized_name$Map().put(key, value);\n"
624 " return this;\n"
625 "}\n");
626 printer->Annotate("{", "}", descriptor_);
627 WriteFieldDocComment(printer, descriptor_);
628 printer->Print(
629 variables_,
630 "$deprecation$public Builder ${$putAll$capitalized_name$$}$(\n"
631 " java.util.Map<$boxed_key_type$, $value_enum_type$> values) {\n"
632 " copyOnWrite();\n"
633 " instance.getMutable$capitalized_name$Map().putAll(values);\n"
634 " return this;\n"
635 "}\n");
636 printer->Annotate("{", "}", descriptor_);
637 if (SupportUnknownEnumValue(descriptor_->file())) {
638 printer->Print(
639 variables_,
640 "/**\n"
641 " * Use {@link #get$capitalized_name$ValueMap()} instead.\n"
642 " */\n"
643 "@java.lang.Override\n"
644 "@java.lang.Deprecated\n"
645 "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n"
646 "${$get$capitalized_name$Value$}$() {\n"
647 " return get$capitalized_name$ValueMap();\n"
648 "}\n");
649 printer->Annotate("{", "}", descriptor_);
650 WriteFieldDocComment(printer, descriptor_);
651 printer->Print(
652 variables_,
653 "@java.lang.Override\n"
654 "$deprecation$\n"
655 "public java.util.Map<$boxed_key_type$, $boxed_value_type$>\n"
656 "${$get$capitalized_name$ValueMap$}$() {\n"
657 " return java.util.Collections.unmodifiableMap(\n"
658 " instance.get$capitalized_name$ValueMap());\n"
659 "}\n");
660 printer->Annotate("{", "}", descriptor_);
661 WriteFieldDocComment(printer, descriptor_);
662 printer->Print(
663 variables_,
664 "@java.lang.Override\n"
665 "$deprecation$\n"
666 "public $value_type$ ${$get$capitalized_name$ValueOrDefault$}$(\n"
667 " $key_type$ key,\n"
668 " $value_type$ defaultValue) {\n"
669 " $key_null_check$\n"
670 " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
671 " instance.get$capitalized_name$ValueMap();\n"
672 " return map.containsKey(key) ? map.get(key) : defaultValue;\n"
673 "}\n");
674 printer->Annotate("{", "}", descriptor_);
675 WriteFieldDocComment(printer, descriptor_);
676 printer->Print(
677 variables_,
678 "@java.lang.Override\n"
679 "$deprecation$\n"
680 "public $value_type$ ${$get$capitalized_name$ValueOrThrow$}$(\n"
681 " $key_type$ key) {\n"
682 " $key_null_check$\n"
683 " java.util.Map<$boxed_key_type$, $boxed_value_type$> map =\n"
684 " instance.get$capitalized_name$ValueMap();\n"
685 " if (!map.containsKey(key)) {\n"
686 " throw new java.lang.IllegalArgumentException();\n"
687 " }\n"
688 " return map.get(key);\n"
689 "}\n");
690 printer->Annotate("{", "}", descriptor_);
691 WriteFieldDocComment(printer, descriptor_);
692 printer->Print(
693 variables_,
694 "$deprecation$public Builder ${$put$capitalized_name$Value$}$(\n"
695 " $key_type$ key,\n"
696 " $value_type$ value) {\n"
697 " $key_null_check$\n"
698 " copyOnWrite();\n"
699 " instance.getMutable$capitalized_name$ValueMap().put(key, value);\n"
700 " return this;\n"
701 "}\n");
702 printer->Annotate("{", "}", descriptor_);
703 WriteFieldDocComment(printer, descriptor_);
704 printer->Print(
705 variables_,
706 "$deprecation$public Builder ${$putAll$capitalized_name$Value$}$(\n"
707 " java.util.Map<$boxed_key_type$, $boxed_value_type$> values) {\n"
708 " copyOnWrite();\n"
709 " instance.getMutable$capitalized_name$ValueMap().putAll(values);\n"
710 " return this;\n"
711 "}\n");
712 printer->Annotate("{", "}", descriptor_);
713 }
714 } else {
715 printer->Print(variables_,
716 "/**\n"
717 " * Use {@link #get$capitalized_name$Map()} instead.\n"
718 " */\n"
719 "@java.lang.Override\n"
720 "@java.lang.Deprecated\n"
721 "public java.util.Map<$type_parameters$> "
722 "${$get$capitalized_name$$}$() {\n"
723 " return get$capitalized_name$Map();\n"
724 "}\n");
725 printer->Annotate("{", "}", descriptor_);
726 WriteFieldDocComment(printer, descriptor_);
727 printer->Print(variables_,
728 "@java.lang.Override\n"
729 "$deprecation$"
730 "public java.util.Map<$type_parameters$> "
731 "${$get$capitalized_name$Map$}$() {\n"
732 " return java.util.Collections.unmodifiableMap(\n"
733 " instance.get$capitalized_name$Map());\n"
734 "}\n");
735 printer->Annotate("{", "}", descriptor_);
736 WriteFieldDocComment(printer, descriptor_);
737 printer->Print(
738 variables_,
739 "@java.lang.Override\n"
740 "$deprecation$\n"
741 "public $value_type$ ${$get$capitalized_name$OrDefault$}$(\n"
742 " $key_type$ key,\n"
743 " $value_type$ defaultValue) {\n"
744 " $key_null_check$\n"
745 " java.util.Map<$type_parameters$> map =\n"
746 " instance.get$capitalized_name$Map();\n"
747 " return map.containsKey(key) ? map.get(key) : defaultValue;\n"
748 "}\n");
749 printer->Annotate("{", "}", descriptor_);
750 WriteFieldDocComment(printer, descriptor_);
751 printer->Print(variables_,
752 "@java.lang.Override\n"
753 "$deprecation$\n"
754 "public $value_type$ ${$get$capitalized_name$OrThrow$}$(\n"
755 " $key_type$ key) {\n"
756 " $key_null_check$\n"
757 " java.util.Map<$type_parameters$> map =\n"
758 " instance.get$capitalized_name$Map();\n"
759 " if (!map.containsKey(key)) {\n"
760 " throw new java.lang.IllegalArgumentException();\n"
761 " }\n"
762 " return map.get(key);\n"
763 "}\n");
764 printer->Annotate("{", "}", descriptor_);
765 WriteFieldDocComment(printer, descriptor_);
766 printer->Print(
767 variables_,
768 "$deprecation$"
769 "public Builder ${$put$capitalized_name$$}$(\n"
770 " $key_type$ key,\n"
771 " $value_type$ value) {\n"
772 " $key_null_check$\n"
773 " $value_null_check$\n"
774 " copyOnWrite();\n"
775 " instance.getMutable$capitalized_name$Map().put(key, value);\n"
776 " return this;\n"
777 "}\n");
778 printer->Annotate("{", "}", descriptor_);
779 WriteFieldDocComment(printer, descriptor_);
780 printer->Print(
781 variables_,
782 "$deprecation$"
783 "public Builder ${$putAll$capitalized_name$$}$(\n"
784 " java.util.Map<$type_parameters$> values) {\n"
785 " copyOnWrite();\n"
786 " instance.getMutable$capitalized_name$Map().putAll(values);\n"
787 " return this;\n"
788 "}\n");
789 printer->Annotate("{", "}", descriptor_);
790 }
791 }
792
GenerateInitializationCode(io::Printer * printer) const793 void ImmutableMapFieldLiteGenerator::GenerateInitializationCode(
794 io::Printer* printer) const {
795 // Nothing to initialize.
796 }
797
GetBoxedType() const798 std::string ImmutableMapFieldLiteGenerator::GetBoxedType() const {
799 return name_resolver_->GetImmutableClassName(descriptor_->message_type());
800 }
801
802 } // namespace java
803 } // namespace compiler
804 } // namespace protobuf
805 } // namespace google
806