pull the mini descriptor encoders into their proper .c files

Performance neutral but it simplifies the code, shrinks the public surface,
and makes logical sense

PiperOrigin-RevId: 478038589
pull/13171/head
Eric Salo 2 years ago committed by Copybara-Service
parent ce3a28f75c
commit b8bec58e01
  1. 4
      BUILD
  2. 53
      upb/reflection/desc_state.c
  3. 34
      upb/reflection/desc_state.h
  4. 45
      upb/reflection/enum_def.c
  5. 7
      upb/reflection/enum_def.h
  6. 28
      upb/reflection/field_def.c
  7. 6
      upb/reflection/field_def.h
  8. 55
      upb/reflection/message_def.c
  9. 8
      upb/reflection/message_def.h
  10. 202
      upb/reflection/mini_descriptor_encode.c
  11. 7
      upbc/code_generator_request.c

@ -399,6 +399,8 @@ cc_library(
"upb/reflection/def_pool.h",
"upb/reflection/def_type.c",
"upb/reflection/def_type.h",
"upb/reflection/desc_state.c",
"upb/reflection/desc_state.h",
"upb/reflection/enum_def.c",
"upb/reflection/enum_def.h",
"upb/reflection/enum_value_def.c",
@ -414,7 +416,6 @@ cc_library(
"upb/reflection/message_def.h",
"upb/reflection/method_def.c",
"upb/reflection/method_def.h",
"upb/reflection/mini_descriptor_encode.c",
"upb/reflection/oneof_def.c",
"upb/reflection/oneof_def.h",
"upb/reflection/service_def.c",
@ -429,7 +430,6 @@ cc_library(
"upb/reflection/def.hpp",
"upb/reflection/message.h",
"upb/reflection/message.hpp",
"upb/reflection/mini_descriptor_encode.h",
],
copts = UPB_DEFAULT_COPTS,
visibility = ["//visibility:public"],

@ -0,0 +1,53 @@
/*
* Copyright (c) 2009-2022, Google LLC
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Google LLC nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "upb/reflection/desc_state.h"
// Must be last.
#include "upb/port_def.inc"
bool _upb_DescState_Grow(upb_DescState* d, upb_Arena* a) {
const size_t oldbufsize = d->bufsize;
const int used = d->ptr - d->buf;
if (!d->buf) {
d->buf = upb_Arena_Malloc(a, d->bufsize);
if (!d->buf) return false;
d->ptr = d->buf;
d->e.end = d->buf + d->bufsize;
}
if (oldbufsize - used < kUpb_MtDataEncoder_MinSize) {
d->bufsize *= 2;
d->buf = upb_Arena_Realloc(a, d->buf, oldbufsize, d->bufsize);
if (!d->buf) return false;
d->ptr = d->buf + used;
d->e.end = d->buf + d->bufsize;
}
return true;
}

@ -25,30 +25,34 @@
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef UPB_REFLECTION_MINI_DESCRIPTOR_ENCODE_H_
#define UPB_REFLECTION_MINI_DESCRIPTOR_ENCODE_H_
#ifndef UPB_REFLECTION_DESC_STATE_H_
#define UPB_REFLECTION_DESC_STATE_H_
#include "upb/reflection/common.h"
#include "upb/string_view.h"
#include "upb/mini_table.h"
// Must be last.
#include "upb/port_def.inc"
// Manages the storage for mini descriptor strings as they are being encoded.
// TODO(b/234740652): Move some of this state directly into the encoder, maybe.
typedef struct {
upb_MtDataEncoder e;
size_t bufsize;
char* buf;
char* ptr;
} upb_DescState;
#ifdef __cplusplus
extern "C" {
#endif
// 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 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);
UPB_INLINE void _upb_DescState_Init(upb_DescState* d) {
d->bufsize = kUpb_MtDataEncoder_MinSize * 2;
d->buf = NULL;
d->ptr = NULL;
}
// 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);
bool _upb_DescState_Grow(upb_DescState* d, upb_Arena* a);
#ifdef __cplusplus
} /* extern "C" */
@ -56,4 +60,4 @@ bool upb_MiniDescriptor_EncodeMessage(const upb_MessageDef* m, upb_Arena* a,
#include "upb/port_undef.inc"
#endif /* UPB_REFLECTION_MINI_DESCRIPTOR_ENCODE_H_ */
#endif /* UPB_REFLECTION_DESC_STATE_H_ */

@ -32,10 +32,10 @@
#include "upb/mini_table.h"
#include "upb/reflection/def_builder.h"
#include "upb/reflection/def_type.h"
#include "upb/reflection/desc_state.h"
#include "upb/reflection/enum_value_def.h"
#include "upb/reflection/file_def.h"
#include "upb/reflection/message_def.h"
#include "upb/reflection/mini_descriptor_encode.h"
// Must be last.
#include "upb/port_def.inc"
@ -85,8 +85,6 @@ bool _upb_EnumDef_Insert(upb_EnumDef* e, upb_EnumValueDef* v, upb_Arena* a) {
return true;
}
bool _upb_EnumDef_IsSorted(const upb_EnumDef* e) { return e->is_sorted; }
const google_protobuf_EnumOptions* upb_EnumDef_Options(const upb_EnumDef* e) {
return e->opts;
}
@ -145,10 +143,49 @@ const upb_EnumValueDef* upb_EnumDef_Value(const upb_EnumDef* e, int i) {
return _upb_EnumValueDef_At(e->values, i);
}
bool upb_EnumDef_MiniDescriptorEncode(const upb_EnumDef* e, upb_Arena* a,
upb_StringView* out) {
upb_DescState s;
_upb_DescState_Init(&s);
const upb_EnumValueDef** sorted = NULL;
if (!e->is_sorted) {
sorted = _upb_EnumValueDefs_Sorted(e->values, e->value_count, a);
if (!sorted) return false;
}
upb_MtDataEncoder_StartEnum(&s.e);
// Duplicate values are allowed but we only encode each value once.
uint32_t previous = 0;
for (size_t i = 0; i < e->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 false;
s.ptr = upb_MtDataEncoder_PutEnumValue(&s.e, s.ptr, current);
previous = current;
}
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';
out->data = s.buf;
out->size = s.ptr - s.buf;
return true;
}
static upb_MiniTable_Enum* create_enumlayout(upb_DefBuilder* ctx,
const upb_EnumDef* e) {
upb_StringView sv;
bool ok = upb_MiniDescriptor_EncodeEnum(e, ctx->tmp_arena, &sv);
bool ok = upb_EnumDef_MiniDescriptorEncode(e, ctx->tmp_arena, &sv);
if (!ok) _upb_DefBuilder_Errf(ctx, "OOM while building enum MiniDescriptor");
upb_Status status;

@ -31,6 +31,7 @@
#define UPB_REFLECTION_ENUM_DEF_H_
#include "upb/reflection/common.h"
#include "upb/string_view.h"
// Must be last.
#include "upb/port_def.inc"
@ -51,6 +52,11 @@ const upb_EnumValueDef* upb_EnumDef_FindValueByNumber(const upb_EnumDef* e,
int32_t num);
const char* upb_EnumDef_FullName(const upb_EnumDef* e);
bool upb_EnumDef_HasOptions(const upb_EnumDef* e);
// Creates a mini descriptor string for an enum, returns true on success.
bool upb_EnumDef_MiniDescriptorEncode(const upb_EnumDef* e, upb_Arena* a,
upb_StringView* out);
const char* upb_EnumDef_Name(const upb_EnumDef* e);
const google_protobuf_EnumOptions* upb_EnumDef_Options(const upb_EnumDef* e);
const upb_EnumValueDef* upb_EnumDef_Value(const upb_EnumDef* e, int i);
@ -60,7 +66,6 @@ int upb_EnumDef_ValueCount(const upb_EnumDef* e);
upb_EnumDef* _upb_EnumDef_At(const upb_EnumDef* e, int i);
bool _upb_EnumDef_Insert(upb_EnumDef* e, upb_EnumValueDef* v, upb_Arena* a);
bool _upb_EnumDef_IsSorted(const upb_EnumDef* e);
const upb_MiniTable_Enum* _upb_EnumDef_MiniTable(const upb_EnumDef* e);
// Allocate and initialize an array of |n| enum defs.

@ -34,12 +34,12 @@
#include "upb/reflection/def_builder.h"
#include "upb/reflection/def_pool.h"
#include "upb/reflection/def_type.h"
#include "upb/reflection/desc_state.h"
#include "upb/reflection/enum_def.h"
#include "upb/reflection/enum_value_def.h"
#include "upb/reflection/extension_range.h"
#include "upb/reflection/file_def.h"
#include "upb/reflection/message_def.h"
#include "upb/reflection/mini_descriptor_encode.h"
#include "upb/reflection/oneof_def.h"
// Must be last.
@ -817,6 +817,30 @@ const upb_FieldDef** _upb_FieldDefs_Sorted(const upb_FieldDef* f, int n,
return (const upb_FieldDef**)out;
}
bool upb_FieldDef_MiniDescriptorEncode(const upb_FieldDef* f, upb_Arena* a,
upb_StringView* out) {
UPB_ASSERT(f->is_extension_);
upb_DescState s;
_upb_DescState_Init(&s);
if (!_upb_DescState_Grow(&s, a)) return false;
s.ptr = upb_MtDataEncoder_StartMessage(&s.e, s.ptr, 0);
const int number = upb_FieldDef_Number(f);
const uint64_t modifiers = _upb_FieldDef_Modifiers(f);
if (!_upb_DescState_Grow(&s, a)) return false;
s.ptr = upb_MtDataEncoder_PutField(&s.e, s.ptr, f->type_, number, modifiers);
if (!_upb_DescState_Grow(&s, a)) return false;
*s.ptr = '\0';
out->data = s.buf;
out->size = s.ptr - s.buf;
return true;
}
static void resolve_extension(upb_DefBuilder* ctx, const char* prefix,
upb_FieldDef* f,
const google_protobuf_FieldDescriptorProto* field_proto) {
@ -843,7 +867,7 @@ static void resolve_extension(upb_DefBuilder* ctx, const char* prefix,
UPB_ASSERT(upb_FieldDef_Number(f) == ext->field.number);
} else {
upb_StringView desc;
if (!upb_MiniDescriptor_EncodeField(f, ctx->tmp_arena, &desc)) {
if (!upb_FieldDef_MiniDescriptorEncode(f, ctx->tmp_arena, &desc)) {
_upb_DefBuilder_OomErr(ctx);
}

@ -31,6 +31,7 @@
#define UPB_REFLECTION_FIELD_DEF_H_
#include "upb/reflection/common.h"
#include "upb/string_view.h"
// Must be last.
#include "upb/port_def.inc"
@ -68,6 +69,11 @@ bool upb_FieldDef_IsSubMessage(const upb_FieldDef* f);
const char* upb_FieldDef_JsonName(const upb_FieldDef* f);
upb_Label upb_FieldDef_Label(const upb_FieldDef* f);
const upb_MessageDef* upb_FieldDef_MessageSubDef(const upb_FieldDef* f);
// Creates a mini descriptor string for a field, returns true on success.
bool upb_FieldDef_MiniDescriptorEncode(const upb_FieldDef* f, upb_Arena* a,
upb_StringView* out);
const upb_MiniTable_Field* upb_FieldDef_MiniTable(const upb_FieldDef* f);
const char* upb_FieldDef_Name(const upb_FieldDef* f);
uint32_t upb_FieldDef_Number(const upb_FieldDef* f);

@ -30,11 +30,11 @@
#include "upb/mini_table.h"
#include "upb/reflection/def_builder.h"
#include "upb/reflection/def_type.h"
#include "upb/reflection/desc_state.h"
#include "upb/reflection/enum_def.h"
#include "upb/reflection/extension_range.h"
#include "upb/reflection/field_def.h"
#include "upb/reflection/file_def.h"
#include "upb/reflection/mini_descriptor_encode.h"
#include "upb/reflection/oneof_def.h"
// Must be last.
@ -132,8 +132,6 @@ bool _upb_MessageDef_IsValidExtensionNumber(const upb_MessageDef* m, int n) {
return false;
}
bool _upb_MessageDef_IsSorted(const upb_MessageDef* m) { return m->is_sorted; }
const google_protobuf_MessageOptions* upb_MessageDef_Options(
const upb_MessageDef* m) {
return m->opts;
@ -344,7 +342,7 @@ static upb_MiniTable* _upb_MessageDef_MakeMiniTable(upb_DefBuilder* ctx,
}
upb_StringView desc;
bool ok = upb_MiniDescriptor_EncodeMessage(m, ctx->tmp_arena, &desc);
bool ok = upb_MessageDef_MiniDescriptorEncode(m, ctx->tmp_arena, &desc);
if (!ok) _upb_DefBuilder_OomErr(ctx);
void** scratch_data = _upb_DefPool_ScratchData(ctx->symtab);
@ -458,7 +456,7 @@ void _upb_MessageDef_LinkMiniTable(upb_DefBuilder* ctx,
}
}
uint64_t _upb_MessageDef_Modifiers(const upb_MessageDef* m) {
static uint64_t _upb_MessageDef_Modifiers(const upb_MessageDef* m) {
uint64_t out = 0;
if (upb_FileDef_Syntax(m->file) == kUpb_Syntax_Proto3) {
out |= kUpb_MessageModifier_ValidateUtf8;
@ -470,6 +468,53 @@ uint64_t _upb_MessageDef_Modifiers(const upb_MessageDef* m) {
return out;
}
bool upb_MessageDef_MiniDescriptorEncode(const upb_MessageDef* m, upb_Arena* a,
upb_StringView* out) {
upb_DescState s;
_upb_DescState_Init(&s);
const upb_FieldDef** sorted = NULL;
if (!m->is_sorted) {
sorted = _upb_FieldDefs_Sorted(m->fields, m->field_count, a);
if (!sorted) return false;
}
if (!_upb_DescState_Grow(&s, a)) return false;
s.ptr =
upb_MtDataEncoder_StartMessage(&s.e, s.ptr, _upb_MessageDef_Modifiers(m));
for (int i = 0; i < m->field_count; i++) {
const upb_FieldDef* f = sorted ? sorted[i] : upb_MessageDef_Field(m, i);
const upb_FieldType type = upb_FieldDef_Type(f);
const int number = upb_FieldDef_Number(f);
const uint64_t modifiers = _upb_FieldDef_Modifiers(f);
if (!_upb_DescState_Grow(&s, a)) return false;
s.ptr = upb_MtDataEncoder_PutField(&s.e, s.ptr, type, number, modifiers);
}
for (int i = 0; i < m->oneof_count; i++) {
if (!_upb_DescState_Grow(&s, a)) return false;
s.ptr = upb_MtDataEncoder_StartOneof(&s.e, s.ptr);
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 int number = upb_FieldDef_Number(upb_OneofDef_Field(o, j));
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 false;
*s.ptr = '\0';
out->data = s.buf;
out->size = s.ptr - s.buf;
return true;
}
static void create_msgdef(upb_DefBuilder* ctx, const char* prefix,
const google_protobuf_DescriptorProto* msg_proto,
const upb_MessageDef* containing_type,

@ -31,6 +31,7 @@
#define UPB_REFLECTION_MESSAGE_DEF_H_
#include "upb/reflection/common.h"
#include "upb/string_view.h"
// Must be last.
#include "upb/port_def.inc"
@ -129,6 +130,11 @@ const char* upb_MessageDef_FullName(const upb_MessageDef* m);
bool upb_MessageDef_HasOptions(const upb_MessageDef* m);
bool upb_MessageDef_IsMapEntry(const upb_MessageDef* m);
bool upb_MessageDef_IsMessageSet(const upb_MessageDef* m);
// Creates a mini descriptor string for a message, returns true on success.
bool upb_MessageDef_MiniDescriptorEncode(const upb_MessageDef* m, upb_Arena* a,
upb_StringView* out);
const upb_MiniTable* upb_MessageDef_MiniTable(const upb_MessageDef* m);
const char* upb_MessageDef_Name(const upb_MessageDef* m);
@ -157,11 +163,9 @@ bool _upb_MessageDef_Insert(upb_MessageDef* m, const char* name, size_t size,
upb_value v, upb_Arena* a);
void _upb_MessageDef_InsertField(upb_DefBuilder* ctx, upb_MessageDef* m,
const upb_FieldDef* f);
bool _upb_MessageDef_IsSorted(const upb_MessageDef* m);
bool _upb_MessageDef_IsValidExtensionNumber(const upb_MessageDef* m, int n);
void _upb_MessageDef_LinkMiniTable(upb_DefBuilder* ctx,
const upb_MessageDef* m);
uint64_t _upb_MessageDef_Modifiers(const upb_MessageDef* m);
void _upb_MessageDef_Resolve(upb_DefBuilder* ctx, upb_MessageDef* m);
// Allocate and initialize an array of |n| message defs.

@ -1,202 +0,0 @@
/*
* Copyright (c) 2009-2022, Google LLC
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of Google LLC nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "upb/reflection/mini_descriptor_encode.h"
#include "upb/mini_table.h"
#include "upb/reflection/def_builder.h"
#include "upb/reflection/def_type.h"
#include "upb/reflection/enum_def.h"
#include "upb/reflection/enum_value_def.h"
#include "upb/reflection/field_def.h"
#include "upb/reflection/file_def.h"
#include "upb/reflection/message_def.h"
#include "upb/reflection/oneof_def.h"
// Must be last.
#include "upb/port_def.inc"
/* DescState ******************************************************************/
// Manages the storage for mini descriptor strings as they are being encoded.
// TODO(b/234740652): Move some of this state directly into the encoder, maybe.
typedef struct {
upb_MtDataEncoder e;
size_t bufsize;
char* buf;
char* ptr;
} DescState;
static void upb_DescState_Init(DescState* d) {
d->bufsize = kUpb_MtDataEncoder_MinSize * 2;
d->buf = NULL;
d->ptr = NULL;
}
static bool upb_DescState_Grow(DescState* d, upb_Arena* a) {
const size_t oldbufsize = d->bufsize;
const int used = d->ptr - d->buf;
if (!d->buf) {
d->buf = upb_Arena_Malloc(a, d->bufsize);
if (!d->buf) return false;
d->ptr = d->buf;
d->e.end = d->buf + d->bufsize;
}
if (oldbufsize - used < kUpb_MtDataEncoder_MinSize) {
d->bufsize *= 2;
d->buf = upb_Arena_Realloc(a, d->buf, oldbufsize, d->bufsize);
if (!d->buf) return false;
d->ptr = d->buf + used;
d->e.end = d->buf + d->bufsize;
}
return true;
}
/******************************************************************************/
bool upb_MiniDescriptor_EncodeEnum(const upb_EnumDef* e, upb_Arena* a,
upb_StringView* out) {
DescState s;
upb_DescState_Init(&s);
const upb_EnumValueDef** sorted = NULL;
if (!_upb_EnumDef_IsSorted(e)) {
sorted = _upb_EnumValueDefs_Sorted(upb_EnumDef_Value(e, 0),
upb_EnumDef_ValueCount(e), a);
if (!sorted) return false;
}
upb_MtDataEncoder_StartEnum(&s.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 false;
s.ptr = upb_MtDataEncoder_PutEnumValue(&s.e, s.ptr, current);
previous = current;
}
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';
out->data = s.buf;
out->size = s.ptr - s.buf;
return true;
}
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 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_FieldDef_Modifiers(f);
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 false;
*s.ptr = '\0';
out->data = s.buf;
out->size = s.ptr - s.buf;
return true;
}
// If the field numbers happen to be defined in ascending order then |sorted|
// should be NULL. Otherwise it must point to an array containing pointers to
// the field defs in sorted order.
bool upb_MiniDescriptor_EncodeMessage(const upb_MessageDef* m, upb_Arena* a,
upb_StringView* out) {
DescState s;
upb_DescState_Init(&s);
const upb_FieldDef** sorted = NULL;
if (!_upb_MessageDef_IsSorted(m)) {
sorted = _upb_FieldDefs_Sorted(upb_MessageDef_Field(m, 0),
upb_MessageDef_FieldCount(m), a);
if (!sorted) return false;
}
if (!upb_DescState_Grow(&s, a)) return false;
s.ptr =
upb_MtDataEncoder_StartMessage(&s.e, s.ptr, _upb_MessageDef_Modifiers(m));
const int field_count = upb_MessageDef_FieldCount(m);
for (int i = 0; i < field_count; i++) {
const upb_FieldDef* f = sorted ? sorted[i] : upb_MessageDef_Field(m, i);
const upb_FieldType type = upb_FieldDef_Type(f);
const int number = upb_FieldDef_Number(f);
const uint64_t modifiers = _upb_FieldDef_Modifiers(f);
if (!upb_DescState_Grow(&s, a)) return false;
s.ptr = upb_MtDataEncoder_PutField(&s.e, s.ptr, type, number, modifiers);
}
const int oneof_count = upb_MessageDef_OneofCount(m);
for (int i = 0; i < oneof_count; i++) {
if (!upb_DescState_Grow(&s, a)) return false;
s.ptr = upb_MtDataEncoder_StartOneof(&s.e, s.ptr);
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 int number = upb_FieldDef_Number(upb_OneofDef_Field(o, j));
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 false;
*s.ptr = '\0';
out->data = s.buf;
out->size = s.ptr - s.buf;
return true;
}

@ -33,7 +33,6 @@
#include "google/protobuf/compiler/plugin.upb.h"
#include "upb/mini_table.h"
#include "upb/reflection/def.h"
#include "upb/reflection/mini_descriptor_encode.h"
// Must be last.
#include "upb/port_def.inc"
@ -86,7 +85,7 @@ static void upbc_Scrape_Message(upbc_State*, const upb_MessageDef*);
static void upbc_Scrape_Enum(upbc_State* s, const upb_EnumDef* e) {
upb_StringView desc;
bool ok = upb_MiniDescriptor_EncodeEnum(e, s->arena, &desc);
bool ok = upb_EnumDef_MiniDescriptorEncode(e, s->arena, &desc);
if (!ok) upbc_Error(s, __func__, "could not encode enum");
upbc_State_Emit(s, upb_EnumDef_FullName(e), desc);
@ -94,7 +93,7 @@ static void upbc_Scrape_Enum(upbc_State* s, const upb_EnumDef* e) {
static void upbc_Scrape_Extension(upbc_State* s, const upb_FieldDef* f) {
upb_StringView desc;
bool ok = upb_MiniDescriptor_EncodeField(f, s->arena, &desc);
bool ok = upb_FieldDef_MiniDescriptorEncode(f, s->arena, &desc);
if (!ok) upbc_Error(s, __func__, "could not encode extension");
upbc_State_Emit(s, upb_FieldDef_FullName(f), desc);
@ -173,7 +172,7 @@ static void upbc_Scrape_NestedMessages(upbc_State* s, const upb_MessageDef* m) {
static void upbc_Scrape_Message(upbc_State* s, const upb_MessageDef* m) {
upb_StringView desc;
bool ok = upb_MiniDescriptor_EncodeMessage(m, s->arena, &desc);
bool ok = upb_MessageDef_MiniDescriptorEncode(m, s->arena, &desc);
if (!ok) upbc_Error(s, __func__, "could not encode message");
upbc_State_Emit(s, upb_MessageDef_FullName(m), desc);

Loading…
Cancel
Save