reflection.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440
  1. /*
  2. * Copyright (c) 2009-2021, Google LLC
  3. * All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions are met:
  7. * * Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * * Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. * * Neither the name of Google LLC nor the
  13. * names of its contributors may be used to endorse or promote products
  14. * derived from this software without specific prior written permission.
  15. *
  16. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  17. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  18. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  19. * DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY
  20. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  21. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  22. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  23. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  24. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  25. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  26. */
  27. #include "upb/reflection.h"
  28. #include <string.h>
  29. #include "upb/table_internal.h"
  30. #include "upb/msg.h"
  31. #include "upb/port_def.inc"
  32. static size_t get_field_size(const upb_msglayout_field *f) {
  33. static unsigned char sizes[] = {
  34. 0,/* 0 */
  35. 8, /* UPB_DESCRIPTOR_TYPE_DOUBLE */
  36. 4, /* UPB_DESCRIPTOR_TYPE_FLOAT */
  37. 8, /* UPB_DESCRIPTOR_TYPE_INT64 */
  38. 8, /* UPB_DESCRIPTOR_TYPE_UINT64 */
  39. 4, /* UPB_DESCRIPTOR_TYPE_INT32 */
  40. 8, /* UPB_DESCRIPTOR_TYPE_FIXED64 */
  41. 4, /* UPB_DESCRIPTOR_TYPE_FIXED32 */
  42. 1, /* UPB_DESCRIPTOR_TYPE_BOOL */
  43. sizeof(upb_strview), /* UPB_DESCRIPTOR_TYPE_STRING */
  44. sizeof(void*), /* UPB_DESCRIPTOR_TYPE_GROUP */
  45. sizeof(void*), /* UPB_DESCRIPTOR_TYPE_MESSAGE */
  46. sizeof(upb_strview), /* UPB_DESCRIPTOR_TYPE_BYTES */
  47. 4, /* UPB_DESCRIPTOR_TYPE_UINT32 */
  48. 4, /* UPB_DESCRIPTOR_TYPE_ENUM */
  49. 4, /* UPB_DESCRIPTOR_TYPE_SFIXED32 */
  50. 8, /* UPB_DESCRIPTOR_TYPE_SFIXED64 */
  51. 4, /* UPB_DESCRIPTOR_TYPE_SINT32 */
  52. 8, /* UPB_DESCRIPTOR_TYPE_SINT64 */
  53. };
  54. return _upb_repeated_or_map(f) ? sizeof(void *) : sizes[f->descriptortype];
  55. }
  56. /* Strings/bytes are special-cased in maps. */
  57. static char _upb_fieldtype_to_mapsize[12] = {
  58. 0,
  59. 1, /* UPB_TYPE_BOOL */
  60. 4, /* UPB_TYPE_FLOAT */
  61. 4, /* UPB_TYPE_INT32 */
  62. 4, /* UPB_TYPE_UINT32 */
  63. 4, /* UPB_TYPE_ENUM */
  64. sizeof(void*), /* UPB_TYPE_MESSAGE */
  65. 8, /* UPB_TYPE_DOUBLE */
  66. 8, /* UPB_TYPE_INT64 */
  67. 8, /* UPB_TYPE_UINT64 */
  68. 0, /* UPB_TYPE_STRING */
  69. 0, /* UPB_TYPE_BYTES */
  70. };
  71. static const char _upb_fieldtype_to_sizelg2[12] = {
  72. 0,
  73. 0, /* UPB_TYPE_BOOL */
  74. 2, /* UPB_TYPE_FLOAT */
  75. 2, /* UPB_TYPE_INT32 */
  76. 2, /* UPB_TYPE_UINT32 */
  77. 2, /* UPB_TYPE_ENUM */
  78. UPB_SIZE(2, 3), /* UPB_TYPE_MESSAGE */
  79. 3, /* UPB_TYPE_DOUBLE */
  80. 3, /* UPB_TYPE_INT64 */
  81. 3, /* UPB_TYPE_UINT64 */
  82. UPB_SIZE(3, 4), /* UPB_TYPE_STRING */
  83. UPB_SIZE(3, 4), /* UPB_TYPE_BYTES */
  84. };
  85. /** upb_msg *******************************************************************/
  86. upb_msg *upb_msg_new(const upb_msgdef *m, upb_arena *a) {
  87. return _upb_msg_new(upb_msgdef_layout(m), a);
  88. }
  89. static bool in_oneof(const upb_msglayout_field *field) {
  90. return field->presence < 0;
  91. }
  92. static upb_msgval _upb_msg_getraw(const upb_msg *msg, const upb_fielddef *f) {
  93. const upb_msglayout_field *field = upb_fielddef_layout(f);
  94. const char *mem = UPB_PTR_AT(msg, field->offset, char);
  95. upb_msgval val = {0};
  96. memcpy(&val, mem, get_field_size(field));
  97. return val;
  98. }
  99. bool upb_msg_has(const upb_msg *msg, const upb_fielddef *f) {
  100. if (upb_fielddef_isextension(f)) {
  101. const upb_msglayout_ext *ext = _upb_fielddef_extlayout(f);
  102. return _upb_msg_getext(msg, ext) != NULL;
  103. } else {
  104. const upb_msglayout_field *field = upb_fielddef_layout(f);
  105. if (in_oneof(field)) {
  106. return _upb_getoneofcase_field(msg, field) == field->number;
  107. } else if (field->presence > 0) {
  108. return _upb_hasbit_field(msg, field);
  109. } else {
  110. UPB_ASSERT(field->descriptortype == UPB_DESCRIPTOR_TYPE_MESSAGE ||
  111. field->descriptortype == UPB_DESCRIPTOR_TYPE_GROUP);
  112. return _upb_msg_getraw(msg, f).msg_val != NULL;
  113. }
  114. }
  115. }
  116. const upb_fielddef *upb_msg_whichoneof(const upb_msg *msg,
  117. const upb_oneofdef *o) {
  118. const upb_fielddef *f = upb_oneofdef_field(o, 0);
  119. if (upb_oneofdef_issynthetic(o)) {
  120. UPB_ASSERT(upb_oneofdef_fieldcount(o) == 1);
  121. return upb_msg_has(msg, f) ? f : NULL;
  122. } else {
  123. const upb_msglayout_field *field = upb_fielddef_layout(f);
  124. uint32_t oneof_case = _upb_getoneofcase_field(msg, field);
  125. f = oneof_case ? upb_oneofdef_itof(o, oneof_case) : NULL;
  126. UPB_ASSERT((f != NULL) == (oneof_case != 0));
  127. return f;
  128. }
  129. }
  130. upb_msgval upb_msg_get(const upb_msg *msg, const upb_fielddef *f) {
  131. if (upb_fielddef_isextension(f)) {
  132. const upb_msg_ext *ext = _upb_msg_getext(msg, _upb_fielddef_extlayout(f));
  133. if (ext) {
  134. upb_msgval val;
  135. memcpy(&val, &ext->data, sizeof(val));
  136. return val;
  137. } else if (upb_fielddef_isseq(f)) {
  138. return (upb_msgval){.array_val = NULL};
  139. }
  140. } else if (!upb_fielddef_haspresence(f) || upb_msg_has(msg, f)) {
  141. return _upb_msg_getraw(msg, f);
  142. }
  143. return upb_fielddef_default(f);
  144. }
  145. upb_mutmsgval upb_msg_mutable(upb_msg *msg, const upb_fielddef *f,
  146. upb_arena *a) {
  147. UPB_ASSERT(upb_fielddef_issubmsg(f) || upb_fielddef_isseq(f));
  148. if (upb_fielddef_haspresence(f) && !upb_msg_has(msg, f)) {
  149. // We need to skip the upb_msg_get() call in this case.
  150. goto make;
  151. }
  152. upb_msgval val = upb_msg_get(msg, f);
  153. if (val.array_val) {
  154. return (upb_mutmsgval){.array = (upb_array*)val.array_val};
  155. }
  156. upb_mutmsgval ret;
  157. make:
  158. if (!a) return (upb_mutmsgval){.array = NULL};
  159. if (upb_fielddef_ismap(f)) {
  160. const upb_msgdef *entry = upb_fielddef_msgsubdef(f);
  161. const upb_fielddef *key = upb_msgdef_itof(entry, UPB_MAPENTRY_KEY);
  162. const upb_fielddef *value = upb_msgdef_itof(entry, UPB_MAPENTRY_VALUE);
  163. ret.map = upb_map_new(a, upb_fielddef_type(key), upb_fielddef_type(value));
  164. } else if (upb_fielddef_isseq(f)) {
  165. ret.array = upb_array_new(a, upb_fielddef_type(f));
  166. } else {
  167. UPB_ASSERT(upb_fielddef_issubmsg(f));
  168. ret.msg = upb_msg_new(upb_fielddef_msgsubdef(f), a);
  169. }
  170. val.array_val = ret.array;
  171. upb_msg_set(msg, f, val, a);
  172. return ret;
  173. }
  174. bool upb_msg_set(upb_msg *msg, const upb_fielddef *f, upb_msgval val,
  175. upb_arena *a) {
  176. if (upb_fielddef_isextension(f)) {
  177. upb_msg_ext *ext =
  178. _upb_msg_getorcreateext(msg, _upb_fielddef_extlayout(f), a);
  179. if (!ext) return false;
  180. memcpy(&ext->data, &val, sizeof(val));
  181. } else {
  182. const upb_msglayout_field *field = upb_fielddef_layout(f);
  183. char *mem = UPB_PTR_AT(msg, field->offset, char);
  184. memcpy(mem, &val, get_field_size(field));
  185. if (field->presence > 0) {
  186. _upb_sethas_field(msg, field);
  187. } else if (in_oneof(field)) {
  188. *_upb_oneofcase_field(msg, field) = field->number;
  189. }
  190. }
  191. return true;
  192. }
  193. void upb_msg_clearfield(upb_msg *msg, const upb_fielddef *f) {
  194. if (upb_fielddef_isextension(f)) {
  195. _upb_msg_clearext(msg, _upb_fielddef_extlayout(f));
  196. } else {
  197. const upb_msglayout_field *field = upb_fielddef_layout(f);
  198. char *mem = UPB_PTR_AT(msg, field->offset, char);
  199. if (field->presence > 0) {
  200. _upb_clearhas_field(msg, field);
  201. } else if (in_oneof(field)) {
  202. uint32_t *oneof_case = _upb_oneofcase_field(msg, field);
  203. if (*oneof_case != field->number) return;
  204. *oneof_case = 0;
  205. }
  206. memset(mem, 0, get_field_size(field));
  207. }
  208. }
  209. void upb_msg_clear(upb_msg *msg, const upb_msgdef *m) {
  210. _upb_msg_clear(msg, upb_msgdef_layout(m));
  211. }
  212. bool upb_msg_next(const upb_msg *msg, const upb_msgdef *m,
  213. const upb_symtab *ext_pool, const upb_fielddef **out_f,
  214. upb_msgval *out_val, size_t *iter) {
  215. size_t i = *iter;
  216. size_t n = upb_msgdef_fieldcount(m);
  217. const upb_msgval zero = {0};
  218. UPB_UNUSED(ext_pool);
  219. /* Iterate over normal fields, returning the first one that is set. */
  220. while (++i < n) {
  221. const upb_fielddef *f = upb_msgdef_field(m, i);
  222. upb_msgval val = _upb_msg_getraw(msg, f);
  223. /* Skip field if unset or empty. */
  224. if (upb_fielddef_haspresence(f)) {
  225. if (!upb_msg_has(msg, f)) continue;
  226. } else {
  227. upb_msgval test = val;
  228. if (upb_fielddef_isstring(f) && !upb_fielddef_isseq(f)) {
  229. /* Clear string pointer, only size matters (ptr could be non-NULL). */
  230. test.str_val.data = NULL;
  231. }
  232. /* Continue if NULL or 0. */
  233. if (memcmp(&test, &zero, sizeof(test)) == 0) continue;
  234. /* Continue on empty array or map. */
  235. if (upb_fielddef_ismap(f)) {
  236. if (upb_map_size(test.map_val) == 0) continue;
  237. } else if (upb_fielddef_isseq(f)) {
  238. if (upb_array_size(test.array_val) == 0) continue;
  239. }
  240. }
  241. *out_val = val;
  242. *out_f = f;
  243. *iter = i;
  244. return true;
  245. }
  246. if (ext_pool) {
  247. /* Return any extensions that are set. */
  248. size_t count;
  249. const upb_msg_ext *ext = _upb_msg_getexts(msg, &count);
  250. if (i - n < count) {
  251. ext += count - 1 - (i - n);
  252. memcpy(out_val, &ext->data, sizeof(*out_val));
  253. *out_f = _upb_symtab_lookupextfield(ext_pool, ext->ext);
  254. *iter = i;
  255. return true;
  256. }
  257. }
  258. *iter = i;
  259. return false;
  260. }
  261. bool _upb_msg_discardunknown(upb_msg *msg, const upb_msgdef *m, int depth) {
  262. size_t iter = UPB_MSG_BEGIN;
  263. const upb_fielddef *f;
  264. upb_msgval val;
  265. bool ret = true;
  266. if (--depth == 0) return false;
  267. _upb_msg_discardunknown_shallow(msg);
  268. while (upb_msg_next(msg, m, NULL /*ext_pool*/, &f, &val, &iter)) {
  269. const upb_msgdef *subm = upb_fielddef_msgsubdef(f);
  270. if (!subm) continue;
  271. if (upb_fielddef_ismap(f)) {
  272. const upb_fielddef *val_f = upb_msgdef_itof(subm, 2);
  273. const upb_msgdef *val_m = upb_fielddef_msgsubdef(val_f);
  274. upb_map *map = (upb_map*)val.map_val;
  275. size_t iter = UPB_MAP_BEGIN;
  276. if (!val_m) continue;
  277. while (upb_mapiter_next(map, &iter)) {
  278. upb_msgval map_val = upb_mapiter_value(map, iter);
  279. if (!_upb_msg_discardunknown((upb_msg*)map_val.msg_val, val_m, depth)) {
  280. ret = false;
  281. }
  282. }
  283. } else if (upb_fielddef_isseq(f)) {
  284. const upb_array *arr = val.array_val;
  285. size_t i, n = upb_array_size(arr);
  286. for (i = 0; i < n; i++) {
  287. upb_msgval elem = upb_array_get(arr, i);
  288. if (!_upb_msg_discardunknown((upb_msg*)elem.msg_val, subm, depth)) {
  289. ret = false;
  290. }
  291. }
  292. } else {
  293. if (!_upb_msg_discardunknown((upb_msg*)val.msg_val, subm, depth)) {
  294. ret = false;
  295. }
  296. }
  297. }
  298. return ret;
  299. }
  300. bool upb_msg_discardunknown(upb_msg *msg, const upb_msgdef *m, int maxdepth) {
  301. return _upb_msg_discardunknown(msg, m, maxdepth);
  302. }
  303. /** upb_array *****************************************************************/
  304. upb_array *upb_array_new(upb_arena *a, upb_fieldtype_t type) {
  305. return _upb_array_new(a, 4, _upb_fieldtype_to_sizelg2[type]);
  306. }
  307. size_t upb_array_size(const upb_array *arr) {
  308. return arr->len;
  309. }
  310. upb_msgval upb_array_get(const upb_array *arr, size_t i) {
  311. upb_msgval ret;
  312. const char* data = _upb_array_constptr(arr);
  313. int lg2 = arr->data & 7;
  314. UPB_ASSERT(i < arr->len);
  315. memcpy(&ret, data + (i << lg2), 1 << lg2);
  316. return ret;
  317. }
  318. void upb_array_set(upb_array *arr, size_t i, upb_msgval val) {
  319. char* data = _upb_array_ptr(arr);
  320. int lg2 = arr->data & 7;
  321. UPB_ASSERT(i < arr->len);
  322. memcpy(data + (i << lg2), &val, 1 << lg2);
  323. }
  324. bool upb_array_append(upb_array *arr, upb_msgval val, upb_arena *arena) {
  325. if (!upb_array_resize(arr, arr->len + 1, arena)) {
  326. return false;
  327. }
  328. upb_array_set(arr, arr->len - 1, val);
  329. return true;
  330. }
  331. bool upb_array_resize(upb_array *arr, size_t size, upb_arena *arena) {
  332. return _upb_array_resize(arr, size, arena);
  333. }
  334. /** upb_map *******************************************************************/
  335. upb_map *upb_map_new(upb_arena *a, upb_fieldtype_t key_type,
  336. upb_fieldtype_t value_type) {
  337. return _upb_map_new(a, _upb_fieldtype_to_mapsize[key_type],
  338. _upb_fieldtype_to_mapsize[value_type]);
  339. }
  340. size_t upb_map_size(const upb_map *map) {
  341. return _upb_map_size(map);
  342. }
  343. bool upb_map_get(const upb_map *map, upb_msgval key, upb_msgval *val) {
  344. return _upb_map_get(map, &key, map->key_size, val, map->val_size);
  345. }
  346. void upb_map_clear(upb_map *map) {
  347. _upb_map_clear(map);
  348. }
  349. bool upb_map_set(upb_map *map, upb_msgval key, upb_msgval val,
  350. upb_arena *arena) {
  351. return _upb_map_set(map, &key, map->key_size, &val, map->val_size, arena);
  352. }
  353. bool upb_map_delete(upb_map *map, upb_msgval key) {
  354. return _upb_map_delete(map, &key, map->key_size);
  355. }
  356. bool upb_mapiter_next(const upb_map *map, size_t *iter) {
  357. return _upb_map_next(map, iter);
  358. }
  359. bool upb_mapiter_done(const upb_map *map, size_t iter) {
  360. upb_strtable_iter i;
  361. UPB_ASSERT(iter != UPB_MAP_BEGIN);
  362. i.t = &map->table;
  363. i.index = iter;
  364. return upb_strtable_done(&i);
  365. }
  366. /* Returns the key and value for this entry of the map. */
  367. upb_msgval upb_mapiter_key(const upb_map *map, size_t iter) {
  368. upb_strtable_iter i;
  369. upb_msgval ret;
  370. i.t = &map->table;
  371. i.index = iter;
  372. _upb_map_fromkey(upb_strtable_iter_key(&i), &ret, map->key_size);
  373. return ret;
  374. }
  375. upb_msgval upb_mapiter_value(const upb_map *map, size_t iter) {
  376. upb_strtable_iter i;
  377. upb_msgval ret;
  378. i.t = &map->table;
  379. i.index = iter;
  380. _upb_map_fromvalue(upb_strtable_iter_value(&i), &ret, map->val_size);
  381. return ret;
  382. }
  383. /* void upb_mapiter_setvalue(upb_map *map, size_t iter, upb_msgval value); */