您最多选择25个标签 标签必须以中文、字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

extension_set_inl.h 19 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
  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. #ifndef GOOGLE_PROTOBUF_EXTENSION_SET_INL_H__
  31. #define GOOGLE_PROTOBUF_EXTENSION_SET_INL_H__
  32. #include <google/protobuf/extension_set.h>
  33. #include <google/protobuf/metadata_lite.h>
  34. #include <google/protobuf/parse_context.h>
  35. namespace google
  36. {
  37. namespace protobuf
  38. {
  39. namespace internal
  40. {
  41. template<typename T>
  42. const char* ExtensionSet::ParseFieldWithExtensionInfo(
  43. int number, bool was_packed_on_wire, const ExtensionInfo& extension, InternalMetadata* metadata, const char* ptr, internal::ParseContext* ctx
  44. )
  45. {
  46. if (was_packed_on_wire)
  47. {
  48. switch (extension.type)
  49. {
  50. #define HANDLE_TYPE(UPPERCASE, CPP_CAMELCASE) \
  51. case WireFormatLite::TYPE_##UPPERCASE: \
  52. return internal::Packed##CPP_CAMELCASE##Parser( \
  53. MutableRawRepeatedField(number, extension.type, extension.is_packed, extension.descriptor), \
  54. ptr, \
  55. ctx \
  56. );
  57. HANDLE_TYPE(INT32, Int32);
  58. HANDLE_TYPE(INT64, Int64);
  59. HANDLE_TYPE(UINT32, UInt32);
  60. HANDLE_TYPE(UINT64, UInt64);
  61. HANDLE_TYPE(SINT32, SInt32);
  62. HANDLE_TYPE(SINT64, SInt64);
  63. HANDLE_TYPE(FIXED32, Fixed32);
  64. HANDLE_TYPE(FIXED64, Fixed64);
  65. HANDLE_TYPE(SFIXED32, SFixed32);
  66. HANDLE_TYPE(SFIXED64, SFixed64);
  67. HANDLE_TYPE(FLOAT, Float);
  68. HANDLE_TYPE(DOUBLE, Double);
  69. HANDLE_TYPE(BOOL, Bool);
  70. #undef HANDLE_TYPE
  71. case WireFormatLite::TYPE_ENUM:
  72. return internal::PackedEnumParserArg<T>(
  73. MutableRawRepeatedField(number, extension.type, extension.is_packed, extension.descriptor),
  74. ptr,
  75. ctx,
  76. extension.enum_validity_check.func,
  77. extension.enum_validity_check.arg,
  78. metadata,
  79. number
  80. );
  81. case WireFormatLite::TYPE_STRING:
  82. case WireFormatLite::TYPE_BYTES:
  83. case WireFormatLite::TYPE_GROUP:
  84. case WireFormatLite::TYPE_MESSAGE:
  85. GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
  86. break;
  87. }
  88. }
  89. else
  90. {
  91. switch (extension.type)
  92. {
  93. #define HANDLE_VARINT_TYPE(UPPERCASE, CPP_CAMELCASE) \
  94. case WireFormatLite::TYPE_##UPPERCASE: \
  95. { \
  96. uint64_t value; \
  97. ptr = VarintParse(ptr, &value); \
  98. GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); \
  99. if (extension.is_repeated) \
  100. { \
  101. Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, extension.is_packed, value, extension.descriptor); \
  102. } \
  103. else \
  104. { \
  105. Set##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, value, extension.descriptor); \
  106. } \
  107. } \
  108. break
  109. HANDLE_VARINT_TYPE(INT32, Int32);
  110. HANDLE_VARINT_TYPE(INT64, Int64);
  111. HANDLE_VARINT_TYPE(UINT32, UInt32);
  112. HANDLE_VARINT_TYPE(UINT64, UInt64);
  113. HANDLE_VARINT_TYPE(BOOL, Bool);
  114. #undef HANDLE_VARINT_TYPE
  115. #define HANDLE_SVARINT_TYPE(UPPERCASE, CPP_CAMELCASE, SIZE) \
  116. case WireFormatLite::TYPE_##UPPERCASE: \
  117. { \
  118. uint64_t val; \
  119. ptr = VarintParse(ptr, &val); \
  120. GOOGLE_PROTOBUF_PARSER_ASSERT(ptr); \
  121. auto value = WireFormatLite::ZigZagDecode##SIZE(val); \
  122. if (extension.is_repeated) \
  123. { \
  124. Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, extension.is_packed, value, extension.descriptor); \
  125. } \
  126. else \
  127. { \
  128. Set##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, value, extension.descriptor); \
  129. } \
  130. } \
  131. break
  132. HANDLE_SVARINT_TYPE(SINT32, Int32, 32);
  133. HANDLE_SVARINT_TYPE(SINT64, Int64, 64);
  134. #undef HANDLE_SVARINT_TYPE
  135. #define HANDLE_FIXED_TYPE(UPPERCASE, CPP_CAMELCASE, CPPTYPE) \
  136. case WireFormatLite::TYPE_##UPPERCASE: \
  137. { \
  138. auto value = UnalignedLoad<CPPTYPE>(ptr); \
  139. ptr += sizeof(CPPTYPE); \
  140. if (extension.is_repeated) \
  141. { \
  142. Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, extension.is_packed, value, extension.descriptor); \
  143. } \
  144. else \
  145. { \
  146. Set##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, value, extension.descriptor); \
  147. } \
  148. } \
  149. break
  150. HANDLE_FIXED_TYPE(FIXED32, UInt32, uint32_t);
  151. HANDLE_FIXED_TYPE(FIXED64, UInt64, uint64_t);
  152. HANDLE_FIXED_TYPE(SFIXED32, Int32, int32_t);
  153. HANDLE_FIXED_TYPE(SFIXED64, Int64, int64_t);
  154. HANDLE_FIXED_TYPE(FLOAT, Float, float);
  155. HANDLE_FIXED_TYPE(DOUBLE, Double, double);
  156. #undef HANDLE_FIXED_TYPE
  157. case WireFormatLite::TYPE_ENUM:
  158. {
  159. uint64_t val;
  160. ptr = VarintParse(ptr, &val);
  161. GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
  162. int value = val;
  163. if (!extension.enum_validity_check.func(
  164. extension.enum_validity_check.arg, value
  165. ))
  166. {
  167. WriteVarint(number, val, metadata->mutable_unknown_fields<T>());
  168. }
  169. else if (extension.is_repeated)
  170. {
  171. AddEnum(number, WireFormatLite::TYPE_ENUM, extension.is_packed, value, extension.descriptor);
  172. }
  173. else
  174. {
  175. SetEnum(number, WireFormatLite::TYPE_ENUM, value, extension.descriptor);
  176. }
  177. break;
  178. }
  179. case WireFormatLite::TYPE_BYTES:
  180. case WireFormatLite::TYPE_STRING:
  181. {
  182. std::string* value =
  183. extension.is_repeated ? AddString(number, WireFormatLite::TYPE_STRING, extension.descriptor) : MutableString(number, WireFormatLite::TYPE_STRING, extension.descriptor);
  184. int size = ReadSize(&ptr);
  185. GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
  186. return ctx->ReadString(ptr, size, value);
  187. }
  188. case WireFormatLite::TYPE_GROUP:
  189. {
  190. MessageLite* value =
  191. extension.is_repeated ? AddMessage(number, WireFormatLite::TYPE_GROUP, *extension.message_info.prototype, extension.descriptor) : MutableMessage(number, WireFormatLite::TYPE_GROUP, *extension.message_info.prototype, extension.descriptor);
  192. uint32_t tag = (number << 3) + WireFormatLite::WIRETYPE_START_GROUP;
  193. return ctx->ParseGroup(value, ptr, tag);
  194. }
  195. case WireFormatLite::TYPE_MESSAGE:
  196. {
  197. MessageLite* value =
  198. extension.is_repeated ? AddMessage(number, WireFormatLite::TYPE_MESSAGE, *extension.message_info.prototype, extension.descriptor) : MutableMessage(number, WireFormatLite::TYPE_MESSAGE, *extension.message_info.prototype, extension.descriptor);
  199. return ctx->ParseMessage(value, ptr);
  200. }
  201. }
  202. }
  203. return ptr;
  204. }
  205. template<typename Msg, typename T>
  206. const char* ExtensionSet::ParseMessageSetItemTmpl(
  207. const char* ptr, const Msg* extendee, internal::InternalMetadata* metadata, internal::ParseContext* ctx
  208. )
  209. {
  210. std::string payload;
  211. uint32_t type_id;
  212. enum class State
  213. {
  214. kNoTag,
  215. kHasType,
  216. kHasPayload,
  217. kDone
  218. };
  219. State state = State::kNoTag;
  220. while (!ctx->Done(&ptr))
  221. {
  222. uint32_t tag = static_cast<uint8_t>(*ptr++);
  223. if (tag == WireFormatLite::kMessageSetTypeIdTag)
  224. {
  225. uint64_t tmp;
  226. ptr = ParseBigVarint(ptr, &tmp);
  227. GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
  228. if (state == State::kNoTag)
  229. {
  230. type_id = tmp;
  231. state = State::kHasType;
  232. }
  233. else if (state == State::kHasPayload)
  234. {
  235. type_id = tmp;
  236. ExtensionInfo extension;
  237. bool was_packed_on_wire;
  238. if (!FindExtension(2, type_id, extendee, ctx, &extension, &was_packed_on_wire))
  239. {
  240. WriteLengthDelimited(type_id, payload, metadata->mutable_unknown_fields<T>());
  241. }
  242. else
  243. {
  244. MessageLite* value =
  245. extension.is_repeated ? AddMessage(type_id, WireFormatLite::TYPE_MESSAGE, *extension.message_info.prototype, extension.descriptor) : MutableMessage(type_id, WireFormatLite::TYPE_MESSAGE, *extension.message_info.prototype, extension.descriptor);
  246. const char* p;
  247. // We can't use regular parse from string as we have to track
  248. // proper recursion depth and descriptor pools.
  249. ParseContext tmp_ctx(ctx->depth(), false, &p, payload);
  250. tmp_ctx.data().pool = ctx->data().pool;
  251. tmp_ctx.data().factory = ctx->data().factory;
  252. GOOGLE_PROTOBUF_PARSER_ASSERT(value->_InternalParse(p, &tmp_ctx) && tmp_ctx.EndedAtLimit());
  253. }
  254. state = State::kDone;
  255. }
  256. }
  257. else if (tag == WireFormatLite::kMessageSetMessageTag)
  258. {
  259. if (state == State::kHasType)
  260. {
  261. ptr = ParseFieldMaybeLazily(static_cast<uint64_t>(type_id) * 8 + 2, ptr, extendee, metadata, ctx);
  262. GOOGLE_PROTOBUF_PARSER_ASSERT(ptr != nullptr);
  263. state = State::kDone;
  264. }
  265. else
  266. {
  267. std::string tmp;
  268. int32_t size = ReadSize(&ptr);
  269. GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
  270. ptr = ctx->ReadString(ptr, size, &tmp);
  271. GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
  272. if (state == State::kNoTag)
  273. {
  274. payload = std::move(tmp);
  275. state = State::kHasPayload;
  276. }
  277. }
  278. }
  279. else
  280. {
  281. ptr = ReadTag(ptr - 1, &tag);
  282. if (tag == 0 || (tag & 7) == 4)
  283. {
  284. ctx->SetLastTag(tag);
  285. return ptr;
  286. }
  287. ptr = ParseField(tag, ptr, extendee, metadata, ctx);
  288. GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
  289. }
  290. }
  291. return ptr;
  292. }
  293. } // namespace internal
  294. } // namespace protobuf
  295. } // namespace google
  296. #endif // GOOGLE_PROTOBUF_EXTENSION_SET_INL_H__