1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2023 Google LLC. All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file or at
6 // https://developers.google.com/open-source/licenses/bsd
7
8 // upb_Encode: parsing from a upb_Message using a upb_MiniTable.
9
10 #ifndef UPB_WIRE_ENCODE_H_
11 #define UPB_WIRE_ENCODE_H_
12
13 #include <stddef.h>
14 #include <stdint.h>
15
16 #include "upb/mem/arena.h"
17 #include "upb/message/message.h"
18 #include "upb/mini_table/message.h"
19
20 // Must be last.
21 #include "upb/port/def.inc"
22
23 #ifdef __cplusplus
24 extern "C" {
25 #endif
26
27 enum {
28 /* If set, the results of serializing will be deterministic across all
29 * instances of this binary. There are no guarantees across different
30 * binary builds.
31 *
32 * If your proto contains maps, the encoder will need to malloc()/free()
33 * memory during encode. */
34 kUpb_EncodeOption_Deterministic = 1,
35
36 // When set, unknown fields are not encoded.
37 kUpb_EncodeOption_SkipUnknown = 2,
38
39 // When set, the encode will fail if any required fields are missing.
40 kUpb_EncodeOption_CheckRequired = 4,
41 };
42
43 // LINT.IfChange
44 typedef enum {
45 kUpb_EncodeStatus_Ok = 0,
46 kUpb_EncodeStatus_OutOfMemory = 1, // Arena alloc failed
47 kUpb_EncodeStatus_MaxDepthExceeded = 2,
48
49 // kUpb_EncodeOption_CheckRequired failed but the parse otherwise succeeded.
50 kUpb_EncodeStatus_MissingRequired = 3,
51 } upb_EncodeStatus;
52 // LINT.ThenChange(//depot/google3/third_party/protobuf/rust/upb.rs:encode_status)
53
upb_EncodeOptions_MaxDepth(uint16_t depth)54 UPB_INLINE uint32_t upb_EncodeOptions_MaxDepth(uint16_t depth) {
55 return (uint32_t)depth << 16;
56 }
57
upb_EncodeOptions_GetMaxDepth(uint32_t options)58 UPB_INLINE uint16_t upb_EncodeOptions_GetMaxDepth(uint32_t options) {
59 return options >> 16;
60 }
61
62 // Enforce an upper bound on recursion depth.
upb_Encode_LimitDepth(uint32_t encode_options,uint32_t limit)63 UPB_INLINE int upb_Encode_LimitDepth(uint32_t encode_options, uint32_t limit) {
64 uint32_t max_depth = upb_EncodeOptions_GetMaxDepth(encode_options);
65 if (max_depth > limit) max_depth = limit;
66 return upb_EncodeOptions_MaxDepth(max_depth) | (encode_options & 0xffff);
67 }
68
69 UPB_API upb_EncodeStatus upb_Encode(const upb_Message* msg,
70 const upb_MiniTable* l, int options,
71 upb_Arena* arena, char** buf, size_t* size);
72
73 // Encodes the message prepended by a varint of the serialized length.
74 UPB_API upb_EncodeStatus upb_EncodeLengthPrefixed(const upb_Message* msg,
75 const upb_MiniTable* l,
76 int options, upb_Arena* arena,
77 char** buf, size_t* size);
78 // Utility function for wrapper languages to get an error string from a
79 // upb_EncodeStatus.
80 UPB_API const char* upb_EncodeStatus_String(upb_EncodeStatus status);
81
82 #ifdef __cplusplus
83 } /* extern "C" */
84 #endif
85
86 #include "upb/port/undef.inc"
87
88 #endif /* UPB_WIRE_ENCODE_H_ */
89