diff --git a/upb/reflection/enum_def.c b/upb/reflection/enum_def.c index 0998d03c8f..d32ee569cb 100644 --- a/upb/reflection/enum_def.c +++ b/upb/reflection/enum_def.c @@ -91,19 +91,20 @@ static int cmp_values(const void* a, const void* b) { return (A < B) ? -1 : (A > B); } -const char* _upb_EnumDef_MiniDescriptor(const upb_EnumDef* e, upb_Arena* a) { - if (e->is_sorted) return _upb_MiniDescriptor_EncodeEnum(e, NULL, a); +bool _upb_EnumDef_MiniDescriptor(const upb_EnumDef* e, upb_Arena* a, + upb_StringView* out) { + if (e->is_sorted) return _upb_MiniDescriptor_EncodeEnum(e, NULL, a, out); const upb_EnumValueDef** sorted = (const upb_EnumValueDef**)upb_Arena_Malloc( a, e->value_count * sizeof(void*)); - if (!sorted) return NULL; + if (!sorted) return false; for (size_t i = 0; i < e->value_count; i++) { sorted[i] = upb_EnumDef_Value(e, i); } qsort(sorted, e->value_count, sizeof(void*), cmp_values); - return _upb_MiniDescriptor_EncodeEnum(e, sorted, a); + return _upb_MiniDescriptor_EncodeEnum(e, sorted, a, out); } const google_protobuf_EnumOptions* upb_EnumDef_Options(const upb_EnumDef* e) { @@ -166,13 +167,13 @@ const upb_EnumValueDef* upb_EnumDef_Value(const upb_EnumDef* e, int i) { static upb_MiniTable_Enum* create_enumlayout(upb_DefBuilder* ctx, const upb_EnumDef* e) { - const char* desc = _upb_EnumDef_MiniDescriptor(e, ctx->tmp_arena); - if (!desc) - _upb_DefBuilder_Errf(ctx, "OOM while building enum MiniDescriptor"); + upb_StringView sv; + bool ok = _upb_EnumDef_MiniDescriptor(e, ctx->tmp_arena, &sv); + if (!ok) _upb_DefBuilder_Errf(ctx, "OOM while building enum MiniDescriptor"); upb_Status status; upb_MiniTable_Enum* layout = - upb_MiniTable_BuildEnum(desc, strlen(desc), ctx->arena, &status); + upb_MiniTable_BuildEnum(sv.data, sv.size, ctx->arena, &status); if (!layout) _upb_DefBuilder_Errf(ctx, "Error building enum MiniTable: %s", status.msg); return layout; diff --git a/upb/reflection/enum_def.h b/upb/reflection/enum_def.h index 0693453185..0d97b7cf8d 100644 --- a/upb/reflection/enum_def.h +++ b/upb/reflection/enum_def.h @@ -62,8 +62,9 @@ upb_EnumDef* _upb_EnumDef_At(const upb_EnumDef* e, int i); bool _upb_EnumDef_Insert(upb_EnumDef* e, upb_EnumValueDef* v, upb_Arena* a); const upb_MiniTable_Enum* _upb_EnumDef_MiniTable(const upb_EnumDef* e); -// Builds and returns a mini descriptor, or NULL if OOM. -const char* _upb_EnumDef_MiniDescriptor(const upb_EnumDef* e, upb_Arena* a); +// Builds a mini descriptor, returns false if OOM. +bool _upb_EnumDef_MiniDescriptor(const upb_EnumDef* e, upb_Arena* a, + upb_StringView* out); // Allocate and initialize an array of |n| enum defs. upb_EnumDef* _upb_EnumDefs_New(upb_DefBuilder* ctx, int n, diff --git a/upb/reflection/mini_descriptor_encode.c b/upb/reflection/mini_descriptor_encode.c index 3a7a0d55ac..d2ad8c99b9 100644 --- a/upb/reflection/mini_descriptor_encode.c +++ b/upb/reflection/mini_descriptor_encode.c @@ -130,65 +130,68 @@ static int upb_MiniDescriptor_CompareFields(const void* a, const void* b) { return 0; } -const char* _upb_MiniDescriptor_EncodeEnum(const upb_EnumDef* e, - const upb_EnumValueDef** sorted, - upb_Arena* a) { +bool _upb_MiniDescriptor_EncodeEnum(const upb_EnumDef* e, + const upb_EnumValueDef** sorted, + upb_Arena* a, upb_StringView* out) { DescState s; upb_DescState_Init(&s); upb_MtDataEncoder_StartEnum(&s.e); - const size_t value_count = upb_EnumDef_ValueCount(e); - // Duplicate values are allowed but we only encode each value once. uint32_t previous = 0; + const size_t value_count = upb_EnumDef_ValueCount(e); for (size_t i = 0; i < value_count; i++) { const uint32_t current = upb_EnumValueDef_Number(sorted ? sorted[i] : upb_EnumDef_Value(e, i)); if (i != 0 && previous == current) continue; - if (!upb_DescState_Grow(&s, a)) return NULL; + if (!upb_DescState_Grow(&s, a)) return false; s.ptr = upb_MtDataEncoder_PutEnumValue(&s.e, s.ptr, current); previous = current; } - if (!upb_DescState_Grow(&s, a)) return NULL; + if (!upb_DescState_Grow(&s, a)) return false; s.ptr = upb_MtDataEncoder_EndEnum(&s.e, s.ptr); // There will always be room for this '\0' in the encoder buffer because // kUpb_MtDataEncoder_MinSize is overkill for upb_MtDataEncoder_EndEnum(). UPB_ASSERT(s.ptr < s.buf + s.bufsize); - *s.ptr++ = '\0'; + *s.ptr = '\0'; - return s.buf; + out->data = s.buf; + out->size = s.ptr - s.buf; + return true; } -const char* _upb_MiniDescriptor_EncodeField(const upb_FieldDef* f, - upb_Arena* a) { +bool _upb_MiniDescriptor_EncodeField(const upb_FieldDef* f, upb_Arena* a, + upb_StringView* out) { UPB_ASSERT(upb_FieldDef_IsExtension(f)); DescState s; upb_DescState_Init(&s); - if (!upb_DescState_Grow(&s, a)) return NULL; - upb_MtDataEncoder_StartMessage(&s.e, s.ptr, 0); + if (!upb_DescState_Grow(&s, a)) return false; + s.ptr = upb_MtDataEncoder_StartMessage(&s.e, s.ptr, 0); const upb_FieldType type = upb_FieldDef_Type(f); const int number = upb_FieldDef_Number(f); const uint64_t modifiers = upb_Field_Modifiers(f); - if (!upb_DescState_Grow(&s, a)) return NULL; - upb_MtDataEncoder_PutField(&s.e, s.ptr, type, number, modifiers); + if (!upb_DescState_Grow(&s, a)) return false; + s.ptr = upb_MtDataEncoder_PutField(&s.e, s.ptr, type, number, modifiers); - if (!upb_DescState_Grow(&s, a)) return NULL; - *s.ptr++ = '\0'; + if (!upb_DescState_Grow(&s, a)) return false; + *s.ptr = '\0'; - return s.buf; + out->data = s.buf; + out->size = s.ptr - s.buf; + return true; } -const char* _upb_MiniDescriptor_EncodeMessage(const upb_MessageDef* m, - upb_Arena* a) { +bool _upb_MiniDescriptor_EncodeMessage(const upb_MessageDef* m, upb_Arena* a, + upb_StringView* out) { DescState s; upb_DescState_Init(&s); @@ -196,7 +199,7 @@ const char* _upb_MiniDescriptor_EncodeMessage(const upb_MessageDef* m, const size_t field_count = upb_MessageDef_FieldCount(m); const upb_FieldDef** sorted = (const upb_FieldDef**)upb_Arena_Malloc(a, field_count * sizeof(void*)); - if (!sorted) return NULL; + if (!sorted) return false; // Sort the copy. for (size_t i = 0; i < field_count; i++) { @@ -204,56 +207,55 @@ const char* _upb_MiniDescriptor_EncodeMessage(const upb_MessageDef* m, } qsort(sorted, field_count, sizeof(void*), upb_MiniDescriptor_CompareFields); - // Start encoding. - if (!upb_DescState_Grow(&s, a)) return NULL; - upb_MtDataEncoder_StartMessage(&s.e, s.ptr, upb_Message_Modifiers(m)); + if (!upb_DescState_Grow(&s, a)) return false; + s.ptr = upb_MtDataEncoder_StartMessage(&s.e, s.ptr, upb_Message_Modifiers(m)); - // Encode the fields. for (size_t i = 0; i < field_count; i++) { - const upb_FieldDef* field_def = sorted[i]; - const upb_FieldType type = upb_FieldDef_Type(field_def); - const int number = upb_FieldDef_Number(field_def); - const uint64_t modifiers = upb_Field_Modifiers(field_def); + const upb_FieldDef* f = sorted[i]; + const upb_FieldType type = upb_FieldDef_Type(f); + const int number = upb_FieldDef_Number(f); + const uint64_t modifiers = upb_Field_Modifiers(f); - if (!upb_DescState_Grow(&s, a)) return NULL; + if (!upb_DescState_Grow(&s, a)) return false; s.ptr = upb_MtDataEncoder_PutField(&s.e, s.ptr, type, number, modifiers); } - // Encode the oneofs. const int oneof_count = upb_MessageDef_OneofCount(m); for (int i = 0; i < oneof_count; i++) { - if (!upb_DescState_Grow(&s, a)) return NULL; + if (!upb_DescState_Grow(&s, a)) return false; s.ptr = upb_MtDataEncoder_StartOneof(&s.e, s.ptr); - const upb_OneofDef* oneof_def = upb_MessageDef_Oneof(m, i); - const int field_count = upb_OneofDef_FieldCount(oneof_def); + const upb_OneofDef* o = upb_MessageDef_Oneof(m, i); + const int field_count = upb_OneofDef_FieldCount(o); for (int j = 0; j < field_count; j++) { - const upb_FieldDef* field_def = upb_OneofDef_Field(oneof_def, j); - const int number = upb_FieldDef_Number(field_def); + const int number = upb_FieldDef_Number(upb_OneofDef_Field(o, j)); - if (!upb_DescState_Grow(&s, a)) return NULL; + if (!upb_DescState_Grow(&s, a)) return false; s.ptr = upb_MtDataEncoder_PutOneofField(&s.e, s.ptr, number); } } - if (!upb_DescState_Grow(&s, a)) return NULL; - *s.ptr++ = '\0'; + if (!upb_DescState_Grow(&s, a)) return false; + *s.ptr = '\0'; - return s.buf; + out->data = s.buf; + out->size = s.ptr - s.buf; + return true; } /******************************************************************************/ -const char* upb_MiniDescriptor_EncodeEnum(const upb_EnumDef* e, upb_Arena* a) { - return _upb_EnumDef_MiniDescriptor(e, a); +bool upb_MiniDescriptor_EncodeEnum(const upb_EnumDef* e, upb_Arena* a, + upb_StringView* out) { + return _upb_EnumDef_MiniDescriptor(e, a, out); } -const char* upb_MiniDescriptor_EncodeField(const upb_FieldDef* f, - upb_Arena* a) { - return _upb_MiniDescriptor_EncodeField(f, a); +bool upb_MiniDescriptor_EncodeField(const upb_FieldDef* f, upb_Arena* a, + upb_StringView* out) { + return _upb_MiniDescriptor_EncodeField(f, a, out); } -const char* upb_MiniDescriptor_EncodeMessage(const upb_MessageDef* m, - upb_Arena* a) { - return _upb_MiniDescriptor_EncodeMessage(m, a); +bool upb_MiniDescriptor_EncodeMessage(const upb_MessageDef* m, upb_Arena* a, + upb_StringView* out) { + return _upb_MiniDescriptor_EncodeMessage(m, a, out); } diff --git a/upb/reflection/mini_descriptor_encode.h b/upb/reflection/mini_descriptor_encode.h index f197ce7b99..a9677abfd0 100644 --- a/upb/reflection/mini_descriptor_encode.h +++ b/upb/reflection/mini_descriptor_encode.h @@ -29,6 +29,7 @@ #define UPB_REFLECTION_MINI_DESCRIPTOR_ENCODE_H_ #include "upb/reflection/common.h" +#include "upb/string_view.h" // Must be last. #include "upb/port_def.inc" @@ -37,15 +38,17 @@ extern "C" { #endif -// Creates and returns a mini descriptor string for an enum, or NULL on error. -const char* upb_MiniDescriptor_EncodeEnum(const upb_EnumDef* e, upb_Arena* a); +// Creates a mini descriptor string for an enum, returns true on success. +bool upb_MiniDescriptor_EncodeEnum(const upb_EnumDef* e, upb_Arena* a, + upb_StringView* out); -// Creates and returns a mini descriptor string for a field, or NULL on error. -const char* upb_MiniDescriptor_EncodeField(const upb_FieldDef* f, upb_Arena* a); +// Creates a mini descriptor string for a field, returns true on success. +bool upb_MiniDescriptor_EncodeField(const upb_FieldDef* f, upb_Arena* a, + upb_StringView* out); -// Creates and returns a mini descriptor string for a message, or NULL on error. -const char* upb_MiniDescriptor_EncodeMessage(const upb_MessageDef* m, - upb_Arena* a); +// Creates a mini descriptor string for a message, returns true on success. +bool upb_MiniDescriptor_EncodeMessage(const upb_MessageDef* m, upb_Arena* a, + upb_StringView* out); // EVERYTHING BELOW THIS LINE IS INTERNAL - DO NOT USE ///////////////////////// @@ -53,17 +56,12 @@ const char* upb_MiniDescriptor_EncodeMessage(const upb_MessageDef* m, // If the values in the enum happen to be defined in ascending order (when cast // to uint32_t) then |sorted| should be NULL. Otherwise it must point to an // array containing pointers to the enum value defs in sorted order. -const char* _upb_MiniDescriptor_EncodeEnum(const upb_EnumDef* e, - const upb_EnumValueDef** sorted, - upb_Arena* a); - -// Creates and returns a mini descriptor string for a field, or NULL on error. -const char* _upb_MiniDescriptor_EncodeField(const upb_FieldDef* f, - upb_Arena* a); +bool _upb_MiniDescriptor_EncodeEnum(const upb_EnumDef* e, + const upb_EnumValueDef** sorted, + upb_Arena* a, upb_StringView* out); -// Creates and returns a mini descriptor string for a message, or NULL on error. -const char* _upb_MiniDescriptor_EncodeMessage(const upb_MessageDef* m, - upb_Arena* a); +bool _upb_MiniDescriptor_EncodeField(const upb_FieldDef* f, upb_Arena* a, + upb_StringView* out); #ifdef __cplusplus } /* extern "C" */ diff --git a/upbc/code_generator_request.c b/upbc/code_generator_request.c index ce6227d5a1..e3eca5a4c3 100644 --- a/upbc/code_generator_request.c +++ b/upbc/code_generator_request.c @@ -71,9 +71,9 @@ static void upbc_State_Init(upbc_State* s) { if (!s->out) upbc_Error(s, __func__, "could not allocate request"); } -static void upbc_State_Emit(upbc_State* s, const char* name, const char* data) { +static void upbc_State_Emit(upbc_State* s, const char* name, + upb_StringView encoding) { const upb_StringView key = upb_StringView_FromString(name); - const upb_StringView encoding = upb_StringView_FromString(data); bool ok = upbc_CodeGeneratorRequest_mini_descriptors_set(s->out, key, encoding, s->arena); if (!ok) upbc_Error(s, __func__, "could not set mini descriptor in map"); @@ -85,15 +85,17 @@ static void upbc_State_Emit(upbc_State* s, const char* name, const char* data) { static void upbc_Scrape_Message(upbc_State*, const upb_MessageDef*); static void upbc_Scrape_Enum(upbc_State* s, const upb_EnumDef* e) { - const char* desc = upb_MiniDescriptor_EncodeEnum(e, s->arena); - if (!desc) upbc_Error(s, __func__, "could not encode enum"); + upb_StringView desc; + bool ok = upb_MiniDescriptor_EncodeEnum(e, s->arena, &desc); + if (!ok) upbc_Error(s, __func__, "could not encode enum"); upbc_State_Emit(s, upb_EnumDef_FullName(e), desc); } static void upbc_Scrape_Extension(upbc_State* s, const upb_FieldDef* f) { - const char* desc = upb_MiniDescriptor_EncodeField(f, s->arena); - if (!desc) upbc_Error(s, __func__, "could not encode extension"); + upb_StringView desc; + bool ok = upb_MiniDescriptor_EncodeField(f, s->arena, &desc); + if (!ok) upbc_Error(s, __func__, "could not encode extension"); upbc_State_Emit(s, upb_FieldDef_FullName(f), desc); } @@ -170,8 +172,9 @@ static void upbc_Scrape_NestedMessages(upbc_State* s, const upb_MessageDef* m) { } static void upbc_Scrape_Message(upbc_State* s, const upb_MessageDef* m) { - const char* desc = upb_MiniDescriptor_EncodeMessage(m, s->arena); - if (!desc) upbc_Error(s, __func__, "could not encode message"); + upb_StringView desc; + bool ok = upb_MiniDescriptor_EncodeMessage(m, s->arena, &desc); + if (!ok) upbc_Error(s, __func__, "could not encode message"); upbc_State_Emit(s, upb_MessageDef_FullName(m), desc);