protobuf/src/google/protobuf/compiler/csharp/csharp_message.cc
Go to the documentation of this file.
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 <sstream>
32 #include <algorithm>
33 #include <map>
34 
35 #include <google/protobuf/compiler/code_generator.h>
36 #include <google/protobuf/descriptor.h>
37 #include <google/protobuf/descriptor.pb.h>
38 #include <google/protobuf/io/printer.h>
39 #include <google/protobuf/io/zero_copy_stream.h>
40 #include <google/protobuf/stubs/strutil.h>
41 #include <google/protobuf/wire_format.h>
42 #include <google/protobuf/wire_format_lite.h>
43 
44 #include <google/protobuf/compiler/csharp/csharp_options.h>
45 #include <google/protobuf/compiler/csharp/csharp_doc_comment.h>
46 #include <google/protobuf/compiler/csharp/csharp_enum.h>
47 #include <google/protobuf/compiler/csharp/csharp_field_base.h>
48 #include <google/protobuf/compiler/csharp/csharp_helpers.h>
49 #include <google/protobuf/compiler/csharp/csharp_message.h>
50 #include <google/protobuf/compiler/csharp/csharp_names.h>
51 
52 namespace google {
53 namespace protobuf {
54 namespace compiler {
55 namespace csharp {
56 
57 bool CompareFieldNumbers(const FieldDescriptor* d1, const FieldDescriptor* d2) {
58  return d1->number() < d2->number();
59 }
60 
62  const Options* options)
63  : SourceGeneratorBase(options),
65  has_bit_field_count_(0),
66  end_tag_(GetGroupEndTag(descriptor)),
67  has_extension_ranges_(descriptor->extension_range_count() > 0) {
68  // fields by number
69  for (int i = 0; i < descriptor_->field_count(); i++) {
70  fields_by_number_.push_back(descriptor_->field(i));
71  }
72  std::sort(fields_by_number_.begin(), fields_by_number_.end(),
74 
75  int presence_bit_count = 0;
76  for (int i = 0; i < descriptor_->field_count(); i++) {
79  presence_bit_count++;
80  if (has_bit_field_count_ == 0 || (presence_bit_count % 32) == 0) {
82  }
83  }
84  }
85 }
86 
88 }
89 
91  return descriptor_->name();
92 }
93 
95  return GetClassName(descriptor_);
96 }
97 
98 const std::vector<const FieldDescriptor*>& MessageGenerator::fields_by_number() {
99  return fields_by_number_;
100 }
101 
103  if (descriptor_->options().deprecated()) {
104  printer->Print("[global::System.ObsoleteAttribute]\n");
105  }
106 }
107 
109  if (this->options()->serializable) {
110  printer->Print("[global::System.SerializableAttribute]\n");
111  }
112 }
113 
115  std::map<std::string, std::string> vars;
116  vars["class_name"] = class_name();
117  vars["access_level"] = class_access_level();
118 
120  AddDeprecatedFlag(printer);
121  AddSerializableAttribute(printer);
122 
123  printer->Print(
124  vars,
125  "$access_level$ sealed partial class $class_name$ : ");
126 
127  if (has_extension_ranges_) {
128  printer->Print(vars, "pb::IExtendableMessage<$class_name$>\n");
129  }
130  else {
131  printer->Print(vars, "pb::IMessage<$class_name$>\n");
132  }
133  printer->Print("#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE\n");
134  printer->Print(" , pb::IBufferMessage\n");
135  printer->Print("#endif\n");
136  printer->Print("{\n");
137  printer->Indent();
138 
139  // All static fields and properties
140  printer->Print(
141  vars,
142  "private static readonly pb::MessageParser<$class_name$> _parser = new pb::MessageParser<$class_name$>(() => new $class_name$());\n");
143 
144  printer->Print(
145  "private pb::UnknownFieldSet _unknownFields;\n");
146 
147  if (has_extension_ranges_) {
149  printer->Print(vars, "internal pb::ExtensionSet<$class_name$> _extensions;\n"); // CustomOptions compatibility
150  } else {
151  printer->Print(vars, "private pb::ExtensionSet<$class_name$> _extensions;\n");
152  }
153 
154  // a read-only property for fast
155  // retrieval of the set in IsInitialized
156  printer->Print(vars,
157  "private pb::ExtensionSet<$class_name$> _Extensions { get { "
158  "return _extensions; } }\n");
159  }
160 
161  for (int i = 0; i < has_bit_field_count_; i++) {
162  // don't use arrays since all arrays are heap allocated, saving allocations
163  // use ints instead of bytes since bytes lack bitwise operators, saving casts
164  printer->Print("private int _hasBits$i$;\n", "i", StrCat(i));
165  }
166 
168 
169  printer->Print(
170  vars,
171  "public static pb::MessageParser<$class_name$> Parser { get { return _parser; } }\n\n");
172 
173  // Access the message descriptor via the relevant file descriptor or containing message descriptor.
174  if (!descriptor_->containing_type()) {
175  vars["descriptor_accessor"] = GetReflectionClassName(descriptor_->file())
176  + ".Descriptor.MessageTypes[" + StrCat(descriptor_->index()) + "]";
177  } else {
178  vars["descriptor_accessor"] = GetClassName(descriptor_->containing_type())
179  + ".Descriptor.NestedTypes[" + StrCat(descriptor_->index()) + "]";
180  }
181 
183  printer->Print(
184  vars,
185  "public static pbr::MessageDescriptor Descriptor {\n"
186  " get { return $descriptor_accessor$; }\n"
187  "}\n"
188  "\n");
190  printer->Print(
191  vars,
192  "pbr::MessageDescriptor pb::IMessage.Descriptor {\n"
193  " get { return Descriptor; }\n"
194  "}\n"
195  "\n");
196 
197  // Parameterless constructor and partial OnConstruction method.
199  printer->Print(
200  vars,
201  "public $class_name$() {\n"
202  " OnConstruction();\n"
203  "}\n\n"
204  "partial void OnConstruction();\n\n");
205 
206  GenerateCloningCode(printer);
207  GenerateFreezingCode(printer);
208 
209  // Fields/properties
210  for (int i = 0; i < descriptor_->field_count(); i++) {
211  const FieldDescriptor* fieldDescriptor = descriptor_->field(i);
212 
213  // Rats: we lose the debug comment here :(
214  printer->Print(
215  "/// <summary>Field number for the \"$field_name$\" field.</summary>\n"
216  "public const int $field_constant_name$ = $index$;\n",
217  "field_name", fieldDescriptor->name(),
218  "field_constant_name", GetFieldConstantName(fieldDescriptor),
219  "index", StrCat(fieldDescriptor->number()));
220  std::unique_ptr<FieldGeneratorBase> generator(
221  CreateFieldGeneratorInternal(fieldDescriptor));
222  generator->GenerateMembers(printer);
223  printer->Print("\n");
224  }
225 
226  // oneof properties (for real oneofs, which come before synthetic ones)
227  for (int i = 0; i < descriptor_->real_oneof_decl_count(); i++) {
228  const OneofDescriptor* oneof = descriptor_->oneof_decl(i);
229  vars["name"] = UnderscoresToCamelCase(oneof->name(), false);
230  vars["property_name"] = UnderscoresToCamelCase(oneof->name(), true);
231  vars["original_name"] = oneof->name();
232  printer->Print(
233  vars,
234  "private object $name$_;\n"
235  "/// <summary>Enum of possible cases for the \"$original_name$\" oneof.</summary>\n"
236  "public enum $property_name$OneofCase {\n");
237  printer->Indent();
238  printer->Print("None = 0,\n");
239  for (int j = 0; j < oneof->field_count(); j++) {
240  const FieldDescriptor* field = oneof->field(j);
241  printer->Print("$field_property_name$ = $index$,\n",
242  "field_property_name", GetPropertyName(field),
243  "index", StrCat(field->number()));
244  }
245  printer->Outdent();
246  printer->Print("}\n");
247  // TODO: Should we put the oneof .proto comments here?
248  // It's unclear exactly where they should go.
249  printer->Print(
250  vars,
251  "private $property_name$OneofCase $name$Case_ = $property_name$OneofCase.None;\n");
253  printer->Print(
254  vars,
255  "public $property_name$OneofCase $property_name$Case {\n"
256  " get { return $name$Case_; }\n"
257  "}\n\n");
259  printer->Print(
260  vars,
261  "public void Clear$property_name$() {\n"
262  " $name$Case_ = $property_name$OneofCase.None;\n"
263  " $name$_ = null;\n"
264  "}\n\n");
265  }
266 
267  // Standard methods
268  GenerateFrameworkMethods(printer);
270  GenerateMergingMethods(printer);
271 
272  if (has_extension_ranges_) {
273  printer->Print(
274  vars,
275  "public TValue GetExtension<TValue>(pb::Extension<$class_name$, "
276  "TValue> extension) {\n"
277  " return pb::ExtensionSet.Get(ref _extensions, extension);\n"
278  "}\n"
279  "public pbc::RepeatedField<TValue> "
280  "GetExtension<TValue>(pb::RepeatedExtension<$class_name$, TValue> "
281  "extension) {\n"
282  " return pb::ExtensionSet.Get(ref _extensions, extension);\n"
283  "}\n"
284  "public pbc::RepeatedField<TValue> "
285  "GetOrInitializeExtension<TValue>(pb::RepeatedExtension<$class_name$, "
286  "TValue> extension) {\n"
287  " return pb::ExtensionSet.GetOrInitialize(ref _extensions, "
288  "extension);\n"
289  "}\n"
290  "public void SetExtension<TValue>(pb::Extension<$class_name$, TValue> "
291  "extension, TValue value) {\n"
292  " pb::ExtensionSet.Set(ref _extensions, extension, value);\n"
293  "}\n"
294  "public bool HasExtension<TValue>(pb::Extension<$class_name$, TValue> "
295  "extension) {\n"
296  " return pb::ExtensionSet.Has(ref _extensions, extension);\n"
297  "}\n"
298  "public void ClearExtension<TValue>(pb::Extension<$class_name$, "
299  "TValue> extension) {\n"
300  " pb::ExtensionSet.Clear(ref _extensions, extension);\n"
301  "}\n"
302  "public void "
303  "ClearExtension<TValue>(pb::RepeatedExtension<$class_name$, TValue> "
304  "extension) {\n"
305  " pb::ExtensionSet.Clear(ref _extensions, extension);\n"
306  "}\n\n");
307  }
308 
309  // Nested messages and enums
310  if (HasNestedGeneratedTypes()) {
311  printer->Print(
312  vars,
313  "#region Nested types\n"
314  "/// <summary>Container for nested types declared in the $class_name$ message type.</summary>\n");
316  printer->Print("public static partial class Types {\n");
317  printer->Indent();
318  for (int i = 0; i < descriptor_->enum_type_count(); i++) {
319  EnumGenerator enumGenerator(descriptor_->enum_type(i), this->options());
320  enumGenerator.Generate(printer);
321  }
322  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
323  // Don't generate nested types for maps...
325  MessageGenerator messageGenerator(
326  descriptor_->nested_type(i), this->options());
327  messageGenerator.Generate(printer);
328  }
329  }
330  printer->Outdent();
331  printer->Print("}\n"
332  "#endregion\n"
333  "\n");
334  }
335 
336  if (descriptor_->extension_count() > 0) {
337  printer->Print(
338  vars,
339  "#region Extensions\n"
340  "/// <summary>Container for extensions for other messages declared in the $class_name$ message type.</summary>\n");
342  printer->Print("public static partial class Extensions {\n");
343  printer->Indent();
344  for (int i = 0; i < descriptor_->extension_count(); i++) {
345  std::unique_ptr<FieldGeneratorBase> generator(
347  generator->GenerateExtensionCode(printer);
348  }
349  printer->Outdent();
350  printer->Print(
351  "}\n"
352  "#endregion\n"
353  "\n");
354  }
355 
356  printer->Outdent();
357  printer->Print("}\n");
358  printer->Print("\n");
359 }
360 
361 // Helper to work out whether we need to generate a class to hold nested types/enums.
362 // Only tricky because we don't want to generate map entry types.
364 {
365  if (descriptor_->enum_type_count() > 0) {
366  return true;
367  }
368  for (int i = 0; i < descriptor_->nested_type_count(); i++) {
370  return true;
371  }
372  }
373  return false;
374 }
375 
377  std::map<std::string, std::string> vars;
379  vars["class_name"] = class_name();
380  printer->Print(
381  vars,
382  "public $class_name$($class_name$ other) : this() {\n");
383  printer->Indent();
384  for (int i = 0; i < has_bit_field_count_; i++) {
385  printer->Print("_hasBits$i$ = other._hasBits$i$;\n", "i", StrCat(i));
386  }
387  // Clone non-oneof fields first (treating optional proto3 fields as non-oneof)
388  for (int i = 0; i < descriptor_->field_count(); i++) {
389  const FieldDescriptor* field = descriptor_->field(i);
390  if (field->real_containing_oneof()) {
391  continue;
392  }
393  std::unique_ptr<FieldGeneratorBase> generator(CreateFieldGeneratorInternal(field));
394  generator->GenerateCloningCode(printer);
395  }
396  // Clone just the right field for each real oneof
397  for (int i = 0; i < descriptor_->real_oneof_decl_count(); ++i) {
398  const OneofDescriptor* oneof = descriptor_->oneof_decl(i);
399  vars["name"] = UnderscoresToCamelCase(oneof->name(), false);
400  vars["property_name"] = UnderscoresToCamelCase(oneof->name(), true);
401  printer->Print(vars, "switch (other.$property_name$Case) {\n");
402  printer->Indent();
403  for (int j = 0; j < oneof->field_count(); j++) {
404  const FieldDescriptor* field = oneof->field(j);
405  std::unique_ptr<FieldGeneratorBase> generator(CreateFieldGeneratorInternal(field));
406  vars["field_property_name"] = GetPropertyName(field);
407  printer->Print(
408  vars,
409  "case $property_name$OneofCase.$field_property_name$:\n");
410  printer->Indent();
411  generator->GenerateCloningCode(printer);
412  printer->Print("break;\n");
413  printer->Outdent();
414  }
415  printer->Outdent();
416  printer->Print("}\n\n");
417  }
418  // Clone unknown fields
419  printer->Print(
420  "_unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);\n");
421  if (has_extension_ranges_) {
422  printer->Print(
423  "_extensions = pb::ExtensionSet.Clone(other._extensions);\n");
424  }
425 
426  printer->Outdent();
427  printer->Print("}\n\n");
428 
430  printer->Print(
431  vars,
432  "public $class_name$ Clone() {\n"
433  " return new $class_name$(this);\n"
434  "}\n\n");
435 }
436 
438 }
439 
441  std::map<std::string, std::string> vars;
442  vars["class_name"] = class_name();
443 
444  // Equality
446  printer->Print(
447  vars,
448  "public override bool Equals(object other) {\n"
449  " return Equals(other as $class_name$);\n"
450  "}\n\n");
452  printer->Print(
453  vars,
454  "public bool Equals($class_name$ other) {\n"
455  " if (ReferenceEquals(other, null)) {\n"
456  " return false;\n"
457  " }\n"
458  " if (ReferenceEquals(other, this)) {\n"
459  " return true;\n"
460  " }\n");
461  printer->Indent();
462  for (int i = 0; i < descriptor_->field_count(); i++) {
463  std::unique_ptr<FieldGeneratorBase> generator(
465  generator->WriteEquals(printer);
466  }
467  for (int i = 0; i < descriptor_->real_oneof_decl_count(); i++) {
468  printer->Print("if ($property_name$Case != other.$property_name$Case) return false;\n",
469  "property_name", UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), true));
470  }
471  if (has_extension_ranges_) {
472  printer->Print(
473  "if (!Equals(_extensions, other._extensions)) {\n"
474  " return false;\n"
475  "}\n");
476  }
477  printer->Outdent();
478  printer->Print(
479  " return Equals(_unknownFields, other._unknownFields);\n"
480  "}\n\n");
481 
482  // GetHashCode
483  // Start with a non-zero value to easily distinguish between null and "empty" messages.
485  printer->Print(
486  "public override int GetHashCode() {\n"
487  " int hash = 1;\n");
488  printer->Indent();
489  for (int i = 0; i < descriptor_->field_count(); i++) {
490  std::unique_ptr<FieldGeneratorBase> generator(
492  generator->WriteHash(printer);
493  }
494  for (int i = 0; i < descriptor_->real_oneof_decl_count(); i++) {
495  printer->Print("hash ^= (int) $name$Case_;\n",
496  "name", UnderscoresToCamelCase(descriptor_->oneof_decl(i)->name(), false));
497  }
498  if (has_extension_ranges_) {
499  printer->Print(
500  "if (_extensions != null) {\n"
501  " hash ^= _extensions.GetHashCode();\n"
502  "}\n");
503  }
504  printer->Print(
505  "if (_unknownFields != null) {\n"
506  " hash ^= _unknownFields.GetHashCode();\n"
507  "}\n"
508  "return hash;\n");
509  printer->Outdent();
510  printer->Print("}\n\n");
511 
513  printer->Print(
514  "public override string ToString() {\n"
515  " return pb::JsonFormatter.ToDiagnosticString(this);\n"
516  "}\n\n");
517 }
518 
521  printer->Print(
522  "public void WriteTo(pb::CodedOutputStream output) {\n");
523  printer->Print("#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE\n");
524  printer->Indent();
525  printer->Print("output.WriteRawMessage(this);\n");
526  printer->Outdent();
527  printer->Print("#else\n");
528  printer->Indent();
529  GenerateWriteToBody(printer, false);
530  printer->Outdent();
531  printer->Print("#endif\n");
532  printer->Print("}\n\n");
533 
534  printer->Print("#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE\n");
536  printer->Print("void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {\n");
537  printer->Indent();
538  GenerateWriteToBody(printer, true);
539  printer->Outdent();
540  printer->Print("}\n");
541  printer->Print("#endif\n\n");
542 
544  printer->Print(
545  "public int CalculateSize() {\n");
546  printer->Indent();
547  printer->Print("int size = 0;\n");
548  for (int i = 0; i < descriptor_->field_count(); i++) {
549  std::unique_ptr<FieldGeneratorBase> generator(
551  generator->GenerateSerializedSizeCode(printer);
552  }
553 
554  if (has_extension_ranges_) {
555  printer->Print(
556  "if (_extensions != null) {\n"
557  " size += _extensions.CalculateSize();\n"
558  "}\n");
559  }
560 
561  printer->Print(
562  "if (_unknownFields != null) {\n"
563  " size += _unknownFields.CalculateSize();\n"
564  "}\n");
565 
566  printer->Print("return size;\n");
567  printer->Outdent();
568  printer->Print("}\n\n");
569 }
570 
571 void MessageGenerator::GenerateWriteToBody(io::Printer* printer, bool use_write_context) {
572  // Serialize all the fields
573  for (int i = 0; i < fields_by_number().size(); i++) {
574  std::unique_ptr<FieldGeneratorBase> generator(
576  generator->GenerateSerializationCode(printer, use_write_context);
577  }
578 
579  if (has_extension_ranges_) {
580  // Serialize extensions
581  printer->Print(
582  use_write_context
583  ? "if (_extensions != null) {\n"
584  " _extensions.WriteTo(ref output);\n"
585  "}\n"
586  : "if (_extensions != null) {\n"
587  " _extensions.WriteTo(output);\n"
588  "}\n");
589  }
590 
591  // Serialize unknown fields
592  printer->Print(
593  use_write_context
594  ? "if (_unknownFields != null) {\n"
595  " _unknownFields.WriteTo(ref output);\n"
596  "}\n"
597  : "if (_unknownFields != null) {\n"
598  " _unknownFields.WriteTo(output);\n"
599  "}\n");
600 
601  // TODO(jonskeet): Memoize size of frozen messages?
602 }
603 
605  // Note: These are separate from GenerateMessageSerializationMethods()
606  // because they need to be generated even for messages that are optimized
607  // for code size.
608  std::map<std::string, std::string> vars;
609  vars["class_name"] = class_name();
610 
612  printer->Print(
613  vars,
614  "public void MergeFrom($class_name$ other) {\n");
615  printer->Indent();
616  printer->Print(
617  "if (other == null) {\n"
618  " return;\n"
619  "}\n");
620  // Merge non-oneof fields, treating optional proto3 fields as normal fields
621  for (int i = 0; i < descriptor_->field_count(); i++) {
622  const FieldDescriptor* field = descriptor_->field(i);
623  if (field->real_containing_oneof()) {
624  continue;
625  }
626  std::unique_ptr<FieldGeneratorBase> generator(CreateFieldGeneratorInternal(field));
627  generator->GenerateMergingCode(printer);
628  }
629  // Merge oneof fields (for non-synthetic oneofs)
630  for (int i = 0; i < descriptor_->real_oneof_decl_count(); ++i) {
631  const OneofDescriptor* oneof = descriptor_->oneof_decl(i);
632  vars["name"] = UnderscoresToCamelCase(oneof->name(), false);
633  vars["property_name"] = UnderscoresToCamelCase(oneof->name(), true);
634  printer->Print(vars, "switch (other.$property_name$Case) {\n");
635  printer->Indent();
636  for (int j = 0; j < oneof->field_count(); j++) {
637  const FieldDescriptor* field = oneof->field(j);
638  vars["field_property_name"] = GetPropertyName(field);
639  printer->Print(
640  vars,
641  "case $property_name$OneofCase.$field_property_name$:\n");
642  printer->Indent();
643  std::unique_ptr<FieldGeneratorBase> generator(CreateFieldGeneratorInternal(field));
644  generator->GenerateMergingCode(printer);
645  printer->Print("break;\n");
646  printer->Outdent();
647  }
648  printer->Outdent();
649  printer->Print("}\n\n");
650  }
651  // Merge extensions
652  if (has_extension_ranges_) {
653  printer->Print("pb::ExtensionSet.MergeFrom(ref _extensions, other._extensions);\n");
654  }
655 
656  // Merge unknown fields.
657  printer->Print(
658  "_unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);\n");
659 
660  printer->Outdent();
661  printer->Print("}\n\n");
662 
664  printer->Print("public void MergeFrom(pb::CodedInputStream input) {\n");
665  printer->Print("#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE\n");
666  printer->Indent();
667  printer->Print("input.ReadRawMessage(this);\n");
668  printer->Outdent();
669  printer->Print("#else\n");
670  printer->Indent();
671  GenerateMainParseLoop(printer, false);
672  printer->Outdent();
673  printer->Print("#endif\n");
674  printer->Print("}\n\n");
675 
676  printer->Print("#if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE\n");
678  printer->Print("void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {\n");
679  printer->Indent();
680  GenerateMainParseLoop(printer, true);
681  printer->Outdent();
682  printer->Print("}\n"); // method
683  printer->Print("#endif\n\n");
684 
685 }
686 
687 void MessageGenerator::GenerateMainParseLoop(io::Printer* printer, bool use_parse_context) {
688  std::map<std::string, std::string> vars;
689  vars["maybe_ref_input"] = use_parse_context ? "ref input" : "input";
690 
691  printer->Print(
692  "uint tag;\n"
693  "while ((tag = input.ReadTag()) != 0) {\n"
694  " switch(tag) {\n");
695  printer->Indent();
696  printer->Indent();
697  if (end_tag_ != 0) {
698  printer->Print(
699  "case $end_tag$:\n"
700  " return;\n",
701  "end_tag", StrCat(end_tag_));
702  }
703  if (has_extension_ranges_) {
704  printer->Print(vars,
705  "default:\n"
706  " if (!pb::ExtensionSet.TryMergeFieldFrom(ref _extensions, $maybe_ref_input$)) {\n"
707  " _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, $maybe_ref_input$);\n"
708  " }\n"
709  " break;\n");
710  } else {
711  printer->Print(vars,
712  "default:\n"
713  " _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, $maybe_ref_input$);\n"
714  " break;\n");
715  }
716  for (int i = 0; i < fields_by_number().size(); i++) {
721  // Handle both packed and unpacked repeated fields with the same Read*Array call;
722  // the two generated cases are the packed and unpacked tags.
723  // TODO(jonskeet): Check that is_packable is equivalent to
724  // is_repeated && wt in { VARINT, FIXED32, FIXED64 }.
725  // It looks like it is...
726  if (field->is_packable()) {
727  printer->Print(
728  "case $packed_tag$:\n",
729  "packed_tag",
730  StrCat(
732  field->number(),
734  }
735 
736  printer->Print("case $tag$: {\n", "tag", StrCat(tag));
737  printer->Indent();
738  std::unique_ptr<FieldGeneratorBase> generator(
740  generator->GenerateParsingCode(printer, use_parse_context);
741  printer->Print("break;\n");
742  printer->Outdent();
743  printer->Print("}\n");
744  }
745  printer->Outdent();
746  printer->Print("}\n"); // switch
747  printer->Outdent();
748  printer->Print("}\n"); // while
749 }
750 
751 // it's a waste of space to track presence for all values, so we only track them if they're not nullable
754  return -1;
755  }
756 
757  int index = 0;
758  for (int i = 0; i < fields_by_number().size(); i++) {
760  if (field == descriptor) {
761  return index;
762  }
763  if (RequiresPresenceBit(field)) {
764  index++;
765  }
766  }
767  GOOGLE_LOG(DFATAL)<< "Could not find presence index for field " << descriptor->name();
768  return -1;
769 }
770 
772  const FieldDescriptor* descriptor) {
774 }
775 
776 } // namespace csharp
777 } // namespace compiler
778 } // namespace protobuf
779 } // namespace google
google::protobuf::compiler::csharp::CompareFieldNumbers
bool CompareFieldNumbers(const FieldDescriptor *d1, const FieldDescriptor *d2)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_message.cc:57
google::protobuf::io::Printer::Print
void Print(const std::map< std::string, std::string > &variables, const char *text)
Definition: bloaty/third_party/protobuf/src/google/protobuf/io/printer.cc:113
google::protobuf::compiler::csharp::GetFieldConstantName
std::string GetFieldConstantName(const FieldDescriptor *field)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_helpers.cc:352
descriptor_
string_view descriptor_
Definition: elf.cc:154
google::protobuf::FieldDescriptor
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:515
absl::str_format_internal::LengthMod::j
@ j
google::protobuf::compiler::csharp::GetReflectionClassName
std::string GetReflectionClassName(const FileDescriptor *descriptor)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_helpers.cc:315
google::protobuf::compiler::csharp::MessageGenerator::GenerateCloningCode
void GenerateCloningCode(io::Printer *printer)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_message.cc:357
MessageOptions::deprecated
bool deprecated() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.pb.h:12117
google::protobuf::compiler::csharp::GetClassName
std::string GetClassName(const Descriptor *descriptor)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_helpers.cc:333
google::protobuf::Descriptor::real_oneof_decl_count
int real_oneof_decl_count() const
google::protobuf::compiler::csharp::SourceGeneratorBase::WriteGeneratedCodeAttributes
void WriteGeneratedCodeAttributes(io::Printer *printer)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_source_generator_base.cc:57
options
double_dict options[]
Definition: capstone_test.c:55
google::protobuf.internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED
@ WIRETYPE_LENGTH_DELIMITED
Definition: bloaty/third_party/protobuf/src/google/protobuf/wire_format_lite.h:104
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
google::protobuf::Descriptor::nested_type_count
int nested_type_count() const
google::protobuf::compiler::csharp::RequiresPresenceBit
bool RequiresPresenceBit(const FieldDescriptor *descriptor)
Definition: protobuf/src/google/protobuf/compiler/csharp/csharp_helpers.h:181
google::protobuf::compiler::csharp::MessageGenerator::GenerateMainParseLoop
void GenerateMainParseLoop(io::Printer *printer, bool use_parse_context)
Definition: protobuf/src/google/protobuf/compiler/csharp/csharp_message.cc:687
google::protobuf::uint32
uint32_t uint32
Definition: third_party/bloaty/third_party/protobuf/src/google/protobuf/stubs/port.h:155
google::protobuf::Descriptor::containing_type
const Descriptor * containing_type() const
grpc::protobuf::io::Printer
GRPC_CUSTOM_PRINTER Printer
Definition: src/compiler/config.h:54
google::protobuf::compiler::csharp::MessageGenerator::full_class_name
std::string full_class_name()
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_message.cc:96
google::protobuf::compiler::csharp::MessageGenerator::class_name
std::string class_name()
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_message.cc:92
google::protobuf
Definition: bloaty/third_party/protobuf/benchmarks/util/data_proto2_to_proto3_util.h:12
google::protobuf::OneofDescriptor
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:843
google::protobuf::compiler::csharp::MessageGenerator::AddSerializableAttribute
void AddSerializableAttribute(io::Printer *printer)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_message.cc:110
google::protobuf::compiler::csharp::MessageGenerator::fields_by_number
const std::vector< const FieldDescriptor * > & fields_by_number()
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_message.cc:100
google::protobuf::compiler::csharp::MessageGenerator::GenerateFreezingCode
void GenerateFreezingCode(io::Printer *printer)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_message.cc:417
google::protobuf::OneofDescriptor::name
const std::string & name() const
google::protobuf::StrCat
string StrCat(const AlphaNum &a, const AlphaNum &b)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/strutil.cc:1482
google::protobuf::OneofDescriptor::field
const FieldDescriptor * field(int index) const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:2179
Descriptor
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/protobuf.h:121
google::protobuf::compiler::csharp::MessageGenerator::GenerateMessageSerializationMethods
void GenerateMessageSerializationMethods(io::Printer *printer)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_message.cc:499
google::protobuf.internal::WireFormatLite::MakeTag
constexpr static uint32 MakeTag(int field_number, WireType type)
Definition: bloaty/third_party/protobuf/src/google/protobuf/wire_format_lite.h:783
google::protobuf::Descriptor::options
const MessageOptions & options() const
google::protobuf::compiler::csharp::MessageGenerator::GenerateFrameworkMethods
void GenerateFrameworkMethods(io::Printer *printer)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_message.cc:420
FieldDescriptor
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/protobuf.h:133
google::protobuf::Descriptor::field
const FieldDescriptor * field(int index) const
google::protobuf::io::Printer::Indent
void Indent()
Definition: bloaty/third_party/protobuf/src/google/protobuf/io/printer.cc:186
d2
static const fe d2
Definition: curve25519_tables.h:39
tag
static void * tag(intptr_t t)
Definition: bad_client.cc:318
google::protobuf::Descriptor::oneof_decl
const OneofDescriptor * oneof_decl(int index) const
google::protobuf::compiler::csharp::IsDescriptorProto
bool IsDescriptorProto(const FileDescriptor *descriptor)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_helpers.h:131
google::protobuf::compiler::csharp::MessageGenerator::CreateFieldGeneratorInternal
FieldGeneratorBase * CreateFieldGeneratorInternal(const FieldDescriptor *descriptor)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_message.cc:702
google::protobuf::compiler::csharp::MessageGenerator::descriptor_
const Descriptor * descriptor_
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_message.h:62
google::protobuf::Descriptor::extension_count
int extension_count() const
google::protobuf::Descriptor::enum_type
const EnumDescriptor * enum_type(int index) const
google::protobuf::compiler::csharp::MessageGenerator::GenerateWriteToBody
void GenerateWriteToBody(io::Printer *printer, bool use_write_context)
Definition: protobuf/src/google/protobuf/compiler/csharp/csharp_message.cc:571
google::protobuf::compiler::csharp::MessageGenerator::fields_by_number_
std::vector< const FieldDescriptor * > fields_by_number_
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_message.h:63
google::protobuf::Descriptor::extension
const FieldDescriptor * extension(int index) const
google::protobuf::Descriptor::field_count
int field_count() const
google::protobuf::compiler::csharp::MessageGenerator::Generate
void Generate(io::Printer *printer)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_message.cc:116
google::protobuf::compiler::csharp::GetPropertyName
std::string GetPropertyName(const FieldDescriptor *descriptor)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_helpers.cc:356
google::protobuf::io::Printer
Definition: bloaty/third_party/protobuf/src/google/protobuf/io/printer.h:181
google::protobuf::compiler::csharp::WriteMessageDocComment
void WriteMessageDocComment(io::Printer *printer, const Descriptor *message)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_doc_comment.cc:93
google::protobuf::compiler::csharp::GetGroupEndTag
uint GetGroupEndTag(const Descriptor *descriptor)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_helpers.cc:285
google::protobuf::compiler::csharp::MessageGenerator::end_tag_
uint end_tag_
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_message.h:65
google::protobuf::Descriptor::nested_type
const Descriptor * nested_type(int index) const
google::protobuf::Descriptor::enum_type_count
int enum_type_count() const
field
const FieldDescriptor * field
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/parser_unittest.cc:2692
google::protobuf::compiler::csharp::SourceGeneratorBase::class_access_level
std::string class_access_level()
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_source_generator_base.cc:61
OneofDescriptor
Definition: bloaty/third_party/protobuf/ruby/ext/google/protobuf_c/protobuf.h:138
google::protobuf::compiler::csharp::IsMapEntryMessage
bool IsMapEntryMessage(const Descriptor *descriptor)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_helpers.h:121
google::protobuf::EnumDescriptor::options
const EnumOptions & options() const
index
int index
Definition: bloaty/third_party/protobuf/php/ext/google/protobuf/protobuf.h:1184
google::protobuf::compiler::csharp::SourceGeneratorBase::options
const Options * options()
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_source_generator_base.cc:65
google::protobuf.internal::WireFormat::WireTypeForFieldType
static WireFormatLite::WireType WireTypeForFieldType(FieldDescriptor::Type type)
Definition: bloaty/third_party/protobuf/src/google/protobuf/wire_format.h:319
google::protobuf::compiler::csharp::MessageGenerator::HasNestedGeneratedTypes
bool HasNestedGeneratedTypes()
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_message.cc:344
google::protobuf::Descriptor::name
const std::string & name() const
google::protobuf::Descriptor::file
const FileDescriptor * file() const
google::protobuf.internal::WireFormatLite::WireType
WireType
Definition: bloaty/third_party/protobuf/src/google/protobuf/wire_format_lite.h:101
google::protobuf::compiler::csharp::MessageGenerator::AddDeprecatedFlag
void AddDeprecatedFlag(io::Printer *printer)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_message.cc:104
google::protobuf::compiler::csharp::MessageGenerator::MessageGenerator
MessageGenerator(const Descriptor *descriptor, const Options *options)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_message.cc:61
google::protobuf::compiler::csharp::MessageGenerator::GetPresenceIndex
int GetPresenceIndex(const FieldDescriptor *descriptor)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_message.cc:683
google::protobuf::compiler::csharp::UnderscoresToCamelCase
std::string UnderscoresToCamelCase(const std::string &input, bool cap_next_letter, bool preserve_period)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_helpers.cc:143
google::protobuf::OneofDescriptor::field_count
int field_count() const
google::protobuf::compiler::csharp::MessageGenerator::has_bit_field_count_
int has_bit_field_count_
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_message.h:64
google::protobuf::compiler::csharp::MessageGenerator::GenerateMergingMethods
void GenerateMergingMethods(io::Printer *printer)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_message.cc:559
google::protobuf::compiler::csharp::CreateFieldGenerator
FieldGeneratorBase * CreateFieldGenerator(const FieldDescriptor *descriptor, int presenceIndex, const Options *options)
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_helpers.cc:479
GOOGLE_LOG
#define GOOGLE_LOG(LEVEL)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/logging.h:146
descriptor
static const char descriptor[1336]
Definition: certs.upbdefs.c:16
google::protobuf::io::Printer::Outdent
void Outdent()
Definition: bloaty/third_party/protobuf/src/google/protobuf/io/printer.cc:188
google::protobuf::Descriptor::index
int index() const
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:2091
compiler
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/plugin.pb.cc:21
google
Definition: bloaty/third_party/protobuf/benchmarks/util/data_proto2_to_proto3_util.h:11
google::protobuf::compiler::csharp::MessageGenerator::has_extension_ranges_
bool has_extension_ranges_
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_message.h:66
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230
google::protobuf::compiler::csharp::MessageGenerator::~MessageGenerator
~MessageGenerator()
Definition: bloaty/third_party/protobuf/src/google/protobuf/compiler/csharp/csharp_message.cc:89


grpc
Author(s):
autogenerated on Fri May 16 2025 02:58:07