csharp_message.cc 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701
  1. // Protocol Buffers - Google's data interchange format
  2. // Copyright 2008 Google Inc.
  3. // http://code.google.com/p/protobuf/
  4. //
  5. // Licensed under the Apache License, Version 2.0 (the "License");
  6. // you may not use this file except in compliance with the License.
  7. // You may obtain a copy of the License at
  8. //
  9. // http://www.apache.org/licenses/LICENSE-2.0
  10. //
  11. // Unless required by applicable law or agreed to in writing, software
  12. // distributed under the License is distributed on an "AS IS" BASIS,
  13. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. // See the License for the specific language governing permissions and
  15. // limitations under the License.
  16. // Author: jonskeet@google.com (Jon Skeet)
  17. // Following the Java generator by kenton@google.com (Kenton Varda)
  18. // Based on original Protocol Buffers design by
  19. // Sanjay Ghemawat, Jeff Dean, and others.
  20. #include <algorithm>
  21. #include <google/protobuf/stubs/hash.h>
  22. #include <google/protobuf/compiler/csharp/csharp_message.h>
  23. #include <google/protobuf/compiler/csharp/csharp_enum.h>
  24. #include <google/protobuf/compiler/csharp/csharp_extension.h>
  25. #include <google/protobuf/compiler/csharp/csharp_helpers.h>
  26. #include <google/protobuf/stubs/strutil.h>
  27. #include <google/protobuf/io/printer.h>
  28. #include <google/protobuf/io/coded_stream.h>
  29. #include <google/protobuf/wire_format.h>
  30. #include <google/protobuf/descriptor.pb.h>
  31. namespace google {
  32. namespace protobuf {
  33. namespace compiler {
  34. namespace csharp {
  35. using internal::WireFormat;
  36. namespace {
  37. void PrintFieldComment(io::Printer* printer, const FieldDescriptor* field) {
  38. // Print the field's proto-syntax definition as a comment. We don't want to
  39. // print group bodies so we cut off after the first line.
  40. string def = field->DebugString();
  41. printer->Print("// $def$\r\n",
  42. "def", def.substr(0, def.find_first_of('\n')));
  43. }
  44. struct FieldOrderingByNumber {
  45. inline bool operator()(const FieldDescriptor* a,
  46. const FieldDescriptor* b) const {
  47. return a->number() < b->number();
  48. }
  49. };
  50. struct ExtensionRangeOrdering {
  51. bool operator()(const Descriptor::ExtensionRange* a,
  52. const Descriptor::ExtensionRange* b) const {
  53. return a->start < b->start;
  54. }
  55. };
  56. // Sort the fields of the given Descriptor by number into a new[]'d array
  57. // and return it.
  58. const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor) {
  59. const FieldDescriptor** fields =
  60. new const FieldDescriptor*[descriptor->field_count()];
  61. for (int i = 0; i < descriptor->field_count(); i++) {
  62. fields[i] = descriptor->field(i);
  63. }
  64. sort(fields, fields + descriptor->field_count(),
  65. FieldOrderingByNumber());
  66. return fields;
  67. }
  68. // Get an identifier that uniquely identifies this type within the file.
  69. // This is used to declare static variables related to this type at the
  70. // outermost file scope.
  71. string UniqueFileScopeIdentifier(const Descriptor* descriptor) {
  72. return "static_" + StringReplace(descriptor->full_name(), ".", "_", true);
  73. }
  74. // Returns true if the message type has any required fields. If it doesn't,
  75. // we can optimize out calls to its isInitialized() method.
  76. //
  77. // already_seen is used to avoid checking the same type multiple times
  78. // (and also to protect against recursion).
  79. static bool HasRequiredFields(
  80. const Descriptor* type,
  81. hash_set<const Descriptor*>* already_seen) {
  82. if (already_seen->count(type) > 0) {
  83. // The type is already in cache. This means that either:
  84. // a. The type has no required fields.
  85. // b. We are in the midst of checking if the type has required fields,
  86. // somewhere up the stack. In this case, we know that if the type
  87. // has any required fields, they'll be found when we return to it,
  88. // and the whole call to HasRequiredFields() will return true.
  89. // Therefore, we don't have to check if this type has required fields
  90. // here.
  91. return false;
  92. }
  93. already_seen->insert(type);
  94. // If the type has extensions, an extension with message type could contain
  95. // required fields, so we have to be conservative and assume such an
  96. // extension exists.
  97. if (type->extension_range_count() > 0) return true;
  98. for (int i = 0; i < type->field_count(); i++) {
  99. const FieldDescriptor* field = type->field(i);
  100. if (field->is_required()) {
  101. return true;
  102. }
  103. if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
  104. if (HasRequiredFields(field->message_type(), already_seen)) {
  105. return true;
  106. }
  107. }
  108. }
  109. return false;
  110. }
  111. static bool HasRequiredFields(const Descriptor* type) {
  112. hash_set<const Descriptor*> already_seen;
  113. return HasRequiredFields(type, &already_seen);
  114. }
  115. } // namespace
  116. // ===================================================================
  117. MessageGenerator::MessageGenerator(const Descriptor* descriptor)
  118. : descriptor_(descriptor),
  119. field_generators_(descriptor) {
  120. }
  121. MessageGenerator::~MessageGenerator() {}
  122. void MessageGenerator::GenerateStaticVariables(io::Printer* printer) {
  123. // Because descriptor.proto (Google.ProtocolBuffers.DescriptorProtos) is
  124. // used in the construction of descriptors, we have a tricky bootstrapping
  125. // problem. To help control static initialization order, we make sure all
  126. // descriptors and other static data that depends on them are members of
  127. // the proto-descriptor class. This way, they will be initialized in
  128. // a deterministic order.
  129. map<string, string> vars;
  130. vars["identifier"] = UniqueFileScopeIdentifier(descriptor_);
  131. vars["index"] = SimpleItoa(descriptor_->index());
  132. vars["classname"] = ClassName(descriptor_);
  133. if (descriptor_->containing_type() != NULL) {
  134. vars["parent"] = UniqueFileScopeIdentifier(descriptor_->containing_type());
  135. }
  136. if (!descriptor_->file()->options().csharp_nest_classes()) {
  137. // We can only make these assembly-private since the classes that use them
  138. // aren't nested.
  139. vars["private"] = "internal ";
  140. } else {
  141. vars["private"] = "private ";
  142. }
  143. // The descriptor for this type.
  144. if (descriptor_->containing_type() == NULL) {
  145. printer->Print(vars,
  146. "$private$static readonly pbd::MessageDescriptor internal__$identifier$__Descriptor \r\n"
  147. " = Descriptor.MessageTypes[$index$];\r\n");
  148. } else {
  149. printer->Print(vars,
  150. "$private$static readonly pbd::MessageDescriptor internal__$identifier$__Descriptor \r\n"
  151. " = internal__$parent$__Descriptor.NestedTypes[$index$];\r\n");
  152. }
  153. // And the FieldAccessorTable.
  154. printer->Print(vars,
  155. "$private$static pb::FieldAccess.FieldAccessorTable internal__$identifier$__FieldAccessorTable\r\n"
  156. " = new pb::FieldAccess.FieldAccessorTable(internal__$identifier$__Descriptor,\r\n"
  157. " new string[] { ");
  158. for (int i = 0; i < descriptor_->field_count(); i++) {
  159. printer->Print(
  160. "\"$field_name$\", ",
  161. "field_name",
  162. UnderscoresToCapitalizedCamelCase(descriptor_->field(i)));
  163. }
  164. printer->Print("},\r\n"
  165. " typeof ($classname$),\r\n"
  166. " typeof ($classname$.Builder));\r\n",
  167. "classname", ClassName(descriptor_));
  168. // Generate static members for all nested types.
  169. for (int i = 0; i < descriptor_->nested_type_count(); i++) {
  170. // TODO(kenton): Reuse MessageGenerator objects?
  171. MessageGenerator(descriptor_->nested_type(i))
  172. .GenerateStaticVariables(printer);
  173. }
  174. }
  175. void MessageGenerator::Generate(io::Printer* printer) {
  176. bool is_own_file =
  177. descriptor_->containing_type() == NULL &&
  178. descriptor_->file()->options().csharp_multiple_files();
  179. if (descriptor_->extension_range_count() > 0) {
  180. printer->Print(
  181. "$access$ sealed partial class $classname$ : pb::ExtendableMessage<$classname$, $classname$.Builder> {\r\n",
  182. "classname", descriptor_->name(),
  183. "access", ClassAccessLevel(descriptor_->file()));
  184. } else {
  185. printer->Print(
  186. "$access$ sealed partial class $classname$ : pb::GeneratedMessage<$classname$, $classname$.Builder> {\r\n",
  187. "classname", descriptor_->name(),
  188. "access", ClassAccessLevel(descriptor_->file()));
  189. }
  190. printer->Indent();
  191. printer->Print(
  192. "private static readonly $classname$ defaultInstance = new $classname$();\r\n"
  193. "public static $classname$ DefaultInstance {\r\n"
  194. " get { return defaultInstance; }\r\n"
  195. "}\r\n"
  196. "\r\n"
  197. "public override $classname$ DefaultInstanceForType {\r\n"
  198. " get { return defaultInstance; }\r\n"
  199. "}\r\n"
  200. "\r\n",
  201. "classname", descriptor_->name());
  202. printer->Print(
  203. "public static pbd::MessageDescriptor Descriptor {\r\n"
  204. " get { return $fileclass$.internal__$identifier$__Descriptor; }\r\n"
  205. "}\r\n"
  206. "\r\n"
  207. "protected override pb::FieldAccess.FieldAccessorTable InternalFieldAccessors {\r\n"
  208. " get { return $fileclass$.internal__$identifier$__FieldAccessorTable; }\r\n"
  209. "}\r\n"
  210. "\r\n",
  211. "fileclass", ClassName(descriptor_->file()),
  212. "identifier", UniqueFileScopeIdentifier(descriptor_));
  213. // Extensions don't need to go in an extra nested type
  214. for (int i = 0; i < descriptor_->extension_count(); i++) {
  215. ExtensionGenerator(descriptor_->extension(i)).Generate(printer);
  216. }
  217. if (descriptor_->enum_type_count()
  218. + descriptor_->nested_type_count()
  219. + descriptor_->extension_count() > 0) {
  220. printer->Print("#region Nested types\r\n");
  221. printer->Print("public static class Types {\r\n");
  222. printer->Indent();
  223. // Nested types and extensions
  224. for (int i = 0; i < descriptor_->enum_type_count(); i++) {
  225. EnumGenerator(descriptor_->enum_type(i)).Generate(printer);
  226. }
  227. for (int i = 0; i < descriptor_->nested_type_count(); i++) {
  228. MessageGenerator(descriptor_->nested_type(i)).Generate(printer);
  229. }
  230. printer->Outdent();
  231. printer->Print("}\r\n");
  232. printer->Print("#endregion\r\n\r\n");
  233. }
  234. // Fields
  235. for (int i = 0; i < descriptor_->field_count(); i++) {
  236. PrintFieldComment(printer, descriptor_->field(i));
  237. field_generators_.get(descriptor_->field(i)).GenerateMembers(printer);
  238. printer->Print("\r\n");
  239. }
  240. if (descriptor_->file()->options().optimize_for() == FileOptions::SPEED) {
  241. GenerateIsInitialized(printer);
  242. GenerateMessageSerializationMethods(printer);
  243. }
  244. GenerateParseFromMethods(printer);
  245. GenerateBuilder(printer);
  246. }
  247. // ===================================================================
  248. void MessageGenerator::
  249. GenerateMessageSerializationMethods(io::Printer* printer) {
  250. scoped_array<const FieldDescriptor*> sorted_fields(
  251. SortFieldsByNumber(descriptor_));
  252. vector<const Descriptor::ExtensionRange*> sorted_extensions;
  253. for (int i = 0; i < descriptor_->extension_range_count(); ++i) {
  254. sorted_extensions.push_back(descriptor_->extension_range(i));
  255. }
  256. sort(sorted_extensions.begin(), sorted_extensions.end(),
  257. ExtensionRangeOrdering());
  258. printer->Print("public override void WriteTo(pb::CodedOutputStream output) {\r\n");
  259. printer->Indent();
  260. if (descriptor_->extension_range_count() > 0) {
  261. printer->Print(
  262. "pb::ExtendableMessage<$classname$, $classname$.Builder>.ExtensionWriter extensionWriter = CreateExtensionWriter(this);\r\n",
  263. "classname", descriptor_->name());
  264. }
  265. // Merge the fields and the extension ranges, both sorted by field number.
  266. for (int i = 0, j = 0;
  267. i < descriptor_->field_count() || j < sorted_extensions.size();
  268. ) {
  269. if (i == descriptor_->field_count()) {
  270. GenerateSerializeOneExtensionRange(printer, sorted_extensions[j++]);
  271. } else if (j == sorted_extensions.size()) {
  272. GenerateSerializeOneField(printer, sorted_fields[i++]);
  273. } else if (sorted_fields[i]->number() < sorted_extensions[j]->start) {
  274. GenerateSerializeOneField(printer, sorted_fields[i++]);
  275. } else {
  276. GenerateSerializeOneExtensionRange(printer, sorted_extensions[j++]);
  277. }
  278. }
  279. if (descriptor_->options().message_set_wire_format()) {
  280. printer->Print(
  281. "UnknownFields.WriteAsMessageSetTo(output);\r\n");
  282. } else {
  283. printer->Print(
  284. "UnknownFields.WriteTo(output);\r\n");
  285. }
  286. printer->Outdent();
  287. printer->Print(
  288. "}\r\n"
  289. "\r\n"
  290. "private int memoizedSerializedSize = -1;\r\n"
  291. "public override int SerializedSize {\r\n");
  292. printer->Indent();
  293. printer->Print("get {\r\n");
  294. printer->Indent();
  295. printer->Print(
  296. "int size = memoizedSerializedSize;\r\n"
  297. "if (size != -1) return size;\r\n"
  298. "\r\n"
  299. "size = 0;\r\n");
  300. for (int i = 0; i < descriptor_->field_count(); i++) {
  301. field_generators_.get(sorted_fields[i]).GenerateSerializedSizeCode(printer);
  302. }
  303. if (descriptor_->extension_range_count() > 0) {
  304. printer->Print(
  305. "size += ExtensionsSerializedSize;\r\n");
  306. }
  307. if (descriptor_->options().message_set_wire_format()) {
  308. printer->Print(
  309. "size += UnknownFields.SerializedSizeAsMessageSet;\r\n");
  310. } else {
  311. printer->Print(
  312. "size += UnknownFields.SerializedSize;\r\n");
  313. }
  314. printer->Outdent();
  315. printer->Outdent();
  316. printer->Print(
  317. " memoizedSerializedSize = size;\r\n"
  318. " return size;\r\n"
  319. " }\r\n"
  320. "}\r\n"
  321. "\r\n");
  322. }
  323. void MessageGenerator::
  324. GenerateParseFromMethods(io::Printer* printer) {
  325. // Note: These are separate from GenerateMessageSerializationMethods()
  326. // because they need to be generated even for messages that are optimized
  327. // for code size.
  328. printer->Print(
  329. "public static $classname$ ParseFrom(pb::ByteString data) {\r\n"
  330. " return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();\r\n"
  331. "}\r\n"
  332. "public static $classname$ ParseFrom(pb::ByteString data,\r\n"
  333. " pb::ExtensionRegistry extensionRegistry) {\r\n"
  334. " return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry))\r\n"
  335. " .BuildParsed();\r\n"
  336. "}\r\n"
  337. "public static $classname$ ParseFrom(byte[] data) {\r\n"
  338. " return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();\r\n"
  339. "}\r\n"
  340. "public static $classname$ ParseFrom(byte[] data,\r\n"
  341. " pb::ExtensionRegistry extensionRegistry) {\r\n"
  342. " return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry))\r\n"
  343. " .BuildParsed();\r\n"
  344. "}\r\n"
  345. "public static $classname$ ParseFrom(global::System.IO.Stream input) {\r\n"
  346. " return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();\r\n"
  347. "}\r\n"
  348. "public static $classname$ ParseFrom(\r\n"
  349. " global::System.IO.Stream input,\r\n"
  350. " pb::ExtensionRegistry extensionRegistry) {\r\n"
  351. " return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry))\r\n"
  352. " .BuildParsed();\r\n"
  353. "}\r\n"
  354. "public static $classname$ ParseFrom(pb::CodedInputStream input) {\r\n"
  355. " return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();\r\n"
  356. "}\r\n"
  357. "public static $classname$ ParseFrom(pb::CodedInputStream input,\r\n"
  358. " pb::ExtensionRegistry extensionRegistry) {\r\n"
  359. " return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry))\r\n"
  360. " .BuildParsed();\r\n"
  361. "}\r\n"
  362. "\r\n",
  363. "classname", ClassName(descriptor_));
  364. }
  365. void MessageGenerator::GenerateSerializeOneField(
  366. io::Printer* printer, const FieldDescriptor* field) {
  367. field_generators_.get(field).GenerateSerializationCode(printer);
  368. }
  369. void MessageGenerator::GenerateSerializeOneExtensionRange(
  370. io::Printer* printer, const Descriptor::ExtensionRange* range) {
  371. printer->Print(
  372. "extensionWriter.WriteUntil($end$, output);\r\n",
  373. "end", SimpleItoa(range->end));
  374. }
  375. // ===================================================================
  376. void MessageGenerator::GenerateBuilder(io::Printer* printer) {
  377. printer->Print(
  378. "public static Builder CreateBuilder() { return new Builder(); }\r\n"
  379. "public override Builder CreateBuilderForType() { return new Builder(); }\r\n"
  380. "public static Builder CreateBuilder($classname$ prototype) {\r\n"
  381. " return (Builder) new Builder().MergeFrom(prototype);\r\n"
  382. "}\r\n"
  383. "\r\n",
  384. "classname", ClassName(descriptor_));
  385. if (descriptor_->extension_range_count() > 0) {
  386. printer->Print(
  387. "$access$ sealed partial class Builder : pb::ExtendableBuilder<$classname$, $classname$.Builder> {\r\n",
  388. "classname", ClassName(descriptor_),
  389. "access", ClassAccessLevel(descriptor_->file()));
  390. } else {
  391. printer->Print(
  392. "$access$ sealed partial class Builder : pb::GeneratedBuilder<$classname$, Builder> {\r\n",
  393. "classname", ClassName(descriptor_),
  394. "access", ClassAccessLevel(descriptor_->file()));
  395. }
  396. printer->Indent();
  397. printer->Print(
  398. "protected override Builder ThisBuilder {\r\n"
  399. " get { return this; }\r\n"
  400. "}\r\n\r\n");
  401. GenerateCommonBuilderMethods(printer);
  402. if (descriptor_->file()->options().optimize_for() == FileOptions::SPEED) {
  403. GenerateBuilderParsingMethods(printer);
  404. }
  405. for (int i = 0; i < descriptor_->field_count(); i++) {
  406. printer->Print("\r\n");
  407. PrintFieldComment(printer, descriptor_->field(i));
  408. field_generators_.get(descriptor_->field(i))
  409. .GenerateBuilderMembers(printer);
  410. }
  411. printer->Outdent();
  412. printer->Print("}\r\n");
  413. printer->Outdent();
  414. printer->Print("}\r\n\r\n");
  415. }
  416. // ===================================================================
  417. void MessageGenerator::GenerateCommonBuilderMethods(io::Printer* printer) {
  418. printer->Print(
  419. "// Construct using $classname$.CreateBuilder()\r\n"
  420. "internal Builder() {}\r\n"
  421. "\r\n"
  422. "$classname$ result = new $classname$();\r\n"
  423. "\r\n"
  424. "protected override $classname$ MessageBeingBuilt {\r\n"
  425. " get { return result; }\r\n"
  426. "}\r\n"
  427. "\r\n"
  428. "public override Builder Clear() {\r\n"
  429. " result = new $classname$();\r\n"
  430. " return this;\r\n"
  431. "}\r\n"
  432. "\r\n"
  433. "public override Builder Clone() {\r\n"
  434. " return new Builder().MergeFrom(result);\r\n"
  435. "}\r\n"
  436. "\r\n"
  437. "public override pbd::MessageDescriptor DescriptorForType {\r\n"
  438. " get { return $classname$.Descriptor; }\r\n"
  439. "}\r\n"
  440. "\r\n"
  441. "public override $classname$ DefaultInstanceForType {\r\n"
  442. " get { return $classname$.DefaultInstance; }\r\n"
  443. "}\r\n"
  444. "\r\n",
  445. "classname", ClassName(descriptor_));
  446. // -----------------------------------------------------------------
  447. printer->Print(
  448. "public override $classname$ BuildPartial() {\r\n",
  449. "classname", ClassName(descriptor_));
  450. printer->Indent();
  451. for (int i = 0; i < descriptor_->field_count(); i++) {
  452. field_generators_.get(descriptor_->field(i)).GenerateBuildingCode(printer);
  453. }
  454. printer->Outdent();
  455. printer->Print(
  456. " $classname$ returnMe = result;\r\n"
  457. " result = null;\r\n"
  458. " return returnMe;\r\n"
  459. "}\r\n"
  460. "\r\n",
  461. "classname", ClassName(descriptor_));
  462. // -----------------------------------------------------------------
  463. if (descriptor_->file()->options().optimize_for() == FileOptions::SPEED) {
  464. printer->Print(
  465. /*
  466. "protected override Builder MergeFrom(CodedInputStream data, ExtensionRegistry extensionRegistry) {\r\n"
  467. " return MergeFrom(data, extensionRegistry);\r\n"
  468. "}\r\n"
  469. "\r\n"*/
  470. "public override Builder MergeFrom(pb::IMessage other) {\r\n"
  471. " if (other is $classname$) {\r\n"
  472. " return MergeFrom(($classname$) other);\r\n"
  473. " } else {\r\n"
  474. " base.MergeFrom(other);\r\n"
  475. " return this;\r\n"
  476. " }\r\n"
  477. "}\r\n"
  478. "\r\n"
  479. "public override Builder MergeFrom($classname$ other) {\r\n"
  480. // Optimization: If other is the default instance, we know none of its
  481. // fields are set so we can skip the merge.
  482. " if (other == $classname$.DefaultInstance) return this;\r\n",
  483. "classname", ClassName(descriptor_));
  484. printer->Indent();
  485. for (int i = 0; i < descriptor_->field_count(); i++) {
  486. field_generators_.get(descriptor_->field(i)).GenerateMergingCode(printer);
  487. }
  488. printer->Outdent();
  489. printer->Print(
  490. " this.MergeUnknownFields(other.UnknownFields);\r\n"
  491. " return this;\r\n"
  492. "}\r\n"
  493. "\r\n");
  494. }
  495. }
  496. // ===================================================================
  497. void MessageGenerator::GenerateBuilderParsingMethods(io::Printer* printer) {
  498. scoped_array<const FieldDescriptor*> sorted_fields(
  499. SortFieldsByNumber(descriptor_));
  500. printer->Print(
  501. "public override Builder MergeFrom(pb::CodedInputStream input) {\r\n"
  502. " return MergeFrom(input, pb::ExtensionRegistry.Empty);\r\n"
  503. "}\r\n"
  504. "\r\n"
  505. "public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {\r\n",
  506. "classname", ClassName(descriptor_));
  507. printer->Indent();
  508. printer->Print(
  509. "pb::UnknownFieldSet.Builder unknownFields =\r\n"
  510. " pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);\r\n"
  511. "while (true) {\r\n");
  512. printer->Indent();
  513. printer->Print(
  514. "uint tag = input.ReadTag();\r\n"
  515. "switch (tag) {\r\n");
  516. printer->Indent();
  517. printer->Print(
  518. "case 0:\r\n" // zero signals EOF / limit reached
  519. " this.UnknownFields = unknownFields.Build();\r\n"
  520. " return this;\r\n"
  521. "default: {\r\n"
  522. " if (!ParseUnknownField(input, unknownFields,\r\n"
  523. " extensionRegistry, tag)) {\r\n"
  524. " this.UnknownFields = unknownFields.Build();\r\n"
  525. " return this;\r\n" // it's an endgroup tag
  526. " }\r\n"
  527. " break;\r\n"
  528. "}\r\n");
  529. for (int i = 0; i < descriptor_->field_count(); i++) {
  530. const FieldDescriptor* field = sorted_fields[i];
  531. uint32 tag = WireFormat::MakeTag(field->number(),
  532. WireFormat::WireTypeForFieldType(field->type()));
  533. printer->Print(
  534. "case $tag$: {\r\n",
  535. "tag", SimpleItoa(tag));
  536. printer->Indent();
  537. field_generators_.get(field).GenerateParsingCode(printer);
  538. printer->Outdent();
  539. printer->Print(
  540. " break;\r\n"
  541. "}\r\n");
  542. }
  543. printer->Outdent();
  544. printer->Outdent();
  545. printer->Outdent();
  546. printer->Print(
  547. " }\r\n" // switch (tag)
  548. " }\r\n" // while (true)
  549. "}\r\n"
  550. "\r\n");
  551. }
  552. // ===================================================================
  553. void MessageGenerator::GenerateIsInitialized(io::Printer* printer) {
  554. printer->Print("public override bool IsInitialized {\r\n");
  555. printer->Indent();
  556. printer->Print("get {\r\n");
  557. printer->Indent();
  558. // Check that all required fields in this message are set.
  559. // TODO(kenton): We can optimize this when we switch to putting all the
  560. // "has" fields into a single bitfield.
  561. for (int i = 0; i < descriptor_->field_count(); i++) {
  562. const FieldDescriptor* field = descriptor_->field(i);
  563. if (field->is_required()) {
  564. printer->Print(
  565. "if (!has$name$) return false;\r\n",
  566. "name", UnderscoresToCapitalizedCamelCase(field));
  567. }
  568. }
  569. // Now check that all embedded messages are initialized.
  570. for (int i = 0; i < descriptor_->field_count(); i++) {
  571. const FieldDescriptor* field = descriptor_->field(i);
  572. if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
  573. HasRequiredFields(field->message_type())) {
  574. switch (field->label()) {
  575. case FieldDescriptor::LABEL_REQUIRED:
  576. printer->Print(
  577. "if (!$name$.IsInitialized) return false;\r\n",
  578. "type", ClassName(field->message_type()),
  579. "name", UnderscoresToCapitalizedCamelCase(field));
  580. break;
  581. case FieldDescriptor::LABEL_OPTIONAL:
  582. printer->Print(
  583. "if (Has$name$) {\r\n"
  584. " if (!$name$.IsInitialized) return false;\r\n"
  585. "}\r\n",
  586. "type", ClassName(field->message_type()),
  587. "name", UnderscoresToCapitalizedCamelCase(field));
  588. break;
  589. case FieldDescriptor::LABEL_REPEATED:
  590. printer->Print(
  591. "foreach ($type$ element in $name$List) {\r\n"
  592. " if (!element.IsInitialized) return false;\r\n"
  593. "}\r\n",
  594. "type", ClassName(field->message_type()),
  595. "name", UnderscoresToCapitalizedCamelCase(field));
  596. break;
  597. }
  598. }
  599. }
  600. if (descriptor_->extension_range_count() > 0) {
  601. printer->Print(
  602. "if (!ExtensionsAreInitialized) return false;\r\n");
  603. }
  604. printer->Outdent();
  605. printer->Print(
  606. " return true;\r\n"
  607. "}\r\n");
  608. printer->Outdent();
  609. printer->Print(
  610. "}\r\n"
  611. "\r\n");
  612. }
  613. } // namespace csharp
  614. } // namespace compiler
  615. } // namespace protobuf
  616. } // namespace google