PageRenderTime 39ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 0ms

/compiler/as3/as3_message.cc

http://protobuf-actionscript3.googlecode.com/
C++ | 763 lines | 433 code | 98 blank | 232 comment | 59 complexity | 8c290d79f9a473c771018c07725b3bf5 MD5 | raw file
  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: Robert Blackwood (ported from Kenton's)
  17. // Based on original Protocol Buffers design by
  18. // Sanjay Ghemawat, Jeff Dean, and others.
  19. #include <algorithm>
  20. #include <google/protobuf/stubs/hash.h>
  21. #include <google/protobuf/compiler/as3/as3_message.h>
  22. #include <google/protobuf/compiler/as3/as3_enum.h>
  23. #include <google/protobuf/compiler/as3/as3_extension.h>
  24. #include <google/protobuf/compiler/as3/as3_helpers.h>
  25. #include <google/protobuf/stubs/strutil.h>
  26. #include <google/protobuf/io/printer.h>
  27. #include <google/protobuf/io/coded_stream.h>
  28. #include <google/protobuf/wire_format.h>
  29. #include <google/protobuf/descriptor.pb.h>
  30. namespace google {
  31. namespace protobuf {
  32. namespace compiler {
  33. namespace as3 {
  34. using internal::WireFormat;
  35. namespace {
  36. const char* LabelName(FieldDescriptor::Label label) {
  37. switch (label) {
  38. case FieldDescriptor::LABEL_OPTIONAL : return "LABEL_OPTIONAL";
  39. case FieldDescriptor::LABEL_REQUIRED : return "LABEL_REQUIRED";
  40. case FieldDescriptor::LABEL_REPEATED : return "LABEL_REPEATED";
  41. }
  42. GOOGLE_LOG(FATAL) << "Can't get here.";
  43. return NULL;
  44. }
  45. const char* AllCapsTypeName(FieldDescriptor::Type type) {
  46. switch (type) {
  47. case FieldDescriptor::TYPE_DOUBLE : return "DOUBLE";
  48. case FieldDescriptor::TYPE_FLOAT : return "FLOAT";
  49. case FieldDescriptor::TYPE_INT64 : return "INT64";
  50. case FieldDescriptor::TYPE_UINT64 : return "UINT64";
  51. case FieldDescriptor::TYPE_INT32 : return "INT32";
  52. case FieldDescriptor::TYPE_FIXED64 : return "FIXED64";
  53. case FieldDescriptor::TYPE_FIXED32 : return "FIXED32";
  54. case FieldDescriptor::TYPE_BOOL : return "BOOL";
  55. case FieldDescriptor::TYPE_STRING : return "STRING";
  56. case FieldDescriptor::TYPE_GROUP : return "GROUP";
  57. case FieldDescriptor::TYPE_MESSAGE : return "MESSAGE";
  58. case FieldDescriptor::TYPE_BYTES : return "BYTES";
  59. case FieldDescriptor::TYPE_UINT32 : return "UINT32";
  60. case FieldDescriptor::TYPE_ENUM : return "ENUM";
  61. case FieldDescriptor::TYPE_SFIXED32 : return "SFIXED32";
  62. case FieldDescriptor::TYPE_SFIXED64 : return "SFIXED64";
  63. case FieldDescriptor::TYPE_SINT32 : return "SINT32";
  64. case FieldDescriptor::TYPE_SINT64 : return "SINT64";
  65. }
  66. GOOGLE_LOG(FATAL) << "Can't get here.";
  67. return NULL;
  68. }
  69. void PrintFieldComment(io::Printer* printer, const FieldDescriptor* field) {
  70. // Print the field's proto-syntax definition as a comment. We don't want to
  71. // print group bodies so we cut off after the first line.
  72. string def = field->DebugString();
  73. printer->Print("// $def$\n",
  74. "def", def.substr(0, def.find_first_of('\n')));
  75. }
  76. struct FieldOrderingByNumber {
  77. inline bool operator()(const FieldDescriptor* a,
  78. const FieldDescriptor* b) const {
  79. return a->number() < b->number();
  80. }
  81. };
  82. struct ExtensionRangeOrdering {
  83. bool operator()(const Descriptor::ExtensionRange* a,
  84. const Descriptor::ExtensionRange* b) const {
  85. return a->start < b->start;
  86. }
  87. };
  88. // Sort the fields of the given Descriptor by number into a new[]'d array
  89. // and return it.
  90. const FieldDescriptor** SortFieldsByNumber(const Descriptor* descriptor) {
  91. const FieldDescriptor** fields =
  92. new const FieldDescriptor*[descriptor->field_count()];
  93. for (int i = 0; i < descriptor->field_count(); i++) {
  94. fields[i] = descriptor->field(i);
  95. }
  96. sort(fields, fields + descriptor->field_count(),
  97. FieldOrderingByNumber());
  98. return fields;
  99. }
  100. // Get an identifier that uniquely identifies this type within the file.
  101. // This is used to declare static variables related to this type at the
  102. // outermost file scope.
  103. string UniqueFileScopeIdentifier(const Descriptor* descriptor) {
  104. return "static_" + StringReplace(descriptor->full_name(), ".", "_", true);
  105. }
  106. // Returns true if the message type has any required fields. If it doesn't,
  107. // we can optimize out calls to its isInitialized() method.
  108. //
  109. // already_seen is used to avoid checking the same type multiple times
  110. // (and also to protect against recursion).
  111. static bool HasRequiredFields(
  112. const Descriptor* type,
  113. hash_set<const Descriptor*>* already_seen) {
  114. if (already_seen->count(type) > 0) {
  115. // The type is already in cache. This means that either:
  116. // a. The type has no required fields.
  117. // b. We are in the midst of checking if the type has required fields,
  118. // somewhere up the stack. In this case, we know that if the type
  119. // has any required fields, they'll be found when we return to it,
  120. // and the whole call to HasRequiredFields() will return true.
  121. // Therefore, we don't have to check if this type has required fields
  122. // here.
  123. return false;
  124. }
  125. already_seen->insert(type);
  126. // If the type has extensions, an extension with message type could contain
  127. // required fields, so we have to be conservative and assume such an
  128. // extension exists.
  129. if (type->extension_range_count() > 0) return true;
  130. for (int i = 0; i < type->field_count(); i++) {
  131. const FieldDescriptor* field = type->field(i);
  132. if (field->is_required()) {
  133. return true;
  134. }
  135. if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
  136. if (HasRequiredFields(field->message_type(), already_seen)) {
  137. return true;
  138. }
  139. }
  140. }
  141. return false;
  142. }
  143. static bool HasRequiredFields(const Descriptor* type) {
  144. hash_set<const Descriptor*> already_seen;
  145. return HasRequiredFields(type, &already_seen);
  146. }
  147. } // namespace
  148. // ===================================================================
  149. MessageGenerator::MessageGenerator(const Descriptor* descriptor)
  150. : descriptor_(descriptor),
  151. field_generators_(descriptor) {
  152. }
  153. MessageGenerator::~MessageGenerator() {}
  154. void MessageGenerator::GenerateStaticVariables(io::Printer* printer) {
  155. // Because descriptor.proto (com.google.protobuf.DescriptorProtos) is
  156. // used in the construction of descriptors, we have a tricky bootstrapping
  157. // problem. To help control static initialization order, we make sure all
  158. // descriptors and other static data that depends on them are members of
  159. // the outermost class in the file. This way, they will be initialized in
  160. // a deterministic order.
  161. map<string, string> vars;
  162. vars["identifier"] = UniqueFileScopeIdentifier(descriptor_);
  163. vars["index"] = SimpleItoa(descriptor_->index());
  164. vars["classname"] = ClassName(descriptor_);
  165. if (descriptor_->containing_type() != NULL) {
  166. vars["parent"] = UniqueFileScopeIdentifier(descriptor_->containing_type());
  167. }
  168. if (descriptor_->file()->options().java_multiple_files()) {
  169. // We can only make these package-private since the classes that use them
  170. // are in separate files.
  171. vars["private"] = "";
  172. } else {
  173. vars["private"] = "private ";
  174. }
  175. // The descriptor for this type.
  176. if (descriptor_->containing_type() == NULL) {
  177. printer->Print(vars,
  178. "$private$static final internal_$identifier$_descriptor:com.google.protobuf.Descriptors.Descriptor =\n"
  179. " getDescriptor().getMessageTypes().get($index$);\n");
  180. } else {
  181. printer->Print(vars,
  182. "$private$static final internal_$identifier$_descriptor:com.google.protobuf.Descriptors.Descriptor =\n"
  183. " internal_$parent$_descriptor.getNestedTypes().get($index$);\n");
  184. }
  185. // And the FieldAccessorTable.
  186. printer->Print(vars,
  187. "$private$static\n"
  188. " internal_$identifier$_fieldAccessorTable:com.google.protobuf.GeneratedMessage.FieldAccessorTable = new\n"
  189. " com.google.protobuf.GeneratedMessage.FieldAccessorTable(\n"
  190. " internal_$identifier$_descriptor,\n"
  191. " new String[] { ");
  192. for (int i = 0; i < descriptor_->field_count(); i++) {
  193. printer->Print(
  194. "\"$field_name$\", ",
  195. "field_name",
  196. UnderscoresToCapitalizedCamelCase(descriptor_->field(i)));
  197. }
  198. printer->Print("},\n"
  199. " $classname$.class,\n"
  200. " $classname$.Builder.class);\n",
  201. "classname", ClassName(descriptor_));
  202. // Generate static members for all nested types.
  203. for (int i = 0; i < descriptor_->nested_type_count(); i++) {
  204. // TODO(kenton): Reuse MessageGenerator objects?
  205. MessageGenerator(descriptor_->nested_type(i))
  206. .GenerateStaticVariables(printer);
  207. }
  208. }
  209. void MessageGenerator::Generate(io::Printer* printer) {
  210. bool is_own_file =
  211. descriptor_->containing_type() == NULL &&
  212. descriptor_->file()->options().java_multiple_files();
  213. printer->Print("import com.google.protobuf.*;\n");
  214. printer->Print("import flash.utils.*;\n");
  215. printer->Print("import com.hurlant.math.BigInteger;\n");
  216. for (int i = 0; i < descriptor_->field_count(); i++) {
  217. if (descriptor_->field(i)->type() == FieldDescriptor::TYPE_MESSAGE) {
  218. string p = descriptor_->field(i)->message_type()->file()->options().java_package();
  219. if(!p.empty()) {
  220. p = p.append(".");
  221. }
  222. printer->Print("import $package$$messagetype$;\n"
  223. ,"package", p
  224. ,"messagetype", descriptor_->field(i)->message_type()->name());
  225. }
  226. }
  227. printer->Print("public final class $classname$ extends Message {\n",
  228. "classname", descriptor_->name());
  229. printer->Indent();
  230. printer->Print("public function $classname$() {\n",
  231. "classname", descriptor_->name());
  232. printer->Indent();
  233. for (int i = 0; i < descriptor_->field_count(); i++) {
  234. printer->Print("registerField(\"$name$\",", "name", UnderscoresToCamelCase(descriptor_->field(i)));
  235. if (descriptor_->field(i)->type() == FieldDescriptor::TYPE_MESSAGE) {
  236. string p = descriptor_->field(i)->message_type()->file()->options().java_package();
  237. if(!p.empty()) {
  238. p = p.append(".");
  239. }
  240. printer->Print("\"$package$$messagetype$\","
  241. ,"package",p
  242. ,"messagetype", descriptor_->field(i)->message_type()->name());
  243. } else {
  244. printer->Print("\"\",");
  245. }
  246. printer->Print("Descriptor.$type$,", "type", AllCapsTypeName(descriptor_->field(i)->type()));
  247. printer->Print("Descriptor.$label$,", "label", LabelName(descriptor_->field(i)->label()));
  248. printer->Print("$fieldNum$);", "fieldNum", SimpleItoa(descriptor_->field(i)->number()));
  249. printer->Print("\n");
  250. }
  251. printer->Outdent();
  252. printer->Print("}\n");
  253. // printer->Print(
  254. // "\n"
  255. //"private static final var defaultInstance:$classname$ = new $classname$();\n"
  256. //"public static function getDefaultInstance():$classname$ {\n"
  257. // " return defaultInstance;\n"
  258. // "}\n"
  259. // "\n"
  260. //"public function getDefaultInstanceForType():$classname$ {\n"
  261. // " return defaultInstance;\n"
  262. // "}\n"
  263. // "\n",
  264. // "classname", descriptor_->name());
  265. //printer->Print(
  266. //"public static final function getDescriptor():com.google.protobuf.Descriptors.Descriptor {\n"
  267. // " return $fileclass$.internal_$identifier$_descriptor;\n"
  268. // "}\n"
  269. // "\n"
  270. //"protected function internalGetFieldAccessorTable():com.google.protobuf.GeneratedMessage.FieldAccessorTable {\n"
  271. // " return $fileclass$.internal_$identifier$_fieldAccessorTable;\n"
  272. // "}\n"
  273. // "\n",
  274. // "fileclass", ClassName(descriptor_->file()),
  275. // "identifier", UniqueFileScopeIdentifier(descriptor_));
  276. // Nested types and extensions
  277. //for (int i = 0; i < descriptor_->enum_type_count(); i++) {
  278. // EnumGenerator(descriptor_->enum_type(i)).Generate(printer);
  279. //}
  280. //for (int i = 0; i < descriptor_->nested_type_count(); i++) {
  281. // MessageGenerator(descriptor_->nested_type(i)).Generate(printer);
  282. //}
  283. //for (int i = 0; i < descriptor_->extension_count(); i++) {
  284. // ExtensionGenerator(descriptor_->extension(i)).Generate(printer);
  285. //}
  286. // Fields
  287. for (int i = 0; i < descriptor_->field_count(); i++) {
  288. PrintFieldComment(printer, descriptor_->field(i));
  289. field_generators_.get(descriptor_->field(i)).GenerateMembers(printer);
  290. printer->Print("\n");
  291. }
  292. //not supported for now - [Philippe Pascal (Sorrydevil) Oct15th 2009 - protobuf-actionscript3 project]
  293. //if (descriptor_->file()->options().optimize_for() == FileOptions::SPEED) {
  294. // GenerateIsInitialized(printer);
  295. // GenerateMessageSerializationMethods(printer);
  296. // }
  297. //not supported for now -- EOB
  298. //GenerateParseFromMethods(printer);
  299. //GenerateBuilder(printer);
  300. printer->Outdent();
  301. printer->Print("\n}");
  302. }
  303. // ===================================================================
  304. void MessageGenerator::
  305. GenerateMessageSerializationMethods(io::Printer* printer) {
  306. scoped_array<const FieldDescriptor*> sorted_fields(
  307. SortFieldsByNumber(descriptor_));
  308. vector<const Descriptor::ExtensionRange*> sorted_extensions;
  309. for (int i = 0; i < descriptor_->extension_range_count(); ++i) {
  310. sorted_extensions.push_back(descriptor_->extension_range(i));
  311. }
  312. sort(sorted_extensions.begin(), sorted_extensions.end(),
  313. ExtensionRangeOrdering());
  314. printer->Print(
  315. "public function writeTo(output:com.google.protobuf.CodedOutputStream) : void\n"
  316. "{\n");
  317. printer->Indent();
  318. if (descriptor_->extension_range_count() > 0) {
  319. printer->Print(
  320. "com.google.protobuf.GeneratedMessage.ExtendableMessage"
  321. ".ExtensionWriter extensionWriter = new ExtensionWriter();\n");
  322. }
  323. // Merge the fields and the extension ranges, both sorted by field number.
  324. for (int i = 0, j = 0;
  325. i < descriptor_->field_count() || j < sorted_extensions.size();
  326. ) {
  327. if (i == descriptor_->field_count()) {
  328. GenerateSerializeOneExtensionRange(printer, sorted_extensions[j++]);
  329. } else if (j == sorted_extensions.size()) {
  330. GenerateSerializeOneField(printer, sorted_fields[i++]);
  331. } else if (sorted_fields[i]->number() < sorted_extensions[j]->start) {
  332. GenerateSerializeOneField(printer, sorted_fields[i++]);
  333. } else {
  334. GenerateSerializeOneExtensionRange(printer, sorted_extensions[j++]);
  335. }
  336. }
  337. if (descriptor_->options().message_set_wire_format()) {
  338. printer->Print(
  339. "getUnknownFields().writeAsMessageSetTo(output);\n");
  340. } else {
  341. printer->Print(
  342. "getUnknownFields().writeTo(output);\n");
  343. }
  344. printer->Outdent();
  345. printer->Print(
  346. "}\n"
  347. "\n"
  348. "private memoizedSerializedSize:int = -1;\n"
  349. "public getSerializedSize():int {\n"
  350. " var size:int = memoizedSerializedSize;\n"
  351. " if (size != -1) return size;\n"
  352. "\n"
  353. " size = 0;\n");
  354. printer->Indent();
  355. for (int i = 0; i < descriptor_->field_count(); i++) {
  356. field_generators_.get(sorted_fields[i]).GenerateSerializedSizeCode(printer);
  357. }
  358. if (descriptor_->extension_range_count() > 0) {
  359. printer->Print(
  360. "size += extensionsSerializedSize();\n");
  361. }
  362. if (descriptor_->options().message_set_wire_format()) {
  363. printer->Print(
  364. "size += getUnknownFields().getSerializedSizeAsMessageSet();\n");
  365. } else {
  366. printer->Print(
  367. "size += getUnknownFields().getSerializedSize();\n");
  368. }
  369. printer->Outdent();
  370. printer->Print(
  371. " memoizedSerializedSize = size;\n"
  372. " return size;\n"
  373. "}\n"
  374. "\n");
  375. }
  376. void MessageGenerator::
  377. GenerateParseFromMethods(io::Printer* printer) {
  378. // Note: These are separate from GenerateMessageSerializationMethods()
  379. // because they need to be generated even for messages that are optimized
  380. // for code size.
  381. // printer->Print(
  382. // "/*\n"
  383. //"public static function parseFrom(\n"
  384. //" data:ByteArray):$classname$ \n"
  385. // "{\n"
  386. // " return mergeFrom(data).buildParsed();\n"
  387. // "}\n"
  388. // "public static function parseFrom(\n"
  389. // " data:ByteArray,\n"
  390. //" extensionRegistry:com.google.protobuf.ExtensionRegistry ):$classname$ \n"
  391. // "{\n"
  392. // " return mergeFrom(data, extensionRegistry)\n"
  393. // " .buildParsed();\n"
  394. // "}\n"
  395. //"public static function parseFrom(input:InputStream):$classname$ \n"
  396. // "{\n"
  397. // " return mergeFrom(input).buildParsed();\n"
  398. // "}\n"
  399. // "public static function parseFrom(\n"
  400. //" input:IDataInput,\n"
  401. //" extensionRegistry:com.google.protobuf.ExtensionRegistry):$classname$ \n"
  402. // "{\n"
  403. // " return newBuilder().mergeFrom(input, extensionRegistry)\n"
  404. // " .buildParsed();\n"
  405. // "}\n"
  406. // "public static function parseFrom(\n"
  407. //" input:com.google.protobuf.CodedInputStream):$classname$\n"
  408. // "{\n"
  409. // " return newBuilder().mergeFrom(input).buildParsed();\n"
  410. // "}\n"
  411. //"public static function parseFrom(\n"
  412. //" input:com.google.protobuf.CodedInputStream,\n"
  413. // " extensionRegistry:com.google.protobuf.ExtensionRegistry):$classname$\n"
  414. // "{\n"
  415. // " return newBuilder().mergeFrom(input, extensionRegistry)\n"
  416. // " .buildParsed();\n"
  417. // "}\n"
  418. // "\n */",
  419. // "classname", descriptor_->name());
  420. }
  421. void MessageGenerator::GenerateSerializeOneField(
  422. io::Printer* printer, const FieldDescriptor* field) {
  423. field_generators_.get(field).GenerateSerializationCode(printer);
  424. }
  425. void MessageGenerator::GenerateSerializeOneExtensionRange(
  426. io::Printer* printer, const Descriptor::ExtensionRange* range) {
  427. printer->Print(
  428. "extensionWriter.writeUntil($end$, output);\n",
  429. "end", SimpleItoa(range->end));
  430. }
  431. // ===================================================================
  432. void MessageGenerator::GenerateBuilder(io::Printer* printer) {
  433. GenerateCommonBuilderMethods(printer);
  434. if (descriptor_->file()->options().optimize_for() == FileOptions::SPEED) {
  435. GenerateBuilderParsingMethods(printer);
  436. }
  437. for (int i = 0; i < descriptor_->field_count(); i++) {
  438. printer->Print("\n");
  439. PrintFieldComment(printer, descriptor_->field(i));
  440. field_generators_.get(descriptor_->field(i))
  441. .GenerateBuilderMembers(printer);
  442. }
  443. printer->Outdent();
  444. printer->Print("}\n\n");
  445. }
  446. // ===================================================================
  447. void MessageGenerator::GenerateCommonBuilderMethods(io::Printer* printer) {
  448. printer->Print(
  449. "\n\n"
  450. //"private var result:Object = {};\n"
  451. //"\n"
  452. //"protected function internalGetResult():Object {\n"
  453. //" return result;\n"
  454. //"}\n"
  455. //"\n"
  456. //"public function clear():$classname$ {\n"
  457. //" result = {};\n"
  458. //" return this;\n"
  459. //"}\n"
  460. //"\n"
  461. //"public function clone():$classname$ {\n"
  462. //" return new Builder().mergeFrom(result);\n"
  463. //"}\n"
  464. //"\n"
  465. "public function getDescriptors():Array {\n"
  466. " return fieldDescriptors;\n"
  467. "}\n"
  468. "\n"
  469. "public static function getDefaultInstance():$classname$ {\n"
  470. " return new $classname$();\n"
  471. "}\n"
  472. "\n",
  473. "classname", descriptor_->name());
  474. // -----------------------------------------------------------------
  475. // printer->Print(
  476. // "public function build():Object {\n"
  477. // " if (!isInitialized()) {\n"
  478. // " throw new com.google.protobuf.UninitializedMessageException(\n"
  479. // " result);\n"
  480. // " }\n"
  481. // " return buildPartial();\n"
  482. // "}\n"
  483. // "\n"
  484. //"private function buildParsed():Object\n"
  485. // "{\n"
  486. // " if (!isInitialized()) {\n"
  487. // " throw new com.google.protobuf.UninitializedMessageException(\n"
  488. // " result).asInvalidProtocolBufferException();\n"
  489. // " }\n"
  490. // " return buildPartial();\n"
  491. // "}\n"
  492. //"\n"
  493. //"private function buildPartial():Object\n"
  494. // "{\n"
  495. // " if (!isInitialized()) {\n"
  496. // " throw new com.google.protobuf.UninitializedMessageException(\n"
  497. // " result).asInvalidProtocolBufferException();\n"
  498. // " }\n"
  499. // " return result;\n"
  500. // "}\n"
  501. //"public function buildPartial():$classname$ {\n",
  502. // "classname", ClassName(descriptor_));
  503. //printer->Indent();
  504. //for (int i = 0; i < descriptor_->field_count(); i++) {
  505. // field_generators_.get(descriptor_->field(i)).GenerateBuildingCode(printer);
  506. //}
  507. //printer->Outdent();
  508. //printer->Print(
  509. // " var returnMe:$classname$ = result;\n"
  510. // " result = null;\n"
  511. // " return returnMe;\n"
  512. // "}\n"
  513. // "\n",
  514. // "classname", ClassName(descriptor_));
  515. // -----------------------------------------------------------------
  516. // if (descriptor_->file()->options().optimize_for() == FileOptions::SPEED) {
  517. // printer->Print(
  518. // "public function mergeFrom(com.google.protobuf.Message other):Builder {\n"
  519. // " if (other instanceof $classname$) {\n"
  520. // " return mergeFrom(($classname$)other);\n"
  521. // " } else {\n"
  522. // " super.mergeFrom(other);\n"
  523. // " return this;\n"
  524. // " }\n"
  525. // "}\n"
  526. // "\n"
  527. // "public function mergeFrom($classname$ other):Builder {\n"
  528. // // Optimization: If other is the default instance, we know none of its
  529. // // fields are set so we can skip the merge.
  530. // " if (other == $classname$.getDefaultInstance()) return this;\n",
  531. // "classname", ClassName(descriptor_));
  532. // printer->Indent();
  533. // for (int i = 0; i < descriptor_->field_count(); i++) {
  534. // field_generators_.get(descriptor_->field(i)).GenerateMergingCode(printer);
  535. //}
  536. // printer->Outdent();
  537. // printer->Print(
  538. // " this.mergeUnknownFields(other.getUnknownFields());\n"
  539. // " return this;\n"
  540. // "}\n"
  541. // "\n");
  542. // }
  543. }
  544. // ===================================================================
  545. void MessageGenerator::GenerateBuilderParsingMethods(io::Printer* printer) {
  546. scoped_array<const FieldDescriptor*> sorted_fields(
  547. SortFieldsByNumber(descriptor_));
  548. printer->Print(
  549. "public function mergeFrom(\n"
  550. " com.google.protobuf.CodedInputStream input):Builder\n"
  551. "{\n"
  552. " return mergeFrom(input,\n"
  553. " com.google.protobuf.ExtensionRegistry.getEmptyRegistry());\n"
  554. "}\n"
  555. "\n"
  556. "public function mergeFrom(\n"
  557. " com.google.protobuf.CodedInputStream input,\n"
  558. " extensionRegistry:com.google.protobuf.ExtensionRegistry ):Builder\n"
  559. "{\n");
  560. printer->Indent();
  561. printer->Print(
  562. "com.google.protobuf.UnknownFieldSet.Builder unknownFields =\n"
  563. " com.google.protobuf.UnknownFieldSet.newBuilder(\n"
  564. " this.getUnknownFields());\n"
  565. "while (true) {\n");
  566. printer->Indent();
  567. printer->Print(
  568. "int tag = input.readTag();\n"
  569. "switch (tag) {\n");
  570. printer->Indent();
  571. printer->Print(
  572. "case 0:\n" // zero signals EOF / limit reached
  573. " this.setUnknownFields(unknownFields.build());\n"
  574. " return this;\n"
  575. "default: {\n"
  576. " if (!parseUnknownField(input, unknownFields,\n"
  577. " extensionRegistry, tag)) {\n"
  578. " this.setUnknownFields(unknownFields.build());\n"
  579. " return this;\n" // it's an endgroup tag
  580. " }\n"
  581. " break;\n"
  582. "}\n");
  583. for (int i = 0; i < descriptor_->field_count(); i++) {
  584. const FieldDescriptor* field = sorted_fields[i];
  585. uint32 tag = WireFormat::MakeTag(field);
  586. printer->Print(
  587. "case $tag$: {\n",
  588. "tag", SimpleItoa(tag));
  589. printer->Indent();
  590. field_generators_.get(field).GenerateParsingCode(printer);
  591. printer->Outdent();
  592. printer->Print(
  593. " break;\n"
  594. "}\n");
  595. }
  596. printer->Outdent();
  597. printer->Outdent();
  598. printer->Outdent();
  599. printer->Print(
  600. " }\n" // switch (tag)
  601. " }\n" // while (true)
  602. "}\n"
  603. "\n");
  604. }
  605. // ===================================================================
  606. void MessageGenerator::GenerateIsInitialized(io::Printer* printer) {
  607. printer->Print(
  608. "public final function isInitialized():Boolean {\n");
  609. printer->Indent();
  610. // Check that all required fields in this message are set.
  611. // TODO(kenton): We can optimize this when we switch to putting all the
  612. // "has" fields into a single bitfield.
  613. for (int i = 0; i < descriptor_->field_count(); i++) {
  614. const FieldDescriptor* field = descriptor_->field(i);
  615. if (field->is_required()) {
  616. printer->Print(
  617. "if (!has$name$) return false;\n",
  618. "name", UnderscoresToCapitalizedCamelCase(field));
  619. }
  620. }
  621. // Now check that all embedded messages are initialized.
  622. for (int i = 0; i < descriptor_->field_count(); i++) {
  623. const FieldDescriptor* field = descriptor_->field(i);
  624. if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
  625. HasRequiredFields(field->message_type())) {
  626. switch (field->label()) {
  627. case FieldDescriptor::LABEL_REQUIRED:
  628. printer->Print(
  629. "if (!get$name$().isInitialized()) return false;\n",
  630. "type", ClassName(field->message_type()),
  631. "name", UnderscoresToCapitalizedCamelCase(field));
  632. break;
  633. case FieldDescriptor::LABEL_OPTIONAL:
  634. printer->Print(
  635. "if (has$name$()) {\n"
  636. " if (!get$name$().isInitialized()) return false;\n"
  637. "}\n",
  638. "type", ClassName(field->message_type()),
  639. "name", UnderscoresToCapitalizedCamelCase(field));
  640. break;
  641. case FieldDescriptor::LABEL_REPEATED:
  642. printer->Print(
  643. "for (var element:$type$ in get$name$List()) {\n"
  644. " if (!element.isInitialized()) return false;\n"
  645. "}\n",
  646. "type", ClassName(field->message_type()),
  647. "name", UnderscoresToCapitalizedCamelCase(field));
  648. break;
  649. }
  650. }
  651. }
  652. if (descriptor_->extension_range_count() > 0) {
  653. printer->Print(
  654. "if (!extensionsAreInitialized()) return false;\n");
  655. }
  656. printer->Outdent();
  657. printer->Print(
  658. " return true;\n"
  659. "}\n"
  660. "\n");
  661. }
  662. } // namespace as3
  663. } // namespace compiler
  664. } // namespace protobuf
  665. } // namespace google