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 | // Author: dweis@google.com (Daniel Weis) |
32 | // Based on original Protocol Buffers design by |
33 | // Sanjay Ghemawat, Jeff Dean, and others. |
34 | |
35 | #include <google/protobuf/compiler/java/message_lite.h> |
36 | |
37 | #include <algorithm> |
38 | #include <cstdint> |
39 | #include <map> |
40 | #include <memory> |
41 | #include <vector> |
42 | |
43 | #include <google/protobuf/io/coded_stream.h> |
44 | #include <google/protobuf/io/printer.h> |
45 | #include <google/protobuf/wire_format.h> |
46 | #include <google/protobuf/stubs/strutil.h> |
47 | #include <google/protobuf/stubs/substitute.h> |
48 | #include <google/protobuf/compiler/java/context.h> |
49 | #include <google/protobuf/compiler/java/doc_comment.h> |
50 | #include <google/protobuf/compiler/java/enum_lite.h> |
51 | #include <google/protobuf/compiler/java/extension_lite.h> |
52 | #include <google/protobuf/compiler/java/generator_factory.h> |
53 | #include <google/protobuf/compiler/java/helpers.h> |
54 | #include <google/protobuf/compiler/java/message_builder.h> |
55 | #include <google/protobuf/compiler/java/message_builder_lite.h> |
56 | #include <google/protobuf/compiler/java/name_resolver.h> |
57 | #include <google/protobuf/descriptor.pb.h> |
58 | |
59 | // Must be last. |
60 | #include <google/protobuf/port_def.inc> |
61 | |
62 | namespace google { |
63 | namespace protobuf { |
64 | namespace compiler { |
65 | namespace java { |
66 | |
67 | using internal::WireFormat; |
68 | using internal::WireFormatLite; |
69 | |
70 | // =================================================================== |
71 | ImmutableMessageLiteGenerator::ImmutableMessageLiteGenerator( |
72 | const Descriptor* descriptor, Context* context) |
73 | : MessageGenerator(descriptor), |
74 | context_(context), |
75 | name_resolver_(context->GetNameResolver()), |
76 | field_generators_(descriptor, context_) { |
77 | GOOGLE_CHECK(!HasDescriptorMethods(descriptor->file(), context->EnforceLite())) |
78 | << "Generator factory error: A lite message generator is used to " |
79 | "generate non-lite messages." ; |
80 | for (int i = 0; i < descriptor_->field_count(); i++) { |
81 | if (IsRealOneof(descriptor: descriptor_->field(index: i))) { |
82 | oneofs_.insert(x: descriptor_->field(index: i)->containing_oneof()); |
83 | } |
84 | } |
85 | } |
86 | |
87 | ImmutableMessageLiteGenerator::~ImmutableMessageLiteGenerator() {} |
88 | |
89 | void ImmutableMessageLiteGenerator::GenerateStaticVariables( |
90 | io::Printer* printer, int* bytecode_estimate) { |
91 | // Generate static members for all nested types. |
92 | for (int i = 0; i < descriptor_->nested_type_count(); i++) { |
93 | // TODO(kenton): Reuse MessageGenerator objects? |
94 | ImmutableMessageLiteGenerator(descriptor_->nested_type(index: i), context_) |
95 | .GenerateStaticVariables(printer, bytecode_estimate); |
96 | } |
97 | } |
98 | |
99 | int ImmutableMessageLiteGenerator::GenerateStaticVariableInitializers( |
100 | io::Printer* printer) { |
101 | int bytecode_estimate = 0; |
102 | // Generate static member initializers for all nested types. |
103 | for (int i = 0; i < descriptor_->nested_type_count(); i++) { |
104 | // TODO(kenton): Reuse MessageGenerator objects? |
105 | bytecode_estimate += |
106 | ImmutableMessageLiteGenerator(descriptor_->nested_type(index: i), context_) |
107 | .GenerateStaticVariableInitializers(printer); |
108 | } |
109 | return bytecode_estimate; |
110 | } |
111 | |
112 | // =================================================================== |
113 | |
114 | void ImmutableMessageLiteGenerator::GenerateInterface(io::Printer* printer) { |
115 | MaybePrintGeneratedAnnotation(context: context_, printer, descriptor: descriptor_, |
116 | /* immutable = */ true, suffix: "OrBuilder" ); |
117 | if (descriptor_->extension_range_count() > 0) { |
118 | printer->Print( |
119 | text: "$deprecation$public interface ${$$classname$OrBuilder$}$ extends \n" |
120 | " $extra_interfaces$\n" |
121 | " com.google.protobuf.GeneratedMessageLite.\n" |
122 | " ExtendableMessageOrBuilder<\n" |
123 | " $classname$, $classname$.Builder> {\n" , |
124 | args: "deprecation" , |
125 | args: descriptor_->options().deprecated() ? "@java.lang.Deprecated " : "" , |
126 | args: "extra_interfaces" , args: ExtraMessageOrBuilderInterfaces(descriptor: descriptor_), |
127 | args: "classname" , args: descriptor_->name(), args: "{" , args: "" , args: "}" , args: "" ); |
128 | } else { |
129 | printer->Print( |
130 | text: "$deprecation$public interface ${$$classname$OrBuilder$}$ extends\n" |
131 | " $extra_interfaces$\n" |
132 | " com.google.protobuf.MessageLiteOrBuilder {\n" , |
133 | args: "deprecation" , |
134 | args: descriptor_->options().deprecated() ? "@java.lang.Deprecated " : "" , |
135 | args: "extra_interfaces" , args: ExtraMessageOrBuilderInterfaces(descriptor: descriptor_), |
136 | args: "classname" , args: descriptor_->name(), args: "{" , args: "" , args: "}" , args: "" ); |
137 | } |
138 | printer->Annotate(begin_varname: "{" , end_varname: "}" , descriptor: descriptor_); |
139 | |
140 | printer->Indent(); |
141 | for (int i = 0; i < descriptor_->field_count(); i++) { |
142 | printer->Print(text: "\n" ); |
143 | field_generators_.get(field: descriptor_->field(index: i)) |
144 | .GenerateInterfaceMembers(printer); |
145 | } |
146 | for (auto oneof : oneofs_) { |
147 | printer->Print( |
148 | text: "\n" |
149 | "public $classname$.$oneof_capitalized_name$Case " |
150 | "get$oneof_capitalized_name$Case();\n" , |
151 | args: "oneof_capitalized_name" , |
152 | args: context_->GetOneofGeneratorInfo(oneof)->capitalized_name, args: "classname" , |
153 | args: context_->GetNameResolver()->GetImmutableClassName(descriptor: descriptor_)); |
154 | } |
155 | printer->Outdent(); |
156 | |
157 | printer->Print(text: "}\n" ); |
158 | } |
159 | |
160 | // =================================================================== |
161 | |
162 | void ImmutableMessageLiteGenerator::Generate(io::Printer* printer) { |
163 | bool is_own_file = IsOwnFile(descriptor: descriptor_, /* immutable = */ true); |
164 | |
165 | std::map<std::string, std::string> variables; |
166 | variables["static" ] = is_own_file ? " " : " static " ; |
167 | variables["classname" ] = descriptor_->name(); |
168 | variables["extra_interfaces" ] = ExtraMessageInterfaces(descriptor: descriptor_); |
169 | variables["deprecation" ] = |
170 | descriptor_->options().deprecated() ? "@java.lang.Deprecated " : "" ; |
171 | |
172 | WriteMessageDocComment(printer, message: descriptor_); |
173 | MaybePrintGeneratedAnnotation(context: context_, printer, descriptor: descriptor_, |
174 | /* immutable = */ true); |
175 | |
176 | |
177 | // The builder_type stores the super type name of the nested Builder class. |
178 | std::string builder_type; |
179 | if (descriptor_->extension_range_count() > 0) { |
180 | printer->Print( |
181 | variables, |
182 | text: "$deprecation$public $static$final class $classname$ extends\n" |
183 | " com.google.protobuf.GeneratedMessageLite.ExtendableMessage<\n" |
184 | " $classname$, $classname$.Builder> implements\n" |
185 | " $extra_interfaces$\n" |
186 | " $classname$OrBuilder {\n" ); |
187 | builder_type = strings::Substitute( |
188 | format: "com.google.protobuf.GeneratedMessageLite.ExtendableBuilder<$0, ?>" , |
189 | arg0: name_resolver_->GetImmutableClassName(descriptor: descriptor_)); |
190 | } else { |
191 | printer->Print( |
192 | variables, |
193 | text: "$deprecation$public $static$final class $classname$ extends\n" |
194 | " com.google.protobuf.GeneratedMessageLite<\n" |
195 | " $classname$, $classname$.Builder> implements\n" |
196 | " $extra_interfaces$\n" |
197 | " $classname$OrBuilder {\n" ); |
198 | |
199 | builder_type = "com.google.protobuf.GeneratedMessageLite.Builder" ; |
200 | } |
201 | printer->Indent(); |
202 | |
203 | GenerateConstructor(printer); |
204 | |
205 | // Nested types |
206 | for (int i = 0; i < descriptor_->enum_type_count(); i++) { |
207 | EnumLiteGenerator(descriptor_->enum_type(index: i), true, context_) |
208 | .Generate(printer); |
209 | } |
210 | |
211 | for (int i = 0; i < descriptor_->nested_type_count(); i++) { |
212 | // Don't generate Java classes for map entry messages. |
213 | if (IsMapEntry(descriptor: descriptor_->nested_type(index: i))) continue; |
214 | ImmutableMessageLiteGenerator messageGenerator(descriptor_->nested_type(index: i), |
215 | context_); |
216 | messageGenerator.GenerateInterface(printer); |
217 | messageGenerator.Generate(printer); |
218 | } |
219 | |
220 | // Integers for bit fields. |
221 | int totalBits = 0; |
222 | for (int i = 0; i < descriptor_->field_count(); i++) { |
223 | totalBits += |
224 | field_generators_.get(field: descriptor_->field(index: i)).GetNumBitsForMessage(); |
225 | } |
226 | int totalInts = (totalBits + 31) / 32; |
227 | for (int i = 0; i < totalInts; i++) { |
228 | printer->Print(text: "private int $bit_field_name$;\n" , args: "bit_field_name" , |
229 | args: GetBitFieldName(index: i)); |
230 | } |
231 | |
232 | // oneof |
233 | std::map<std::string, std::string> vars; |
234 | for (auto oneof : oneofs_) { |
235 | vars["oneof_name" ] = context_->GetOneofGeneratorInfo(oneof)->name; |
236 | vars["oneof_capitalized_name" ] = |
237 | context_->GetOneofGeneratorInfo(oneof)->capitalized_name; |
238 | vars["oneof_index" ] = StrCat(a: (oneof)->index()); |
239 | // oneofCase_ and oneof_ |
240 | printer->Print(variables: vars, |
241 | text: "private int $oneof_name$Case_ = 0;\n" |
242 | "private java.lang.Object $oneof_name$_;\n" ); |
243 | // OneofCase enum |
244 | printer->Print(variables: vars, text: "public enum $oneof_capitalized_name$Case {\n" ); |
245 | printer->Indent(); |
246 | for (int j = 0; j < (oneof)->field_count(); j++) { |
247 | const FieldDescriptor* field = (oneof)->field(index: j); |
248 | printer->Print(text: "$field_name$($field_number$),\n" , args: "field_name" , |
249 | args: ToUpper(s: field->name()), args: "field_number" , |
250 | args: StrCat(a: field->number())); |
251 | } |
252 | printer->Print(text: "$cap_oneof_name$_NOT_SET(0);\n" , args: "cap_oneof_name" , |
253 | args: ToUpper(s: vars["oneof_name" ])); |
254 | printer->Print(variables: vars, |
255 | text: "private final int value;\n" |
256 | "private $oneof_capitalized_name$Case(int value) {\n" |
257 | " this.value = value;\n" |
258 | "}\n" ); |
259 | printer->Print( |
260 | variables: vars, |
261 | text: "/**\n" |
262 | " * @deprecated Use {@link #forNumber(int)} instead.\n" |
263 | " */\n" |
264 | "@java.lang.Deprecated\n" |
265 | "public static $oneof_capitalized_name$Case valueOf(int value) {\n" |
266 | " return forNumber(value);\n" |
267 | "}\n" |
268 | "\n" |
269 | "public static $oneof_capitalized_name$Case forNumber(int value) {\n" |
270 | " switch (value) {\n" ); |
271 | for (int j = 0; j < (oneof)->field_count(); j++) { |
272 | const FieldDescriptor* field = (oneof)->field(index: j); |
273 | printer->Print(text: " case $field_number$: return $field_name$;\n" , |
274 | args: "field_number" , args: StrCat(a: field->number()), |
275 | args: "field_name" , args: ToUpper(s: field->name())); |
276 | } |
277 | printer->Print( |
278 | text: " case 0: return $cap_oneof_name$_NOT_SET;\n" |
279 | " default: return null;\n" |
280 | " }\n" |
281 | "}\n" |
282 | // TODO(b/135620659): Rename this to "getFieldNumber" or something to |
283 | // disambiguate it from actual proto enums. |
284 | "public int getNumber() {\n" |
285 | " return this.value;\n" |
286 | "}\n" , |
287 | args: "cap_oneof_name" , args: ToUpper(s: vars["oneof_name" ])); |
288 | printer->Outdent(); |
289 | printer->Print(text: "};\n\n" ); |
290 | // oneofCase() |
291 | printer->Print(variables: vars, |
292 | text: "@java.lang.Override\n" |
293 | "public $oneof_capitalized_name$Case\n" |
294 | "get$oneof_capitalized_name$Case() {\n" |
295 | " return $oneof_capitalized_name$Case.forNumber(\n" |
296 | " $oneof_name$Case_);\n" |
297 | "}\n" |
298 | "\n" |
299 | "private void clear$oneof_capitalized_name$() {\n" |
300 | " $oneof_name$Case_ = 0;\n" |
301 | " $oneof_name$_ = null;\n" |
302 | "}\n" |
303 | "\n" ); |
304 | } |
305 | |
306 | // Fields |
307 | for (int i = 0; i < descriptor_->field_count(); i++) { |
308 | printer->Print(text: "public static final int $constant_name$ = $number$;\n" , |
309 | args: "constant_name" , args: FieldConstantName(field: descriptor_->field(index: i)), |
310 | args: "number" , args: StrCat(a: descriptor_->field(index: i)->number())); |
311 | field_generators_.get(field: descriptor_->field(index: i)).GenerateMembers(printer); |
312 | printer->Print(text: "\n" ); |
313 | } |
314 | |
315 | GenerateParseFromMethods(printer); |
316 | GenerateBuilder(printer); |
317 | |
318 | if (HasRequiredFields(descriptor: descriptor_)) { |
319 | // Memoizes whether the protocol buffer is fully initialized (has all |
320 | // required fields). 0 means false, 1 means true, and all other values |
321 | // mean not yet computed. |
322 | printer->Print(text: "private byte memoizedIsInitialized = 2;\n" ); |
323 | } |
324 | |
325 | printer->Print( |
326 | text: "@java.lang.Override\n" |
327 | "@java.lang.SuppressWarnings({\"unchecked\", \"fallthrough\"})\n" |
328 | "protected final java.lang.Object dynamicMethod(\n" |
329 | " com.google.protobuf.GeneratedMessageLite.MethodToInvoke method,\n" |
330 | " java.lang.Object arg0, java.lang.Object arg1) {\n" |
331 | " switch (method) {\n" |
332 | " case NEW_MUTABLE_INSTANCE: {\n" |
333 | " return new $classname$();\n" |
334 | " }\n" , |
335 | args: "classname" , args: name_resolver_->GetImmutableClassName(descriptor: descriptor_)); |
336 | |
337 | printer->Indent(); |
338 | printer->Indent(); |
339 | |
340 | printer->Print(text: "case NEW_BUILDER: {\n" ); |
341 | |
342 | printer->Indent(); |
343 | GenerateDynamicMethodNewBuilder(printer); |
344 | printer->Outdent(); |
345 | |
346 | printer->Print( |
347 | text: "}\n" |
348 | "case BUILD_MESSAGE_INFO: {\n" ); |
349 | |
350 | printer->Indent(); |
351 | GenerateDynamicMethodNewBuildMessageInfo(printer); |
352 | printer->Outdent(); |
353 | |
354 | printer->Print( |
355 | text: "}\n" |
356 | "// fall through\n" |
357 | "case GET_DEFAULT_INSTANCE: {\n" |
358 | " return DEFAULT_INSTANCE;\n" |
359 | "}\n" |
360 | "case GET_PARSER: {\n" |
361 | // Generally one would use the lazy initialization holder pattern for |
362 | // manipulating static fields but that has exceptional cost on Android as |
363 | // it will generate an extra class for every message. Instead, use the |
364 | // double-check locking pattern which works just as well. |
365 | // |
366 | // The "parser" temporary mirrors the "PARSER" field to eliminate a read |
367 | // at the final return statement. |
368 | " com.google.protobuf.Parser<$classname$> parser = PARSER;\n" |
369 | " if (parser == null) {\n" |
370 | " synchronized ($classname$.class) {\n" |
371 | " parser = PARSER;\n" |
372 | " if (parser == null) {\n" |
373 | " parser =\n" |
374 | " new DefaultInstanceBasedParser<$classname$>(\n" |
375 | " DEFAULT_INSTANCE);\n" |
376 | " PARSER = parser;\n" |
377 | " }\n" |
378 | " }\n" |
379 | " }\n" |
380 | " return parser;\n" , |
381 | args: "classname" , args: name_resolver_->GetImmutableClassName(descriptor: descriptor_)); |
382 | |
383 | printer->Outdent(); |
384 | |
385 | if (HasRequiredFields(descriptor: descriptor_)) { |
386 | printer->Print( |
387 | text: "}\n" |
388 | "case GET_MEMOIZED_IS_INITIALIZED: {\n" |
389 | " return memoizedIsInitialized;\n" |
390 | "}\n" |
391 | "case SET_MEMOIZED_IS_INITIALIZED: {\n" |
392 | " memoizedIsInitialized = (byte) (arg0 == null ? 0 : 1);\n" |
393 | " return null;\n" |
394 | "}\n" ); |
395 | } else { |
396 | printer->Print( |
397 | text: "}\n" |
398 | "case GET_MEMOIZED_IS_INITIALIZED: {\n" |
399 | " return (byte) 1;\n" |
400 | "}\n" |
401 | "case SET_MEMOIZED_IS_INITIALIZED: {\n" |
402 | " return null;\n" |
403 | "}\n" ); |
404 | } |
405 | |
406 | printer->Outdent(); |
407 | printer->Print( |
408 | text: " }\n" |
409 | " throw new UnsupportedOperationException();\n" |
410 | "}\n" |
411 | "\n" , |
412 | args: "classname" , args: name_resolver_->GetImmutableClassName(descriptor: descriptor_)); |
413 | |
414 | printer->Print( |
415 | text: "\n" |
416 | "// @@protoc_insertion_point(class_scope:$full_name$)\n" , |
417 | args: "full_name" , args: descriptor_->full_name()); |
418 | |
419 | // Carefully initialize the default instance in such a way that it doesn't |
420 | // conflict with other initialization. |
421 | printer->Print(text: "private static final $classname$ DEFAULT_INSTANCE;\n" , |
422 | args: "classname" , |
423 | args: name_resolver_->GetImmutableClassName(descriptor: descriptor_)); |
424 | |
425 | printer->Print( |
426 | text: "static {\n" |
427 | " $classname$ defaultInstance = new $classname$();\n" |
428 | " // New instances are implicitly immutable so no need to make\n" |
429 | " // immutable.\n" |
430 | " DEFAULT_INSTANCE = defaultInstance;\n" |
431 | // Register the default instance in a map. This map will be used by |
432 | // experimental runtime to lookup default instance given a class instance |
433 | // without using Java reflection. |
434 | " com.google.protobuf.GeneratedMessageLite.registerDefaultInstance(\n" |
435 | " $classname$.class, defaultInstance);\n" |
436 | "}\n" |
437 | "\n" , |
438 | args: "classname" , args: descriptor_->name()); |
439 | |
440 | printer->Print( |
441 | text: "public static $classname$ getDefaultInstance() {\n" |
442 | " return DEFAULT_INSTANCE;\n" |
443 | "}\n" |
444 | "\n" , |
445 | args: "classname" , args: name_resolver_->GetImmutableClassName(descriptor: descriptor_)); |
446 | |
447 | // 'of' method for Wrappers |
448 | if (IsWrappersProtoFile(descriptor: descriptor_->file())) { |
449 | printer->Print( |
450 | text: "public static $classname$ of($field_type$ value) {\n" |
451 | " return newBuilder().setValue(value).build();\n" |
452 | "}\n" |
453 | "\n" , |
454 | args: "classname" , args: name_resolver_->GetImmutableClassName(descriptor: descriptor_), |
455 | args: "field_type" , args: PrimitiveTypeName(type: GetJavaType(field: descriptor_->field(index: 0)))); |
456 | } |
457 | |
458 | GenerateParser(printer); |
459 | |
460 | // Extensions must be declared after the DEFAULT_INSTANCE is initialized |
461 | // because the DEFAULT_INSTANCE is used by the extension to lazily retrieve |
462 | // the outer class's FileDescriptor. |
463 | for (int i = 0; i < descriptor_->extension_count(); i++) { |
464 | ImmutableExtensionLiteGenerator(descriptor_->extension(index: i), context_) |
465 | .Generate(printer); |
466 | } |
467 | |
468 | printer->Outdent(); |
469 | printer->Print(text: "}\n\n" ); |
470 | } |
471 | |
472 | void ImmutableMessageLiteGenerator::GenerateDynamicMethodNewBuildMessageInfo( |
473 | io::Printer* printer) { |
474 | printer->Indent(); |
475 | |
476 | // Collect field info into a sequence of UTF-16 chars. It will be embedded |
477 | // as a Java string in the generated code. |
478 | std::vector<uint16_t> chars; |
479 | |
480 | int flags = 0; |
481 | if (IsProto2(descriptor: descriptor_->file())) { |
482 | flags |= 0x1; |
483 | } |
484 | if (descriptor_->options().message_set_wire_format()) { |
485 | flags |= 0x2; |
486 | } |
487 | WriteIntToUtf16CharSequence(value: flags, output: &chars); |
488 | WriteIntToUtf16CharSequence(value: descriptor_->field_count(), output: &chars); |
489 | |
490 | if (descriptor_->field_count() == 0) { |
491 | printer->Print(text: "java.lang.Object[] objects = null;" ); |
492 | } else { |
493 | // A single array of all fields (including oneof, oneofCase, hasBits). |
494 | printer->Print(text: "java.lang.Object[] objects = new java.lang.Object[] {\n" ); |
495 | printer->Indent(); |
496 | |
497 | // Record the number of oneofs. |
498 | WriteIntToUtf16CharSequence(value: oneofs_.size(), output: &chars); |
499 | for (auto oneof : oneofs_) { |
500 | printer->Print( |
501 | text: "\"$oneof_name$_\",\n" |
502 | "\"$oneof_name$Case_\",\n" , |
503 | args: "oneof_name" , args: context_->GetOneofGeneratorInfo(oneof)->name); |
504 | } |
505 | |
506 | // Integers for bit fields. |
507 | int total_bits = 0; |
508 | for (int i = 0; i < descriptor_->field_count(); i++) { |
509 | total_bits += |
510 | field_generators_.get(field: descriptor_->field(index: i)).GetNumBitsForMessage(); |
511 | } |
512 | int total_ints = (total_bits + 31) / 32; |
513 | for (int i = 0; i < total_ints; i++) { |
514 | printer->Print(text: "\"$bit_field_name$\",\n" , args: "bit_field_name" , |
515 | args: GetBitFieldName(index: i)); |
516 | } |
517 | WriteIntToUtf16CharSequence(value: total_ints, output: &chars); |
518 | |
519 | int map_count = 0; |
520 | int repeated_count = 0; |
521 | std::unique_ptr<const FieldDescriptor*[]> sorted_fields( |
522 | SortFieldsByNumber(descriptor: descriptor_)); |
523 | for (int i = 0; i < descriptor_->field_count(); i++) { |
524 | const FieldDescriptor* field = sorted_fields[i]; |
525 | if (field->is_map()) { |
526 | map_count++; |
527 | } else if (field->is_repeated()) { |
528 | repeated_count++; |
529 | } |
530 | } |
531 | |
532 | WriteIntToUtf16CharSequence(value: sorted_fields[0]->number(), output: &chars); |
533 | WriteIntToUtf16CharSequence( |
534 | value: sorted_fields[descriptor_->field_count() - 1]->number(), output: &chars); |
535 | WriteIntToUtf16CharSequence(value: descriptor_->field_count(), output: &chars); |
536 | WriteIntToUtf16CharSequence(value: map_count, output: &chars); |
537 | WriteIntToUtf16CharSequence(value: repeated_count, output: &chars); |
538 | |
539 | std::vector<const FieldDescriptor*> fields_for_is_initialized_check; |
540 | for (int i = 0; i < descriptor_->field_count(); i++) { |
541 | if (descriptor_->field(index: i)->is_required() || |
542 | (GetJavaType(field: descriptor_->field(index: i)) == JAVATYPE_MESSAGE && |
543 | HasRequiredFields(descriptor: descriptor_->field(index: i)->message_type()))) { |
544 | fields_for_is_initialized_check.push_back(x: descriptor_->field(index: i)); |
545 | } |
546 | } |
547 | WriteIntToUtf16CharSequence(value: fields_for_is_initialized_check.size(), output: &chars); |
548 | |
549 | for (int i = 0; i < descriptor_->field_count(); i++) { |
550 | const FieldDescriptor* field = sorted_fields[i]; |
551 | field_generators_.get(field).GenerateFieldInfo(printer, output: &chars); |
552 | } |
553 | printer->Outdent(); |
554 | printer->Print(text: "};\n" ); |
555 | } |
556 | |
557 | printer->Print(text: "java.lang.String info =\n" ); |
558 | std::string line; |
559 | for (size_t i = 0; i < chars.size(); i++) { |
560 | uint16_t code = chars[i]; |
561 | EscapeUtf16ToString(code, output: &line); |
562 | if (line.size() >= 80) { |
563 | printer->Print(text: " \"$string$\" +\n" , args: "string" , args: line); |
564 | line.clear(); |
565 | } |
566 | } |
567 | printer->Print(text: " \"$string$\";\n" , args: "string" , args: line); |
568 | |
569 | printer->Print(text: "return newMessageInfo(DEFAULT_INSTANCE, info, objects);\n" ); |
570 | printer->Outdent(); |
571 | } |
572 | |
573 | // =================================================================== |
574 | |
575 | void ImmutableMessageLiteGenerator::GenerateParseFromMethods( |
576 | io::Printer* printer) { |
577 | printer->Print( |
578 | text: "public static $classname$ parseFrom(\n" |
579 | " java.nio.ByteBuffer data)\n" |
580 | " throws com.google.protobuf.InvalidProtocolBufferException {\n" |
581 | " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n" |
582 | " DEFAULT_INSTANCE, data);\n" |
583 | "}\n" |
584 | "public static $classname$ parseFrom(\n" |
585 | " java.nio.ByteBuffer data,\n" |
586 | " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n" |
587 | " throws com.google.protobuf.InvalidProtocolBufferException {\n" |
588 | " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n" |
589 | " DEFAULT_INSTANCE, data, extensionRegistry);\n" |
590 | "}\n" |
591 | "public static $classname$ parseFrom(\n" |
592 | " com.google.protobuf.ByteString data)\n" |
593 | " throws com.google.protobuf.InvalidProtocolBufferException {\n" |
594 | " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n" |
595 | " DEFAULT_INSTANCE, data);\n" |
596 | "}\n" |
597 | "public static $classname$ parseFrom(\n" |
598 | " com.google.protobuf.ByteString data,\n" |
599 | " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n" |
600 | " throws com.google.protobuf.InvalidProtocolBufferException {\n" |
601 | " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n" |
602 | " DEFAULT_INSTANCE, data, extensionRegistry);\n" |
603 | "}\n" |
604 | "public static $classname$ parseFrom(byte[] data)\n" |
605 | " throws com.google.protobuf.InvalidProtocolBufferException {\n" |
606 | " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n" |
607 | " DEFAULT_INSTANCE, data);\n" |
608 | "}\n" |
609 | "public static $classname$ parseFrom(\n" |
610 | " byte[] data,\n" |
611 | " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n" |
612 | " throws com.google.protobuf.InvalidProtocolBufferException {\n" |
613 | " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n" |
614 | " DEFAULT_INSTANCE, data, extensionRegistry);\n" |
615 | "}\n" |
616 | "public static $classname$ parseFrom(java.io.InputStream input)\n" |
617 | " throws java.io.IOException {\n" |
618 | " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n" |
619 | " DEFAULT_INSTANCE, input);\n" |
620 | "}\n" |
621 | "public static $classname$ parseFrom(\n" |
622 | " java.io.InputStream input,\n" |
623 | " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n" |
624 | " throws java.io.IOException {\n" |
625 | " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n" |
626 | " DEFAULT_INSTANCE, input, extensionRegistry);\n" |
627 | "}\n" |
628 | "public static $classname$ parseDelimitedFrom(java.io.InputStream " |
629 | "input)\n" |
630 | " throws java.io.IOException {\n" |
631 | " return parseDelimitedFrom(DEFAULT_INSTANCE, input);\n" |
632 | "}\n" |
633 | "public static $classname$ parseDelimitedFrom(\n" |
634 | " java.io.InputStream input,\n" |
635 | " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n" |
636 | " throws java.io.IOException {\n" |
637 | " return parseDelimitedFrom(DEFAULT_INSTANCE, input, " |
638 | "extensionRegistry);\n" |
639 | "}\n" |
640 | "public static $classname$ parseFrom(\n" |
641 | " com.google.protobuf.CodedInputStream input)\n" |
642 | " throws java.io.IOException {\n" |
643 | " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n" |
644 | " DEFAULT_INSTANCE, input);\n" |
645 | "}\n" |
646 | "public static $classname$ parseFrom(\n" |
647 | " com.google.protobuf.CodedInputStream input,\n" |
648 | " com.google.protobuf.ExtensionRegistryLite extensionRegistry)\n" |
649 | " throws java.io.IOException {\n" |
650 | " return com.google.protobuf.GeneratedMessageLite.parseFrom(\n" |
651 | " DEFAULT_INSTANCE, input, extensionRegistry);\n" |
652 | "}\n" |
653 | "\n" , |
654 | args: "classname" , args: name_resolver_->GetImmutableClassName(descriptor: descriptor_)); |
655 | } |
656 | |
657 | // =================================================================== |
658 | |
659 | void ImmutableMessageLiteGenerator::GenerateBuilder(io::Printer* printer) { |
660 | printer->Print( |
661 | text: "public static Builder newBuilder() {\n" |
662 | " return (Builder) DEFAULT_INSTANCE.createBuilder();\n" |
663 | "}\n" |
664 | "public static Builder newBuilder($classname$ prototype) {\n" |
665 | " return (Builder) DEFAULT_INSTANCE.createBuilder(prototype);\n" |
666 | "}\n" |
667 | "\n" , |
668 | args: "classname" , args: name_resolver_->GetImmutableClassName(descriptor: descriptor_)); |
669 | |
670 | MessageBuilderLiteGenerator builderGenerator(descriptor_, context_); |
671 | builderGenerator.Generate(printer); |
672 | } |
673 | |
674 | // =================================================================== |
675 | |
676 | void ImmutableMessageLiteGenerator::GenerateDynamicMethodNewBuilder( |
677 | io::Printer* printer) { |
678 | printer->Print(text: "return new Builder();\n" ); |
679 | } |
680 | |
681 | // =================================================================== |
682 | |
683 | void ImmutableMessageLiteGenerator::GenerateExtensionRegistrationCode( |
684 | io::Printer* printer) { |
685 | for (int i = 0; i < descriptor_->extension_count(); i++) { |
686 | ImmutableExtensionLiteGenerator(descriptor_->extension(index: i), context_) |
687 | .GenerateRegistrationCode(printer); |
688 | } |
689 | |
690 | for (int i = 0; i < descriptor_->nested_type_count(); i++) { |
691 | ImmutableMessageLiteGenerator(descriptor_->nested_type(index: i), context_) |
692 | .GenerateExtensionRegistrationCode(printer); |
693 | } |
694 | } |
695 | |
696 | // =================================================================== |
697 | void ImmutableMessageLiteGenerator::GenerateConstructor(io::Printer* printer) { |
698 | printer->Print(text: "private $classname$() {\n" , args: "classname" , args: descriptor_->name()); |
699 | printer->Indent(); |
700 | |
701 | // Initialize all fields to default. |
702 | GenerateInitializers(printer); |
703 | |
704 | printer->Outdent(); |
705 | printer->Print(text: "}\n" ); |
706 | } |
707 | |
708 | // =================================================================== |
709 | void ImmutableMessageLiteGenerator::GenerateParser(io::Printer* printer) { |
710 | printer->Print( |
711 | text: "private static volatile com.google.protobuf.Parser<$classname$> " |
712 | "PARSER;\n" |
713 | "\n" |
714 | "public static com.google.protobuf.Parser<$classname$> parser() {\n" |
715 | " return DEFAULT_INSTANCE.getParserForType();\n" |
716 | "}\n" , |
717 | args: "classname" , args: descriptor_->name()); |
718 | } |
719 | |
720 | // =================================================================== |
721 | void ImmutableMessageLiteGenerator::GenerateInitializers(io::Printer* printer) { |
722 | for (int i = 0; i < descriptor_->field_count(); i++) { |
723 | if (!IsRealOneof(descriptor: descriptor_->field(index: i))) { |
724 | field_generators_.get(field: descriptor_->field(index: i)) |
725 | .GenerateInitializationCode(printer); |
726 | } |
727 | } |
728 | } |
729 | |
730 | void ImmutableMessageLiteGenerator::GenerateKotlinDsl( |
731 | io::Printer* printer) const { |
732 | printer->Print( |
733 | text: "@kotlin.OptIn" |
734 | "(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)\n" |
735 | "@com.google.protobuf.kotlin.ProtoDslMarker\n" ); |
736 | printer->Print( |
737 | text: "class Dsl private constructor(\n" |
738 | " private val _builder: $message$.Builder\n" |
739 | ") {\n" |
740 | " companion object {\n" |
741 | " @kotlin.jvm.JvmSynthetic\n" |
742 | " @kotlin.PublishedApi\n" |
743 | " internal fun _create(builder: $message$.Builder): Dsl = " |
744 | "Dsl(builder)\n" |
745 | " }\n" |
746 | "\n" |
747 | " @kotlin.jvm.JvmSynthetic\n" |
748 | " @kotlin.PublishedApi\n" |
749 | " internal fun _build(): $message$ = _builder.build()\n" , |
750 | args: "message" , args: name_resolver_->GetClassName(descriptor: descriptor_, immutable: true)); |
751 | |
752 | printer->Indent(); |
753 | |
754 | for (int i = 0; i < descriptor_->field_count(); i++) { |
755 | printer->Print(text: "\n" ); |
756 | field_generators_.get(field: descriptor_->field(index: i)) |
757 | .GenerateKotlinDslMembers(printer); |
758 | } |
759 | |
760 | for (auto oneof : oneofs_) { |
761 | printer->Print( |
762 | text: "val $oneof_name$Case: $message$.$oneof_capitalized_name$Case\n" |
763 | " @JvmName(\"get$oneof_capitalized_name$Case\")\n" |
764 | " get() = _builder.get$oneof_capitalized_name$Case()\n\n" |
765 | "fun clear$oneof_capitalized_name$() {\n" |
766 | " _builder.clear$oneof_capitalized_name$()\n" |
767 | "}\n" , |
768 | args: "oneof_name" , args: context_->GetOneofGeneratorInfo(oneof)->name, |
769 | args: "oneof_capitalized_name" , |
770 | args: context_->GetOneofGeneratorInfo(oneof)->capitalized_name, args: "message" , |
771 | args: name_resolver_->GetClassName(descriptor: descriptor_, immutable: true)); |
772 | } |
773 | |
774 | if (descriptor_->extension_range_count() > 0) { |
775 | GenerateKotlinExtensions(printer); |
776 | } |
777 | |
778 | printer->Outdent(); |
779 | printer->Print(text: "}\n" ); |
780 | } |
781 | |
782 | void ImmutableMessageLiteGenerator::GenerateKotlinMembers( |
783 | io::Printer* printer) const { |
784 | printer->Print( |
785 | text: "@kotlin.jvm.JvmName(\"-initialize$camelcase_name$\")\n" |
786 | "inline fun $camelcase_name$(block: $message_kt$.Dsl.() -> " |
787 | "kotlin.Unit): " |
788 | "$message$ =\n" |
789 | " $message_kt$.Dsl._create($message$.newBuilder()).apply { block() " |
790 | "}._build()\n" , |
791 | args: "camelcase_name" , args: name_resolver_->GetKotlinFactoryName(descriptor: descriptor_), |
792 | args: "message_kt" , args: name_resolver_->GetKotlinExtensionsClassName(descriptor: descriptor_), |
793 | args: "message" , args: name_resolver_->GetClassName(descriptor: descriptor_, immutable: true)); |
794 | |
795 | printer->Print(text: "object $name$Kt {\n" , args: "name" , args: descriptor_->name()); |
796 | printer->Indent(); |
797 | GenerateKotlinDsl(printer); |
798 | for (int i = 0; i < descriptor_->nested_type_count(); i++) { |
799 | if (IsMapEntry(descriptor: descriptor_->nested_type(index: i))) continue; |
800 | ImmutableMessageLiteGenerator(descriptor_->nested_type(index: i), context_) |
801 | .GenerateKotlinMembers(printer); |
802 | } |
803 | printer->Outdent(); |
804 | printer->Print(text: "}\n" ); |
805 | } |
806 | |
807 | void ImmutableMessageLiteGenerator::GenerateTopLevelKotlinMembers( |
808 | io::Printer* printer) const { |
809 | printer->Print( |
810 | text: "inline fun $message$.copy(block: $message_kt$.Dsl.() -> " |
811 | "kotlin.Unit): " |
812 | "$message$ =\n" |
813 | " $message_kt$.Dsl._create(this.toBuilder()).apply { block() " |
814 | "}._build()\n\n" , |
815 | args: "message" , args: name_resolver_->GetClassName(descriptor: descriptor_, immutable: true), args: "message_kt" , |
816 | args: name_resolver_->GetKotlinExtensionsClassName(descriptor: descriptor_)); |
817 | |
818 | for (int i = 0; i < descriptor_->nested_type_count(); i++) { |
819 | if (IsMapEntry(descriptor: descriptor_->nested_type(index: i))) continue; |
820 | ImmutableMessageLiteGenerator(descriptor_->nested_type(index: i), context_) |
821 | .GenerateTopLevelKotlinMembers(printer); |
822 | } |
823 | |
824 | GenerateKotlinOrNull(printer); |
825 | } |
826 | |
827 | void ImmutableMessageLiteGenerator::GenerateKotlinOrNull(io::Printer* printer) const { |
828 | // Generate getFieldOrNull getters for all optional message fields. |
829 | for (int i = 0; i < descriptor_->field_count(); i++) { |
830 | const FieldDescriptor* field = descriptor_->field(index: i); |
831 | if (field->has_presence() && GetJavaType(field) == JAVATYPE_MESSAGE) { |
832 | printer->Print( |
833 | text: "val $full_classname$OrBuilder.$camelcase_name$OrNull: " |
834 | "$full_name$?\n" |
835 | " get() = if (has$name$()) get$name$() else null\n\n" , |
836 | args: "full_classname" , args: name_resolver_->GetClassName(descriptor: descriptor_, immutable: true), |
837 | args: "camelcase_name" , args: context_->GetFieldGeneratorInfo(field)->name, |
838 | args: "full_name" , |
839 | args: name_resolver_->GetImmutableClassName(descriptor: field->message_type()), args: "name" , |
840 | args: context_->GetFieldGeneratorInfo(field)->capitalized_name); |
841 | } |
842 | } |
843 | } |
844 | |
845 | void ImmutableMessageLiteGenerator::GenerateKotlinExtensions( |
846 | io::Printer* printer) const { |
847 | std::string message_name = name_resolver_->GetClassName(descriptor: descriptor_, immutable: true); |
848 | |
849 | printer->Print( |
850 | text: "@Suppress(\"UNCHECKED_CAST\")\n" |
851 | "@kotlin.jvm.JvmSynthetic\n" |
852 | "operator fun <T : kotlin.Any> get(extension: " |
853 | "com.google.protobuf.ExtensionLite<$message$, T>): T {\n" |
854 | " return if (extension.isRepeated) {\n" |
855 | " get(extension as com.google.protobuf.ExtensionLite<$message$, " |
856 | "List<*>>) as T\n" |
857 | " } else {\n" |
858 | " _builder.getExtension(extension)\n" |
859 | " }\n" |
860 | "}\n\n" , |
861 | args: "message" , args: message_name); |
862 | |
863 | printer->Print( |
864 | text: "@kotlin.jvm.JvmSynthetic\n" |
865 | "@kotlin.OptIn" |
866 | "(com.google.protobuf.kotlin.OnlyForUseByGeneratedProtoCode::class)\n" |
867 | "@kotlin.jvm.JvmName(\"-getRepeatedExtension\")\n" |
868 | "operator fun <E : kotlin.Any> get(\n" |
869 | " extension: com.google.protobuf.ExtensionLite<$message$, List<E>>\n" |
870 | "): com.google.protobuf.kotlin.ExtensionList<E, $message$> {\n" |
871 | " return com.google.protobuf.kotlin.ExtensionList(extension, " |
872 | "_builder.getExtension(extension))\n" |
873 | "}\n\n" , |
874 | args: "message" , args: message_name); |
875 | |
876 | printer->Print( |
877 | text: "@kotlin.jvm.JvmSynthetic\n" |
878 | "operator fun contains(extension: " |
879 | "com.google.protobuf.ExtensionLite<$message$, *>): " |
880 | "Boolean {\n" |
881 | " return _builder.hasExtension(extension)\n" |
882 | "}\n\n" , |
883 | args: "message" , args: message_name); |
884 | |
885 | printer->Print( |
886 | text: "@kotlin.jvm.JvmSynthetic\n" |
887 | "fun clear(extension: " |
888 | "com.google.protobuf.ExtensionLite<$message$, *>) " |
889 | "{\n" |
890 | " _builder.clearExtension(extension)\n" |
891 | "}\n\n" , |
892 | args: "message" , args: message_name); |
893 | |
894 | printer->Print( |
895 | text: "@kotlin.jvm.JvmSynthetic\n" |
896 | "@kotlin.PublishedApi\n" |
897 | "internal fun <T : kotlin.Any> setExtension(extension: " |
898 | "com.google.protobuf.ExtensionLite<$message$, T>, " |
899 | "value: T) {\n" |
900 | " _builder.setExtension(extension, value)\n" |
901 | "}\n\n" , |
902 | args: "message" , args: message_name); |
903 | |
904 | printer->Print( |
905 | text: "@kotlin.jvm.JvmSynthetic\n" |
906 | "@Suppress(\"NOTHING_TO_INLINE\")\n" |
907 | "inline operator fun <T : Comparable<T>> set(\n" |
908 | " extension: com.google.protobuf.ExtensionLite<$message$, T>,\n" |
909 | " value: T\n" |
910 | ") {\n" |
911 | " setExtension(extension, value)\n" |
912 | "}\n\n" , |
913 | args: "message" , args: message_name); |
914 | |
915 | printer->Print( |
916 | text: "@kotlin.jvm.JvmSynthetic\n" |
917 | "@Suppress(\"NOTHING_TO_INLINE\")\n" |
918 | "inline operator fun set(\n" |
919 | " extension: com.google.protobuf.ExtensionLite<$message$, " |
920 | "com.google.protobuf.ByteString>,\n" |
921 | " value: com.google.protobuf.ByteString\n" |
922 | ") {\n" |
923 | " setExtension(extension, value)\n" |
924 | "}\n\n" , |
925 | args: "message" , args: message_name); |
926 | |
927 | printer->Print( |
928 | text: "@kotlin.jvm.JvmSynthetic\n" |
929 | "@Suppress(\"NOTHING_TO_INLINE\")\n" |
930 | "inline operator fun <T : com.google.protobuf.MessageLite> set(\n" |
931 | " extension: com.google.protobuf.ExtensionLite<$message$, T>,\n" |
932 | " value: T\n" |
933 | ") {\n" |
934 | " setExtension(extension, value)\n" |
935 | "}\n\n" , |
936 | args: "message" , args: message_name); |
937 | |
938 | printer->Print( |
939 | text: "@kotlin.jvm.JvmSynthetic\n" |
940 | "fun<E : kotlin.Any> com.google.protobuf.kotlin.ExtensionList<E, " |
941 | "$message$>.add(value: E) {\n" |
942 | " _builder.addExtension(this.extension, value)\n" |
943 | "}\n\n" , |
944 | args: "message" , args: message_name); |
945 | |
946 | printer->Print( |
947 | text: "@kotlin.jvm.JvmSynthetic\n" |
948 | "@Suppress(\"NOTHING_TO_INLINE\")\n" |
949 | "inline operator fun <E : kotlin.Any> " |
950 | "com.google.protobuf.kotlin.ExtensionList<E, " |
951 | "$message$>.plusAssign" |
952 | "(value: E) {\n" |
953 | " add(value)\n" |
954 | "}\n\n" , |
955 | args: "message" , args: message_name); |
956 | |
957 | printer->Print( |
958 | text: "@kotlin.jvm.JvmSynthetic\n" |
959 | "fun<E : kotlin.Any> com.google.protobuf.kotlin.ExtensionList<E, " |
960 | "$message$>.addAll(values: Iterable<E>) {\n" |
961 | " for (value in values) {\n" |
962 | " add(value)\n" |
963 | " }\n" |
964 | "}\n\n" , |
965 | args: "message" , args: message_name); |
966 | |
967 | printer->Print( |
968 | text: "@kotlin.jvm.JvmSynthetic\n" |
969 | "@Suppress(\"NOTHING_TO_INLINE\")\n" |
970 | "inline operator fun <E : kotlin.Any> " |
971 | "com.google.protobuf.kotlin.ExtensionList<E, " |
972 | "$message$>.plusAssign(values: " |
973 | "Iterable<E>) {\n" |
974 | " addAll(values)\n" |
975 | "}\n\n" , |
976 | args: "message" , args: message_name); |
977 | |
978 | printer->Print( |
979 | text: "@kotlin.jvm.JvmSynthetic\n" |
980 | "operator fun <E : kotlin.Any> " |
981 | "com.google.protobuf.kotlin.ExtensionList<E, " |
982 | "$message$>.set(index: Int, value: " |
983 | "E) {\n" |
984 | " _builder.setExtension(this.extension, index, value)\n" |
985 | "}\n\n" , |
986 | args: "message" , args: message_name); |
987 | |
988 | printer->Print( |
989 | text: "@kotlin.jvm.JvmSynthetic\n" |
990 | "@Suppress(\"NOTHING_TO_INLINE\")\n" |
991 | "inline fun com.google.protobuf.kotlin.ExtensionList<*, " |
992 | "$message$>.clear() {\n" |
993 | " clear(extension)\n" |
994 | "}\n\n" , |
995 | args: "message" , args: message_name); |
996 | } |
997 | |
998 | } // namespace java |
999 | } // namespace compiler |
1000 | } // namespace protobuf |
1001 | } // namespace google |
1002 | |
1003 | #include <google/protobuf/port_undef.inc> |
1004 | |