PageRenderTime 27ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/src/cpp/cpp_primitive_field.cc

http://protoc-gen-luabind.googlecode.com/
C++ | 382 lines | 298 code | 43 blank | 41 comment | 21 complexity | eda23d09d4c93143a9c88fe1ffa04669 MD5 | raw file
  1. // Protocol Buffers - Google's data interchange format
  2. // Copyright 2008 Google Inc. All rights reserved.
  3. // http://code.google.com/p/protobuf/
  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. // Author: kenton@google.com (Kenton Varda)
  31. // Based on original Protocol Buffers design by
  32. // Sanjay Ghemawat, Jeff Dean, and others.
  33. #include "cpp/cpp_primitive_field.h"
  34. #include "cpp/cpp_helpers.h"
  35. #include <google/protobuf/io/printer.h>
  36. #include <google/protobuf/wire_format.h>
  37. #include <google/protobuf/stubs/strutil.h>
  38. namespace google {
  39. namespace protobuf {
  40. namespace compiler {
  41. namespace cpp {
  42. using internal::WireFormatLite;
  43. namespace {
  44. // For encodings with fixed sizes, returns that size in bytes. Otherwise
  45. // returns -1.
  46. int FixedSize(FieldDescriptor::Type type) {
  47. switch (type) {
  48. case FieldDescriptor::TYPE_INT32 : return -1;
  49. case FieldDescriptor::TYPE_INT64 : return -1;
  50. case FieldDescriptor::TYPE_UINT32 : return -1;
  51. case FieldDescriptor::TYPE_UINT64 : return -1;
  52. case FieldDescriptor::TYPE_SINT32 : return -1;
  53. case FieldDescriptor::TYPE_SINT64 : return -1;
  54. case FieldDescriptor::TYPE_FIXED32 : return WireFormatLite::kFixed32Size;
  55. case FieldDescriptor::TYPE_FIXED64 : return WireFormatLite::kFixed64Size;
  56. case FieldDescriptor::TYPE_SFIXED32: return WireFormatLite::kSFixed32Size;
  57. case FieldDescriptor::TYPE_SFIXED64: return WireFormatLite::kSFixed64Size;
  58. case FieldDescriptor::TYPE_FLOAT : return WireFormatLite::kFloatSize;
  59. case FieldDescriptor::TYPE_DOUBLE : return WireFormatLite::kDoubleSize;
  60. case FieldDescriptor::TYPE_BOOL : return WireFormatLite::kBoolSize;
  61. case FieldDescriptor::TYPE_ENUM : return -1;
  62. case FieldDescriptor::TYPE_STRING : return -1;
  63. case FieldDescriptor::TYPE_BYTES : return -1;
  64. case FieldDescriptor::TYPE_GROUP : return -1;
  65. case FieldDescriptor::TYPE_MESSAGE : return -1;
  66. // No default because we want the compiler to complain if any new
  67. // types are added.
  68. }
  69. GOOGLE_LOG(FATAL) << "Can't get here.";
  70. return -1;
  71. }
  72. void SetPrimitiveVariables(const FieldDescriptor* descriptor,
  73. map<string, string>* variables) {
  74. SetCommonFieldVariables(descriptor, variables);
  75. (*variables)["type"] = PrimitiveTypeName(descriptor->cpp_type());
  76. (*variables)["default"] = DefaultValue(descriptor);
  77. (*variables)["tag"] = SimpleItoa(internal::WireFormat::MakeTag(descriptor));
  78. int fixed_size = FixedSize(descriptor->type());
  79. if (fixed_size != -1) {
  80. (*variables)["fixed_size"] = SimpleItoa(fixed_size);
  81. }
  82. (*variables)["wire_format_field_type"] =
  83. "::google::protobuf::internal::WireFormatLite::" + FieldDescriptorProto_Type_Name(
  84. static_cast<FieldDescriptorProto_Type>(descriptor->type()));
  85. }
  86. } // namespace
  87. // ===================================================================
  88. PrimitiveFieldGenerator::
  89. PrimitiveFieldGenerator(const FieldDescriptor* descriptor)
  90. : descriptor_(descriptor) {
  91. SetPrimitiveVariables(descriptor, &variables_);
  92. }
  93. PrimitiveFieldGenerator::~PrimitiveFieldGenerator() {}
  94. void PrimitiveFieldGenerator::
  95. GeneratePrivateMembers(io::Printer* printer) const {
  96. printer->Print(variables_, "$type$ $name$_;\n");
  97. }
  98. void PrimitiveFieldGenerator::
  99. GenerateAccessorDeclarations(io::Printer* printer) const {
  100. printer->Print(variables_,
  101. "inline $type$ $name$() const$deprecation$;\n"
  102. "inline void set_$name$($type$ value)$deprecation$;\n");
  103. }
  104. void PrimitiveFieldGenerator::
  105. GenerateInlineAccessorDefinitions(io::Printer* printer) const {
  106. printer->Print(variables_,
  107. "inline $type$ $classname$::$name$() const {\n"
  108. " return $name$_;\n"
  109. "}\n"
  110. "inline void $classname$::set_$name$($type$ value) {\n"
  111. " set_has_$name$();\n"
  112. " $name$_ = value;\n"
  113. "}\n");
  114. }
  115. void PrimitiveFieldGenerator::
  116. GenerateClearingCode(io::Printer* printer) const {
  117. printer->Print(variables_, "$name$_ = $default$;\n");
  118. }
  119. void PrimitiveFieldGenerator::
  120. GenerateMergingCode(io::Printer* printer) const {
  121. printer->Print(variables_, "set_$name$(from.$name$());\n");
  122. }
  123. void PrimitiveFieldGenerator::
  124. GenerateSwappingCode(io::Printer* printer) const {
  125. printer->Print(variables_, "std::swap($name$_, other->$name$_);\n");
  126. }
  127. void PrimitiveFieldGenerator::
  128. GenerateConstructorCode(io::Printer* printer) const {
  129. printer->Print(variables_, "$name$_ = $default$;\n");
  130. }
  131. void PrimitiveFieldGenerator::
  132. GenerateMergeFromCodedStream(io::Printer* printer) const {
  133. printer->Print(variables_,
  134. "DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n"
  135. " $type$, $wire_format_field_type$>(\n"
  136. " input, &$name$_)));\n"
  137. "set_has_$name$();\n");
  138. }
  139. void PrimitiveFieldGenerator::
  140. GenerateSerializeWithCachedSizes(io::Printer* printer) const {
  141. printer->Print(variables_,
  142. "::google::protobuf::internal::WireFormatLite::Write$declared_type$("
  143. "$number$, this->$name$(), output);\n");
  144. }
  145. void PrimitiveFieldGenerator::
  146. GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
  147. printer->Print(variables_,
  148. "target = ::google::protobuf::internal::WireFormatLite::Write$declared_type$ToArray("
  149. "$number$, this->$name$(), target);\n");
  150. }
  151. void PrimitiveFieldGenerator::
  152. GenerateByteSize(io::Printer* printer) const {
  153. int fixed_size = FixedSize(descriptor_->type());
  154. if (fixed_size == -1) {
  155. printer->Print(variables_,
  156. "total_size += $tag_size$ +\n"
  157. " ::google::protobuf::internal::WireFormatLite::$declared_type$Size(\n"
  158. " this->$name$());\n");
  159. } else {
  160. printer->Print(variables_,
  161. "total_size += $tag_size$ + $fixed_size$;\n");
  162. }
  163. }
  164. // ===================================================================
  165. RepeatedPrimitiveFieldGenerator::
  166. RepeatedPrimitiveFieldGenerator(const FieldDescriptor* descriptor)
  167. : descriptor_(descriptor) {
  168. SetPrimitiveVariables(descriptor, &variables_);
  169. if (descriptor->options().packed()) {
  170. variables_["packed_reader"] = "ReadPackedPrimitive";
  171. variables_["repeated_reader"] = "ReadRepeatedPrimitiveNoInline";
  172. } else {
  173. variables_["packed_reader"] = "ReadPackedPrimitiveNoInline";
  174. variables_["repeated_reader"] = "ReadRepeatedPrimitive";
  175. }
  176. }
  177. RepeatedPrimitiveFieldGenerator::~RepeatedPrimitiveFieldGenerator() {}
  178. void RepeatedPrimitiveFieldGenerator::
  179. GeneratePrivateMembers(io::Printer* printer) const {
  180. printer->Print(variables_,
  181. "::google::protobuf::RepeatedField< $type$ > $name$_;\n");
  182. if (descriptor_->options().packed() && HasGeneratedMethods(descriptor_->file())) {
  183. printer->Print(variables_,
  184. "mutable int _$name$_cached_byte_size_;\n");
  185. }
  186. }
  187. void RepeatedPrimitiveFieldGenerator::
  188. GenerateAccessorDeclarations(io::Printer* printer) const {
  189. printer->Print(variables_,
  190. "inline $type$ $name$(int index) const$deprecation$;\n"
  191. "inline void set_$name$(int index, $type$ value)$deprecation$;\n"
  192. "inline void add_$name$($type$ value)$deprecation$;\n");
  193. printer->Print(variables_,
  194. "inline const ::google::protobuf::RepeatedField< $type$ >&\n"
  195. " $name$() const$deprecation$;\n"
  196. "inline ::google::protobuf::RepeatedField< $type$ >*\n"
  197. " mutable_$name$()$deprecation$;\n");
  198. }
  199. void RepeatedPrimitiveFieldGenerator::
  200. GenerateInlineAccessorDefinitions(io::Printer* printer) const {
  201. printer->Print(variables_,
  202. "inline $type$ $classname$::$name$(int index) const {\n"
  203. " return $name$_.Get(index);\n"
  204. "}\n"
  205. "inline void $classname$::set_$name$(int index, $type$ value) {\n"
  206. " $name$_.Set(index, value);\n"
  207. "}\n"
  208. "inline void $classname$::add_$name$($type$ value) {\n"
  209. " $name$_.Add(value);\n"
  210. "}\n");
  211. printer->Print(variables_,
  212. "inline const ::google::protobuf::RepeatedField< $type$ >&\n"
  213. "$classname$::$name$() const {\n"
  214. " return $name$_;\n"
  215. "}\n"
  216. "inline ::google::protobuf::RepeatedField< $type$ >*\n"
  217. "$classname$::mutable_$name$() {\n"
  218. " return &$name$_;\n"
  219. "}\n");
  220. }
  221. void RepeatedPrimitiveFieldGenerator::
  222. GenerateClearingCode(io::Printer* printer) const {
  223. printer->Print(variables_, "$name$_.Clear();\n");
  224. }
  225. void RepeatedPrimitiveFieldGenerator::
  226. GenerateMergingCode(io::Printer* printer) const {
  227. printer->Print(variables_, "$name$_.MergeFrom(from.$name$_);\n");
  228. }
  229. void RepeatedPrimitiveFieldGenerator::
  230. GenerateSwappingCode(io::Printer* printer) const {
  231. printer->Print(variables_, "$name$_.Swap(&other->$name$_);\n");
  232. }
  233. void RepeatedPrimitiveFieldGenerator::
  234. GenerateConstructorCode(io::Printer* printer) const {
  235. // Not needed for repeated fields.
  236. }
  237. void RepeatedPrimitiveFieldGenerator::
  238. GenerateMergeFromCodedStream(io::Printer* printer) const {
  239. printer->Print(variables_,
  240. "DO_((::google::protobuf::internal::WireFormatLite::$repeated_reader$<\n"
  241. " $type$, $wire_format_field_type$>(\n"
  242. " $tag_size$, $tag$, input, this->mutable_$name$())));\n");
  243. }
  244. void RepeatedPrimitiveFieldGenerator::
  245. GenerateMergeFromCodedStreamWithPacking(io::Printer* printer) const {
  246. printer->Print(variables_,
  247. "DO_((::google::protobuf::internal::WireFormatLite::$packed_reader$<\n"
  248. " $type$, $wire_format_field_type$>(\n"
  249. " input, this->mutable_$name$())));\n");
  250. }
  251. void RepeatedPrimitiveFieldGenerator::
  252. GenerateSerializeWithCachedSizes(io::Printer* printer) const {
  253. if (descriptor_->options().packed()) {
  254. // Write the tag and the size.
  255. printer->Print(variables_,
  256. "if (this->$name$_size() > 0) {\n"
  257. " ::google::protobuf::internal::WireFormatLite::WriteTag("
  258. "$number$, "
  259. "::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, "
  260. "output);\n"
  261. " output->WriteVarint32(_$name$_cached_byte_size_);\n"
  262. "}\n");
  263. }
  264. printer->Print(variables_,
  265. "for (int i = 0; i < this->$name$_size(); i++) {\n");
  266. if (descriptor_->options().packed()) {
  267. printer->Print(variables_,
  268. " ::google::protobuf::internal::WireFormatLite::Write$declared_type$NoTag(\n"
  269. " this->$name$(i), output);\n");
  270. } else {
  271. printer->Print(variables_,
  272. " ::google::protobuf::internal::WireFormatLite::Write$declared_type$(\n"
  273. " $number$, this->$name$(i), output);\n");
  274. }
  275. printer->Print("}\n");
  276. }
  277. void RepeatedPrimitiveFieldGenerator::
  278. GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
  279. if (descriptor_->options().packed()) {
  280. // Write the tag and the size.
  281. printer->Print(variables_,
  282. "if (this->$name$_size() > 0) {\n"
  283. " target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(\n"
  284. " $number$,\n"
  285. " ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,\n"
  286. " target);\n"
  287. " target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(\n"
  288. " _$name$_cached_byte_size_, target);\n"
  289. "}\n");
  290. }
  291. printer->Print(variables_,
  292. "for (int i = 0; i < this->$name$_size(); i++) {\n");
  293. if (descriptor_->options().packed()) {
  294. printer->Print(variables_,
  295. " target = ::google::protobuf::internal::WireFormatLite::\n"
  296. " Write$declared_type$NoTagToArray(this->$name$(i), target);\n");
  297. } else {
  298. printer->Print(variables_,
  299. " target = ::google::protobuf::internal::WireFormatLite::\n"
  300. " Write$declared_type$ToArray($number$, this->$name$(i), target);\n");
  301. }
  302. printer->Print("}\n");
  303. }
  304. void RepeatedPrimitiveFieldGenerator::
  305. GenerateByteSize(io::Printer* printer) const {
  306. printer->Print(variables_,
  307. "{\n"
  308. " int data_size = 0;\n");
  309. printer->Indent();
  310. int fixed_size = FixedSize(descriptor_->type());
  311. if (fixed_size == -1) {
  312. printer->Print(variables_,
  313. "for (int i = 0; i < this->$name$_size(); i++) {\n"
  314. " data_size += ::google::protobuf::internal::WireFormatLite::\n"
  315. " $declared_type$Size(this->$name$(i));\n"
  316. "}\n");
  317. } else {
  318. printer->Print(variables_,
  319. "data_size = $fixed_size$ * this->$name$_size();\n");
  320. }
  321. if (descriptor_->options().packed()) {
  322. printer->Print(variables_,
  323. "if (data_size > 0) {\n"
  324. " total_size += $tag_size$ +\n"
  325. " ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);\n"
  326. "}\n"
  327. "_$name$_cached_byte_size_ = data_size;\n"
  328. "total_size += data_size;\n");
  329. } else {
  330. printer->Print(variables_,
  331. "total_size += $tag_size$ * this->$name$_size() + data_size;\n");
  332. }
  333. printer->Outdent();
  334. printer->Print("}\n");
  335. }
  336. } // namespace cpp
  337. } // namespace compiler
  338. } // namespace protobuf
  339. } // namespace google