/thirdparty/breakpad/third_party/protobuf/protobuf/src/google/protobuf/compiler/cpp/cpp_enum_field.cc

http://github.com/tomahawk-player/tomahawk · C++ · 361 lines · 284 code · 37 blank · 40 comment · 14 complexity · ff00a623405133779496d0ec1468a520 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 <google/protobuf/compiler/cpp/cpp_enum_field.h>
  34. #include <google/protobuf/compiler/cpp/cpp_helpers.h>
  35. #include <google/protobuf/io/printer.h>
  36. #include <google/protobuf/descriptor.pb.h>
  37. #include <google/protobuf/stubs/strutil.h>
  38. namespace google {
  39. namespace protobuf {
  40. namespace compiler {
  41. namespace cpp {
  42. namespace {
  43. void SetEnumVariables(const FieldDescriptor* descriptor,
  44. map<string, string>* variables) {
  45. SetCommonFieldVariables(descriptor, variables);
  46. const EnumValueDescriptor* default_value = descriptor->default_value_enum();
  47. (*variables)["type"] = ClassName(descriptor->enum_type(), true);
  48. (*variables)["default"] = SimpleItoa(default_value->number());
  49. }
  50. } // namespace
  51. // ===================================================================
  52. EnumFieldGenerator::
  53. EnumFieldGenerator(const FieldDescriptor* descriptor)
  54. : descriptor_(descriptor) {
  55. SetEnumVariables(descriptor, &variables_);
  56. }
  57. EnumFieldGenerator::~EnumFieldGenerator() {}
  58. void EnumFieldGenerator::
  59. GeneratePrivateMembers(io::Printer* printer) const {
  60. printer->Print(variables_, "int $name$_;\n");
  61. }
  62. void EnumFieldGenerator::
  63. GenerateAccessorDeclarations(io::Printer* printer) const {
  64. printer->Print(variables_,
  65. "inline $type$ $name$() const$deprecation$;\n"
  66. "inline void set_$name$($type$ value)$deprecation$;\n");
  67. }
  68. void EnumFieldGenerator::
  69. GenerateInlineAccessorDefinitions(io::Printer* printer) const {
  70. printer->Print(variables_,
  71. "inline $type$ $classname$::$name$() const {\n"
  72. " return static_cast< $type$ >($name$_);\n"
  73. "}\n"
  74. "inline void $classname$::set_$name$($type$ value) {\n"
  75. " GOOGLE_DCHECK($type$_IsValid(value));\n"
  76. " set_has_$name$();\n"
  77. " $name$_ = value;\n"
  78. "}\n");
  79. }
  80. void EnumFieldGenerator::
  81. GenerateClearingCode(io::Printer* printer) const {
  82. printer->Print(variables_, "$name$_ = $default$;\n");
  83. }
  84. void EnumFieldGenerator::
  85. GenerateMergingCode(io::Printer* printer) const {
  86. printer->Print(variables_, "set_$name$(from.$name$());\n");
  87. }
  88. void EnumFieldGenerator::
  89. GenerateSwappingCode(io::Printer* printer) const {
  90. printer->Print(variables_, "std::swap($name$_, other->$name$_);\n");
  91. }
  92. void EnumFieldGenerator::
  93. GenerateConstructorCode(io::Printer* printer) const {
  94. printer->Print(variables_, "$name$_ = $default$;\n");
  95. }
  96. void EnumFieldGenerator::
  97. GenerateMergeFromCodedStream(io::Printer* printer) const {
  98. printer->Print(variables_,
  99. "int value;\n"
  100. "DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n"
  101. " int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(\n"
  102. " input, &value)));\n"
  103. "if ($type$_IsValid(value)) {\n"
  104. " set_$name$(static_cast< $type$ >(value));\n");
  105. if (HasUnknownFields(descriptor_->file())) {
  106. printer->Print(variables_,
  107. "} else {\n"
  108. " mutable_unknown_fields()->AddVarint($number$, value);\n");
  109. }
  110. printer->Print(variables_,
  111. "}\n");
  112. }
  113. void EnumFieldGenerator::
  114. GenerateSerializeWithCachedSizes(io::Printer* printer) const {
  115. printer->Print(variables_,
  116. "::google::protobuf::internal::WireFormatLite::WriteEnum(\n"
  117. " $number$, this->$name$(), output);\n");
  118. }
  119. void EnumFieldGenerator::
  120. GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
  121. printer->Print(variables_,
  122. "target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(\n"
  123. " $number$, this->$name$(), target);\n");
  124. }
  125. void EnumFieldGenerator::
  126. GenerateByteSize(io::Printer* printer) const {
  127. printer->Print(variables_,
  128. "total_size += $tag_size$ +\n"
  129. " ::google::protobuf::internal::WireFormatLite::EnumSize(this->$name$());\n");
  130. }
  131. // ===================================================================
  132. RepeatedEnumFieldGenerator::
  133. RepeatedEnumFieldGenerator(const FieldDescriptor* descriptor)
  134. : descriptor_(descriptor) {
  135. SetEnumVariables(descriptor, &variables_);
  136. }
  137. RepeatedEnumFieldGenerator::~RepeatedEnumFieldGenerator() {}
  138. void RepeatedEnumFieldGenerator::
  139. GeneratePrivateMembers(io::Printer* printer) const {
  140. printer->Print(variables_,
  141. "::google::protobuf::RepeatedField<int> $name$_;\n");
  142. if (descriptor_->options().packed() && HasGeneratedMethods(descriptor_->file())) {
  143. printer->Print(variables_,
  144. "mutable int _$name$_cached_byte_size_;\n");
  145. }
  146. }
  147. void RepeatedEnumFieldGenerator::
  148. GenerateAccessorDeclarations(io::Printer* printer) const {
  149. printer->Print(variables_,
  150. "inline $type$ $name$(int index) const$deprecation$;\n"
  151. "inline void set_$name$(int index, $type$ value)$deprecation$;\n"
  152. "inline void add_$name$($type$ value)$deprecation$;\n");
  153. printer->Print(variables_,
  154. "inline const ::google::protobuf::RepeatedField<int>& $name$() const$deprecation$;\n"
  155. "inline ::google::protobuf::RepeatedField<int>* mutable_$name$()$deprecation$;\n");
  156. }
  157. void RepeatedEnumFieldGenerator::
  158. GenerateInlineAccessorDefinitions(io::Printer* printer) const {
  159. printer->Print(variables_,
  160. "inline $type$ $classname$::$name$(int index) const {\n"
  161. " return static_cast< $type$ >($name$_.Get(index));\n"
  162. "}\n"
  163. "inline void $classname$::set_$name$(int index, $type$ value) {\n"
  164. " GOOGLE_DCHECK($type$_IsValid(value));\n"
  165. " $name$_.Set(index, value);\n"
  166. "}\n"
  167. "inline void $classname$::add_$name$($type$ value) {\n"
  168. " GOOGLE_DCHECK($type$_IsValid(value));\n"
  169. " $name$_.Add(value);\n"
  170. "}\n");
  171. printer->Print(variables_,
  172. "inline const ::google::protobuf::RepeatedField<int>&\n"
  173. "$classname$::$name$() const {\n"
  174. " return $name$_;\n"
  175. "}\n"
  176. "inline ::google::protobuf::RepeatedField<int>*\n"
  177. "$classname$::mutable_$name$() {\n"
  178. " return &$name$_;\n"
  179. "}\n");
  180. }
  181. void RepeatedEnumFieldGenerator::
  182. GenerateClearingCode(io::Printer* printer) const {
  183. printer->Print(variables_, "$name$_.Clear();\n");
  184. }
  185. void RepeatedEnumFieldGenerator::
  186. GenerateMergingCode(io::Printer* printer) const {
  187. printer->Print(variables_, "$name$_.MergeFrom(from.$name$_);\n");
  188. }
  189. void RepeatedEnumFieldGenerator::
  190. GenerateSwappingCode(io::Printer* printer) const {
  191. printer->Print(variables_, "$name$_.Swap(&other->$name$_);\n");
  192. }
  193. void RepeatedEnumFieldGenerator::
  194. GenerateConstructorCode(io::Printer* printer) const {
  195. // Not needed for repeated fields.
  196. }
  197. void RepeatedEnumFieldGenerator::
  198. GenerateMergeFromCodedStream(io::Printer* printer) const {
  199. // Don't use ReadRepeatedPrimitive here so that the enum can be validated.
  200. printer->Print(variables_,
  201. "int value;\n"
  202. "DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n"
  203. " int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(\n"
  204. " input, &value)));\n"
  205. "if ($type$_IsValid(value)) {\n"
  206. " add_$name$(static_cast< $type$ >(value));\n");
  207. if (HasUnknownFields(descriptor_->file())) {
  208. printer->Print(variables_,
  209. "} else {\n"
  210. " mutable_unknown_fields()->AddVarint($number$, value);\n");
  211. }
  212. printer->Print("}\n");
  213. }
  214. void RepeatedEnumFieldGenerator::
  215. GenerateMergeFromCodedStreamWithPacking(io::Printer* printer) const {
  216. if (!descriptor_->options().packed()) {
  217. // We use a non-inlined implementation in this case, since this path will
  218. // rarely be executed.
  219. printer->Print(variables_,
  220. "DO_((::google::protobuf::internal::WireFormatLite::ReadPackedEnumNoInline(\n"
  221. " input,\n"
  222. " &$type$_IsValid,\n"
  223. " this->mutable_$name$())));\n");
  224. } else {
  225. printer->Print(variables_,
  226. "::google::protobuf::uint32 length;\n"
  227. "DO_(input->ReadVarint32(&length));\n"
  228. "::google::protobuf::io::CodedInputStream::Limit limit = "
  229. "input->PushLimit(length);\n"
  230. "while (input->BytesUntilLimit() > 0) {\n"
  231. " int value;\n"
  232. " DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<\n"
  233. " int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(\n"
  234. " input, &value)));\n"
  235. " if ($type$_IsValid(value)) {\n"
  236. " add_$name$(static_cast< $type$ >(value));\n"
  237. " }\n"
  238. "}\n"
  239. "input->PopLimit(limit);\n");
  240. }
  241. }
  242. void RepeatedEnumFieldGenerator::
  243. GenerateSerializeWithCachedSizes(io::Printer* printer) const {
  244. if (descriptor_->options().packed()) {
  245. // Write the tag and the size.
  246. printer->Print(variables_,
  247. "if (this->$name$_size() > 0) {\n"
  248. " ::google::protobuf::internal::WireFormatLite::WriteTag(\n"
  249. " $number$,\n"
  250. " ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,\n"
  251. " output);\n"
  252. " output->WriteVarint32(_$name$_cached_byte_size_);\n"
  253. "}\n");
  254. }
  255. printer->Print(variables_,
  256. "for (int i = 0; i < this->$name$_size(); i++) {\n");
  257. if (descriptor_->options().packed()) {
  258. printer->Print(variables_,
  259. " ::google::protobuf::internal::WireFormatLite::WriteEnumNoTag(\n"
  260. " this->$name$(i), output);\n");
  261. } else {
  262. printer->Print(variables_,
  263. " ::google::protobuf::internal::WireFormatLite::WriteEnum(\n"
  264. " $number$, this->$name$(i), output);\n");
  265. }
  266. printer->Print("}\n");
  267. }
  268. void RepeatedEnumFieldGenerator::
  269. GenerateSerializeWithCachedSizesToArray(io::Printer* printer) const {
  270. if (descriptor_->options().packed()) {
  271. // Write the tag and the size.
  272. printer->Print(variables_,
  273. "if (this->$name$_size() > 0) {\n"
  274. " target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(\n"
  275. " $number$,\n"
  276. " ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,\n"
  277. " target);\n"
  278. " target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray("
  279. " _$name$_cached_byte_size_, target);\n"
  280. "}\n");
  281. }
  282. printer->Print(variables_,
  283. "for (int i = 0; i < this->$name$_size(); i++) {\n");
  284. if (descriptor_->options().packed()) {
  285. printer->Print(variables_,
  286. " target = ::google::protobuf::internal::WireFormatLite::WriteEnumNoTagToArray(\n"
  287. " this->$name$(i), target);\n");
  288. } else {
  289. printer->Print(variables_,
  290. " target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(\n"
  291. " $number$, this->$name$(i), target);\n");
  292. }
  293. printer->Print("}\n");
  294. }
  295. void RepeatedEnumFieldGenerator::
  296. GenerateByteSize(io::Printer* printer) const {
  297. printer->Print(variables_,
  298. "{\n"
  299. " int data_size = 0;\n");
  300. printer->Indent();
  301. printer->Print(variables_,
  302. "for (int i = 0; i < this->$name$_size(); i++) {\n"
  303. " data_size += ::google::protobuf::internal::WireFormatLite::EnumSize(\n"
  304. " this->$name$(i));\n"
  305. "}\n");
  306. if (descriptor_->options().packed()) {
  307. printer->Print(variables_,
  308. "if (data_size > 0) {\n"
  309. " total_size += $tag_size$ +\n"
  310. " ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);\n"
  311. "}\n"
  312. "_$name$_cached_byte_size_ = data_size;\n"
  313. "total_size += data_size;\n");
  314. } else {
  315. printer->Print(variables_,
  316. "total_size += $tag_size$ * this->$name$_size() + data_size;\n");
  317. }
  318. printer->Outdent();
  319. printer->Print("}\n");
  320. }
  321. } // namespace cpp
  322. } // namespace compiler
  323. } // namespace protobuf
  324. } // namespace google