summaryrefslogtreecommitdiff
path: root/upb/msg.h
diff options
context:
space:
mode:
authorJoshua Haberman <jhaberman@gmail.com>2017-07-01 15:15:52 -0700
committerJosh Haberman <jhaberman@gmail.com>2017-07-02 00:28:25 +0100
commit1b9d37a00ebae8b59773c8501d8712e1c3335302 (patch)
tree1295ee5099609f5a6c05689adfa7962ad4cdc5ab /upb/msg.h
parente38098cbfc58c0e2911b2c2b2abff043de42a85b (diff)
Start migrating upb_msglayout to be suitable for generated code.
This involves: - remove upb_msglayout -> upb_msgfactory dependency. - remove upb_msglayout -> upb_msgdef dependency (in progress). - make upb_msglayout use a representation that can be statically initialized by generated code. The goal here is that upb_msglayout becomes a kind of "descriptor lite": it contains enough data to parser and serialize protobufs and manipulate a upb_msg in memory, while being far smaller and simpler than a full descriptor. It also does not include field names, which can be a benefit for applications that do not want to leak field names. Generated code can then create a upb_msglayout, and do most things without ever needing to construct full descriptors/defs if they don't want to.
Diffstat (limited to 'upb/msg.h')
-rw-r--r--upb/msg.h69
1 files changed, 52 insertions, 17 deletions
diff --git a/upb/msg.h b/upb/msg.h
index 36470ae..c2b5cf0 100644
--- a/upb/msg.h
+++ b/upb/msg.h
@@ -65,18 +65,6 @@ typedef void upb_msg;
* instances of this from a upb_msgfactory, and the factory always owns the
* msglayout. */
-/* Gets the factory for this layout */
-upb_msgfactory *upb_msglayout_factory(const upb_msglayout *l);
-
-/* Get the msglayout for a submessage. This requires that this field is a
- * submessage, ie. upb_fielddef_issubmsg(upb_msglayout_msgdef(l)) == true.
- *
- * Since map entry messages don't have layouts, if upb_fielddef_ismap(f) == true
- * then this function will return the layout for the map's value. It requires
- * that the value type of the map field is a submessage. */
-const upb_msglayout *upb_msglayout_sublayout(const upb_msglayout *l,
- const upb_fielddef *f);
-
/* Returns the msgdef for this msglayout. */
const upb_msgdef *upb_msglayout_msgdef(const upb_msglayout *l);
@@ -212,19 +200,29 @@ size_t upb_msg_sizeof(const upb_msglayout *l);
* upb_msg_uninit() must be called to release internally-allocated memory
* unless the allocator is an arena that does not require freeing.
*
+ * Please note that upb_msg_init() may return a value that is different than
+ * |msg|, so you must assign the return value and not cast your memory block
+ * to upb_msg* directly!
+ *
* Please note that upb_msg_uninit() does *not* free any submessages, maps,
* or arrays referred to by this message's fields. You must free them manually
- * yourself. */
-void upb_msg_init(upb_msg *msg, const upb_msglayout *l, upb_alloc *a);
-void upb_msg_uninit(upb_msg *msg, const upb_msglayout *l);
+ * yourself.
+ *
+ * upb_msg_uninit returns the original memory block, which may be useful if
+ * you dynamically allocated it (though upb_msg_new() would normally be more
+ * appropriate in this case). */
+upb_msg *upb_msg_init(void *msg, const upb_msglayout *l, upb_alloc *a);
+void *upb_msg_uninit(upb_msg *msg, const upb_msglayout *l);
/* Like upb_msg_init() / upb_msg_uninit(), except the message's memory is
* allocated / freed from the given upb_alloc. */
upb_msg *upb_msg_new(const upb_msglayout *l, upb_alloc *a);
void upb_msg_free(upb_msg *msg, const upb_msglayout *l);
-/* Returns the upb_alloc for the given message. */
-upb_alloc *upb_msg_alloc(const upb_msg *msg, const upb_msglayout *l);
+/* Returns the upb_alloc for the given message.
+ * TODO(haberman): get rid of this? Not sure we want to be storing this
+ * for every message. */
+upb_alloc *upb_msg_alloc(const upb_msg *msg);
/* Packs the tree of messages rooted at "msg" into a single hunk of memory,
* allocated from the given allocator. */
@@ -400,6 +398,43 @@ bool upb_msg_getscalarhandlerdata(const upb_handlers *h,
size_t *offset,
int32_t *hasbit);
+
+/** Interfaces for generated code *********************************************/
+
+struct upb_msglayout_strinit_v1 {
+ const char *ptr;
+ uint32_t length;
+};
+
+struct upb_msglayout_fieldinit_v1 {
+ uint32_t number;
+ uint32_t offset;
+ uint16_t hasbit;
+ uint16_t oneof_index;
+ uint16_t submsg_index;
+ uint8_t type;
+ uint8_t label;
+};
+
+struct upb_msglayout_msginit_v1 {
+ struct upb_msglayout_fieldinit_v1 *fields;
+ struct upb_msglayout_msginit_v1 **submsgs;
+ uint32_t *case_offsets;
+ void *default_msg;
+ /* Must be aligned to 8. Doesn't include internal members like unknown
+ * fields, extension dict, pointer to msglayout, etc. */
+ uint32_t size;
+ bool extendable;
+ char align;
+};
+
+/* Initialize/uninitialize a msglayout from a msginit. If upb uses v1
+ * internally, this will not allocate any memory. Should only be used by
+ * generated code. */
+upb_msglayout *upb_msglayout_frominit_v1(
+ const struct upb_msglayout_msginit_v1 *init, upb_alloc *a);
+void upb_msglayout_uninit_v1(upb_msglayout *layout, upb_alloc *a);
+
UPB_END_EXTERN_C
#endif /* UPB_MSG_H_ */
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback